0

我正在尝试实施计算倾斜太阳能电池板上入射的全球辐射所需的公式。

我使用的公式是在以下研究论文中找到的:

--> ipac.kacst.edu.sa/eDoc/2010/191048_1.pdf

这是注释的 JavaScript 代码:

var config = require('./configuration.json'),
    pi = Math.PI;

function solar_efficiency(angle, day) {
    var R_mD,  // average sun-earth distance (m)
        a,     // semi-major axis (km)
        e,     // oval orbit eccentricity (km)
        theta, // angle with the perihelion
        n,     // current nth day of the year (int)
        R_D,   // actual sun-earth distance (m)
        I_o;   // extraterrestrial radiation (indice)

    R_mD = config.avg_sun_earth_dist;
    a = config.semi_major_axis;
    e = config.eccentricity;
    n = day;
    theta = n * 365.25 / 360;
    R_D = a * (1 - e * e) / (1 + e * Math.cos(theta));
    I_o = 1367 * Math.pow(R_mD / R_D, 2);

    var axis,  // angle of the earth's axis
        D;     // sun declination (radian)

    axis = config.earth_axis;
    D = ((axis * pi) / 180) * Math.sin(((2 * pi) * (284 + n)) / 365);

    var Eq_t;  // solar time correction (float)

    if((1 <= n) && (n <= 106)) {
        Eq_t = -14.2 * Math.sin((pi * (n + 7)) / 111);
    }
    else if((107 <= n) && (n <= 166)) {
        Eq_t = 4.0 * Math.sin((pi * (n - 106)) / 59);
    }
    else if((167 <= n) && (n <= 246)) {
        Eq_t = -6.5 * Math.sin((pi * (n - 166)) / 80);
    }
    else if((247 <= n) && (n <= 365)) {
        Eq_t = 16.4 * Math.sin((pi * (n - 247)) / 113);
    }

    var Long_sm,    // longitude of the standard meridian (longitude)
        Long_local, // longitude of the panels (longitude)
        T_local,    // local time (h)
        T_solar;    // solar time (h)

    Long_sm = config.std_meridian_long;
    Long_local = config.current_longitutde;
    T_local = config.local_time;
    T_solar = T_local + (Eq_t / 60) + ((Long_sm - Long_local) / 15);

    var W; // hour angle (radian)

    W = pi * ((12 - T_solar) / 12);

    var Lat_local,  // latitude of the panels (latitude)
        W_sr,       // sunrise hour angle (°)
        W_ss;       // sunset hour angle (°)

    Lat_local = config.current_latitude;
    W_sr = W_ss = Math.acos(-1 * Math.tan(Lat_local) * Math.tan(D));

    var alpha, // angle between solar panel and horizontal (°)        -FIND!!!
        R_b;   // ratio of avg. beam radiation on horiz. / inclined surface

    alpha = angle; // /!\ TESTING ONLY /!\

    var num_1 = Math.cos(Lat_local - alpha) * Math.cos(D) * Math.sin(W_ss);
    var num_2 = W_ss * Math.sin(Lat_local - alpha) * Math.sin(D);
    var det_1 = Math.cos(Lat_local) * Math.cos(D) * Math.sin(W_ss);
    var det_2 = W_ss * Math.sin(Lat_local) * Math.sin(D);

    R_b = (num_1 + num_2) / (det_1 + det_2);  // in the northern hemisphere

    var H_g, // global radiation on horizontal surface (W h/m^2/day)  ---DB!!!
        H_d, // diffuse radiation on horizontal surface (W h/m^2/day) ---DB!!!
        H_B; // beam radiation on inclined surface (W h/m^2/day)

    H_g = 700;
    H_d = 500;
    H_B = (H_g - H_d) / R_b;

    var R_d; // ratio of avg. daily diffuse radiation tilted / horiz. surface

    R_d = (3 + Math.cos(2 * alpha)) / 2; // isotropic Badesco model

    var H_D; // sky-diffuse radiation on inclined surface (W h/m^2/day)

    H_D = R_d * H_d;

    var p,   // albedo std. = 0.2 (soil = 0.17, grass = 0.25, concrete = 0.55)
        H_R; // ground reflected radiation on inclined surface (W h/m^2/day)

    p = config.ground_albedo;
    H_R = H_g * p * ((1 - Math.cos(alpha)) / 2);

    var H_T; // daily global radiation on a tilted surface (W h/m^2/day)

    H_T = H_B + H_D + H_R;
    return H_T;
}

var results = {}, current_day;
for(var i = 0; i < 365; i++) {
    current_day = [];
    for(var k = 0; k <= 90; k++) {
        current_day.push([k, solar_efficiency(k, i)]);
    }
    current_day.sort(function(a, b) { return b[1] - a[1]; });
    current_day.length = 1;
    results[i] = current_day[0];
}

console.log(results);

纬度和经度等配置位于 JSON 文件中。以下是我正在测试程序的值:

{
    "avg_sun_earth_dist" : 149597870.7,
    "earth_axis" : 23.45,

    "eccentricity" : 0.0167,
    "semi_major_axis" : 149598261,

    "local_time" : 12,

    "std_meridian_long" : 0,
    "current_longitude" : 2.294351,
    "current_latitude" : 48.858844,

    "ground_albedo" : 0.2
}

如果你稍微改变纬度,你会看到你要么得到 NaN,要么值稳定,但突然对于“i”的某些值就猛增了。

问题似乎是这一行:

W_sr = W_ss = Math.acos(-1 * Math.tan(Lat_local) * Math.tan(D));

我不确定输入数据是否错误从而导致程序崩溃,或者我是否只是错误地执行了公式。

4

1 回答 1

0

使用那个floats不适合这样的计算。你总是会以错误告终。BigDecimal在每种语言中都使用了此类算术

于 2013-02-16T03:17:56.283 回答