// -------------------------------------------------
// Math utilities
// -------------------------------------------------
const PI = Math.PI;
const TWOPI = 2. * PI;
const PI_2 = .5 * PI;
function sqr(b) { return Math.pow(b, 2) }
function log10(b) { return Math.log(b) / Math.LN10 }
function toRad(b) { return PI / 180 * b }
function toDeg(b) { return 180 / PI * b }
function sind(b) { return Math.sin(toRad(b)) }
function cosd(b) { return Math.cos(toRad(b)) }
function tand(b) { return Math.tan(toRad(b)) }
function asind(b) { return toDeg(Math.asin(b)) }
function acosd(b) { return toDeg(Math.acos(b)) }
function trunc(b) { return 0 < b ? Math.floor(b) : Math.ceil(b) }
function sinh(b) { return (Math.pow(Math.E, b) - Math.pow(Math.E, -b)) / 2 }
function cosh(b) { return (Math.pow(Math.E, b) + Math.pow(Math.E, -b)) / 2 }
// -------------------------------------------------
// Solar utilities
// -------------------------------------------------
function Declination(b) {
return 23.45 * Math.sin(toRad(360 / 365 * (b - 81)));
}
function sunRiseSet(b, c, d) {
b = -1 * sind(b) * sind(c) / (cosd(b) * cosd(c));
b = acosd(b) / 15;
return [12 - b - d / 60, 12 + b - d / 60];
}
function airMassSimple(b) {
return 1 / cosd(b);
}
function airMassIntensity(b) {
return 1.353 * Math.pow(.7, Math.pow(b, .678));
}
function elevation(b, c, d) {
return asind(sind(b) * sind(c) + cosd(b) * cosd(c) * cosd(d));
}
// -------------------------------------------------
// Calculating solar radiation on tilted surface
// -------------------------------------------------
function solarRadiationOnTiltedSurface(latitude, arrayTilt) {
let sIncidentTotal = 0.;
let sHorizontalTotal = 0.;
let sModuleTotal = 0.;
// sum over days in a year
for (let i = 0; i < 365; i++) {
let day = i;
let dec = Declination(day);
let sunrise, sunset;
[sunrise, sunset] = sunRiseSet(latitude * 0.99, dec, 0);
sunrise *= 1;
sunrise = (isNaN(sunrise)) ? 0.1 : sunrise;
sunset = (isNaN(sunset)) ? 23.9 : sunset;
// sum over hours in the day
let Stot = 0.0;
for (let t = sunrise; t <= sunset; t++) {
let hourAngle = 15.0 * (t - 12.0);
let elev = elevation(dec, latitude, hourAngle);
let am = airMassSimple(90 - elev);
let insolation = airMassIntensity(am);
insolation = (isNaN(insolation)) ? 0 : insolation;
Stot += insolation;
}
let el;
if (latitude < 0) { el = 90.0 + latitude - dec; }
else { el = 90.0 - latitude + dec; }
// compute solar radiations
let incidentPerDay = Stot;
let horizontalPerDay = Stot * sind(el);
let modulePerDay = Stot * sind(arrayTilt + el);
sIncidentTotal += incidentPerDay;
sHorizontalTotal += horizontalPerDay;
sModuleTotal += modulePerDay;
}
let s = new Object();
s.IncidentTotal = sIncidentTotal;
s.HorizontalTotal = sHorizontalTotal;
s.ModuleTotal = sModuleTotal;
return s;
}
// -------------------------------------------------
// Inputs
// -------------------------------------------------
let springerLat = 37.3713; // latitude of school
let springerLong = -122.0952 // longitude of school
let beta = 10.; // tilt-angle of solar panel
let sole = 1380.; // Solar output is 1367 W / m^2
let s = solarRadiationOnTiltedSurface(springerLat, beta);
console.log(s.IncidentTotal + " -- " + s.ModuleTotal);