地外水平/斜面的太阳理论辐照度计算及其python实现

引入

最近项目需要计算地外水平/斜面太阳理论辐照度,为此搜集了资料,并在python中进行了实现,现将其分享于此。

水平理论辐照度

地球与太阳之间的相对运动,即地球自转与公转,会对理论辐照度产生影响。在忽略极移和地轴进动微小影响的条件下地球大气层上界单位面积、单位时间接收的太阳辐射与日地距离的平方成反比。地球自转对应太阳时角和太阳高度角的变化,公转对应太阳赤纬和日地距离的变化。

水平太阳辐照度的计算公式为:

水平太阳辐照度


在计算某地太阳福射时采用的是当地的真太阳时,所以需要根据当地的区时和经度来求取对应的真太阳时和太阳时角,此求取过程分步完成:①根据当地经度对已知的当地区时进行修正得到当地的地方时;②根据真太阳时和平太阳时之间的时差对该地方时进行修正得到当地的真太阳时;③根据当地的真太阳时计算得到当地区时对应的太阳时角。

按照上式,可计算得到指定地点、指定日期的水平地外辐照度理论值,并绘制对应的地外辐照度理论值曲线。

任意斜面的太阳辐照度

代码

python代码如下,略长,主要牵扯到真太阳时转换数组的赋值。
代码最后有运行示例。

import pandas as pd
import numpy as np
import math
from datetime import datetime, timedelta


def calculate_sun_time(time_str, latitude, longitude, tilt, azimuth, longitude_time):
    """从datetime类型的时间计算日出日落及白天时间"""
    cur_time = datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')
    day_year = int(datetime.strftime(cur_time, '%j'))  # j是积日

    delta = 23.45 / 180 * math.pi * math.sin(2 * math.pi * (284 + day_year) / 365)  # 计算太阳赤纬(弧度)
    latitude = latitude / 180 * math.pi     # 纬度转换为弧度
    cos_omega = - math.sin(delta) * math.sin(latitude) / (math.cos(delta) * math.cos(latitude))
    omega = math.acos(cos_omega)            # 计算真太阳时时角

    true_time_down = (omega * 180 / math.pi / 15 + 12) * 60   # 计算基于真太阳时的日落时间
    true_time_up = 60 * 24 - true_time_down
    time_sun = (true_time_down - 12 * 60) * 2

    # 计算偏差时间
    bias_time = dif_true_solar_time(day_year).split(':')
    if '-' in bias_time[0]:
        pos_flag = -1
    else:
        pos_flag = 1
    bias_minute = int(bias_time[0])
    bias_second = int(bias_time[1])
    bias = pos_flag * (abs(bias_minute) + bias_second / 60)

    minute_sun_down = true_time_down - bias - 4 * (longitude - longitude_time)
    minute_sun_up = true_time_up - bias - 4 * (longitude - longitude_time)

    return time_sun, minute_sun_up, minute_sun_down


def calculate_irradiance_base(day_year, minute_day, latitude, longitude, tilt, azimuth, longitude_time):
    """
    根据给定的日期与时间,计算当前位置的大气外理论辐照度,只适用于南北回归线之外的情况,假定电站方位角为0
    北纬为正,东经为正
    latitude:电站所在维度
    longitude:电站所在经度
    tilt:电站光伏板安装角度
    azimuth:电站斜面方位角
    longitude_time:电站所采用时区的中心经度
    """
    G_0 = 1368  # 取太阳常数为1368(W/m2)
    k = 1 + 0.034 * (math.cos(2 * math.pi / 365 * day_year))        # 计算日地距离修正系数
    delta = 23.45 / 180 * math.pi * math.sin(2 * math.pi * (284 + day_year) / 365)    # 计算太阳赤纬(弧度)

    # 计算偏差时间
    bias_time = dif_true_solar_time(day_year).split(':')
    if '-' in bias_time[0]:
        pos_flag = -1
    else:
        pos_flag = 1
    bias_minute = int(bias_time[0])
    bias_second = int(bias_time[1])
    bias = pos_flag * (abs(bias_minute) + bias_second / 60)

    true_time = minute_day + 4 * (longitude - longitude_time) + bias     # 计算真太阳时
    omega = (true_time / 60 - 12) * 15 / 180 * math.pi      # 计算太阳时角(弧度)
    latitude = latitude / 180 * math.pi                     # 纬度转换为弧度

    # theta为天顶角
    cos_theta = math.sin(delta)*math.sin(latitude) + math.cos(delta)*math.cos(latitude)*math.cos(omega)
    h = math.pi / 2 - math.acos(cos_theta)  # 太阳高度角
    # 当天顶角cos<=0时,认为无光
    # if cos_theta <= 0:
    #     G = 0
    if tilt != 0:
        tilt = tilt / 180 * math.pi
        azimuth = azimuth / 180 * math.pi
        cos_alpha = (math.sin(h) * math.sin(latitude) - math.sin(delta)) / (math.cos(h) * math.cos(latitude))
        alpha = math.acos(cos_alpha)    # 计算太阳方位角
        # 不用sin的原因是,asin无法分辨alpha大于90°的情况
        # sin_alpha = -math.cos(delta) * math.sin(omega) / math.cos(h)
        # if sin_alpha > 1:
        #     sin_alpha = (math.sin(h) * math.sin(latitude) - math.sin(delta)) / (math.cos(h) * math.cos(latitude))
        # alpha = math.asin(sin_alpha)    # 计算太阳方位角
        if true_time > 60 * 12:         # 使下午的太阳方位角正常
            alpha = -alpha
        # 计算对于斜面的太阳入射角
        cos_i = math.cos(tilt) * math.sin(h) + math.sin(tilt) * math.cos(h) * math.cos(alpha - azimuth)
        G = k * G_0 * cos_i
    else:
        G = k * G_0 * cos_theta
    if G < 0:
        G = 0
    return G


def calculate_irradiance(time_str, latitude, longitude, tilt, azimuth, longitude_time):
    """从datetime类型的时间计算当前大气外理论辐照度"""
    cur_time = datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')

    day_year = int(datetime.strftime(cur_time, '%j'))   # j是积日

    hour = int(datetime.strftime(cur_time, "%H"))
    minute = int(datetime.strftime(cur_time, "%M"))
    minute_day = 60 * hour + minute                     # 计算当前时刻的日分钟数

    return calculate_irradiance_base(day_year, minute_day, latitude, longitude, tilt, azimuth, longitude_time)


def dif_true_solar_time(day_year):
    sun_array = list(range(0, 366))
    # <editor-fold desc="真平太阳时差的赋值">
    sun_array[0] = "-3:9"
    sun_array[1] = "-3:38"
    sun_array[2] = "-4:6"
    sun_array[3] = "-4:33"
    sun_array[4] = "-5:1"
    sun_array[5] = "-5:27"
    sun_array[6] = "-5:54"
    sun_array[7] = "-6:20"
    sun_array[8] = "-6:45"
    sun_array[9] = "-7:10"
    sun_array[10] = "-7:35"
    sun_array[11] = "-7:59"
    sun_array[12] = "-8:22"
    sun_array[13] = "-8:45"
    sun_array[14] = "-9:7"
    sun_array[15] = "-9:28"
    sun_array[16] = "-9:49"
    sun_array[17] = "-10:9"
    sun_array[18] = "-10:28"
    sun_array[19] = "-10:47"
    sun_array[20] = "-11:5"
    sun_array[21] = "-11:22"
    sun_array[22] = "-11:38"
    sun_array[23] = "-11:54"
    sun_array[24] = "-12:8"
    sun_array[25] = "-12:22"
    sun_array[26] = "-12:35"
    sun_array[27] = "-12:59"
    sun_array[28] = "-13:10"
    sun_array[29] = "-13:19"
    sun_array[30] = "-13:37"
    sun_array[31] = "-13:44"
    sun_array[32] = "-13:50"
    sun_array[33] = "-13:56"
    sun_array[34] = "-14:1"
    sun_array[35] = "-14:5"
    sun_array[36] = "-14:9"
    sun_array[37] = "-14:11"
    sun_array[38] = "-14:13"
    sun_array[39] = "-14:14"
    sun_array[40] = "-14:15"
    sun_array[41] = "-14:14"
    sun_array[42] = "-14:13"
    sun_array[43] = "-14:11"
    sun_array[44] = "-14:8"
    sun_array[45] = "-14:5"
    sun_array[46] = "-14:1"
    sun_array[47] = "-13:56"
    sun_array[48] = "-13:51"
    sun_array[49] = "-13:44"
    sun_array[50] = "-13:38"
    sun_array[51] = "-13:30"
    sun_array[52] = "-13:22"
    sun_array[53] = "-13:13"
    sun_array[54] = "-11:4"
    sun_array[55] = "-12:54"
    sun_array[56] = "-12:43"
    sun_array[57] = "-12:32"
    sun_array[58] = "-12:21"
    sun_array[59] = "-12:8"
    sun_array[60] = "-11:56"
    sun_array[61] = "-11:43"
    sun_array[62] = "-11:29"
    sun_array[63] = "-11:15"
    sun_array[64] = "-11:1"
    sun_array[65] = "-10:47"
    sun_array[66] = "-10:32"
    sun_array[67] = "-10:16"
    sun_array[68] = "-10:1"
    sun_array[69] = "-9:45"
    sun_array[70] = "-9:28"
    sun_array[71] = "-9:12"
    sun_array[72] = "-8:55"
    sun_array[73] = "-8:38"
    sun_array[74] = "-8:21"
    sun_array[75] = "-8:4"
    sun_array[76] = "-7:46"
    sun_array[77] = "-7:29"
    sun_array[78] = "-7:11"
    sun_array[79] = "-6:53"
    sun_array[80] = "-6:35"
    sun_array[81] = "-6:17"
    sun_array[82] = "-5:58"
    sun_array[83] = "-5:40"
    sun_array[84] = "-5:22"
    sun_array[85] = "-5:4"
    sun_array[86] = "-4:45"
    sun_array[87] = "-4:27"
    sun_array[88] = "-4:9"
    sun_array[89] = "-3:51"
    sun_array[90] = "-3:33"
    sun_array[91] = "-3:16"
    sun_array[92] = "-2:58"
    sun_array[93] = "-2:41"
    sun_array[94] = "-2:24"
    sun_array[95] = "-2:7"
    sun_array[96] = "-1:50"
    sun_array[97] = "-1:33"
    sun_array[98] = "-1:17"
    sun_array[99] = "-1:1"
    sun_array[100] = "0:46"
    sun_array[101] = "0:30"
    sun_array[102] = "0:16"
    sun_array[103] = "0:1"
    sun_array[104] = "0:13"
    sun_array[105] = "0:27"
    sun_array[106] = "0:41"
    sun_array[107] = "0:54"
    sun_array[108] = "1:6"
    sun_array[109] = "1:19"
    sun_array[110] = "1:31"
    sun_array[111] = "1:42"
    sun_array[112] = "1:53"
    sun_array[113] = "2:4"
    sun_array[114] = "2:14"
    sun_array[115] = "2:23"
    sun_array[116] = "2:33"
    sun_array[117] = "2:41"
    sun_array[118] = "2:49"
    sun_array[119] = "2:57"
    sun_array[120] = "3:4"
    sun_array[121] = "1:10"
    sun_array[122] = "3:16"
    sun_array[123] = "3:21"
    sun_array[124] = "3:26"
    sun_array[125] = "3:30"
    sun_array[126] = "3:37"
    sun_array[127] = "3:36"
    sun_array[128] = "3:39"
    sun_array[129] = "3:40"
    sun_array[130] = "3:42"
    sun_array[131] = "3:42"
    sun_array[132] = "3:42"
    sun_array[133] = "3:42"
    sun_array[134] = "3:41"
    sun_array[135] = "3:39"
    sun_array[136] = "3:37"
    sun_array[137] = "3:34"
    sun_array[138] = "3:31"
    sun_array[139] = "3:27"
    sun_array[140] = "3:23"
    sun_array[141] = "3:18"
    sun_array[142] = "3:13"
    sun_array[143] = "3:7"
    sun_array[144] = "3:1"
    sun_array[145] = "2:54"
    sun_array[146] = "2:47"
    sun_array[147] = "2:39"
    sun_array[148] = "2:31"
    sun_array[149] = "2:22"
    sun_array[150] = "2:13"
    sun_array[151] = "2:4"
    sun_array[152] = "1:54"
    sun_array[153] = "1:44"
    sun_array[154] = "1:34"
    sun_array[155] = "1:23"
    sun_array[156] = "1:12"
    sun_array[157] = "1:0"
    sun_array[158] = "0:48"
    sun_array[159] = "0:36"
    sun_array[160] = "0:24"
    sun_array[161] = "0:12"
    sun_array[162] = "0:1"
    sun_array[163] = "0:14"
    sun_array[164] = "0:39"
    sun_array[165] = "0:52"
    sun_array[166] = "1:5"
    sun_array[167] = "1:18"
    sun_array[168] = "1:31"
    sun_array[169] = "1:45"
    sun_array[170] = "1:57"
    sun_array[171] = "2:10"
    sun_array[172] = "2:23"
    sun_array[173] = "2:36"
    sun_array[174] = "2:48"
    sun_array[175] = "3:1"
    sun_array[176] = "3:13"
    sun_array[177] = "3:25"
    sun_array[178] = "3:37"
    sun_array[179] = "3:49"
    sun_array[180] = "4:0"
    sun_array[181] = "4:11"
    sun_array[182] = "4:22"
    sun_array[183] = "4:33"
    sun_array[184] = "4:43"
    sun_array[185] = "4:53"
    sun_array[186] = "5:2"
    sun_array[187] = "5:11"
    sun_array[188] = "5:20"
    sun_array[189] = "5:28"
    sun_array[190] = "5:36"
    sun_array[191] = "5:43"
    sun_array[192] = "5:50"
    sun_array[193] = "5:56"
    sun_array[194] = "6:2"
    sun_array[195] = "6:8"
    sun_array[196] = "6:12"
    sun_array[197] = "6:16"
    sun_array[198] = "6:20"
    sun_array[199] = "6:23"
    sun_array[200] = "6:25"
    sun_array[201] = "6:27"
    sun_array[202] = "6:29"
    sun_array[203] = "6:29"
    sun_array[204] = "6:29"
    sun_array[205] = "6:29"
    sun_array[206] = "6:28"
    sun_array[207] = "6:26"
    sun_array[208] = "6:24"
    sun_array[209] = "6:21"
    sun_array[210] = "6:17"
    sun_array[211] = "6:13"
    sun_array[212] = "6:8"
    sun_array[213] = "6:3"
    sun_array[214] = "5:57"
    sun_array[215] = "5:51"
    sun_array[216] = "5:44"
    sun_array[217] = "5:36"
    sun_array[218] = "5:28"
    sun_array[219] = "5:19"
    sun_array[220] = "5:10"
    sun_array[221] = "5:0"
    sun_array[222] = "4:50"
    sun_array[223] = "4:39"
    sun_array[224] = "4:27"
    sun_array[225] = "4:15"
    sun_array[226] = "4:2"
    sun_array[227] = "3:49"
    sun_array[228] = "3:36"
    sun_array[229] = "3:21"
    sun_array[230] = "3:7"
    sun_array[231] = "2:51"
    sun_array[232] = "2:36"
    sun_array[233] = "2:20"
    sun_array[234] = "2:3"
    sun_array[235] = "1:47"
    sun_array[236] = "1:29"
    sun_array[237] = "1:12"
    sun_array[238] = "0:54"
    sun_array[239] = "0:35"
    sun_array[240] = "0:17"
    sun_array[241] = "0:2"
    sun_array[242] = "0:21"
    sun_array[243] = "0:41"
    sun_array[244] = "1:0"
    sun_array[245] = "1:20"
    sun_array[246] = "1:40"
    sun_array[247] = "2:1"
    sun_array[248] = "2:21"
    sun_array[249] = "2:42"
    sun_array[250] = "3:3"
    sun_array[251] = "3:3"
    sun_array[252] = "3:24"
    sun_array[253] = "3:45"
    sun_array[254] = "4:6"
    sun_array[255] = "4:27"
    sun_array[256] = "4:48"
    sun_array[257] = "5:10"
    sun_array[258] = "5:31"
    sun_array[259] = "5:53"
    sun_array[260] = "6:14"
    sun_array[261] = "6:35"
    sun_array[262] = "6:57"
    sun_array[263] = "7:18"
    sun_array[264] = "7:39"
    sun_array[265] = "8:0"
    sun_array[266] = "8:21"
    sun_array[267] = "8:42"
    sun_array[268] = "9:2"
    sun_array[269] = "9:22"
    sun_array[270] = "9:42"
    sun_array[271] = "10:2"
    sun_array[272] = "10:21"
    sun_array[273] = "10:40"
    sun_array[274] = "+10:59"
    sun_array[275] = "+11:18"
    sun_array[276] = "+11:36"
    sun_array[277] = "+11:36"
    sun_array[278] = "+11:53"
    sun_array[279] = "+12:11"
    sun_array[280] = "+12:28"
    sun_array[281] = "+12:44"
    sun_array[282] = "+12:60"
    sun_array[283] = "+13:16"
    sun_array[284] = "+13:16"
    sun_array[285] = "+13:31"
    sun_array[286] = "+13:45"
    sun_array[287] = "+13:59"
    sun_array[288] = "+14:13"
    sun_array[289] = "+14:26"
    sun_array[290] = "+14:38"
    sun_array[291] = "+14:50"
    sun_array[292] = "+15:1"
    sun_array[293] = "+15:12"
    sun_array[294] = "+11:21"
    sun_array[295] = "+15:31"
    sun_array[296] = "+15:40"
    sun_array[297] = "+15:48"
    sun_array[298] = "+15:55"
    sun_array[299] = "+16:1"
    sun_array[300] = "+16:7"
    sun_array[301] = "+16:12"
    sun_array[302] = "+16:16"
    sun_array[303] = "+16:20"
    sun_array[304] = "+16:22"
    sun_array[305] = "+16:24"
    sun_array[306] = "+16:25"
    sun_array[307] = "+16:25"
    sun_array[308] = "+16:24"
    sun_array[309] = "+16:23"
    sun_array[310] = "+16:21"
    sun_array[311] = "+16:17"
    sun_array[312] = "+16:13"
    sun_array[313] = "+16:9"
    sun_array[314] = "+16:3"
    sun_array[315] = "+15:56"
    sun_array[316] = "+15:49"
    sun_array[317] = "+15:41"
    sun_array[318] = "+15:32"
    sun_array[319] = "+15:22"
    sun_array[320] = "+15:11"
    sun_array[321] = "+14:60"
    sun_array[322] = "+14:47"
    sun_array[323] = "+14:34"
    sun_array[324] = "+14:20"
    sun_array[325] = "+14:6"
    sun_array[326] = "+13:50"
    sun_array[327] = "+13:34"
    sun_array[328] = "+13:17"
    sun_array[329] = "+12:59"
    sun_array[330] = "+12:40"
    sun_array[331] = "+12:21"
    sun_array[332] = "+12:1"
    sun_array[333] = "+11:40"
    sun_array[334] = "+11:18"
    sun_array[335] = "+10:56"
    sun_array[336] = "+10:33"
    sun_array[337] = "+10:9"
    sun_array[338] = "+9:45"
    sun_array[339] = "+9:21"
    sun_array[340] = "+8:55"
    sun_array[341] = "+8:29"
    sun_array[342] = "+8:3"
    sun_array[343] = "+7:36"
    sun_array[344] = "+7:9"
    sun_array[345] = "+6:42"
    sun_array[346] = "+6:14"
    sun_array[347] = "+5:46"
    sun_array[348] = "+5:17"
    sun_array[349] = "+4:48"
    sun_array[350] = "+4:19"
    sun_array[351] = "+3:50"
    sun_array[352] = "+3:21"
    sun_array[353] = "+2:51"
    sun_array[354] = "+2:22"
    sun_array[355] = "+1:52"
    sun_array[356] = "+1:22"
    sun_array[357] = "+0:52"
    sun_array[358] = "+0:23"
    sun_array[359] = "+0:7"
    sun_array[360] = "+0:37"
    sun_array[361] = "-1:6"
    sun_array[362] = "-1:36"
    sun_array[363] = "-2:5"
    sun_array[364] = "-2:34"
    sun_array[365] = "-3:3"
    # </editor-fold>
    return sun_array[day_year - 1]

# # 函数测试
# # Latitude 39.1319° [°N], Longitude -77.2141° [°E], Elevation 138 m [m])
tilt = 20

pd_data = pd.DataFrame(np.arange(1, 60*24+1, 30), columns=['minute_day'])
pd_data['day_year'] = 142
pd_data['G'] = pd_data.apply(lambda x: calculate_irradiance_base(int(x['day_year']), x['minute_day'], 40, 110, 0, 0, 120), axis=1)
pd_data['tilt_G'] = pd_data.apply(lambda x: calculate_irradiance_base(int(x['day_year']), x['minute_day'], 40, 110, tilt, 0, 120), axis=1)

print(pd_data)

time_str = '2008-06-23 14:35:22'
G = calculate_irradiance(time_str, 30, 122, tilt, 0, 120)
print(G)

[time_sun, minute_sun_up, minute_sun_down] = calculate_sun_time(time_str, 30, 122, tilt, 0, 120)
print(G)

参考:
[1] https://wenku.baidu.com/view/0989752c3169a4517723a3d8.html
[2] https://www.pveducation.org/zh-hans/pvcdrom/%E4%BB%BB%E6%84%8F%E6%9C%9D%E5%90%91%E5%92%8C%E5%80%BE%E6%96%9C%E5%BA%A6
[3] 王飞, 并网型光伏电站发电功率预测方法与系统, 2013, 华北电力大学.

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2022年5月12日
下一篇 2022年5月12日

相关推荐