Пример цепочки моделей PVLIB - не доверяйте выходу переменного тока с отслеживанием 1 оси

Я пытаюсь использовать PVLIB для оценки выходной мощности фотоэлектрической системы, установленной на западе моей страны.

В качестве примера у меня есть два дня почасового GHI, температура 2 м и скорость ветра 10 м из повторного анализа MERRA2.

Я хочу оценить, сколько энергии будет генерировать фиксированная фотоэлектрическая система или система слежения за одной осью, используя вышеупомянутый набор данных и функцию ModelChain из PVLIB. Сначала я оцениваю DNI и DHI из данных GHI, используя модель DISC, чтобы получить DNI, а затем DHI - это разница между GHI и DNI * cos (Z)

а) Первое поведение. Я не совсем уверен, что это нормально. Вот график GHI, DNI, DHI, T2m и скорости ветра. Кажется, что DNI сдвигается, и его максимум приходится на 1 час до максимума GHI.

Рисунок погоды

После подготовки данных об освещенности я рассчитал переменный ток, используя цепочку моделей, указав фиксированную PV-систему и 1-осевую систему с одним слежением. Дело в том, что я не верю в выход переменного тока для одноосной системы. Я ожидал плато на выходе переменного тока и обнаружил странное поведение.

Вот некоторые значения выработки электроэнергии, которые я ожидал увидеть:

Ожидание

А вот примерный выпуск PVLIB

Реальность

Я надеюсь, что кто-нибудь поможет мне найти ошибку в моей процедуре.

Вот код:

# =============================================================================
# Example of using MERRA2 data and PVLIB
# =============================================================================
import numpy as np
import pandas as pd
import pandas as pd
import matplotlib.pyplot as plt
import pvlib
from pvlib.pvsystem import PVSystem
from pvlib.location import Location
from pvlib.modelchain import ModelChain

# =============================================================================
# 1) Create small data set extracted from MERRA
# =============================================================================
GHI             = np.array([0,0,0,0,0,0,0,0,0,10.8,148.8,361,583,791.5,998.5,1105.5,1146.5,1118.5,1023.5,
                            860.2,650.2,377.1,165.1,16,0,0,0,0,0,0,0,0,0,11.3,166.2,395.8,624.5,827,986,
                            1065.5,1079,1025.5,941.5,777,581.5,378.9,156.2,20.6,0,0,0,0])
temp_air        = np.array([21.5,20.5,19.7,19.6,18.8,17.9,17.1,16.5,16.2,16.2,17,21.3,24.7,26.9,28.8,30.5,
                            31.6,32.4,33,33.3,32.9,32,30.6,28.7,25.4,23.9,22.6,21.2,20.3,19.9,19.5,19.1,18.4,
                            17.7,18.3,23,25.1,27.3,29.5,31.2,32.1,32.6,32.6,32.5,31.8,30.7,29.6,28.1,24.6,22.9,
                            22.3,23.2])
wind_speed      = np.array([3.1,2.7,2.5,2.6,2.8,3,3,3,2.8,2.5,2.1,1,2.2,3.7,4.8,5.6,6.1,6.4,6.5,6.6,6.3,5.8,5.3,
                            3.7,3.9,4,3.6,3.4,3.4,3,2.6,2.3,2.1,2,2.2,2.7,3.2,4.3,5.1,5.6,5.7,5.8,5.8,5.7,5.4,4.8,
                            4.4,3.1,2.7,2.3,1.1,0.6])
local_timestamp = pd.DatetimeIndex(start='1979-12-31 21:00', end='1980-01-03 00:00', freq='1h',tz='America/Argentina/Buenos_Aires')
d               = {'ghi':GHI,'temp_air':temp_air,'wind_speed':wind_speed}
data            = pd.DataFrame(data=d)
data.index      = local_timestamp

lat             = -31.983   
lon             = -68.530
location        = Location(latitude  = lat, 
                           longitude = lon,
                           tz        = 'America/Argentina/Buenos_Aires',
                            altitude = 601)

# =============================================================================
# 2) SOLAR POSITION AND ATMOSPHERIC MODELING
# =============================================================================
solpos          = pvlib.solarposition.get_solarposition(time      = local_timestamp, 
                                                        latitude  = lat,
                                                        longitude = lon,
                                                        altitude  = 601)

# DNI and DHI calculation from GHI data
DNI             = pvlib.irradiance.disc(ghi             = data.ghi, 
                                        solar_zenith    = solpos.zenith, 
                                        datetime_or_doy = local_timestamp)
DHI             = data.ghi - DNI.dni*np.cos(np.radians(solpos.zenith.values))

d               = {'ghi': data.ghi,'dni': DNI.dni,'dhi': DHI,'temp_air':data.temp_air,'wind_speed':data.wind_speed }
weather         = pd.DataFrame(data=d)
plt.plot(weather)

# =============================================================================
# 3) SYSTEM SPECIFICATIONS
# =============================================================================
# load some module and inverter specifications
sandia_modules    = pvlib.pvsystem.retrieve_sam('SandiaMod')
cec_inverters     = pvlib.pvsystem.retrieve_sam('cecinverter')
sandia_module     = sandia_modules['Canadian_Solar_CS5P_220M___2009_']
cec_inverter      = cec_inverters['Power_Electronics__FS2400CU15__645V__645V__CEC_2018_']

# Fixed system with tilt=abs(lat)-10
f_system          = PVSystem(      surface_tilt                                = abs(lat)-10, 
                                   surface_azimuth                             = 0,
                                   module                                      = sandia_module,
                                   inverter                                    = cec_inverter,
                                   module_parameters                           = sandia_module,
                                   inverter_parameters                         = cec_inverter,
                                   albedo                                      = 0.20,
                                   modules_per_string                          = 100,
                                   strings_per_inverter                        = 100)
# 1 axis tracking system
t_system          = pvlib.tracking.SingleAxisTracker(axis_tilt                 = 0, #abs(-33.5)-10
                                                     axis_azimuth              = 0,
                                                     max_angle                 = 52,
                                                     backtrack                 = True,
                                                     module                    = sandia_module,
                                                     inverter                  = cec_inverter,                                                       
                                                     module_parameters         = sandia_module,
                                                     inverter_parameters       = cec_inverter,
                                                     name                      = 'tracking',
                                                     gcr                       = .3,
                                                     modules_per_string        = 100,
                                                     strings_per_inverter      = 100)

# =============================================================================
# 4) MODEL CHAIN USING ALL THE SPECIFICATIONS for a fixed and 1 axis tracking systems
# =============================================================================
mc_f       = ModelChain(f_system, location)
mc_t       = ModelChain(t_system, location)


# Next, we run a model with some simple weather data.
mc_f.run_model(times=weather.index, weather=weather)
mc_t.run_model(times=weather.index, weather=weather)

# =============================================================================
# 5) Get only AC output form a fixed and 1 axis tracking systems and assign 
# 0 values to each NaN
# =============================================================================
d              = {'fixed':mc_f.ac,'tracking':mc_t.ac}
AC             = pd.DataFrame(data=d)
i              = np.isnan(AC.tracking)
AC.tracking[i] = 0
i              = np.isnan(AC.fixed)
AC.fixed[i]    = 0

plt.plot(AC)

Надеюсь, кто-нибудь сможет мне помочь с интерпретацией результатов и отладкой кода.

Большое спасибо!

Можете ли вы более конкретно рассказать о том, что вы видели, и о том, что вы ожидали увидеть? Может быть, вы можете опубликовать файл png. Я также предлагаю посмотреть на промежуточные результаты, чтобы понять, где расчеты перестают иметь для вас смысл.

Will Holmgren 01.11.2018 04:43

Спасибо, Уилл. Я отредактировал сообщение и добавил несколько цифр, показывающих некоторые сомнения по поводу процедуры. Я считаю, что что-то не так с оценкой DNI и DHI по данным GHI, а также в определении PV-системы, но я не уверен.

Cristian W 01.11.2018 14:09

У меня была такая же проблема несколько недель назад, когда я начал более интенсивно использовать pvlib. И Уилл Холмгрен прав. Вы должны позаботиться о временных метках (конец или начало), временных сдвигах и усредненных или мгновенных значениях.

dl.meteo 14.03.2019 17:16
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
396
1

Ответы 1

Я подозреваю, что ваша проблема связана с тем, как обрабатываются почасовые данные. Убедитесь, что вы согласны с маркировкой интервалов (начало / конец) и обработкой мгновенных и средних данных. Одна из вероятных причин - использование среднечасовых данных GHI для получения данных DNI. pvlib.solarposition.get_solarposition возвращает положение Солнца в переданные ему моменты времени. Таким образом, вы смешиваете среднечасовые значения GHI с мгновенными значениями положения Солнца, когда используете pvlib.irradiance.disc для расчета DNI и когда вы рассчитываете DHI. Сдвиг временного индекса на 30 минут уменьшит, но не устранит ошибку. Другой подход состоит в том, чтобы пересчитать входные данные с разрешением 1–5 минут.

Другие вопросы по теме