使用pvlib计算POA时DNI估算模型的技术疑问求助
PVlib辐照度计算疑问解答
背景
拥有7年、采样间隔5分钟的数据集,包含功率值、GHI(水平面总辐照度)、DHI(水平面散射辐照度)、倾斜面总辐照度及倾斜面散射辐照度数据,尝试计算POA(平面阵列辐照度)时遇到三个疑问。
疑问1:计算DNI时使用GHI和DHI、未用倾斜面数据是否正确?
正确。DNI(法向直射辐照度)的定义是垂直于太阳光线方向的辐照度,核心推导逻辑基于水平面辐照的能量平衡公式:GHI = DNI * cos(太阳天顶角) + DHI。因此,用水平面的GHI和DHI估算DNI是完全合理的,倾斜面辐照数据和DNI的直接计算无关,不需要纳入。
疑问2:计算POA时使用倾斜面总辐照度和散射辐照度数据是否正确?
不正确。pvlib.irradiance.get_total_irradiance的设计逻辑是基于水平面辐照数据(GHI/DHI/DNI)推导倾斜面的POA辐照度,而非直接用倾斜面数据作为输入:
- 参数
ghi要求传入水平面总辐照度,而非倾斜面的tilted_ghi - 参数
dhi要求传入水平面散射辐照度,你用pvlib.irradiance.isotropic处理倾斜面散射得到的结果不符合参数要求
另外,如果你手中的Radiation_Global_Tilted数据可靠,这个值本身就是POA总辐照度,无需再调用get_total_irradiance计算;若需补全缺失值或验证数据,应使用水平面辐照数据反向推导POA。
疑问3:Perez模型是否可用于计算DNI?
不能。Perez模型的作用是将水平面散射辐照度分解到倾斜面上,pvlib中pvlib.irradiance.perez的参数明确要求传入DNI作为输入,它根本不是用于估算DNI的工具。
要估算DNI,推荐两种正确方式:
- 基于能量平衡公式直接计算(需处理太阳天顶角接近90度的异常情况):
import math cos_zenith = solar_position['apparent_zenith'].apply(lambda x: max(0.001, math.cos(math.radians(x)))) dni_estimated = (ghi - dhi) / cos_zenith - 使用专门的DNI估算模型(如Erbs模型):
dni_estimated = pvlib.irradiance.erbs(ghi, solar_position['apparent_zenith'], times)['dni']
修正后的完整代码示例
import pandas as pd import pvlib import math # Load the solar irradiance data from the CSV file data = pd.read_csv(r"C:\Users\test\Downloads\70-Site_3-BP-Solar.csv") # Set up the location information for the site latitude = -23.761683875154326 longitude = 133.87495009067854 altitude = 560 tz = 'Australia/Darwin' location = pvlib.location.Location(latitude=latitude, longitude=longitude, altitude=altitude, tz=tz) # Calculate the solar position and air mass for each timestamp in the data times = pd.to_datetime(data['timestamp']).dt.tz_localize(tz) solar_position = location.get_solarposition(times) airmass = location.get_airmass(times)['airmass_absolute'] # 正确估算DNI:基于水平面GHI、DHI和太阳天顶角 ghi = data['Global_Horizontal_Radiation'] dhi = data['Diffuse_Horizontal_Radiation'] zenith = solar_position['apparent_zenith'] # 避免cos(zenith)为0或负数导致的计算异常 cos_zenith = zenith.apply(lambda x: max(0.001, math.cos(math.radians(x)))) dni_estimated = (ghi - dhi) / cos_zenith # 正确计算POA:使用水平面辐照数据作为输入 tilt_angle = 20.0 poa_irradiance = pvlib.irradiance.get_total_irradiance( surface_tilt=tilt_angle, surface_azimuth=0, dni=dni_estimated, ghi=ghi, dhi=dhi, solar_zenith=solar_position['apparent_zenith'], solar_azimuth=solar_position['azimuth'], model='haydavies', albedo=0.2, surface_type='urban' ) # Add the POA data to the DataFrame data['POA'] = poa_irradiance['poa_global'] data.to_csv(r"C:\Users\test\Downloads\POA.csv")
内容的提问来源于stack exchange,提问作者Maysa Sarsour
相关产品推荐
相关产品推荐

