From 6d3c8c83a3baa0b2a636c323d35dd682a728b483 Mon Sep 17 00:00:00 2001 From: Changgang Li Date: Mon, 11 Mar 2024 19:33:19 +0800 Subject: [PATCH] add pv and energy storage to dynamic Y matrix. add PV related models. --- code/steps/STEPS.cbp | 21 +- code/steps/STEPS.depend | 215 ++- code/steps/header/basic/constants.h | 3 +- .../header/data_imexporter/steps_imexporter.h | 4 + code/steps/header/device/pv_unit.h | 6 +- .../steps/header/model/all_supported_models.h | 5 +- .../pv_converter_model/pv_converter_model.h | 10 +- .../pv_converter_model/pv_converter_models.h | 1 + .../pvu_models/pv_converter_model/pvcvx.h | 92 ++ .../pv_electrical_model/pv_electrical_model.h | 9 +- .../pv_electrical_models.h | 2 +- .../pvu_models/pv_electrical_model/pvex.h | 149 ++ .../{fileirrd.h => fileirrad.h} | 12 + .../{fileirrd_test.h => fileirrad_test.h} | 0 .../pv_irradiance_model/pv_irradiance_model.h | 2 +- .../pv_irradiance_models.h | 1 + .../pv_panel_model/pv_panel_model.h | 24 +- .../pv_panel_model/pv_panel_models.h | 2 + .../pv_panel_model/{pvp0.h => pvpnlx.h} | 35 +- .../{pvp0_test.h => pvpnlx_test.h} | 12 +- .../pvu_models/pv_vrt_model/pv_vrt_model.h | 1 + .../model/pvu_models/supported_pvu_models.h | 11 + .../wtg_models/wind_speed_model/filewind.h | 2 +- .../wtg_models/wt_vrt_model/wt_vrt_model.h | 3 +- .../model/wtg_models/wt_vrt_model/wtvrt3.h | 2 + code/steps/header/network/network_matrix.h | 10 + code/steps/main_tests.cpp | 4 + .../steps_dynamics_imexporter.cpp | 125 ++ code/steps/source/device/pv_unit.cpp | 32 +- code/steps/source/dynamic_model_database.cpp | 4 + .../pv_converter_model/pv_converter_model.cpp | 101 +- .../pvu_models/pv_converter_model/pvcvx.cpp | 705 +++++++++ .../pv_electrical_model.cpp | 32 + .../pv_electrical_model_test.cpp | 4 +- .../pvu_models/pv_electrical_model/pvex.cpp | 1348 +++++++++++++++++ .../pv_irradiance_model/fileirrad.cpp | 467 ++++++ .../{fileirrd_test.cpp => fileirrad_test.cpp} | 2 +- .../pv_irradiance_model/fileirrd.cpp | 197 --- .../pv_irradiance_model.cpp | 10 +- .../pv_panel_model/pv_panel_model.cpp | 52 +- .../model/pvu_models/pv_panel_model/pvp0.cpp | 173 --- .../pvu_models/pv_panel_model/pvpnlx.cpp | 329 ++++ .../{pvp0_test.cpp => pvpnlx_test.cpp} | 22 +- .../pv_relay_model/pv_relay_model.cpp | 1 - .../compensator_model/compensator_model.cpp | 1 - .../sg_models/exciter_model/exciter_model.cpp | 1 - .../stabilizer_model/stabilizer_model.cpp | 1 - .../sync_generator_model.cpp | 2 - .../turbine_governor_model.cpp | 1 - .../turbine_load_controller_model.cpp | 1 - .../wtg_models/wind_speed_model/filewind.cpp | 10 +- .../wind_speed_model/wind_speed_model.cpp | 2 - .../wt_generator_model/wt_generator_model.cpp | 2 - .../wt_pitch_model/wt_pitch_model.cpp | 1 - .../wt_relay_model/wt_relay_model.cpp | 1 - .../wt_turbine_model/wt_turbine_model.cpp | 2 - .../wtg_models/wt_vrt_model/wt_vrt_model.cpp | 5 - .../model/wtg_models/wt_vrt_model/wtvrt3.cpp | 5 + code/steps/source/network/network_matrix.cpp | 115 ++ 59 files changed, 3851 insertions(+), 541 deletions(-) create mode 100644 code/steps/header/model/pvu_models/pv_converter_model/pvcvx.h create mode 100644 code/steps/header/model/pvu_models/pv_electrical_model/pvex.h rename code/steps/header/model/pvu_models/pv_irradiance_model/{fileirrd.h => fileirrad.h} (74%) rename code/steps/header/model/pvu_models/pv_irradiance_model/{fileirrd_test.h => fileirrad_test.h} (100%) rename code/steps/header/model/pvu_models/pv_panel_model/{pvp0.h => pvpnlx.h} (64%) rename code/steps/header/model/pvu_models/pv_panel_model/{pvp0_test.h => pvpnlx_test.h} (70%) create mode 100644 code/steps/header/model/pvu_models/supported_pvu_models.h create mode 100644 code/steps/source/model/pvu_models/pv_converter_model/pvcvx.cpp create mode 100644 code/steps/source/model/pvu_models/pv_electrical_model/pvex.cpp create mode 100644 code/steps/source/model/pvu_models/pv_irradiance_model/fileirrad.cpp rename code/steps/source/model/pvu_models/pv_irradiance_model/{fileirrd_test.cpp => fileirrad_test.cpp} (95%) delete mode 100644 code/steps/source/model/pvu_models/pv_irradiance_model/fileirrd.cpp delete mode 100644 code/steps/source/model/pvu_models/pv_panel_model/pvp0.cpp create mode 100644 code/steps/source/model/pvu_models/pv_panel_model/pvpnlx.cpp rename code/steps/source/model/pvu_models/pv_panel_model/{pvp0_test.cpp => pvpnlx_test.cpp} (58%) diff --git a/code/steps/STEPS.cbp b/code/steps/STEPS.cbp index f7c62939..3bbac897 100644 --- a/code/steps/STEPS.cbp +++ b/code/steps/STEPS.cbp @@ -247,21 +247,23 @@ + - - + + + - - + + @@ -269,6 +271,7 @@ + @@ -683,18 +686,20 @@ + - - + + + - - + + diff --git a/code/steps/STEPS.depend b/code/steps/STEPS.depend index 4a6f27f6..00db0098 100644 --- a/code/steps/STEPS.depend +++ b/code/steps/STEPS.depend @@ -67,7 +67,7 @@ "terminal.h" -1709799282 d:\steps\code\steps\header\basic\constants.h +1710154432 d:\steps\code\steps\header\basic\constants.h 1708517753 d:\steps\code\steps\header\basic\steps_enum.h @@ -299,14 +299,14 @@ 1634637238 d:\steps\code\steps\header\model\wtg_models\wind_speed_model\wind_speed_model.h "header/model/wtg_models/wtg_model.h" -1709522409 d:\steps\code\steps\header\model\wtg_models\wt_vrt_model\wt_vrt_model.h +1710152136 d:\steps\code\steps\header\model\wtg_models\wt_vrt_model\wt_vrt_model.h "header/model/wtg_models/wtg_model.h" 1634637238 d:\steps\code\steps\header\model\wtg_models\wt_relay_model\wt_relay_model.h "header/model/wtg_models/wtg_model.h" -1709519047 d:\steps\code\steps\header\device\pv_unit.h +1710151590 d:\steps\code\steps\header\device\pv_unit.h "header/device/source.h" @@ -317,7 +317,7 @@ "header/model/pvu_models/pv_vrt_model/pv_vrt_model.h" "header/model/pvu_models/pv_relay_model/pv_relay_model.h" -1634637238 d:\steps\code\steps\header\model\pvu_models\pv_converter_model\pv_converter_model.h +1710054158 d:\steps\code\steps\header\model\pvu_models\pv_converter_model\pv_converter_model.h "header/model/pvu_models/pvu_model.h" "header/block/integral_block.h" "header/block/saturation_block.h" @@ -326,18 +326,18 @@ "header/model/model.h" -1634637238 d:\steps\code\steps\header\model\pvu_models\pv_panel_model\pv_panel_model.h +1709884512 d:\steps\code\steps\header\model\pvu_models\pv_panel_model\pv_panel_model.h "header/model/pvu_models/pvu_model.h" -1664187911 d:\steps\code\steps\header\model\pvu_models\pv_electrical_model\pv_electrical_model.h +1709981158 d:\steps\code\steps\header\model\pvu_models\pv_electrical_model\pv_electrical_model.h "header/model/pvu_models/pvu_model.h" -1634637238 d:\steps\code\steps\header\model\pvu_models\pv_irradiance_model\pv_irradiance_model.h +1710153891 d:\steps\code\steps\header\model\pvu_models\pv_irradiance_model\pv_irradiance_model.h "header/model/pvu_models/pvu_model.h" -1709512769 d:\steps\code\steps\header\model\pvu_models\pv_vrt_model\pv_vrt_model.h +1710152209 d:\steps\code\steps\header\model\pvu_models\pv_vrt_model\pv_vrt_model.h "header/model/pvu_models/pvu_model.h" @@ -570,7 +570,7 @@ "header/network/jacobian_builder.h" "header/basic/sparse_matrix_define.h" -1697457172 d:\steps\code\steps\header\network\network_matrix.h +1710153086 d:\steps\code\steps\header\network\network_matrix.h "header/power_system_database.h" "header/basic/sparse_matrix_define.h" "header/basic/inphno.h" @@ -709,7 +709,7 @@ "header/basic/utility.h" "header/data_imexporter/psse_imexporter.h" -1710119997 source:d:\steps\code\steps\main_tests.cpp +1710156628 source:d:\steps\code\steps\main_tests.cpp @@ -1227,7 +1227,7 @@ "header/data_imexporter/steps_imexporter.h" "header/STEPS.h" -1709799961 d:\steps\code\steps\header\data_imexporter\steps_imexporter.h +1710156628 d:\steps\code\steps\header\data_imexporter\steps_imexporter.h "header/data_imexporter/data_imexporter.h" "header/device/source.h" "header/device/transformer.h" @@ -2385,7 +2385,7 @@ "header/data_imexporter/psse_imexporter.h" "header/model/all_supported_models.h" -1709800163 d:\steps\code\steps\header\model\all_supported_models.h +1710155764 d:\steps\code\steps\header\model\all_supported_models.h "header/model/sg_models/supported_sg_models.h" "header/model/load_model/load_models.h" "header/model/load_relay_model/load_relay_models.h" @@ -2393,10 +2393,7 @@ "header/model/vsc_hvdc_model/vsc_hvdc_network_model/vsc_hvdc_network_models.h" "header/model/vsc_hvdc_model/vsc_hvdc_converter_model/vsc_hvdc_converter_models.h" "header/model/wtg_models/supported_wtg_models.h" - "header/model/pvu_models/pv_converter_model/pv_converter_models.h" - "header/model/pvu_models/pv_panel_model/pv_panel_models.h" - "header/model/pvu_models/pv_electrical_model/pv_electrical_models.h" - "header/model/pvu_models/pv_irradiance_model/pv_irradiance_models.h" + "header/model/pvu_models/supported_pvu_models.h" "header/model/energy_storage_model/energy_storage_models.h" "header/model/equivalent_model/ARXL.h" @@ -2595,13 +2592,13 @@ 1583938871 d:\steps\code\steps\header\model\wtg_models\wind_speed_model\wind_speed_models.h "header/model/wtg_models/wind_speed_model/filewind.h" -1664187911 d:\steps\code\steps\header\model\wtg_models\wind_speed_model\filewind.h +1710154451 d:\steps\code\steps\header\model\wtg_models\wind_speed_model\filewind.h "header/model/wtg_models/wind_speed_model/wind_speed_model.h" 1709511959 d:\steps\code\steps\header\model\wtg_models\wt_vrt_model\wt_vrt_models.h "header/model/wtg_models/wt_vrt_model/wtvrt3.h" -1709511959 d:\steps\code\steps\header\model\wtg_models\wt_vrt_model\wtvrt3.h +1710152151 d:\steps\code\steps\header\model\wtg_models\wt_vrt_model\wtvrt3.h "header/model/wtg_models/wt_vrt_model/wt_vrt_model.h" "header/model/converter_common_models/vrt_model/lvrt_control.h" "header/model/converter_common_models/vrt_model/hvrt_control.h" @@ -2619,8 +2616,9 @@ "header/basic/timer.h" "header/basic/constants.h" -1583938871 d:\steps\code\steps\header\model\pvu_models\pv_converter_model\pv_converter_models.h +1710156482 d:\steps\code\steps\header\model\pvu_models\pv_converter_model\pv_converter_models.h "header/model/pvu_models/pv_converter_model/pvcv0.h" + "header/model/pvu_models/pv_converter_model/pvcvx.h" "header/model/pvu_models/pv_converter_model/pvgu1.h" 1708511456 d:\steps\code\steps\header\model\pvu_models\pv_converter_model\pvcv0.h @@ -2629,11 +2627,14 @@ "header/block/integral_block.h" "header/block/first_order_block.h" -1583938871 d:\steps\code\steps\header\model\pvu_models\pv_panel_model\pv_panel_models.h +1710156520 d:\steps\code\steps\header\model\pvu_models\pv_panel_model\pv_panel_models.h + "header/model/pvu_models/pv_panel_model/pvpnlx.h" -1583938871 d:\steps\code\steps\header\model\pvu_models\pv_electrical_model\pv_electrical_models.h +1710156496 d:\steps\code\steps\header\model\pvu_models\pv_electrical_model\pv_electrical_models.h + "header/model/pvu_models/pv_electrical_model/pvex.h" -1583938871 d:\steps\code\steps\header\model\pvu_models\pv_irradiance_model\pv_irradiance_models.h +1710155546 d:\steps\code\steps\header\model\pvu_models\pv_irradiance_model\pv_irradiance_models.h + "header/model/pvu_models/pv_irradiance_model/fileirrad.h" 1583938871 d:\steps\code\steps\header\model\energy_storage_model\energy_storage_models.h "header/model/energy_storage_model/estr0.h" @@ -3912,7 +3913,7 @@ -1709799961 source:d:\steps\code\steps\source\data_imexporter\steps_dynamics_imexporter.cpp +1710156628 source:d:\steps\code\steps\source\data_imexporter\steps_dynamics_imexporter.cpp "header/data_imexporter/steps_imexporter.h" "header/basic/utility.h" "header/steps_namespace.h" @@ -4283,7 +4284,7 @@ -1709521308 source:d:\steps\code\steps\source\device\pv_unit.cpp +1710152391 source:d:\steps\code\steps\source\device\pv_unit.cpp "header/device/pv_unit.h" "header/basic/utility.h" "header/steps_namespace.h" @@ -4396,7 +4397,7 @@ -1709799961 source:d:\steps\code\steps\source\dynamic_model_database.cpp +1710156628 source:d:\steps\code\steps\source\dynamic_model_database.cpp "header/dynamic_model_database.h" "header/STEPS.h" "header/steps_namespace.h" @@ -4837,7 +4838,7 @@ "header/model/model_var_table_test.h" "header/basic/utility.h" -1634637238 source:d:\steps\code\steps\source\model\pvu_models\pv_converter_model\pv_converter_model.cpp +1710154601 source:d:\steps\code\steps\source\model\pvu_models\pv_converter_model\pv_converter_model.cpp "header/model/pvu_models/pv_converter_model/pv_converter_model.h" "header/basic/utility.h" "header/basic/constants.h" @@ -4907,14 +4908,14 @@ -1664187911 source:d:\steps\code\steps\source\model\pvu_models\pv_electrical_model\pv_electrical_model.cpp +1709981158 source:d:\steps\code\steps\source\model\pvu_models\pv_electrical_model\pv_electrical_model.cpp "header/model/pvu_models/pv_electrical_model/pv_electrical_model.h" "header/basic/utility.h" "header/device/pv_unit.h" "header/power_system_database.h" "header/STEPS.h" -1664187911 source:d:\steps\code\steps\source\model\pvu_models\pv_electrical_model\pv_electrical_model_test.cpp +1710155008 source:d:\steps\code\steps\source\model\pvu_models\pv_electrical_model\pv_electrical_model_test.cpp "header/basic/test_macro.h" "header/model/pvu_models/pv_electrical_model/pv_electrical_model_test.h" "header/basic/utility.h" @@ -4928,14 +4929,15 @@ "header/model/pvu_models/pvu_model_test.h" "header/power_system_database.h" -1664187911 source:d:\steps\code\steps\source\model\pvu_models\pv_irradiance_model\fileirrd.cpp +1709884404 source:d:\steps\code\steps\source\model\pvu_models\pv_irradiance_model\fileirrd.cpp "header/model/pvu_models/pv_irradiance_model/fileirrd.h" "header/basic/utility.h" "header/steps_namespace.h" + -1634637238 d:\steps\code\steps\header\model\pvu_models\pv_irradiance_model\fileirrd.h +1710154439 d:\steps\code\steps\header\model\pvu_models\pv_irradiance_model\fileirrd.h "header/model/pvu_models/pv_irradiance_model/pv_irradiance_model.h" 1585314815 source:d:\steps\code\steps\source\model\pvu_models\pv_irradiance_model\fileirrd_test.cpp @@ -4967,7 +4969,7 @@ "header/model/pvu_models/pvu_model_test.h" "header/power_system_database.h" -1583938871 source:d:\steps\code\steps\source\model\pvu_models\pv_irradiance_model\pv_irradiance_model.cpp +1710154607 source:d:\steps\code\steps\source\model\pvu_models\pv_irradiance_model\pv_irradiance_model.cpp "header/model/pvu_models/pv_irradiance_model/pv_irradiance_model.h" "header/basic/utility.h" @@ -4984,7 +4986,7 @@ -1583938871 source:d:\steps\code\steps\source\model\pvu_models\pv_panel_model\pv_panel_model.cpp +1709884512 source:d:\steps\code\steps\source\model\pvu_models\pv_panel_model\pv_panel_model.cpp "header/model/pvu_models/pv_panel_model/pv_panel_model.h" "header/basic/utility.h" "header/STEPS.h" @@ -5010,14 +5012,14 @@ "header/model/pvu_models/pvu_model_test.h" "header/power_system_database.h" -1664187911 source:d:\steps\code\steps\source\model\pvu_models\pv_panel_model\pvp0.cpp +1710142730 source:d:\steps\code\steps\source\model\pvu_models\pv_panel_model\pvp0.cpp "header/model/pvu_models/pv_panel_model/pvp0.h" "header/basic/utility.h" "header/steps_namespace.h" -1634637238 d:\steps\code\steps\header\model\pvu_models\pv_panel_model\pvp0.h +1709900976 d:\steps\code\steps\header\model\pvu_models\pv_panel_model\pvp0.h "header/model/pvu_models/pv_panel_model/pv_panel_model.h" @@ -5041,7 +5043,7 @@ "header/model/pvu_models/pv_panel_model/pvp0.h" "header/STEPS.h" -1709512813 source:d:\steps\code\steps\source\model\pvu_models\pv_relay_model\pv_relay_model.cpp +1710154621 source:d:\steps\code\steps\source\model\pvu_models\pv_relay_model\pv_relay_model.cpp "header/model/pvu_models/pv_relay_model/pv_relay_model.h" "header/basic/utility.h" "header/STEPS.h" @@ -5085,7 +5087,7 @@ "header/basic/utility.h" "header/steps_namespace.h" -1634637238 source:d:\steps\code\steps\source\model\sg_models\compensator_model\compensator_model.cpp +1710154688 source:d:\steps\code\steps\source\model\sg_models\compensator_model\compensator_model.cpp "header/model/sg_models/compensator_model/compensator_model.h" "header/device/generator.h" "header/steps_namespace.h" @@ -5177,7 +5179,7 @@ "header/basic/utility.h" "header/steps_namespace.h" -1664187911 source:d:\steps\code\steps\source\model\sg_models\exciter_model\exciter_model.cpp +1710154692 source:d:\steps\code\steps\source\model\sg_models\exciter_model\exciter_model.cpp "header/model/sg_models/exciter_model/exciter_model.h" "header/device/generator.h" "header/steps_namespace.h" @@ -5417,7 +5419,7 @@ "header/basic/utility.h" "header/steps_namespace.h" -1664187911 source:d:\steps\code\steps\source\model\sg_models\stabilizer_model\stabilizer_model.cpp +1710154700 source:d:\steps\code\steps\source\model\sg_models\stabilizer_model\stabilizer_model.cpp "header/model/sg_models/stabilizer_model/stabilizer_model.h" "header/basic/utility.h" @@ -5489,7 +5491,7 @@ -1697457172 source:d:\steps\code\steps\source\model\sg_models\sync_generator_model\sync_generator_model.cpp +1710154706 source:d:\steps\code\steps\source\model\sg_models\sync_generator_model\sync_generator_model.cpp "header/model/sg_models/sync_generator_model/sync_generator_model.h" "header/basic/utility.h" "header/basic/constants.h" @@ -5590,7 +5592,7 @@ "header/basic/utility.h" "header/steps_namespace.h" -1634637238 source:d:\steps\code\steps\source\model\sg_models\turbine_governors\turbine_governor_model.cpp +1710154713 source:d:\steps\code\steps\source\model\sg_models\turbine_governors\turbine_governor_model.cpp "header/model/sg_models/turbine_governor_model/turbine_governor_model.h" "header/model/sg_models/sync_generator_model/sync_generator_model.h" "header/device/generator.h" @@ -5627,7 +5629,7 @@ "header/basic/utility.h" "header/steps_namespace.h" -1634637238 source:d:\steps\code\steps\source\model\sg_models\turbine_load_controller_model\turbine_load_controller_model.cpp +1710154740 source:d:\steps\code\steps\source\model\sg_models\turbine_load_controller_model\turbine_load_controller_model.cpp "header/model/sg_models/turbine_load_controller_model/turbine_load_controller_model.h" "header/basic/utility.h" @@ -5684,7 +5686,7 @@ "header/STEPS.h" -1664187911 source:d:\steps\code\steps\source\model\wtg_models\wind_speed_model\filewind.cpp +1710154451 source:d:\steps\code\steps\source\model\wtg_models\wind_speed_model\filewind.cpp "header/model/wtg_models/wind_speed_model/filewind.h" "header/basic/utility.h" "header/steps_namespace.h" @@ -5705,7 +5707,7 @@ -1634637238 source:d:\steps\code\steps\source\model\wtg_models\wind_speed_model\wind_speed_model.cpp +1710154747 source:d:\steps\code\steps\source\model\wtg_models\wind_speed_model\wind_speed_model.cpp "header/model/wtg_models/wind_speed_model/wind_speed_model.h" "header/basic/utility.h" @@ -5901,7 +5903,7 @@ -1709523668 source:d:\steps\code\steps\source\model\wtg_models\wt_generator_model\wt_generator_model.cpp +1710154754 source:d:\steps\code\steps\source\model\wtg_models\wt_generator_model\wt_generator_model.cpp "header/model/wtg_models/wt_generator_model/wt_generator_model.h" "header/basic/utility.h" "header/basic/constants.h" @@ -5941,7 +5943,7 @@ -1634637239 source:d:\steps\code\steps\source\model\wtg_models\wt_pitch_model\wt_pitch_model.cpp +1710154759 source:d:\steps\code\steps\source\model\wtg_models\wt_pitch_model\wt_pitch_model.cpp "header/model/wtg_models/wt_turbine_model/wt_turbine_model.h" "header/basic/utility.h" "header/STEPS.h" @@ -5962,7 +5964,7 @@ -1634637239 source:d:\steps\code\steps\source\model\wtg_models\wt_relay_model\wt_relay_model.cpp +1710154763 source:d:\steps\code\steps\source\model\wtg_models\wt_relay_model\wt_relay_model.cpp "header/model/wtg_models/wt_relay_model/wt_relay_model.h" "header/basic/utility.h" "header/STEPS.h" @@ -5991,7 +5993,7 @@ -1634637239 source:d:\steps\code\steps\source\model\wtg_models\wt_turbine_model\wt_turbine_model.cpp +1710154766 source:d:\steps\code\steps\source\model\wtg_models\wt_turbine_model\wt_turbine_model.cpp "header/model/wtg_models/wt_turbine_model/wt_turbine_model.h" "header/basic/utility.h" @@ -6010,14 +6012,14 @@ -1709522509 source:d:\steps\code\steps\source\model\wtg_models\wt_vrt_model\wt_vrt_model.cpp +1710152164 source:d:\steps\code\steps\source\model\wtg_models\wt_vrt_model\wt_vrt_model.cpp "header/model/wtg_models/wt_vrt_model/wt_vrt_model.h" "header/basic/utility.h" "header/device/wt_generator.h" "header/power_system_database.h" "header/STEPS.h" -1709511959 source:d:\steps\code\steps\source\model\wtg_models\wt_vrt_model\wtvrt3.cpp +1710152179 source:d:\steps\code\steps\source\model\wtg_models\wt_vrt_model\wtvrt3.cpp "header/model/wtg_models/wt_vrt_model/wtvrt3.h" "header/device/wt_generator.h" "header/power_system_database.h" @@ -6061,7 +6063,7 @@ "header/steps_namespace.h" -1697457172 source:d:\steps\code\steps\source\network\network_matrix.cpp +1710153146 source:d:\steps\code\steps\source\network\network_matrix.cpp "header/network/network_matrix.h" "header/basic/utility.h" "header/STEPS.h" @@ -6561,3 +6563,116 @@ "header/data_imexporter/psse_imexporter.h" "header/prepare_for_tests/prepare_models_for_test.h" +1710144274 source:d:\steps\code\steps\source\model\pvu_models\pv_electrical_model\pve0.cpp + "header/model/pvu_models/pv_electrical_model/pve0.h" + "header/device/pv_unit.h" + "header/power_system_database.h" + "header/STEPS.h" + "header/basic/utility.h" + "header/steps_namespace.h" + + +1710039244 d:\steps\code\steps\header\model\pvu_models\pv_electrical_model\pve0.h + "header/model/pvu_models/pv_electrical_model/pv_electrical_model.h" + "header/block/first_order_block.h" + "header/block/pi_block.h" + "header/block/integral_block.h" + +1710142730 d:\steps\code\steps\header\model\pvu_models\pv_converter_model\pvcv1.h + "header/model/pvu_models/pv_converter_model/pv_converter_model.h" + "header/model/converter_common_models/lvpl_model/lvpl.h" + "header/block/integral_block.h" + "header/block/first_order_block.h" + +1710148096 source:d:\steps\code\steps\source\model\pvu_models\pv_converter_model\pvcv1.cpp + "header/model/pvu_models/pv_converter_model/pvcv1.h" + "header/basic/utility.h" + "header/steps_namespace.h" + + + + +1710154439 d:\steps\code\steps\header\model\pvu_models\pv_irradiance_model\fileirrad.h + "header/model/pvu_models/pv_irradiance_model/pv_irradiance_model.h" + +1710155605 source:d:\steps\code\steps\source\model\pvu_models\pv_irradiance_model\fileirrad_test.cpp + "header/basic/test_macro.h" + "header/model/pvu_models/pv_irradiance_model/fileirrad_test.h" + "header/basic/utility.h" + "header/steps_namespace.h" + + + + + + + +1583938871 d:\steps\code\steps\header\model\pvu_models\pv_irradiance_model\fileirrad_test.h + + + + + "cpptest.h" + "header/model/pvu_models/pv_irradiance_model/pv_irradiance_model_test.h" + "header/STEPS.h" + +1710155800 d:\steps\code\steps\header\model\pvu_models\supported_pvu_models.h + "header/model/pvu_models/pv_converter_model/pv_converter_models.h" + "header/model/pvu_models/pv_panel_model/pv_panel_models.h" + "header/model/pvu_models/pv_electrical_model/pv_electrical_models.h" + "header/model/pvu_models/pv_irradiance_model/pv_irradiance_models.h" + "header/model/pvu_models/pv_vrt_model/pv_vrt_models.h" + "header/model/pvu_models/pv_relay_model/pv_relay_models.h" + +1709512264 d:\steps\code\steps\header\model\pvu_models\pv_vrt_model\pv_vrt_models.h + +1709512448 d:\steps\code\steps\header\model\pvu_models\pv_relay_model\pv_relay_models.h + +1710155628 source:d:\steps\code\steps\source\model\pvu_models\pv_irradiance_model\fileirrad.cpp + "header/model/pvu_models/pv_irradiance_model/fileirrad.h" + "header/basic/utility.h" + "header/steps_namespace.h" + + + + +1710156628 d:\steps\code\steps\header\model\pvu_models\pv_converter_model\pvcvx.h + "header/model/pvu_models/pv_converter_model/pv_converter_model.h" + "header/model/converter_common_models/lvpl_model/lvpl.h" + "header/block/integral_block.h" + "header/block/first_order_block.h" + +1710156628 d:\steps\code\steps\header\model\pvu_models\pv_panel_model\pvpnlx.h + "header/model/pvu_models/pv_panel_model/pv_panel_model.h" + + +1710156628 d:\steps\code\steps\header\model\pvu_models\pv_electrical_model\pvex.h + "header/model/pvu_models/pv_electrical_model/pv_electrical_model.h" + "header/block/first_order_block.h" + "header/block/pi_block.h" + "header/block/integral_block.h" + +1710156628 source:d:\steps\code\steps\source\model\pvu_models\pv_converter_model\pvcvx.cpp + "header/model/pvu_models/pv_converter_model/pvcvx.h" + "header/basic/utility.h" + "header/steps_namespace.h" + + + + +1710156628 source:d:\steps\code\steps\source\model\pvu_models\pv_electrical_model\pvex.cpp + "header/model/pvu_models/pv_electrical_model/pvex.h" + "header/device/pv_unit.h" + "header/power_system_database.h" + "header/STEPS.h" + "header/basic/utility.h" + "header/steps_namespace.h" + + +1710156628 source:d:\steps\code\steps\source\model\pvu_models\pv_panel_model\pvpnlx.cpp + "header/model/pvu_models/pv_panel_model/pvpnlx.h" + "header/basic/utility.h" + "header/steps_namespace.h" + + + diff --git a/code/steps/header/basic/constants.h b/code/steps/header/basic/constants.h index ddce52c4..1efcb6be 100644 --- a/code/steps/header/basic/constants.h +++ b/code/steps/header/basic/constants.h @@ -35,9 +35,10 @@ const unsigned int STEPS_MAX_LOAD_RELAY_STAGE = 50; const unsigned int STEPS_MAX_RELAY_COUNT = 5; const unsigned int STEPS_MAX_STABILIZER_INPUT_SIGNAL_SLOT = 5; const unsigned int STEPS_MAX_CONTINUOUS_BUFFER_SIZE = 1000; -const unsigned int STEPS_MAX_WIND_RECORD_SIZE = 100; +const unsigned int STEPS_MAX_WIND_SPEED_RECORD_SIZE = 100; const unsigned int STEPS_MAX_WIND_TURBINE_MAXIMUM_LOOP = 100; const unsigned int STEPS_MAX_WIND_TURBINE_POWER_SPEED_LOOKUP_TABLE_SIZE = 24; +const unsigned int STEPS_MAX_SOLAR_IRRADIANCE_RECORD_SIZE = 100; const unsigned int STEPS_MAX_VDCOL_TABLE_SIZE = 10; const unsigned int STEPS_MAX_HVDC_BYPASS_RECORD_SIZE = 10; const unsigned int STEPS_SHORT_STRING_SIZE = 64; diff --git a/code/steps/header/data_imexporter/steps_imexporter.h b/code/steps/header/data_imexporter/steps_imexporter.h index 84ad7d9d..37f6d4e1 100644 --- a/code/steps/header/data_imexporter/steps_imexporter.h +++ b/code/steps/header/data_imexporter/steps_imexporter.h @@ -223,6 +223,10 @@ class STEPS_IMEXPORTER : public DATA_IMEXPORTER void add_WTVRT3_model(vector& data); void add_PVGU1_model(vector& data); + void add_PVCVX_model(vector& data); + void add_PVEX_model(vector& data); + void add_FILEIRRAD_model(vector& data); + void add_PVPNLX_model(vector& data); DEVICE_ID get_generator_device_id_from_string_vector(vector& data); DEVICE_ID get_wt_generator_device_id_from_string_vector(vector& data); diff --git a/code/steps/header/device/pv_unit.h b/code/steps/header/device/pv_unit.h index 874b38fe..1cdd822a 100644 --- a/code/steps/header/device/pv_unit.h +++ b/code/steps/header/device/pv_unit.h @@ -25,10 +25,10 @@ class PV_UNIT : public SOURCE void set_unit_bus(unsigned int bus); unsigned int get_unit_bus() const; - void set_number_of_lumped_pv_units(unsigned int n); + void set_number_of_lumped_pv_units(double n); void set_rated_power_per_pv_unit_in_MW(double P); - unsigned int get_number_of_lumped_pv_units() const; + double get_number_of_lumped_pv_units() const; double get_rated_power_per_pv_unit_in_MW() const; virtual void set_model(MODEL* model); @@ -85,7 +85,7 @@ class PV_UNIT : public SOURCE void set_sequence_parameter_import_flag(bool flag); bool get_sequence_parameter_import_flag() const; private: - unsigned int number_of_lumped_pv_units; + double number_of_lumped_pv_units; double rated_power_per_pv_unit_in_MW; PV_CONVERTER_MODEL* pv_converter_model; diff --git a/code/steps/header/model/all_supported_models.h b/code/steps/header/model/all_supported_models.h index 73b56548..9a0d81c2 100644 --- a/code/steps/header/model/all_supported_models.h +++ b/code/steps/header/model/all_supported_models.h @@ -15,10 +15,7 @@ #include "header/model/wtg_models/supported_wtg_models.h" -#include "header/model/pvu_models/pv_converter_model/pv_converter_models.h" -#include "header/model/pvu_models/pv_panel_model/pv_panel_models.h" -#include "header/model/pvu_models/pv_electrical_model/pv_electrical_models.h" -#include "header/model/pvu_models/pv_irradiance_model/pv_irradiance_models.h" +#include "header/model/pvu_models/supported_pvu_models.h" #include "header/model/energy_storage_model/energy_storage_models.h" diff --git a/code/steps/header/model/pvu_models/pv_converter_model/pv_converter_model.h b/code/steps/header/model/pvu_models/pv_converter_model/pv_converter_model.h index d387f279..6e3fba0b 100644 --- a/code/steps/header/model/pvu_models/pv_converter_model/pv_converter_model.h +++ b/code/steps/header/model/pvu_models/pv_converter_model/pv_converter_model.h @@ -37,10 +37,18 @@ class PV_CONVERTER_MODEL : public PVU_MODEL void set_initial_reactive_voltage_command_in_pu(double eq_command); double get_initial_reactive_voltage_command_in_pu() const; + + void set_initial_active_power_command_in_pu_based_on_mbase(double P_command); + double get_initial_active_power_command_in_pu_based_on_mbase() const; + + void set_initial_reactive_power_command_in_pu_based_on_mbase(double Q_command); + double get_initial_reactive_power_command_in_pu_based_on_mbase() const; // get inputs for dynamics run double get_active_current_command_in_pu_based_on_mbase(); double get_reactive_current_command_in_pu_based_on_mbase(); double get_reactive_voltage_command_in_pu() const; + double get_active_power_command_in_pu_based_on_mbase(); + double get_reactive_power_command_in_pu_based_on_mbase(); public: // specific sync generator model virtual string get_model_name() const = 0; @@ -95,7 +103,7 @@ class PV_CONVERTER_MODEL : public PVU_MODEL private: bool current_source_flag; - double IP_command0, IQ_command0, EQ_command0; + double IP_command0, IQ_command0, EQ_command0, P_command0, Q_command0; }; #endif // PV_CONVERTER_MODEL_H diff --git a/code/steps/header/model/pvu_models/pv_converter_model/pv_converter_models.h b/code/steps/header/model/pvu_models/pv_converter_model/pv_converter_models.h index 153c9b34..7d974ad5 100644 --- a/code/steps/header/model/pvu_models/pv_converter_model/pv_converter_models.h +++ b/code/steps/header/model/pvu_models/pv_converter_model/pv_converter_models.h @@ -2,6 +2,7 @@ #define PV_CONVERTER_MODELS_H #include "header/model/pvu_models/pv_converter_model/pvcv0.h" +#include "header/model/pvu_models/pv_converter_model/pvcvx.h" #include "header/model/pvu_models/pv_converter_model/pvgu1.h" #endif // PV_CONVERTER_MODELS_H diff --git a/code/steps/header/model/pvu_models/pv_converter_model/pvcvx.h b/code/steps/header/model/pvu_models/pv_converter_model/pvcvx.h new file mode 100644 index 00000000..98142b14 --- /dev/null +++ b/code/steps/header/model/pvu_models/pv_converter_model/pvcvx.h @@ -0,0 +1,92 @@ +#ifndef PVCVX_H +#define PVCVX_H + +#include "header/model/pvu_models/pv_converter_model/pv_converter_model.h" +#include "header/model/converter_common_models/lvpl_model/lvpl.h" +#include "header/block/integral_block.h" +#include "header/block/first_order_block.h" + +class PVCVX : public PV_CONVERTER_MODEL +{ + public: + PVCVX(STEPS& toolkit); + PVCVX(const PVCVX& model); + virtual ~PVCVX(); + virtual PVCVX& operator=(const PVCVX&); + + void set_Xeq_in_pu(double xeq); + void set_KPLL(double K); + void set_KIPLL(double K); + void set_PLLmax(double pmax); + + double get_Xeq_in_pu() const; + double get_KPLL() const; + double get_KIPLL() const; + double get_PLLmax() const; + + + virtual string get_model_name() const; + + virtual bool setup_model_with_steps_string_vector(vector& data); + virtual bool setup_model_with_psse_string(string data); + virtual bool setup_model_with_bpa_string(string data); + + virtual void prepare_model_data_table(); + virtual void prepare_model_internal_variable_table(); + + virtual void setup_block_toolkit_and_parameters(); + + virtual void initialize(); + virtual void run(DYNAMIC_MODE mode); + virtual complex get_source_Norton_equivalent_complex_current_in_pu_in_xy_axis_based_on_sbase(); + virtual complex get_terminal_complex_current_in_pu_in_xy_axis_based_on_mbase(); + virtual complex get_terminal_complex_current_in_pu_in_xy_axis_based_on_sbase(); + virtual double get_terminal_current_in_pu_based_on_mbase(); + virtual double get_terminal_current_in_pu_based_on_sbase(); + + virtual void check(); + virtual void clear(); + virtual void report(); + virtual void save(); + virtual string get_standard_psse_string(bool export_internal_bus_number=false) const; + + virtual double get_model_data_with_name(string par_name) const; + virtual void set_model_data_with_name(string par_name, double value); + virtual double get_minimum_nonzero_time_constant_in_s(); + virtual double get_model_internal_variable_with_name(string var_name); + + virtual complex get_terminal_complex_power_in_pu_based_on_mbase(); + virtual complex get_terminal_complex_power_in_MVA(); + virtual double get_terminal_active_power_in_pu_based_on_mbase(); + virtual double get_terminal_active_power_in_MW(); + virtual double get_terminal_reactive_power_in_pu_based_on_mbase(); + virtual double get_terminal_reactive_power_in_MVar(); + virtual double get_active_power_generation_including_stator_loss_in_pu_based_on_mbase(); + virtual double get_active_power_generation_including_stator_loss_in_MW(); + + virtual double get_pll_angle_in_rad(); + virtual double get_pll_angle_in_deg(); + virtual double get_pll_frequency_deviation_in_pu(); + virtual double get_pll_frequency_deviation_in_Hz(); + virtual double get_pll_frequency_in_pu(); + virtual double get_pll_frequency_in_Hz(); + virtual complex get_internal_voltage_in_pu_in_xy_axis(); + + virtual string get_dynamic_data_in_psse_format() const; + virtual string get_dynamic_data_in_bpa_format() const; + virtual string get_dynamic_data_in_steps_format() const; + public: + // the following function are used to model PVCVX as ideal voltage source + void set_pll_angle_in_deg(double angle); + private: + void copy_from_const_model(const PVCVX& model); + + double Xeq; + FIRST_ORDER_BLOCK active_current_commander; + FIRST_ORDER_BLOCK reactive_voltage_commander; + + double KPLL; + INTEGRAL_BLOCK PLL_frequency_integrator, PLL_angle_integrator; +}; + +#endif // PVCVX_H diff --git a/code/steps/header/model/pvu_models/pv_electrical_model/pv_electrical_model.h b/code/steps/header/model/pvu_models/pv_electrical_model/pv_electrical_model.h index f468ffeb..f48be6af 100644 --- a/code/steps/header/model/pvu_models/pv_electrical_model/pv_electrical_model.h +++ b/code/steps/header/model/pvu_models/pv_electrical_model/pv_electrical_model.h @@ -22,6 +22,10 @@ class PV_ELECTRICAL_MODEL : public PVU_MODEL public: PV_ELECTRICAL_MODEL(STEPS& toolkit); virtual ~PV_ELECTRICAL_MODEL(); + + void unbypass_model(); + void bypass_model(); + bool is_model_bypassed() const; public: // pe elctricla control common virtual string get_model_type() const; // get input @@ -34,6 +38,8 @@ class PV_ELECTRICAL_MODEL : public PVU_MODEL double get_terminal_bus_frequency_in_pu() const; double get_terminal_bus_frequency_deviation_in_pu() const; + + double get_active_power_reference_in_pu_from_panel_model() const; // reference void set_bus_to_regulate(unsigned int bus); unsigned int get_bus_to_regulate() const; @@ -66,7 +72,6 @@ class PV_ELECTRICAL_MODEL : public PVU_MODEL virtual double get_active_power_command_in_pu_based_on_mbase() const = 0; virtual double get_reactive_current_command_in_pu_based_on_mbase() = 0; virtual double get_reactive_power_command_in_pu_based_on_mbase() = 0; - virtual double get_reactive_voltage_command_in_pu_based_on_mbase() const = 0; virtual double get_reactive_voltage_command_in_pu() const = 0; virtual void check() = 0; virtual void clear() = 0; @@ -93,6 +98,8 @@ class PV_ELECTRICAL_MODEL : public PVU_MODEL double reactive_power_reference_in_pu; double power_factor_reference_in_pu; PE_VAR_CONTROL_MODE pe_var_control_mode; + + bool flag_model_bypassed; }; #endif // PV_ELECTRICAL_MODEL_H diff --git a/code/steps/header/model/pvu_models/pv_electrical_model/pv_electrical_models.h b/code/steps/header/model/pvu_models/pv_electrical_model/pv_electrical_models.h index e7099f9f..f51280c5 100644 --- a/code/steps/header/model/pvu_models/pv_electrical_model/pv_electrical_models.h +++ b/code/steps/header/model/pvu_models/pv_electrical_model/pv_electrical_models.h @@ -1,5 +1,5 @@ #ifndef PV_ELECTRICAL_MODELS_H #define PV_ELECTRICAL_MODELS_H - +#include "header/model/pvu_models/pv_electrical_model/pvex.h" #endif // PV_ELECTRICAL_MODELS_H diff --git a/code/steps/header/model/pvu_models/pv_electrical_model/pvex.h b/code/steps/header/model/pvu_models/pv_electrical_model/pvex.h new file mode 100644 index 00000000..95b17b2a --- /dev/null +++ b/code/steps/header/model/pvu_models/pv_electrical_model/pvex.h @@ -0,0 +1,149 @@ +#ifndef PVEX_H +#define PVEX_H + +#include "header/model/pvu_models/pv_electrical_model/pv_electrical_model.h" +#include "header/block/first_order_block.h" +#include "header/block/pi_block.h" +#include "header/block/integral_block.h" + +class PVEX: public PV_ELECTRICAL_MODEL +{ + public: + PVEX(STEPS& toolkit); + PVEX(const PVEX& model); + virtual ~PVEX(); + virtual PVEX& operator=(const PVEX& model); + public: // specific exciter + virtual string get_model_name() const; + + void set_Xcomp_in_pu(double Xc); + void set_TRV_in_s(double T); + void set_Fn(double Fn); + void set_KIV(double K); + void set_Qmax_in_pu(double q); + void set_Qmin_in_pu(double q); + void set_KPV(double K); + void set_TV_in_s(double T); + void set_TFV_in_s(double T); + void set_TP_in_s(double T); + void set_KQI(double K); + void set_Vmax_in_pu(double v); + void set_Vmin_in_pu(double v); + void set_voltage_flag(unsigned int flag); + void set_KQV(double K); + void set_EQmax_in_pu(double I); + void set_EQmin_in_pu(double I); + + + void set_Kvi(double K); + void set_Tvi_in_s(double T); + void set_Kdroop(double K); + void set_Tdroop_in_s(double T); + void set_frequency_deviation_upper_deadband_in_pu(double f); + void set_frequency_deviation_lower_deadband_in_pu(double f); + void set_Kfint(double K); + void set_rPmax_in_pu(double r); + void set_rPmin_in_pu(double r); + void set_TFP_in_s(double T); + void set_Pmax_in_pu(double p); + void set_Pmin_in_pu(double p); + void set_IPmax_in_pu(double I); + + double get_Xcomp_in_pu() const; + double get_TRV_in_s() const; + double get_Fn() const; + double get_KIV() const; + double get_Qmax_in_pu() const; + double get_Qmin_in_pu() const; + double get_KPV() const; + double get_TV_in_s() const; + double get_TFV_in_s() const; + double get_TP_in_s() const; + double get_KQI() const; + double get_Vmax_in_pu() const; + double get_Vmin_in_pu() const; + unsigned int get_voltage_flag() const; + double get_KQV() const; + double get_EQmax_in_pu() const; + double get_EQmin_in_pu() const; + + double get_Kvi() const; + double get_Tvi_in_s() const; + double get_Kdroop() const; + double get_Tdroop_in_s() const; + double get_frequency_deviation_upper_deadband_in_pu() const; + double get_frequency_deviation_lower_deadband_in_pu() const; + double get_Kfint() const; + double get_TFP_in_s() const; + double get_rPmax_in_pu() const; + double get_rPmin_in_pu() const; + double get_Pmax_in_pu() const; + double get_Pmin_in_pu() const; + double get_IPmax_in_pu() const; + + bool is_frequency_regulation_enabled() const; + + public: + virtual bool setup_model_with_steps_string_vector(vector& data); + virtual bool setup_model_with_psse_string(string data); + virtual bool setup_model_with_bpa_string(string data); + + virtual void prepare_model_data_table(); + virtual void prepare_model_internal_variable_table(); + + virtual void setup_block_toolkit_and_parameters(); + + virtual void initialize(); + virtual void run(DYNAMIC_MODE mode); + virtual double get_active_current_command_in_pu_based_on_mbase(); + virtual double get_active_power_command_in_pu_based_on_mbase() const; + virtual double get_reactive_current_command_in_pu_based_on_mbase(); + virtual double get_reactive_power_command_in_pu_based_on_mbase(); + virtual double get_reactive_voltage_command_in_pu() const; + + + virtual void check(); + virtual void clear(); + virtual void report(); + virtual void save(); + virtual string get_standard_psse_string(bool export_internal_bus_number=false) const; + + virtual double get_model_data_with_name(string par_name) const; + virtual void set_model_data_with_name(string par_name, double value); + virtual double get_minimum_nonzero_time_constant_in_s(); + virtual double get_model_internal_variable_with_name(string var_name); + + virtual string get_dynamic_data_in_psse_format() const; + virtual string get_dynamic_data_in_bpa_format() const; + virtual string get_dynamic_data_in_steps_format() const; + private: + void copy_from_const_model(const PVEX& model); + + void trip_frequency_regulation(); + + double Xcomp; + FIRST_ORDER_BLOCK voltage_sensor; + double Fn; + FIRST_ORDER_BLOCK voltage_regulator_first_order_block; + INTEGRAL_BLOCK voltage_regulator_integrator; + FIRST_ORDER_BLOCK voltage_regulator_filter; + FIRST_ORDER_BLOCK active_power_sensor; + INTEGRAL_BLOCK Q_error_integrator; + unsigned int Voltage_Flag; + INTEGRAL_BLOCK V_error_integrator; + double EQmax, EQmin; + + DIFFERENTIAL_BLOCK virtual_inertia_emulator; + FIRST_ORDER_BLOCK frequency_droop_controller; + + double f_upper_pu, f_lower_pu; + INTEGRAL_BLOCK frequency_integral_controller; + double max_torque_rate, min_torque_rate; + INTEGRAL_BLOCK power_order_integrator; + double IPmax; + + bool frequency_regulation_enabled; + +}; + +#endif // PVEX_H diff --git a/code/steps/header/model/pvu_models/pv_irradiance_model/fileirrd.h b/code/steps/header/model/pvu_models/pv_irradiance_model/fileirrad.h similarity index 74% rename from code/steps/header/model/pvu_models/pv_irradiance_model/fileirrd.h rename to code/steps/header/model/pvu_models/pv_irradiance_model/fileirrad.h index 8435f7b4..88a9317c 100644 --- a/code/steps/header/model/pvu_models/pv_irradiance_model/fileirrd.h +++ b/code/steps/header/model/pvu_models/pv_irradiance_model/fileirrad.h @@ -13,6 +13,7 @@ class FILEIRRAD : public PV_IRRADIANCE_MODEL // inputs void set_solar_irradiance_serial_file(string file); string get_solar_irradiance_serial_file() const; + void load_solar_irradiance_from_file(); public: // specific model level virtual string get_model_name() const; @@ -45,7 +46,18 @@ class FILEIRRAD : public PV_IRRADIANCE_MODEL virtual string get_dynamic_data_in_bpa_format() const; virtual string get_dynamic_data_in_steps_format() const; private: + void clear_solar_irradiance_serial_file(); + void clear_solar_irradiance_data(); void copy_from_const_model(const FILEIRRAD& model); + void search_solar_irradiance_data_at_simulation_time(); + void set_previous_position(unsigned int pos); + unsigned int get_previous_position() const; + unsigned int get_solar_irradiance_record_count() const; + + char solar_irradiance_file[STEPS_LONG_STRING_SIZE]; + double solar_irradiance_data[STEPS_MAX_SOLAR_IRRADIANCE_RECORD_SIZE][3]; + double current_time, current_solar_irradiance, current_solar_irradiance_direction; + unsigned int previous_position; }; #endif // FILEIRRAD_H diff --git a/code/steps/header/model/pvu_models/pv_irradiance_model/fileirrd_test.h b/code/steps/header/model/pvu_models/pv_irradiance_model/fileirrad_test.h similarity index 100% rename from code/steps/header/model/pvu_models/pv_irradiance_model/fileirrd_test.h rename to code/steps/header/model/pvu_models/pv_irradiance_model/fileirrad_test.h diff --git a/code/steps/header/model/pvu_models/pv_irradiance_model/pv_irradiance_model.h b/code/steps/header/model/pvu_models/pv_irradiance_model/pv_irradiance_model.h index 5495505b..5535a6f2 100644 --- a/code/steps/header/model/pvu_models/pv_irradiance_model/pv_irradiance_model.h +++ b/code/steps/header/model/pvu_models/pv_irradiance_model/pv_irradiance_model.h @@ -10,7 +10,7 @@ class PV_IRRADIANCE_MODEL : public PVU_MODEL virtual ~PV_IRRADIANCE_MODEL(); virtual string get_model_type() const; - double get_nominal_irradiance_in_Wpm2() const; + double get_initial_irradiance_in_Wpm2() const; public: // specific model level virtual string get_model_name() const = 0; diff --git a/code/steps/header/model/pvu_models/pv_irradiance_model/pv_irradiance_models.h b/code/steps/header/model/pvu_models/pv_irradiance_model/pv_irradiance_models.h index c86c30fb..f15736aa 100644 --- a/code/steps/header/model/pvu_models/pv_irradiance_model/pv_irradiance_models.h +++ b/code/steps/header/model/pvu_models/pv_irradiance_model/pv_irradiance_models.h @@ -1,4 +1,5 @@ #ifndef PV_IRRADIANCE_MODELS_H #define PV_IRRADIANCE_MODELS_H +#include "header/model/pvu_models/pv_irradiance_model/fileirrad.h" #endif // PV_IRRADIANCE_MODELS_H diff --git a/code/steps/header/model/pvu_models/pv_panel_model/pv_panel_model.h b/code/steps/header/model/pvu_models/pv_panel_model/pv_panel_model.h index 52c82a13..aa20d646 100644 --- a/code/steps/header/model/pvu_models/pv_panel_model/pv_panel_model.h +++ b/code/steps/header/model/pvu_models/pv_panel_model/pv_panel_model.h @@ -4,14 +4,6 @@ #include "header/model/pvu_models/pvu_model.h" #include -enum PV_MODE -{ - PV_UNDERSPEED_MODE = -1, - PV_MPPT_MODE = 0, - PV_OVERSPEED_MODE = 1 -}; - - class PV_PANEL_MODEL : public PVU_MODEL { /* aero dynamic model for WTG @@ -28,6 +20,17 @@ class PV_PANEL_MODEL : public PVU_MODEL void copy_from_const_model(const PV_PANEL_MODEL& model); public: virtual string get_model_type() const; + + void set_S0_in_Wpm2(double S); + void set_Sref_in_Wpm2(double S); + + double get_S0_in_Wpm2() const; + double get_Sref_in_Wpm2() const; + + double get_solar_irradiance_in_Wpm2(); + double get_pv_unit_terminal_active_power_generation_in_pu_based_on_mbase() const; + + virtual double get_Pref_in_pu_base_on_mbase() = 0; public: virtual string get_model_name() const = 0; @@ -40,9 +43,6 @@ class PV_PANEL_MODEL : public PVU_MODEL virtual void initialize() = 0; virtual void run(DYNAMIC_MODE mode) = 0; - virtual double get_Cp(double lambda, double pitch_deg) const = 0; - virtual double get_derivative_of_Cp_over_lambda(double lambda, double pitch_deg) const = 0; - virtual void check() = 0; virtual void clear() = 0; virtual void report() = 0; @@ -61,6 +61,8 @@ class PV_PANEL_MODEL : public PVU_MODEL virtual string get_dynamic_data_in_bpa_format() const = 0; virtual string get_dynamic_data_in_steps_format() const = 0; private: + + double S0_Wpm2, Sref_Wpm2; }; #endif // PV_PANEL_MODEL_H diff --git a/code/steps/header/model/pvu_models/pv_panel_model/pv_panel_models.h b/code/steps/header/model/pvu_models/pv_panel_model/pv_panel_models.h index ad74929f..39929ecf 100644 --- a/code/steps/header/model/pvu_models/pv_panel_model/pv_panel_models.h +++ b/code/steps/header/model/pvu_models/pv_panel_model/pv_panel_models.h @@ -1,4 +1,6 @@ #ifndef PV_PANEL_MODELS_H #define PV_PANEL_MODELS_H +#include "header/model/pvu_models/pv_panel_model/pvpnlx.h" + #endif // PV_PANEL_MODELS_H diff --git a/code/steps/header/model/pvu_models/pv_panel_model/pvp0.h b/code/steps/header/model/pvu_models/pv_panel_model/pvpnlx.h similarity index 64% rename from code/steps/header/model/pvu_models/pv_panel_model/pvp0.h rename to code/steps/header/model/pvu_models/pv_panel_model/pvpnlx.h index dbd6411a..3b4d4be5 100644 --- a/code/steps/header/model/pvu_models/pv_panel_model/pvp0.h +++ b/code/steps/header/model/pvu_models/pv_panel_model/pvpnlx.h @@ -1,17 +1,31 @@ -#ifndef PVP0_H -#define PVP0_H +#ifndef PVPNLX_H +#define PVPNLX_H #include "header/model/pvu_models/pv_panel_model/pv_panel_model.h" #include -class PVP0 : public PV_PANEL_MODEL +class PVPNLX : public PV_PANEL_MODEL { public: - PVP0(STEPS& toolkit); - PVP0(const PVP0& model); - virtual ~PVP0(); - virtual PVP0& operator=(const PVP0& model); + PVPNLX(STEPS& toolkit); + PVPNLX(const PVPNLX& model); + virtual ~PVPNLX(); + virtual PVPNLX& operator=(const PVPNLX& model); public: + void set_Pmsta_in_pu_based_on_mbase(double P); + void set_b(double b); + void set_Krp(double Krp); + + double get_Pmsta_in_pu_based_on_mbase() const; + double get_b() const; + double get_Krp() const; + + double get_Pmmp_in_pu(double S); + double get_Pref_in_pu(double S); + void initialize_S0(); + + virtual double get_Pref_in_pu_base_on_mbase(); + virtual string get_model_name() const; virtual bool setup_model_with_steps_string_vector(vector& data); @@ -41,7 +55,10 @@ class PVP0 : public PV_PANEL_MODEL virtual string get_dynamic_data_in_bpa_format() const; virtual string get_dynamic_data_in_steps_format() const; private: - void copy_from_const_model(const PVP0& model); + void copy_from_const_model(const PVPNLX& model); + + double Pmsta, b, Krp; + }; -#endif // PVP0_H +#endif // PVPNLX_H diff --git a/code/steps/header/model/pvu_models/pv_panel_model/pvp0_test.h b/code/steps/header/model/pvu_models/pv_panel_model/pvpnlx_test.h similarity index 70% rename from code/steps/header/model/pvu_models/pv_panel_model/pvp0_test.h rename to code/steps/header/model/pvu_models/pv_panel_model/pvpnlx_test.h index 83e38f0f..9620f3b9 100644 --- a/code/steps/header/model/pvu_models/pv_panel_model/pvp0_test.h +++ b/code/steps/header/model/pvu_models/pv_panel_model/pvpnlx_test.h @@ -1,5 +1,5 @@ -#ifndef PVP0_TEST_H -#define PVP0_TEST_H +#ifndef PVPNLX_TEST_H +#define PVPNLX_TEST_H #include #include @@ -12,15 +12,15 @@ #include "header/model/pvu_models/pv_panel_model/pv_panel_model_test.h" -#include "header/model/pvu_models/pv_panel_model/pvp0.h" +#include "header/model/pvu_models/pv_panel_model/pvpnlx.h" #include "header/STEPS.h" using namespace std; -class PVP0_TEST : public PV_PANEL_MODEL_TEST +class PVPNLX_TEST : public PV_PANEL_MODEL_TEST { public: - PVP0_TEST(); + PVPNLX_TEST(); protected: virtual void setup(); virtual void tear_down(); @@ -31,4 +31,4 @@ class PVP0_TEST : public PV_PANEL_MODEL_TEST }; -#endif//PVP0_TEST_H +#endif//PVPNLX_TEST_H diff --git a/code/steps/header/model/pvu_models/pv_vrt_model/pv_vrt_model.h b/code/steps/header/model/pvu_models/pv_vrt_model/pv_vrt_model.h index 489e28ba..41faf842 100644 --- a/code/steps/header/model/pvu_models/pv_vrt_model/pv_vrt_model.h +++ b/code/steps/header/model/pvu_models/pv_vrt_model/pv_vrt_model.h @@ -38,6 +38,7 @@ class PV_VRT_MODEL : public PVU_MODEL virtual void initialize() = 0; virtual void run(DYNAMIC_MODE mode) = 0; + virtual bool is_in_vrt_status() const = 0; virtual VRT_STATUS get_lvrt_status() const = 0; virtual VRT_STATUS get_hvrt_status() const = 0; diff --git a/code/steps/header/model/pvu_models/supported_pvu_models.h b/code/steps/header/model/pvu_models/supported_pvu_models.h new file mode 100644 index 00000000..cbfd5a9a --- /dev/null +++ b/code/steps/header/model/pvu_models/supported_pvu_models.h @@ -0,0 +1,11 @@ +#ifndef SUPPORTED_PVU_MODELS_H +#define SUPPORTED_PVU_MODELS_H + +#include "header/model/pvu_models/pv_converter_model/pv_converter_models.h" +#include "header/model/pvu_models/pv_panel_model/pv_panel_models.h" +#include "header/model/pvu_models/pv_electrical_model/pv_electrical_models.h" +#include "header/model/pvu_models/pv_irradiance_model/pv_irradiance_models.h" +#include "header/model/pvu_models/pv_vrt_model/pv_vrt_models.h" +#include "header/model/pvu_models/pv_relay_model/pv_relay_models.h" + +#endif // SUPPORTED_PVU_MODELS_H diff --git a/code/steps/header/model/wtg_models/wind_speed_model/filewind.h b/code/steps/header/model/wtg_models/wind_speed_model/filewind.h index 02cfbea6..58013942 100644 --- a/code/steps/header/model/wtg_models/wind_speed_model/filewind.h +++ b/code/steps/header/model/wtg_models/wind_speed_model/filewind.h @@ -62,7 +62,7 @@ class FILEWIND : public WIND_SPEED_MODEL unsigned int get_wind_record_count() const; char wind_speed_file[STEPS_LONG_STRING_SIZE]; - double wind_data[STEPS_MAX_WIND_RECORD_SIZE][3]; + double wind_data[STEPS_MAX_WIND_SPEED_RECORD_SIZE][3]; double current_time, current_wind_speed, current_wind_direction; unsigned int previous_position; }; diff --git a/code/steps/header/model/wtg_models/wt_vrt_model/wt_vrt_model.h b/code/steps/header/model/wtg_models/wt_vrt_model/wt_vrt_model.h index 952da8a3..b678c3d4 100644 --- a/code/steps/header/model/wtg_models/wt_vrt_model/wt_vrt_model.h +++ b/code/steps/header/model/wtg_models/wt_vrt_model/wt_vrt_model.h @@ -26,8 +26,6 @@ class WT_VRT_MODEL : public WTG_MODEL complex get_wt_generator_terminal_generation_in_pu_based_on_mbase() const; complex get_wt_generator_terminal_complex_current_in_pu() const; double get_wt_generator_terminal_current_in_pu() const; - - bool is_in_vrt_status() const; public: // specific exciter virtual string get_model_name() const = 0; @@ -40,6 +38,7 @@ class WT_VRT_MODEL : public WTG_MODEL virtual void initialize() = 0; virtual void run(DYNAMIC_MODE mode) = 0; + virtual bool is_in_vrt_status() const = 0; virtual VRT_STATUS get_lvrt_status() const = 0; virtual VRT_STATUS get_hvrt_status() const = 0; diff --git a/code/steps/header/model/wtg_models/wt_vrt_model/wtvrt3.h b/code/steps/header/model/wtg_models/wt_vrt_model/wtvrt3.h index dfbc6102..0c8058fa 100644 --- a/code/steps/header/model/wtg_models/wt_vrt_model/wtvrt3.h +++ b/code/steps/header/model/wtg_models/wt_vrt_model/wtvrt3.h @@ -99,6 +99,8 @@ class WTVRT3: public WT_VRT_MODEL virtual void initialize(); virtual void run(DYNAMIC_MODE mode); + + virtual bool is_in_vrt_status() const; virtual VRT_STATUS get_lvrt_status() const; virtual VRT_STATUS get_hvrt_status() const; diff --git a/code/steps/header/network/network_matrix.h b/code/steps/header/network/network_matrix.h index cf361fea..bfedc81c 100644 --- a/code/steps/header/network/network_matrix.h +++ b/code/steps/header/network/network_matrix.h @@ -143,6 +143,10 @@ class NETWORK_MATRIX void add_generator_to_dynamic_network(const GENERATOR& gen); void add_wt_generators_to_dynamic_network(); void add_wt_generator_to_dynamic_network(WT_GENERATOR& gen); + void add_pv_units_to_dynamic_network(); + void add_pv_unit_to_dynamic_network(PV_UNIT& pv_unit); + void add_energy_storages_to_dynamic_network(); + void add_energy_storage_to_dynamic_network(ENERGY_STORAGE& es); void add_motor_loads_to_dynamic_network(); void add_motor_load_to_dynamic_network(const LOAD& load); @@ -171,6 +175,8 @@ class NETWORK_MATRIX void add_direct_driven_wtg_to_positive_sequence_network(const WT_GENERATOR& wt_gen); void add_pv_units_to_positive_sequence_network(); void add_pv_unit_to_positive_sequence_network(const PV_UNIT& pv_unit); + void add_energy_storages_to_positive_sequence_network(); + void add_energy_storage_to_positive_sequence_network(const ENERGY_STORAGE& es); void add_fixed_shunts_to_positive_sequence_network(); void add_hvdcs_to_positive_sequence_network(); void add_hvdc_to_positive_sequence_network(const HVDC& hvdc); @@ -189,6 +195,8 @@ class NETWORK_MATRIX void add_wt_generator_to_negative_sequence_network(const WT_GENERATOR& wt_gen); void add_pv_units_to_negative_sequence_network(); void add_pv_unit_to_negative_sequence_network(const PV_UNIT& pv_unit); + void add_energy_storages_to_negative_sequence_network(); + void add_energy_storage_to_negative_sequence_network(const ENERGY_STORAGE& es); void add_fixed_shunts_to_negative_sequence_network(); void add_lines_to_zero_sequence_network(); @@ -209,6 +217,8 @@ class NETWORK_MATRIX void add_wt_generator_to_zero_sequence_network(const WT_GENERATOR& wt_gen); void add_pv_units_to_zero_sequence_network(); void add_pv_unit_to_zero_sequence_network(const PV_UNIT& pv_unit); + void add_energy_storages_to_zero_sequence_network(); + void add_energy_storage_to_zero_sequence_network(const ENERGY_STORAGE& es); void add_fixed_shunts_to_zero_sequence_network(); void add_fixed_shunt_to_zero_sequence_network(const FIXED_SHUNT& shunt); diff --git a/code/steps/main_tests.cpp b/code/steps/main_tests.cpp index e58c4997..def3887d 100644 --- a/code/steps/main_tests.cpp +++ b/code/steps/main_tests.cpp @@ -351,6 +351,10 @@ int main(int argc, char* argv[]) ts.add(unique_ptr(new FILEWIND_TEST)); ts.add(unique_ptr(new PVGU1_TEST)); + ts.add(unique_ptr(new PVCVX_TEST)); + ts.add(unique_ptr(new PVEX_TEST)); + ts.add(unique_ptr(new FILEIRRAD_TEST)); + ts.add(unique_ptr(new PVPNLX_TEST)); ts.add(unique_ptr(new DYNAMICS_SIMULATOR_TEST)); diff --git a/code/steps/source/data_imexporter/steps_dynamics_imexporter.cpp b/code/steps/source/data_imexporter/steps_dynamics_imexporter.cpp index d5e9ef5c..495f8c70 100644 --- a/code/steps/source/data_imexporter/steps_dynamics_imexporter.cpp +++ b/code/steps/source/data_imexporter/steps_dynamics_imexporter.cpp @@ -175,6 +175,10 @@ void STEPS_IMEXPORTER::load_one_model(vector& data) if(model_name=="WTVRT3") { add_WTVRT3_model(data); return;} if(model_name=="PVGU1") { add_PVGU1_model(data); return;} + if(model_name=="PVCVX") { add_PVCVX_model(data); return;} + if(model_name=="PVEX") { add_PVEX_model(data); return;} + if(model_name=="FILEIRRAD") { add_FILEIRRAD_model(data); return;} + if(model_name=="PVPNLX") { add_PVPNLX_model(data); return;} osstream<<"Warning. Dynamic model '"<& data) } } + +void STEPS_IMEXPORTER::add_PVCVX_model(vector& data) +{ + if(get_dynamic_model_name(data) != "PVCVX") + return; + + if(data.size()<3) + return; + + STEPS& toolkit = get_toolkit(); + POWER_SYSTEM_DATABASE& psdb = toolkit.get_power_system_database(); + DYNAMIC_MODEL_DATABASE& dmdb = toolkit.get_dynamic_model_database(); + DEVICE_ID did = get_pv_unit_device_id_from_string_vector(data); + + PV_UNIT* pvu = psdb.get_pv_unit(did); + if(pvu != NULL) + { + PVCVX model(toolkit); + model.set_device_id(did); + bool successful = model.setup_model_with_steps_string_vector(data); + if(successful) + dmdb.add_model(&model); + else + { + ostringstream osstream; + osstream<<"Warning. Invalid PVCVX model is built, but will not be set for "<get_compound_device_name(); + toolkit.show_information_with_leading_time_stamp(osstream); + } + } +} + +void STEPS_IMEXPORTER::add_PVEX_model(vector& data) +{ + if(get_dynamic_model_name(data) != "PVEX") + return; + + if(data.size()<3) + return; + + STEPS& toolkit = get_toolkit(); + POWER_SYSTEM_DATABASE& psdb = toolkit.get_power_system_database(); + DYNAMIC_MODEL_DATABASE& dmdb = toolkit.get_dynamic_model_database(); + DEVICE_ID did = get_pv_unit_device_id_from_string_vector(data); + + PV_UNIT* pvu = psdb.get_pv_unit(did); + if(pvu != NULL) + { + PVEX model(toolkit); + model.set_device_id(did); + bool successful = model.setup_model_with_steps_string_vector(data); + if(successful) + dmdb.add_model(&model); + else + { + ostringstream osstream; + osstream<<"Warning. Invalid PVEX model is built, but will not be set for "<get_compound_device_name(); + toolkit.show_information_with_leading_time_stamp(osstream); + } + } +} + +void STEPS_IMEXPORTER::add_FILEIRRAD_model(vector& data) +{ + if(get_dynamic_model_name(data) != "FILEIRRAD") + return; + + if(data.size()<3) + return; + + STEPS& toolkit = get_toolkit(); + POWER_SYSTEM_DATABASE& psdb = toolkit.get_power_system_database(); + DYNAMIC_MODEL_DATABASE& dmdb = toolkit.get_dynamic_model_database(); + DEVICE_ID did = get_pv_unit_device_id_from_string_vector(data); + + PV_UNIT* pvu = psdb.get_pv_unit(did); + if(pvu != NULL) + { + FILEIRRAD model(toolkit); + model.set_device_id(did); + bool successful = model.setup_model_with_steps_string_vector(data); + if(successful) + dmdb.add_model(&model); + else + { + ostringstream osstream; + osstream<<"Warning. Invalid FILEIRRAD model is built, but will not be set for "<get_compound_device_name(); + toolkit.show_information_with_leading_time_stamp(osstream); + } + } +} + +void STEPS_IMEXPORTER::add_PVPNLX_model(vector& data) +{ + if(get_dynamic_model_name(data) != "PVPNLX") + return; + + if(data.size()<3) + return; + + STEPS& toolkit = get_toolkit(); + POWER_SYSTEM_DATABASE& psdb = toolkit.get_power_system_database(); + DYNAMIC_MODEL_DATABASE& dmdb = toolkit.get_dynamic_model_database(); + DEVICE_ID did = get_pv_unit_device_id_from_string_vector(data); + + PV_UNIT* pvu = psdb.get_pv_unit(did); + if(pvu != NULL) + { + PVPNLX model(toolkit); + model.set_device_id(did); + bool successful = model.setup_model_with_steps_string_vector(data); + if(successful) + dmdb.add_model(&model); + else + { + ostringstream osstream; + osstream<<"Warning. Invalid PVPNLX model is built, but will not be set for "<get_compound_device_name(); + toolkit.show_information_with_leading_time_stamp(osstream); + } + } +} + void STEPS_IMEXPORTER::export_dynamic_data(string file) { ofstream fid(file); diff --git a/code/steps/source/device/pv_unit.cpp b/code/steps/source/device/pv_unit.cpp index ca448de7..d54d235e 100644 --- a/code/steps/source/device/pv_unit.cpp +++ b/code/steps/source/device/pv_unit.cpp @@ -65,7 +65,7 @@ unsigned int PV_UNIT::get_unit_bus() const return get_source_bus(); } -void PV_UNIT::set_number_of_lumped_pv_units(unsigned int n) +void PV_UNIT::set_number_of_lumped_pv_units(double n) { if(n==0) n = 1; @@ -77,7 +77,7 @@ void PV_UNIT::set_rated_power_per_pv_unit_in_MW(double P) rated_power_per_pv_unit_in_MW = P; } -unsigned int PV_UNIT::get_number_of_lumped_pv_units() const +double PV_UNIT::get_number_of_lumped_pv_units() const { return number_of_lumped_pv_units; } @@ -114,12 +114,12 @@ void PV_UNIT::run(DYNAMIC_MODE mode) return; } - if(irrd!=NULL and irrd->is_model_active()) - irrd->initialize(); - if(panel!=NULL and panel->is_model_active()) panel->initialize(); + if(irrd!=NULL and irrd->is_model_active()) + irrd->initialize(); + if(elec!=NULL and elec->is_model_active()) elec->initialize(); @@ -135,17 +135,32 @@ void PV_UNIT::run(DYNAMIC_MODE mode) case UPDATE_MODE: { if(vrt!=NULL and vrt->is_model_active()) + { vrt->run(mode); + if(elec!=NULL and elec->is_model_active()) + { + if(elec->is_model_bypassed() + and (not vrt->is_in_vrt_status())) + elec->unbypass_model(); + else + { + if(not elec->is_model_bypassed() + and (vrt->is_in_vrt_status())) + elec->bypass_model(); + } + } + } + if(irrd!=NULL and irrd->is_model_active()) irrd->run(mode); - if(elec!=NULL and elec->is_model_active()) - elec->run(mode); - if(panel!=NULL and panel->is_model_active()) panel->run(mode); + if(elec!=NULL and elec->is_model_active() and (not elec->is_model_bypassed())) + elec->run(mode); + if(conv!=NULL and conv->is_model_active()) conv->run(mode); break; @@ -525,6 +540,7 @@ void PV_UNIT::set_sequence_parameter_import_flag(bool flag) { sequence_parameter_import_flag = flag; } + bool PV_UNIT::get_sequence_parameter_import_flag() const { return sequence_parameter_import_flag; diff --git a/code/steps/source/dynamic_model_database.cpp b/code/steps/source/dynamic_model_database.cpp index 3fdbbbb1..0a620b1b 100644 --- a/code/steps/source/dynamic_model_database.cpp +++ b/code/steps/source/dynamic_model_database.cpp @@ -221,6 +221,10 @@ unsigned int DYNAMIC_MODEL_DATABASE::get_model_size(MODEL* model) const if(model_name=="PVCV0") return sizeof(PVCV0); if(model_name=="PVGU1") return sizeof(PVGU1); + if(model_name=="PVCVX") return sizeof(PVCVX); + if(model_name=="PVEX") return sizeof(PVEX); + if(model_name=="FILEIRRAD") return sizeof(FILEIRRAD); + if(model_name=="PVPNLX") return sizeof(PVPNLX); if(model_name=="ARXL") return sizeof(ARXL); diff --git a/code/steps/source/model/pvu_models/pv_converter_model/pv_converter_model.cpp b/code/steps/source/model/pvu_models/pv_converter_model/pv_converter_model.cpp index d873f7fd..033b1851 100644 --- a/code/steps/source/model/pvu_models/pv_converter_model/pv_converter_model.cpp +++ b/code/steps/source/model/pvu_models/pv_converter_model/pv_converter_model.cpp @@ -10,11 +10,12 @@ using namespace std; PV_CONVERTER_MODEL::PV_CONVERTER_MODEL(STEPS& toolkit) : PVU_MODEL(toolkit) { - set_allowed_device_type_CAN_ONLY_BE_CALLED_BY_SPECIFIC_MODEL_CONSTRUCTOR(STEPS_PV_UNIT); - set_current_source_flag(true); set_initial_active_current_command_in_pu_based_on_mbase(0.0); set_initial_reactive_current_command_in_pu_based_on_mbase(0.0); + set_initial_active_power_command_in_pu_based_on_mbase(0.0); + set_initial_reactive_power_command_in_pu_based_on_mbase(0.0); + set_initial_reactive_voltage_command_in_pu(0.0); } PV_CONVERTER_MODEL::~PV_CONVERTER_MODEL() @@ -27,6 +28,7 @@ string PV_CONVERTER_MODEL::get_model_type() const return "PV CONVERTER"; } + void PV_CONVERTER_MODEL::set_current_source_flag(bool flag) { current_source_flag = flag; @@ -77,33 +79,104 @@ double PV_CONVERTER_MODEL::get_initial_reactive_voltage_command_in_pu() const return EQ_command0; } +void PV_CONVERTER_MODEL::set_initial_active_power_command_in_pu_based_on_mbase(double P_command) +{ + P_command0 = P_command; +} + +double PV_CONVERTER_MODEL::get_initial_active_power_command_in_pu_based_on_mbase() const +{ + return P_command0; +} + +void PV_CONVERTER_MODEL::set_initial_reactive_power_command_in_pu_based_on_mbase(double Q_command) +{ + Q_command0 = Q_command; +} + +double PV_CONVERTER_MODEL::get_initial_reactive_power_command_in_pu_based_on_mbase() const +{ + return Q_command0; +} + double PV_CONVERTER_MODEL::get_active_current_command_in_pu_based_on_mbase() { PV_UNIT* pv_unit = get_pv_unit_pointer(); - PV_ELECTRICAL_MODEL* model = pv_unit->get_pv_electrical_model(); - if(model!=NULL and model->is_model_initialized()) - return model->get_active_current_command_in_pu_based_on_mbase(); + PV_ELECTRICAL_MODEL* elec_model = pv_unit->get_pv_electrical_model(); + PV_VRT_MODEL* vrt_model = pv_unit->get_pv_vrt_model(); + if(elec_model!=NULL and elec_model->is_model_initialized() and not elec_model->is_model_bypassed()) + return elec_model->get_active_current_command_in_pu_based_on_mbase(); else - return get_initial_active_current_command_in_pu_based_on_mbase(); + { + if(vrt_model!=NULL and vrt_model->is_model_initialized()) + return vrt_model->get_active_current_command_in_pu_based_on_mbase(); + else + return get_initial_active_current_command_in_pu_based_on_mbase(); + } } double PV_CONVERTER_MODEL::get_reactive_current_command_in_pu_based_on_mbase() { PV_UNIT* pv_unit = get_pv_unit_pointer(); - PV_ELECTRICAL_MODEL* model = pv_unit->get_pv_electrical_model(); - if(model!=NULL and model->is_model_initialized()) - return model->get_reactive_current_command_in_pu_based_on_mbase(); + PV_ELECTRICAL_MODEL* elec_model = pv_unit->get_pv_electrical_model(); + PV_VRT_MODEL* vrt_model = pv_unit->get_pv_vrt_model(); + if(elec_model!=NULL and elec_model->is_model_initialized() and not elec_model->is_model_bypassed()) + return elec_model->get_reactive_current_command_in_pu_based_on_mbase(); else - return get_initial_reactive_current_command_in_pu_based_on_mbase(); + { + if(vrt_model!=NULL and vrt_model->is_model_initialized()) + return vrt_model->get_reactive_current_command_in_pu_based_on_mbase(); + else + return get_initial_reactive_current_command_in_pu_based_on_mbase(); + } } double PV_CONVERTER_MODEL::get_reactive_voltage_command_in_pu() const { PV_UNIT* pv_unit = get_pv_unit_pointer(); - PV_ELECTRICAL_MODEL* model = pv_unit->get_pv_electrical_model(); - if(model!=NULL and model->is_model_initialized()) - return model->get_reactive_voltage_command_in_pu(); + PV_ELECTRICAL_MODEL* elec_model = pv_unit->get_pv_electrical_model(); + PV_VRT_MODEL* vrt_model = pv_unit->get_pv_vrt_model(); + if(elec_model!=NULL and elec_model->is_model_initialized() and not elec_model->is_model_bypassed()) + return elec_model->get_reactive_voltage_command_in_pu(); + else + { + if(vrt_model!=NULL and vrt_model->is_model_initialized()) + return vrt_model->get_reactive_voltage_command_in_pu(); + else + return get_initial_reactive_voltage_command_in_pu(); + } +} + +double PV_CONVERTER_MODEL::get_active_power_command_in_pu_based_on_mbase() +{ + PV_UNIT* pv_unit = get_pv_unit_pointer(); + PV_ELECTRICAL_MODEL* elec_model = pv_unit->get_pv_electrical_model(); + PV_VRT_MODEL* vrt_model = pv_unit->get_pv_vrt_model(); + if(elec_model!=NULL and elec_model->is_model_initialized() and not elec_model->is_model_bypassed()) + return elec_model->get_active_power_command_in_pu_based_on_mbase(); else - return get_initial_reactive_voltage_command_in_pu(); + { + if(vrt_model!=NULL and vrt_model->is_model_initialized()) + return vrt_model->get_active_power_command_in_pu_based_on_mbase(); + else + return get_initial_active_power_command_in_pu_based_on_mbase(); + } } + +double PV_CONVERTER_MODEL::get_reactive_power_command_in_pu_based_on_mbase() +{ + PV_UNIT* pv_unit = get_pv_unit_pointer(); + PV_ELECTRICAL_MODEL* elec_model = pv_unit->get_pv_electrical_model(); + PV_VRT_MODEL* vrt_model = pv_unit->get_pv_vrt_model(); + if(elec_model!=NULL and elec_model->is_model_initialized() and not elec_model->is_model_bypassed()) + return elec_model->get_reactive_power_command_in_pu_based_on_mbase(); + else + { + if(vrt_model!=NULL and vrt_model->is_model_initialized()) + return vrt_model->get_reactive_power_command_in_pu_based_on_mbase(); + else + return get_initial_reactive_power_command_in_pu_based_on_mbase(); + } +} + diff --git a/code/steps/source/model/pvu_models/pv_converter_model/pvcvx.cpp b/code/steps/source/model/pvu_models/pv_converter_model/pvcvx.cpp new file mode 100644 index 00000000..885209d2 --- /dev/null +++ b/code/steps/source/model/pvu_models/pv_converter_model/pvcvx.cpp @@ -0,0 +1,705 @@ +#include "header/model/pvu_models/pv_converter_model/pvcvx.h" +#include "header/basic/utility.h" +#include "header/steps_namespace.h" +#include +#include +#include +using namespace std; + +PVCVX::PVCVX(STEPS& toolkit) : PV_CONVERTER_MODEL(toolkit), + active_current_commander(toolkit), + reactive_voltage_commander(toolkit), + PLL_frequency_integrator(toolkit), + PLL_angle_integrator(toolkit) +{ + clear(); +} + +PVCVX::~PVCVX() +{ +} + +void PVCVX::clear() +{ + set_model_float_parameter_count(5); + + set_current_source_flag(false); + + set_Xeq_in_pu(0.0); + + active_current_commander.set_limiter_type(NO_LIMITER); + active_current_commander.set_K(1.0); + active_current_commander.set_T_in_s(0.02); + + reactive_voltage_commander.set_limiter_type(NO_LIMITER); + reactive_voltage_commander.set_K(1.0); + reactive_voltage_commander.set_T_in_s(0.02); + + PLL_frequency_integrator.set_limiter_type(NON_WINDUP_LIMITER); + + PLL_angle_integrator.set_limiter_type(NO_LIMITER); +} + +void PVCVX::copy_from_const_model(const PVCVX& model) +{ + STEPS& toolkit = model.get_toolkit(); + set_toolkit(toolkit); + active_current_commander.set_toolkit(toolkit); + reactive_voltage_commander.set_toolkit(toolkit); + PLL_frequency_integrator.set_toolkit(toolkit); + PLL_angle_integrator.set_toolkit(toolkit); + + clear(); + set_Xeq_in_pu(model.get_Xeq_in_pu()); + set_KPLL(model.get_KPLL()); + set_KIPLL(model.get_KIPLL()); + set_PLLmax(model.get_PLLmax()); +} + +PVCVX::PVCVX(const PVCVX& model):PV_CONVERTER_MODEL(model.get_toolkit()), + active_current_commander(model.get_toolkit()), + reactive_voltage_commander(model.get_toolkit()), + PLL_frequency_integrator(model.get_toolkit()), + PLL_angle_integrator(model.get_toolkit()) +{ + copy_from_const_model(model); +} + +PVCVX& PVCVX::operator=(const PVCVX& model) +{ + if(this==&model) + return *this; + + copy_from_const_model(model); + + return (*this); +} + +void PVCVX::set_Xeq_in_pu(double xeq) +{ + Xeq = xeq; +} + +void PVCVX::set_KPLL(double K) +{ + KPLL = K; +} + +void PVCVX::set_KIPLL(double K) +{ + PLL_frequency_integrator.set_T_in_s(1.0/K); +} + +void PVCVX::set_PLLmax(double pmax) +{ + PLL_frequency_integrator.set_upper_limit(pmax); +} + +double PVCVX::get_Xeq_in_pu() const +{ + return Xeq; +} + +double PVCVX::get_KPLL() const +{ + return KPLL; +} + +double PVCVX::get_KIPLL() const +{ + return 1.0/PLL_frequency_integrator.get_T_in_s(); +} + +double PVCVX::get_PLLmax() const +{ + return PLL_frequency_integrator.get_upper_limit(); +} + +string PVCVX::get_model_name() const +{ + return "PVCVX"; +} + +bool PVCVX::setup_model_with_steps_string_vector(vector& data) +{ + ostringstream osstream; + + bool is_successful = false; + if(data.size()>=8) + { + string model_name = get_string_data(data[0],""); + if(model_name==get_model_name()) + { + unsigned int ibus; + string id; + double xeq, kpll, kipll, pllmax, prate; + + ibus = (unsigned int)(get_integer_data(data[1],"0")); + id = get_string_data(data[2],""); + + unsigned int i=3; + xeq = get_double_data(data[i],"0.0"); i++; + kpll = get_double_data(data[i],"0.0"); i++; + kipll = get_double_data(data[i],"0.0"); i++; + pllmax = get_double_data(data[i],"0.0"); i++; + prate = get_double_data(data[i],"0.0"); + + DEVICE_ID did = get_pv_unit_device_id(ibus, id); + STEPS& toolkit = get_toolkit(); + POWER_SYSTEM_DATABASE& psdb = toolkit.get_power_system_database(); + PV_UNIT* pv_unit = psdb.get_pv_unit(did); + if(pv_unit==NULL) + { + osstream<<"Error when loading data to build "<get_mbase_in_MVA(); + double n_lumped_turbine; + n_lumped_turbine = mbase/prate; + if(fabs(n_lumped_turbine-round(n_lumped_turbine))>0.1) + { + osstream<<"Warning. The MBASE of "<set_number_of_lumped_pv_units(n_lumped_turbine); + pv_unit->set_rated_power_per_pv_unit_in_MW(prate); + + + set_Xeq_in_pu(xeq); + set_KPLL(kpll); + set_KIPLL(kipll); + set_PLLmax(pllmax); + + complex Z = pv_unit->get_source_impedance_in_pu(); + if(fabs(Z.imag()-xeq)>DOUBLE_EPSILON) + { + osstream<<"Warning. The Xeq of "<(Z.real(), xeq); + pv_unit->set_source_impedance_in_pu(Z); + } + + is_successful = true; + + return is_successful; + } + else + return is_successful; + } + else + return is_successful; +} + +bool PVCVX::setup_model_with_psse_string(string data) +{ + vector record = psse_dyr_string2steps_string_vector(data); + return setup_model_with_steps_string_vector(record); +} + +bool PVCVX::setup_model_with_bpa_string(string data) +{ + ostringstream osstream; + osstream<Zsource(0.0, xeq); + + double P = pv_unit->get_p_generation_in_MW()/n_lumped; + double Q = pv_unit->get_q_generation_in_MVar()/n_lumped; + complex S(P/mbase,Q/mbase); + + + complex Vxy = get_terminal_complex_voltage_in_pu(); + double angle_in_rad = get_terminal_voltage_angle_in_rad(); + // ignore voltage angle + complex Ixy = conj(S/Vxy); + complex Isource = Ixy + Vxy/Zsource; + + double Ix = Isource.real(); + double Iy = Isource.imag(); + + double sine = steps_sin(angle_in_rad), cosine = steps_cos(angle_in_rad); + double IP = Ix*cosine + Iy*sine; + double IQ =-Ix*sine + Iy*cosine; + + double EQ = IQ*(-xeq); + + active_current_commander.set_output(IP); + active_current_commander.initialize(); + + reactive_voltage_commander.set_output(EQ); + reactive_voltage_commander.initialize(); + + if(kipll!=0.0) + { + PLL_frequency_integrator.set_output(0.0); + PLL_frequency_integrator.initialize(); + } + + PLL_angle_integrator.set_output(angle_in_rad); + PLL_angle_integrator.initialize(); + + set_initial_active_current_command_in_pu_based_on_mbase(IP); + set_initial_reactive_current_command_in_pu_based_on_mbase(IQ); + set_initial_reactive_voltage_command_in_pu(EQ); + + set_flag_model_initialized_as_true(); + + if(toolkit.is_detailed_log_enabled()) + { + osstream< Vxy = get_terminal_complex_voltage_in_pu(); + double angle_in_rad = get_terminal_voltage_angle_in_rad(); + double angle_in_deg = rad2deg(angle_in_rad); + + double IP = get_active_current_command_in_pu_based_on_mbase(); + + active_current_commander.set_input(IP); + active_current_commander.run(mode); + + double EQ = get_reactive_voltage_command_in_pu(); + + reactive_voltage_commander.set_input(EQ); + reactive_voltage_commander.run(mode); + + double kpll = get_KPLL(); + double kipll = get_KIPLL(); + if(kpll!=0.0 or kipll!=0.0) + { + double Vr = Vxy.real(); + double Vi = Vxy.imag(); + + double angle = get_pll_angle_in_rad(); + double Vy = -Vr*steps_sin(angle)+Vi*steps_cos(angle); + + double input = Vy*kpll/wbase; + PLL_frequency_integrator.set_input(input); + PLL_frequency_integrator.run(mode); + + double output = PLL_frequency_integrator.get_output(); + input += output; + + double pllmax = get_PLLmax(); + if(input>=-pllmax and input<=pllmax) + ; + else + { + if(input>pllmax) + input = pllmax; + else + input = -pllmax; + } + + PLL_angle_integrator.set_input(input); + PLL_angle_integrator.run(mode); + } + else + { + set_pll_angle_in_deg(angle_in_deg); + } + if(mode==UPDATE_MODE) + set_flag_model_updated_as_true(); +} + +complex PVCVX::get_source_Norton_equivalent_complex_current_in_pu_in_xy_axis_based_on_sbase() +{ + STEPS& toolkit = get_toolkit(); + double one_over_sbase = toolkit.get_one_over_system_base_power_in_one_over_MVA(); + double mbase = get_mbase_in_MVA(); + + double Xeq = get_Xeq_in_pu(); + + double Ip = active_current_commander.get_output(); + double Iq = -reactive_voltage_commander.get_output()/Xeq; + + double pll_angle = get_pll_angle_in_rad(); + + double sine = steps_sin(pll_angle), cosine = steps_cos(pll_angle); + double Ix = Ip*cosine - Iq*sine; + double Iy = Ip*sine + Iq*cosine; + + complex Ixy(Ix, Iy); + //cout<<"Norton Ixy based on mbase = "< PVCVX::get_terminal_complex_current_in_pu_in_xy_axis_based_on_mbase() +{ + STEPS& toolkit = get_toolkit(); + POWER_SYSTEM_DATABASE& psdb = toolkit.get_power_system_database(); + double sbase = psdb.get_system_base_power_in_MVA(); + double one_over_mbase = get_one_over_mbase_in_one_over_MVA(); + complex Ixy = get_terminal_complex_current_in_pu_in_xy_axis_based_on_sbase(); + return Ixy*(sbase*one_over_mbase); +} + +complex PVCVX::get_terminal_complex_current_in_pu_in_xy_axis_based_on_sbase() +{ + STEPS& toolkit = get_toolkit(); + POWER_SYSTEM_DATABASE& psdb = toolkit.get_power_system_database(); + double sbase = psdb.get_system_base_power_in_MVA(); + double one_over_mbase = get_one_over_mbase_in_one_over_MVA(); + + complex Zsource (0.0, get_Xeq_in_pu()); + Zsource *= one_over_mbase; + Zsource *= sbase; + + complex Ixy_norton = get_source_Norton_equivalent_complex_current_in_pu_in_xy_axis_based_on_sbase(); + complex Vxy = get_terminal_complex_voltage_in_pu(); + complex Ixy_term = Ixy_norton - Vxy/Zsource; + return Ixy_term; +} + +double PVCVX::get_terminal_current_in_pu_based_on_mbase() +{ + return steps_fast_complex_abs(get_terminal_complex_current_in_pu_in_xy_axis_based_on_mbase()); +} + +double PVCVX::get_terminal_current_in_pu_based_on_sbase() +{ + return steps_fast_complex_abs(get_terminal_complex_current_in_pu_in_xy_axis_based_on_sbase()); +} + + +void PVCVX::check() +{ + ; +} + +void PVCVX::report() +{ + ostringstream osstream; + osstream<set_number_of_lumped_pv_units((unsigned int)(value)); + } + if(par_name=="KPLL") + return set_KPLL(value); + if(par_name=="KIPLL") + return set_KIPLL(value); + if(par_name=="PLLMAX") + return set_PLLmax(value); + if(par_name=="PN") + { + PV_UNIT* pv_unit= get_pv_unit_pointer(); + return pv_unit->set_rated_power_per_pv_unit_in_MW(value); + } + + return; +} + +double PVCVX::get_minimum_nonzero_time_constant_in_s() +{ + return INFINITE_THRESHOLD; +} + +void PVCVX::prepare_model_internal_variable_table() +{ + clear_model_internal_variable_table(); + unsigned int i=0; + add_model_internal_variable_name_and_index_pair("PLL ANGLE IN DEG", i); i++; + add_model_internal_variable_name_and_index_pair("STATE@ACTIVE CURRENT COMMAND BLOCK", i); i++; + add_model_internal_variable_name_and_index_pair("STATE@REACTIVE VOLTAGE COMMAND BLOCK", i); i++; + add_model_internal_variable_name_and_index_pair("STATE@PLL FREQUENCY BLOCK", i); i++; + add_model_internal_variable_name_and_index_pair("STATE@PLL ANGLE BLOCK", i); i++; +} + +double PVCVX::get_model_internal_variable_with_name(string var_name) +{ + var_name = string2upper(var_name); + if(var_name == "PLL ANGLE IN DEG") + return get_pll_angle_in_deg(); + if(var_name == "STATE@ACTIVE CURRENT COMMAND BLOCK") + return active_current_commander.get_state(); + if(var_name == "STATE@REACTIVE VOLTAGE COMMAND BLOCK") + return reactive_voltage_commander.get_state(); + if(var_name == "STATE@PLL FREQUENCY BLOCK") + return PLL_frequency_integrator.get_state(); + if(var_name == "STATE@PLL ANGLE BLOCK") + return PLL_angle_integrator.get_state(); + + return 0.0; +} + +complex PVCVX::get_terminal_complex_power_in_pu_based_on_mbase() +{ + complex Vxy = get_terminal_complex_voltage_in_pu(); + complex Ixy = get_terminal_complex_current_in_pu_in_xy_axis_based_on_mbase(); + + complex S = Vxy*conj(Ixy); + return S; +} + +complex PVCVX::get_terminal_complex_power_in_MVA() +{ + return get_terminal_complex_power_in_pu_based_on_mbase()*get_mbase_in_MVA(); +} + +double PVCVX::get_terminal_active_power_in_pu_based_on_mbase() +{ + return get_terminal_complex_power_in_pu_based_on_mbase().real(); +} + +double PVCVX::get_terminal_active_power_in_MW() +{ + return get_terminal_complex_power_in_MVA().real(); +} + +double PVCVX::get_terminal_reactive_power_in_pu_based_on_mbase() +{ + return get_terminal_complex_power_in_pu_based_on_mbase().imag(); +} + +double PVCVX::get_terminal_reactive_power_in_MVar() +{ + return get_terminal_complex_power_in_MVA().imag(); +} + +double PVCVX::get_active_power_generation_including_stator_loss_in_pu_based_on_mbase() +{ + return get_active_power_generation_including_stator_loss_in_MW()/get_mbase_in_MVA(); +} + +double PVCVX::get_active_power_generation_including_stator_loss_in_MW() +{ + double pterm = get_terminal_active_power_in_MW(); + return pterm; + + /*double rsource = get_source_impedance_in_pu_based_on_mbase().real(); + double iterm = steps_fast_complex_abs(get_terminal_complex_current_in_pu_in_xy_axis_based_on_mbase()); + double mbase = get_mbase_in_MVA(); + + return pterm+rsource*iterm*iterm*mbase;*/ +} + +double PVCVX::get_pll_angle_in_rad() +{ + double kpll = get_KPLL(); + double kipll = get_KIPLL(); + if(kpll!=0.0 or kipll!=0.0) + return PLL_angle_integrator.get_output(); + else + return get_terminal_voltage_angle_in_rad(); +} + +double PVCVX::get_pll_angle_in_deg() +{ + return rad2deg(get_pll_angle_in_rad()); +} + +double PVCVX::get_pll_frequency_deviation_in_pu() +{ + double fbase = get_bus_base_frequency_in_Hz(); + double wbase = DOUBLE_PI*fbase; + + complex Vxy = get_terminal_complex_voltage_in_pu(); + + double kpll = get_KPLL(); + double kipll = get_KIPLL(); + if(kpll!=0.0 or kipll!=0.0) + { + double Vr = Vxy.real(); + double Vi = Vxy.imag(); + + double angle = get_pll_angle_in_rad(); + double Vy = -Vr*steps_sin(angle)+Vi*steps_cos(angle); + + double input = Vy*kpll/wbase; + + double output = PLL_frequency_integrator.get_output(); + + return input+output; + } + else + return 0.0; +} + +double PVCVX::get_pll_frequency_deviation_in_Hz() +{ + double fbase = get_bus_base_frequency_in_Hz(); + + return fbase*get_pll_frequency_deviation_in_pu(); +} + +double PVCVX::get_pll_frequency_in_pu() +{ + return 1.0+get_pll_frequency_deviation_in_pu(); +} + +double PVCVX::get_pll_frequency_in_Hz() +{ + double fbase = get_bus_base_frequency_in_Hz(); + + return fbase*get_pll_frequency_in_pu(); +} + +complex PVCVX::get_internal_voltage_in_pu_in_xy_axis() +{ + complex Ixy = get_source_Norton_equivalent_complex_current_in_pu_in_xy_axis_based_on_sbase(); + complex Z(0.0, get_Xeq_in_pu()); + + STEPS& toolkit = get_toolkit(); + POWER_SYSTEM_DATABASE& psdb = toolkit.get_power_system_database(); + double sbase = psdb.get_system_base_power_in_MVA(); + double one_over_mbase = get_one_over_mbase_in_one_over_MVA(); + + Z *= (one_over_mbase*sbase); + + return Ixy*Z; +} + + + +void PVCVX::set_pll_angle_in_deg(double angle) +{ + PLL_angle_integrator.set_output(deg2rad(angle)); + PLL_angle_integrator.initialize();// the initialize function is used to update STORE +} + + +string PVCVX::get_dynamic_data_in_psse_format() const +{ + return ""; +} + +string PVCVX::get_dynamic_data_in_bpa_format() const +{ + return get_dynamic_data_in_psse_format(); +} + +string PVCVX::get_dynamic_data_in_steps_format() const +{ + return get_dynamic_data_in_psse_format(); +} diff --git a/code/steps/source/model/pvu_models/pv_electrical_model/pv_electrical_model.cpp b/code/steps/source/model/pvu_models/pv_electrical_model/pv_electrical_model.cpp index 5d573419..099eb464 100644 --- a/code/steps/source/model/pvu_models/pv_electrical_model/pv_electrical_model.cpp +++ b/code/steps/source/model/pvu_models/pv_electrical_model/pv_electrical_model.cpp @@ -6,6 +6,7 @@ PV_ELECTRICAL_MODEL::PV_ELECTRICAL_MODEL(STEPS& toolkit) : PVU_MODEL(toolkit) { + unbypass_model(); } PV_ELECTRICAL_MODEL::~PV_ELECTRICAL_MODEL() @@ -13,6 +14,21 @@ PV_ELECTRICAL_MODEL::~PV_ELECTRICAL_MODEL() ; } +void PV_ELECTRICAL_MODEL::unbypass_model() +{ + flag_model_bypassed = false; +} + +void PV_ELECTRICAL_MODEL::bypass_model() +{ + flag_model_bypassed = true; +} + +bool PV_ELECTRICAL_MODEL::is_model_bypassed() const +{ + return flag_model_bypassed; +} + string PV_ELECTRICAL_MODEL::get_model_type() const { return "PV ELECTRICAL"; @@ -78,6 +94,21 @@ double PV_ELECTRICAL_MODEL::get_pv_unit_terminal_current_in_pu() const double x = I.real(), y = I.imag(); return steps_sqrt(x*x+y*y); } + +double PV_ELECTRICAL_MODEL::get_active_power_reference_in_pu_from_panel_model() const +{ + PV_UNIT* pv_unit = get_pv_unit_pointer(); + PV_PANEL_MODEL* panelmodel = pv_unit->get_pv_panel_model(); + if(panelmodel!=NULL) + { + if(not panelmodel->is_model_initialized()) + panelmodel->initialize(); + + return panelmodel->get_Pref_in_pu_base_on_mbase(); + } + else + return 0.0; +} // reference void PV_ELECTRICAL_MODEL::set_bus_to_regulate(unsigned int bus) @@ -106,6 +137,7 @@ void PV_ELECTRICAL_MODEL::set_voltage_reference_in_pu_with_bus_to_regulate() bus = source->get_source_bus(); return set_voltage_reference_in_pu(psdb.get_bus_positive_sequence_voltage_in_pu(bus)); + } double PV_ELECTRICAL_MODEL::get_voltage_reference_in_pu() const diff --git a/code/steps/source/model/pvu_models/pv_electrical_model/pv_electrical_model_test.cpp b/code/steps/source/model/pvu_models/pv_electrical_model/pv_electrical_model_test.cpp index 8b901cac..695979f4 100644 --- a/code/steps/source/model/pvu_models/pv_electrical_model/pv_electrical_model_test.cpp +++ b/code/steps/source/model/pvu_models/pv_electrical_model/pv_electrical_model_test.cpp @@ -267,9 +267,11 @@ void PV_ELECTRICAL_MODEL_TEST::export_meter_values() osstream<get_active_power_command_in_pu_based_on_mbase()<<"\t" + <get_reactive_power_command_in_pu_based_on_mbase()<<"\t" <get_active_current_command_in_pu_based_on_mbase()<<"\t" <get_reactive_current_command_in_pu_based_on_mbase()<<"\t" - <get_reactive_voltage_command_in_pu_based_on_mbase()<<"\t" + <get_reactive_voltage_command_in_pu()<<"\t" <get_terminal_active_power_in_MW()<<"\t" <get_terminal_reactive_power_in_MVar(); default_toolkit.show_information_with_leading_time_stamp(osstream); diff --git a/code/steps/source/model/pvu_models/pv_electrical_model/pvex.cpp b/code/steps/source/model/pvu_models/pv_electrical_model/pvex.cpp new file mode 100644 index 00000000..d3cbcc89 --- /dev/null +++ b/code/steps/source/model/pvu_models/pv_electrical_model/pvex.cpp @@ -0,0 +1,1348 @@ +#include "header/model/pvu_models/pv_electrical_model/pvex.h" +#include "header/device/pv_unit.h" +#include "header/power_system_database.h" +#include "header/STEPS.h" +#include "header/basic/utility.h" +#include "header/steps_namespace.h" +#include + +using namespace std; + +PVEX::PVEX(STEPS& toolkit) : PV_ELECTRICAL_MODEL(toolkit), + voltage_sensor(toolkit), + voltage_regulator_first_order_block(toolkit), + voltage_regulator_integrator(toolkit), + voltage_regulator_filter(toolkit), + active_power_sensor(toolkit), + Q_error_integrator(toolkit), + V_error_integrator(toolkit), + virtual_inertia_emulator(toolkit), + frequency_droop_controller(toolkit), + frequency_integral_controller(toolkit), + power_order_integrator(toolkit) +{ + clear(); +} + +PVEX::PVEX(const PVEX& model) : PV_ELECTRICAL_MODEL(model.get_toolkit()), + voltage_sensor(model.get_toolkit()), + voltage_regulator_first_order_block(model.get_toolkit()), + voltage_regulator_integrator(model.get_toolkit()), + voltage_regulator_filter(model.get_toolkit()), + active_power_sensor(model.get_toolkit()), + Q_error_integrator(model.get_toolkit()), + V_error_integrator(model.get_toolkit()), + virtual_inertia_emulator(model.get_toolkit()), + frequency_droop_controller(model.get_toolkit()), + frequency_integral_controller(model.get_toolkit()), + power_order_integrator(model.get_toolkit()) +{ + copy_from_const_model(model); +} + +PVEX::~PVEX() +{ + ; +} + +PVEX& PVEX::operator=(const PVEX& model) +{ + if(this==(&model)) return *this; + + copy_from_const_model(model); + + return *this; +} + +void PVEX::clear() +{ + set_model_float_parameter_count(32); + + set_voltage_flag(0); + + voltage_regulator_integrator.set_limiter_type(NON_WINDUP_LIMITER); + Q_error_integrator.set_limiter_type(NON_WINDUP_LIMITER); + V_error_integrator.set_limiter_type(NON_WINDUP_LIMITER); + + power_order_integrator.set_limiter_type(NON_WINDUP_LIMITER); + frequency_integral_controller.set_limiter_type(NO_LIMITER); + + frequency_regulation_enabled = true; +} + +void PVEX::copy_from_const_model(const PVEX& model) +{ + if(model.is_model_bypassed()) bypass_model(); + + STEPS& toolkit = model.get_toolkit(); + set_toolkit(toolkit); + voltage_sensor.set_toolkit(toolkit); + voltage_regulator_first_order_block.set_toolkit(toolkit); + voltage_regulator_integrator.set_toolkit(toolkit); + voltage_regulator_filter.set_toolkit(toolkit); + active_power_sensor.set_toolkit(toolkit); + Q_error_integrator.set_toolkit(toolkit); + V_error_integrator.set_toolkit(toolkit); + + virtual_inertia_emulator.set_toolkit(toolkit); + frequency_droop_controller.set_toolkit(toolkit); + + frequency_integral_controller.set_toolkit(toolkit); + power_order_integrator.set_toolkit(toolkit); + + clear(); + + set_bus_to_regulate(model.get_bus_to_regulate()); + set_var_control_mode(model.get_var_control_mode()); + + set_Xcomp_in_pu(model.get_Xcomp_in_pu()); + set_TRV_in_s(model.get_TRV_in_s()); + set_Fn(model.get_Fn()); + set_KIV(model.get_KIV()); + set_Qmax_in_pu(model.get_Qmax_in_pu()); + set_Qmin_in_pu(model.get_Qmin_in_pu()); + set_KPV(model.get_KPV()); + set_TV_in_s(model.get_TV_in_s()); + set_TFV_in_s(model.get_TFV_in_s()); + set_TP_in_s(model.get_TP_in_s()); + set_KQI(model.get_KQI()); + set_Vmax_in_pu(model.get_Vmax_in_pu()); + set_Vmin_in_pu(model.get_Vmin_in_pu()); + set_voltage_flag(model.get_voltage_flag()); + set_KQV(model.get_KQV()); + set_EQmax_in_pu(model.get_EQmax_in_pu()); + set_EQmin_in_pu(model.get_EQmin_in_pu()); + set_Kvi(model.get_Kvi()); + set_Tvi_in_s(model.get_Tvi_in_s()); + set_Kdroop(model.get_Kdroop()); + set_Tdroop_in_s(model.get_Tdroop_in_s()); + set_frequency_deviation_upper_deadband_in_pu(model.get_frequency_deviation_upper_deadband_in_pu()); + set_frequency_deviation_lower_deadband_in_pu(model.get_frequency_deviation_lower_deadband_in_pu()); + set_Kfint(model.get_Kfint()); + set_rPmax_in_pu(model.get_rPmax_in_pu()); + set_rPmin_in_pu(model.get_rPmin_in_pu()); + set_TFP_in_s(model.get_TFP_in_s()); + set_Pmax_in_pu(model.get_Pmax_in_pu()); + set_Pmin_in_pu(model.get_Pmin_in_pu()); + set_IPmax_in_pu(model.get_IPmax_in_pu()); +} + +string PVEX::get_model_name() const +{ + return "PVEX"; +} + +void PVEX::set_Xcomp_in_pu(double Xc) +{ + Xcomp = Xc; +} + +void PVEX::set_TRV_in_s(double T) +{ + voltage_sensor.set_T_in_s(T); +} + +void PVEX::set_Fn(double Fn) +{ + this->Fn = Fn; +} + +void PVEX::set_KIV(double K) +{ + if(K!=0.0) + voltage_regulator_integrator.set_T_in_s(1.0/K); +} + +void PVEX::set_Qmax_in_pu(double q) +{ + voltage_regulator_integrator.set_upper_limit(q); +} + +void PVEX::set_Qmin_in_pu(double q) +{ + voltage_regulator_integrator.set_lower_limit(q); +} + +void PVEX::set_KPV(double K) +{ + voltage_regulator_first_order_block.set_K(K); +} + +void PVEX::set_TV_in_s(double T) +{ + voltage_regulator_first_order_block.set_T_in_s(T); +} + +void PVEX::set_TFV_in_s(double T) +{ + voltage_regulator_filter.set_T_in_s(T); +} + +void PVEX::set_TP_in_s(double T) +{ + active_power_sensor.set_T_in_s(T); +} + +void PVEX::set_KQI(double K) +{ + if(K!=0.0) + Q_error_integrator.set_T_in_s(1.0/K); +} + +void PVEX::set_Vmax_in_pu(double v) +{ + Q_error_integrator.set_upper_limit(v); +} + +void PVEX::set_Vmin_in_pu(double v) +{ + Q_error_integrator.set_lower_limit(v); +} + +void PVEX::set_voltage_flag(unsigned int flag) +{ + if(flag<3) + Voltage_Flag = flag; + else + { + ostringstream osstream; + osstream<<"Error. "<& data) +{ + bool is_successful = false; + if(data.size()>=35) + { + string model_name = get_string_data(data[0],""); + if(model_name==get_model_name()) + { + unsigned int bus, voltage_flag; + int var_control_flag; + double tfv, kpv, kiv, xc, tfp, pmax, pmin, qmax, qmin, + ipmax, trv, rpmax, rpmin, kqi, vmax, vmin, + kqv, eqmax, eqmin, tv, tp, fn, + kvi, tvi, kdroop, tdroop, fupper, flower, kint; + + unsigned int i=3; + bus = get_integer_data(data[i],"0"); i++; + var_control_flag = get_integer_data(data[i],"0"); i++; + voltage_flag = (unsigned int)(get_integer_data(data[i],"0")); i++; + xc = get_double_data(data[i],"0.0"); i++; + trv = get_double_data(data[i],"0.0"); i++; + fn = get_double_data(data[i],"0.0"); i++; + kpv = get_double_data(data[i],"0.0"); i++; + tv = get_double_data(data[i],"0.0"); i++; + kiv = get_double_data(data[i],"0.0"); i++; + qmin = get_double_data(data[i],"0.0"); i++; + qmax = get_double_data(data[i],"0.0"); i++; + tfv = get_double_data(data[i],"0.0"); i++; + tp = get_double_data(data[i],"0.0"); i++; + kqi = get_double_data(data[i],"0.0"); i++; + vmin = get_double_data(data[i],"0.0"); i++; + vmax = get_double_data(data[i],"0.0"); i++; + kqv = get_double_data(data[i],"0.0"); i++; + eqmin = get_double_data(data[i],"0.0"); i++; + eqmax = get_double_data(data[i],"0.0"); i++; + kvi = get_double_data(data[i],"0.0"); i++; + tvi = get_double_data(data[i],"0.0"); i++; + kdroop = get_double_data(data[i],"0.0"); i++; + tdroop = get_double_data(data[i],"0.0"); i++; + flower = get_double_data(data[i],"0.0"); i++; + fupper = get_double_data(data[i],"0.0"); i++; + kint = get_double_data(data[i],"0.0"); i++; + rpmin = get_double_data(data[i],"0.0"); i++; + rpmax = get_double_data(data[i],"0.0"); i++; + tfp = get_double_data(data[i],"0.0"); i++; + pmin = get_double_data(data[i],"0.0"); i++; + pmax = get_double_data(data[i],"0.0"); i++; + ipmax = get_double_data(data[i],"0.0"); + + set_bus_to_regulate(bus); + PE_VAR_CONTROL_MODE mode; + switch(var_control_flag) + { + case 0: + { + mode = CONSTANT_VAR_MODE; + break; + } + case 1: + { + mode = CONSTANT_VOLTAGE_MODE; + break; + } + case -1: + { + mode = CONSTANT_POWER_FACTOR_MODE; + break; + } + default: + { + mode = CONSTANT_VAR_MODE; + break; + } + } + + set_var_control_mode(mode); + set_Xcomp_in_pu(xc); + set_TRV_in_s(trv); + set_Fn(fn); + set_KPV(kpv); + set_TV_in_s(tv); + set_KIV(kiv); + set_Qmin_in_pu(qmin); + set_Qmax_in_pu(qmax); + set_TFV_in_s(tfv); + set_TP_in_s(tp); + set_KQI(kqi); + set_Vmin_in_pu(vmin); + set_Vmax_in_pu(vmax); + + if(voltage_flag>2) + voltage_flag = 2; + set_voltage_flag(voltage_flag); + set_KQV(kqv); + set_EQmin_in_pu(eqmin); + set_EQmax_in_pu(eqmax); + set_Kvi(kvi); + set_Tvi_in_s(tvi); + set_Kdroop(kdroop); + set_Tdroop_in_s(tdroop); + set_frequency_deviation_lower_deadband_in_pu(flower); + set_frequency_deviation_upper_deadband_in_pu(fupper); + set_Kfint(kint); + set_rPmin_in_pu(rpmin); + set_rPmax_in_pu(rpmax); + set_TFP_in_s(tfp); + set_Pmin_in_pu(pmin); + set_Pmax_in_pu(pmax); + set_IPmax_in_pu(ipmax); + + is_successful = true; + + return is_successful; + } + else + return is_successful; + } + else + return is_successful; +} + +bool PVEX::setup_model_with_psse_string(string data) +{ + vector record = psse_dyr_string2steps_string_vector(data); + return setup_model_with_steps_string_vector(record); +} + +bool PVEX::setup_model_with_bpa_string(string data) +{ + ostringstream osstream; + osstream<get_pv_converter_model(); + if(not pvconmodel->is_model_initialized()) + pvconmodel->initialize(); + + PV_PANEL_MODEL* panelmodel = pv_unit->get_pv_panel_model(); + if(panelmodel!=NULL) + { + if(not panelmodel->is_model_initialized()) + panelmodel->initialize(); + + + setup_block_toolkit_and_parameters(); + + STEPS& toolkit = get_toolkit(); + + double vterm = get_terminal_bus_voltage_in_pu(); + double iterm = get_pv_unit_terminal_current_in_pu(); + //double mbase = get_mbase_in_MVA(); + complex selec = get_pv_unit_terminal_generation_in_pu_based_on_mbase(); + double pelec = selec.real(); + double qelec = selec.imag(); + double pref = get_active_power_reference_in_pu_from_panel_model(); + + set_active_power_reference_in_pu(pref); + + double ipcmd = pvconmodel->get_initial_active_current_command_in_pu_based_on_mbase(); + double ipmax = get_IPmax_in_pu(); + if(ipcmd>ipmax) + { + osstream<<"Initialization error. IPcmd (Active current command) of '"<pmax) + { + osstream<<"Initialization error. Porder (Active power order) of '"<get_initial_reactive_current_command_in_pu_based_on_mbase(); + double xsource = get_source_impedance_in_pu_based_on_mbase().imag(); + double eqcmd = iqcmd*(-xsource); + + double verror = 0.0; + unsigned int vflag = get_voltage_flag(); + if(vflag == 0) + { + V_error_integrator.set_output(0.0); + V_error_integrator.initialize(); + + verror = eqcmd; + } + else + { + if(vflag == 1) + { + V_error_integrator.set_upper_limit(vterm+get_EQmax_in_pu()); + V_error_integrator.set_lower_limit(vterm+get_EQmin_in_pu()); + } + else + { + V_error_integrator.set_upper_limit(get_EQmax_in_pu()); + V_error_integrator.set_lower_limit(get_EQmin_in_pu()); + } + double vmax = V_error_integrator.get_upper_limit(); + double vmin = V_error_integrator.get_lower_limit(); + + V_error_integrator.set_output(eqcmd); + if(eqcmd>vmax) + { + osstream<<"Initialization error. Eqcmd (reactive voltage command) of '"<qmax) + { + osstream<<"Initialization error. Qcmd (reactive power command) of '"<0? pf:-pf); + set_power_factor_reference_in_pu(pf); + + voltage_regulator_filter.set_output(qcmd); + voltage_regulator_filter.initialize(); + + voltage_regulator_integrator.set_output(qcmd); + voltage_regulator_integrator.initialize(); + + voltage_regulator_first_order_block.set_output(0.0); + voltage_regulator_first_order_block.initialize(); + + double xcomp = get_Xcomp_in_pu(); + double vref = vterm+iterm*xcomp; + + voltage_sensor.set_output(vref); + voltage_sensor.initialize(); + + set_voltage_reference_in_pu(vref); + //show_information_with_leading_time_stamp(osstream); + + set_flag_model_initialized_as_true(); + if(toolkit.is_detailed_log_enabled()) + { + osstream< selec = get_pv_unit_terminal_generation_in_pu_based_on_mbase(); + double pelec = selec.real(); + double qelec = selec.imag(); + double pref = get_active_power_reference_in_pu_from_panel_model(); + + virtual_inertia_emulator.set_input(freq); + virtual_inertia_emulator.run(mode); + //osstream<<"virtual_inertia_emulator input = "<<-freq<<", output = "<wmax*1.1: "<"<get_rPmax_in_pu()) + input = get_rPmax_in_pu(); + if(inputget_identifier()+"'"; + + string model_name = "'"+get_model_name()+"'"; + + unsigned int bus_reg = get_bus_to_regulate(); + PE_VAR_CONTROL_MODE mode = get_var_control_mode(); + int var_mode = (mode==CONSTANT_VAR_MODE)? 0: (mode==CONSTANT_POWER_FACTOR_MODE? -1 : 1); + unsigned int voltage_flag = get_voltage_flag(); + double xc = get_Xcomp_in_pu(); + double trv = get_TRV_in_s(); + double fn = get_Fn(); + double kpv = get_KPV(); + double tv = get_TV_in_s(); + double kiv = get_KIV(); + double qmax = get_Qmax_in_pu(); + double qmin = get_Qmin_in_pu(); + double tfv = get_TFV_in_s(); + double tp = get_TP_in_s(); + double kqi = get_KQI(); + double vmin = get_Vmin_in_pu(); + double vmax = get_Vmax_in_pu(); + double kqv = get_KQV(); + double eqmin = get_EQmin_in_pu(); + double eqmax = get_EQmax_in_pu(); + double kvi = get_Kvi(); + double tvi = get_Tvi_in_s(); + double kdroop = get_Kdroop(); + double tdroop = get_Tdroop_in_s(); + double flower = get_frequency_deviation_lower_deadband_in_pu(); + double fupper = get_frequency_deviation_upper_deadband_in_pu(); + double kint = get_Kfint(); + double rpmin = get_rPmin_in_pu(); + double rpmax = get_rPmax_in_pu(); + double tfp = get_TFP_in_s(); + double pmin = get_Pmin_in_pu(); + double pmax = get_Pmax_in_pu(); + double ipmax = get_IPmax_in_pu(); + + STEPS& toolkit = get_toolkit(); + NETWORK_MATRIX& network = toolkit.get_network_matrix(); + if(export_internal_bus_number==true) + { + bus = network.get_internal_bus_number_of_physical_bus(bus)+1; + if(bus_reg!=0) bus_reg = network.get_internal_bus_number_of_physical_bus(bus_reg)+1; + } + + osstream<get_TRV_in_s()) + mint = get_TRV_in_s(); + if(get_TV_in_s()!=0.0 and mint>get_TV_in_s()) + mint = get_TV_in_s(); + if(get_TFV_in_s()!=0.0 and mint>get_TFV_in_s()) + mint = get_TFV_in_s(); + if(get_TP_in_s()!=0.0 and mint>get_TP_in_s()) + mint = get_TP_in_s(); + if(get_Tvi_in_s()!=0.0 and mint>get_Tvi_in_s()) + mint = get_Tvi_in_s(); + if(get_Tdroop_in_s()!=0.0 and mint>get_Tdroop_in_s()) + mint = get_Tdroop_in_s(); + if(get_TFP_in_s()!=0.0 and mint>get_TFP_in_s()) + mint = get_TFP_in_s(); + return mint; +} + +void PVEX::prepare_model_internal_variable_table() +{ + clear_model_internal_variable_table(); + unsigned int i=0; + add_model_internal_variable_name_and_index_pair("STATE@VIRTUAL INERTIA CONTROL", i); i++; + add_model_internal_variable_name_and_index_pair("STATE@PRIMARY FREQUENCY CONTROL", i); i++; + add_model_internal_variable_name_and_index_pair("STATE@SECONDARY FREQUENCY CONTROL", i); i++; + add_model_internal_variable_name_and_index_pair("VIRTUAL INERTIA CONTROL COMMAND", i); i++; + add_model_internal_variable_name_and_index_pair("PRIMARY FREQUENCY CONTROL COMMAND", i); i++; + add_model_internal_variable_name_and_index_pair("SECONDARY FREQUENCY CONTROL COMMAND", i); i++; +} + +double PVEX::get_model_internal_variable_with_name(string var_name) +{ + var_name = string2upper(var_name); + + if(var_name == "STATE@VIRTUAL INERTIA CONTROL") return virtual_inertia_emulator.get_state(); + if(var_name == "STATE@PRIMARY FREQUENCY CONTROL") return frequency_droop_controller.get_state(); + if(var_name == "STATE@SECONDARY FREQUENCY CONTROL") return frequency_integral_controller.get_state(); + if(var_name == "VIRTUAL INERTIA CONTROL COMMAND") return virtual_inertia_emulator.get_output(); + if(var_name == "PRIMARY FREQUENCY CONTROL COMMAND") return frequency_droop_controller.get_output(); + if(var_name == "SECONDARY FREQUENCY CONTROL COMMAND") return frequency_integral_controller.get_output(); + return 0.0; +} + +string PVEX::get_dynamic_data_in_psse_format() const +{ + return get_standard_psse_string(); +} + +string PVEX::get_dynamic_data_in_bpa_format() const +{ + return get_dynamic_data_in_psse_format(); +} + +string PVEX::get_dynamic_data_in_steps_format() const +{ + return get_dynamic_data_in_psse_format(); +} diff --git a/code/steps/source/model/pvu_models/pv_irradiance_model/fileirrad.cpp b/code/steps/source/model/pvu_models/pv_irradiance_model/fileirrad.cpp new file mode 100644 index 00000000..4661b821 --- /dev/null +++ b/code/steps/source/model/pvu_models/pv_irradiance_model/fileirrad.cpp @@ -0,0 +1,467 @@ +#include "header/model/pvu_models/pv_irradiance_model/fileirrad.h" +#include "header/basic/utility.h" +#include "header/steps_namespace.h" +#include +#include +#include + +using namespace std; +FILEIRRAD::FILEIRRAD(STEPS& toolkit) : PV_IRRADIANCE_MODEL(toolkit) +{ + clear(); +} + +FILEIRRAD::~FILEIRRAD() +{ +} + +void FILEIRRAD::clear() +{ + clear_solar_irradiance_serial_file(); + clear_solar_irradiance_data(); + + current_time = -INFINITE_THRESHOLD; + current_solar_irradiance = 0.0; + current_solar_irradiance_direction = 0.0; + + set_previous_position(0); +} + +void FILEIRRAD::clear_solar_irradiance_serial_file() +{ + solar_irradiance_file[0] = '\0'; +} + +void FILEIRRAD::clear_solar_irradiance_data() +{ + for(unsigned int i=0; i datavec; + getline(fid, data); // skip the head line + unsigned int n = 0; + while(true) + { + getline(fid, data); + if(data.size()<3) + break; + data = trim_string(data); + data = string2csv(data); + datavec = split_string(data,","); + if(datavec.size()<2) + break; + + if(n==STEPS_MAX_SOLAR_IRRADIANCE_RECORD_SIZE) + { + osstream<<"Warning. Solar irradiance data in file '"<0) + { + direction = get_double_data(datavec.front(),"0.0"); + datavec.erase(datavec.begin()); + } + + solar_irradiance_data[n][0] = t; + solar_irradiance_data[n][1] = v; + solar_irradiance_data[n][2] = direction; + + ++n; + } + fid.close(); + } + else + { + osstream<<"Initialization error. Fail to load solar irradiance data from file '"<& data) +{ + bool is_successful = false; + if(data.size()>=4) + { + string model_name = get_string_data(data[0],""); + if(model_name==get_model_name()) + { + string file; + file = get_string_data(data[3],"0.0"); + + set_solar_irradiance_serial_file(file); + load_solar_irradiance_from_file(); + + is_successful = true; + return is_successful; + } + else + return is_successful; + } + else + return is_successful; +} + +bool FILEIRRAD::setup_model_with_psse_string(string data) +{ + vector record = psse_dyr_string2steps_string_vector(data); + return setup_model_with_steps_string_vector(record); +} + +bool FILEIRRAD::setup_model_with_bpa_string(string data) +{ + ostringstream osstream; + osstream<=1) + { + if(pos<=n-1) + previous_position = pos; + else + previous_position = n-1; + } + else + previous_position = 0; +} + +unsigned int FILEIRRAD::get_previous_position() const +{ + return previous_position; +} + +void FILEIRRAD::search_solar_irradiance_data_at_simulation_time() +{ + STEPS& toolkit = get_toolkit(); + double simulation_time = toolkit.get_dynamic_simulation_time_in_s(); + + current_time = simulation_time; + + unsigned int n = get_solar_irradiance_record_count(); + double time_min = solar_irradiance_data[0][0]; + double time_max = solar_irradiance_data[n-1][0]; + + if(current_time<=time_min) + { + current_solar_irradiance = solar_irradiance_data[0][1]; + current_solar_irradiance_direction = solar_irradiance_data[0][2]; + } + else + { + if(current_time>=time_max) + { + current_solar_irradiance = solar_irradiance_data[n-1][1]; + current_solar_irradiance_direction = solar_irradiance_data[n-1][2]; + } + else + { + unsigned int previous_index = 0, next_index = n-1; + //unsigned int previous_time = (*time)[previous_index], next_time = (*time)[next_index]; + while(true) + { + unsigned int temp_index = ((previous_index+next_index)>>1); + double temp_time = solar_irradiance_data[temp_index][0]; + if(fabs(temp_time-current_time)current_time) + { + next_index = temp_index; + //next_time = (*time)[next_index]; + } + else + { + previous_index = temp_index; + //previous_time = (*time)[previous_index]; + } + + if(next_index-previous_index==1) + { + double slope; + double previous_time = solar_irradiance_data[previous_index][0]; + double next_time = solar_irradiance_data[next_index][0]; + double previous_irradiance = solar_irradiance_data[previous_index][1]; + double next_irradiance = solar_irradiance_data[next_index][1]; + double previous_direction = solar_irradiance_data[previous_index][2]; + double next_direction = solar_irradiance_data[next_index][2]; + + double one_over_time_change = 1.0/(next_time-previous_time); + slope = (next_irradiance-previous_irradiance)*one_over_time_change; + current_solar_irradiance = previous_irradiance+slope*(current_time-previous_time); + + slope = (next_direction-previous_direction)*one_over_time_change; + current_solar_irradiance_direction = previous_direction+slope*(current_time-previous_time); + break; + } + } + } + } + } +} + + +void FILEIRRAD::check() +{ + ; +} + + +void FILEIRRAD::report() +{ + STEPS& toolkit = get_toolkit(); + toolkit.show_information_with_leading_time_stamp(get_standard_psse_string()); +} + +void FILEIRRAD::save() +{ + ; +} + +string FILEIRRAD::get_standard_psse_string(bool export_internal_bus_number) const +{ + ostringstream osstream; + PV_UNIT* pv_unit = get_pv_unit_pointer(); + unsigned int bus = pv_unit->get_unit_bus(); + string identifier = "'"+pv_unit->get_identifier()+"'"; + + string model_name = "'"+get_model_name()+"'"; + + string file = get_solar_irradiance_serial_file(); + + STEPS& toolkit = get_toolkit(); + NETWORK_MATRIX& network = toolkit.get_network_matrix(); + if(export_internal_bus_number==true) + bus = network.get_internal_bus_number_of_physical_bus(bus)+1; + + osstream< diff --git a/code/steps/source/model/pvu_models/pv_irradiance_model/fileirrd.cpp b/code/steps/source/model/pvu_models/pv_irradiance_model/fileirrd.cpp deleted file mode 100644 index cea1b6f3..00000000 --- a/code/steps/source/model/pvu_models/pv_irradiance_model/fileirrd.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#include "header/model/pvu_models/pv_irradiance_model/fileirrd.h" -#include "header/basic/utility.h" -#include "header/steps_namespace.h" -#include -#include - -using namespace std; -FILEIRRAD::FILEIRRAD(STEPS& toolkit) : PV_IRRADIANCE_MODEL(toolkit) -{ - clear(); -} - -FILEIRRAD::~FILEIRRAD() -{ -} - -void FILEIRRAD::clear() -{ -} - -void FILEIRRAD::copy_from_const_model(const FILEIRRAD& model) -{ - set_toolkit(model.get_toolkit()); - - clear(); -} - -FILEIRRAD::FILEIRRAD(const FILEIRRAD& model):PV_IRRADIANCE_MODEL(model.get_toolkit()) -{ - copy_from_const_model(model); -} - -FILEIRRAD& FILEIRRAD::operator=(const FILEIRRAD& model) -{ - if(this==&model) - return *this; - - copy_from_const_model(model); - - return (*this); -} - -string FILEIRRAD::get_model_name() const -{ - return "FILEIRRAD"; -} - - -void FILEIRRAD::set_solar_irradiance_serial_file(string file) -{ - ; -} - -string FILEIRRAD::get_solar_irradiance_serial_file() const -{ - return ""; -} - -bool FILEIRRAD::setup_model_with_steps_string_vector(vector& data) -{ - ostringstream osstream; - osstream< record = psse_dyr_string2steps_string_vector(data); - return setup_model_with_steps_string_vector(record); -} - -bool FILEIRRAD::setup_model_with_bpa_string(string data) -{ - ostringstream osstream; - osstream<get_pv_irradiance_model(); - if(pvirrd!=NULL) - return pvirrd->get_nominal_irradiance_in_Wpm2(); + PV_PANEL_MODEL* pv_panel = pv_unit->get_pv_panel_model(); + if(pv_panel!=NULL) + return pv_panel->get_S0_in_Wpm2(); else return 0.0; } double PV_IRRADIANCE_MODEL::get_solar_irradiance_in_Wpm2() { - double irrd0 = get_nominal_irradiance_in_Wpm2(); + double irrd0 = get_initial_irradiance_in_Wpm2(); double irrd = get_solar_irradiance_in_pu(); return irrd*irrd0; } diff --git a/code/steps/source/model/pvu_models/pv_panel_model/pv_panel_model.cpp b/code/steps/source/model/pvu_models/pv_panel_model/pv_panel_model.cpp index e0548bcf..a7001d75 100644 --- a/code/steps/source/model/pvu_models/pv_panel_model/pv_panel_model.cpp +++ b/code/steps/source/model/pvu_models/pv_panel_model/pv_panel_model.cpp @@ -8,6 +8,7 @@ using namespace std; PV_PANEL_MODEL::PV_PANEL_MODEL(STEPS& toolkit) : PVU_MODEL(toolkit) { + set_Sref_in_Wpm2(1000); } PV_PANEL_MODEL::PV_PANEL_MODEL(const PV_PANEL_MODEL& model) : PVU_MODEL(model.get_toolkit()) @@ -32,6 +33,8 @@ PV_PANEL_MODEL& PV_PANEL_MODEL::operator=(const PV_PANEL_MODEL& model) void PV_PANEL_MODEL::copy_from_const_model(const PV_PANEL_MODEL& model) { set_toolkit(model.get_toolkit()); + + set_Sref_in_Wpm2(model.get_Sref_in_Wpm2()); } string PV_PANEL_MODEL::get_model_type() const @@ -39,16 +42,53 @@ string PV_PANEL_MODEL::get_model_type() const return "PV PANEL"; } +void PV_PANEL_MODEL::set_S0_in_Wpm2(double S) +{ + this->S0_Wpm2 = S; +} + +void PV_PANEL_MODEL::set_Sref_in_Wpm2(double S) +{ + this->Sref_Wpm2 = S; +} + +double PV_PANEL_MODEL::get_S0_in_Wpm2() const +{ + return S0_Wpm2; +} -void PV_PANEL_MODEL::initialize() +double PV_PANEL_MODEL::get_Sref_in_Wpm2() const { + return Sref_Wpm2; } -void PV_PANEL_MODEL::run(DYNAMIC_MODE mode) +double PV_PANEL_MODEL::get_solar_irradiance_in_Wpm2() { - ostringstream osstream; - osstream<get_pv_irradiance_model(); + if(pv_irrd!=NULL) + { + if(not pv_irrd->is_model_initialized()) + pv_irrd->initialize(); + + return pv_irrd->get_solar_irradiance_in_Wpm2(); + } + else + return S0_Wpm2; +} + +double PV_PANEL_MODEL::get_pv_unit_terminal_active_power_generation_in_pu_based_on_mbase() const +{ + PV_UNIT* pv_unit = get_pv_unit_pointer(); + PV_CONVERTER_MODEL* pv_unitmodel = pv_unit->get_pv_converter_model(); + if(pv_unitmodel!=NULL) + { + if(not pv_unitmodel->is_model_initialized()) + pv_unitmodel->initialize(); + + return pv_unitmodel->get_terminal_active_power_in_pu_based_on_mbase(); + } + else + return 0.0; } diff --git a/code/steps/source/model/pvu_models/pv_panel_model/pvp0.cpp b/code/steps/source/model/pvu_models/pv_panel_model/pvp0.cpp deleted file mode 100644 index 6fecb4c5..00000000 --- a/code/steps/source/model/pvu_models/pv_panel_model/pvp0.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "header/model/pvu_models/pv_panel_model/pvp0.h" -#include "header/basic/utility.h" -#include "header/steps_namespace.h" -#include -#include - -using namespace std; - -PVP0::PVP0(STEPS& toolkit) : PV_PANEL_MODEL(toolkit) -{ - clear(); -} - -PVP0::PVP0(const PVP0& model):PV_PANEL_MODEL(model.get_toolkit()) -{ - copy_from_const_model(model); -} - -PVP0::~PVP0() -{ - ; -} - -PVP0& PVP0::operator=(const PVP0& model) -{ - if(this==(&model)) - return *this; - copy_from_const_model(model); - return *this; -} - -void PVP0::copy_from_const_model(const PVP0& model) -{ - set_toolkit(model.get_toolkit()); - - clear(); - PV_PANEL_MODEL::copy_from_const_model(model); -} - -string PVP0::get_model_name() const -{ - return "PVP0"; -} - -bool PVP0::setup_model_with_steps_string_vector(vector& data) -{ - ostringstream osstream; - osstream< record = psse_dyr_string2steps_string_vector(data); - return setup_model_with_steps_string_vector(record); -} - -bool PVP0::setup_model_with_bpa_string(string data) -{ - ostringstream osstream; - osstream< +#include + +using namespace std; + +PVPNLX::PVPNLX(STEPS& toolkit) : PV_PANEL_MODEL(toolkit) +{ + clear(); +} + +PVPNLX::PVPNLX(const PVPNLX& model):PV_PANEL_MODEL(model.get_toolkit()) +{ + copy_from_const_model(model); +} + +PVPNLX::~PVPNLX() +{ + ; +} + +PVPNLX& PVPNLX::operator=(const PVPNLX& model) +{ + if(this==(&model)) + return *this; + copy_from_const_model(model); + return *this; +} + +void PVPNLX::copy_from_const_model(const PVPNLX& model) +{ + set_toolkit(model.get_toolkit()); + + clear(); + + PV_PANEL_MODEL::copy_from_const_model(model); + set_Pmsta_in_pu_based_on_mbase(model.get_Pmsta_in_pu_based_on_mbase()); + set_b(model.get_b()); + set_Krp(model.get_Krp()); + +} + +void PVPNLX::clear() +{ + set_model_float_parameter_count(4); + set_b(0.0005); + set_Krp(0.1); +} + +void PVPNLX::set_Pmsta_in_pu_based_on_mbase(double P) +{ + this->Pmsta = P; +} + +void PVPNLX::set_b(double b) +{ + this->b = b; +} + +void PVPNLX::set_Krp(double Krp) +{ + this->Krp = Krp; +} + +double PVPNLX::get_Pmsta_in_pu_based_on_mbase() const +{ + return Pmsta; +} + +double PVPNLX::get_b() const +{ + return b; +} + +double PVPNLX::get_Krp() const +{ + return Krp; +} + +double PVPNLX::get_Pmmp_in_pu(double S) +{ + double Sref = get_Sref_in_Wpm2(); + return (S / Sref * (1 + b / exp(1) * (S - Sref))) * Pmsta; +} + +double PVPNLX::get_Pref_in_pu(double S) +{ + double Pmmp = get_Pmmp_in_pu(S); + return Pmmp * (1 - Krp); +} + +void PVPNLX::initialize_S0() +{ + double Sref = get_Sref_in_Wpm2(); + double b_battery = get_b(); + if(Sref-exp(1)/b_battery>0) + { + ostringstream osstream; + STEPS& toolkit = get_toolkit(); + osstream<<"Initialization error. Pmmp (maximum available power from irradiance) of '"<get_pv_converter_model(); + if(not pv_converter_model->is_model_initialized()) + pv_converter_model->initialize(); + + double Pcmd = pv_converter_model->get_initial_active_current_command_in_pu_based_on_mbase() * get_terminal_voltage_in_pu(); + double Pmmax = Pcmd/(1-get_Krp()); + double Pmsta = get_Pmsta_in_pu_based_on_mbase(); + double a = b_battery*Pmsta/(Sref*exp(1)); + double b = Pmsta/Sref-b_battery*Pmsta/exp(1); + double c = -Pmmax; + double S0 = 0.5*(-b + steps_sqrt(b*b-4*a*c))/a; + set_S0_in_Wpm2(S0); +} + +double PVPNLX::get_Pref_in_pu_base_on_mbase() +{ + double S = get_solar_irradiance_in_Wpm2(); + return get_Pref_in_pu(S); +} + +string PVPNLX::get_model_name() const +{ + return "PVPNLX"; +} + +bool PVPNLX::setup_model_with_steps_string_vector(vector& data) +{ + bool is_successful = false; + if(data.size()>=7) + { + string model_name = get_string_data(data[0],""); + if(model_name==get_model_name()) + { + double sref, pmsta, b, krp; + unsigned int i=3; + sref = get_double_data(data[i],"0.0"); i++; + pmsta = get_double_data(data[i],"0.0"); i++; + b = get_double_data(data[i],"0.0"); i++; + krp = get_double_data(data[i],"0.0"); + + set_Sref_in_Wpm2(sref); + set_Pmsta_in_pu_based_on_mbase(pmsta); + set_b(b); + set_Krp(krp); + + is_successful = true; + + return is_successful; + } + else + return is_successful; + } + else + return is_successful; +} + +bool PVPNLX::setup_model_with_psse_string(string data) +{ + vector record = psse_dyr_string2steps_string_vector(data); + return setup_model_with_steps_string_vector(record); +} + +bool PVPNLX::setup_model_with_bpa_string(string data) +{ + ostringstream osstream; + osstream< #include @@ -11,18 +11,18 @@ #ifdef ENABLE_STEPS_TEST using namespace std; -PVP0_TEST::PVP0_TEST() : PV_PANEL_MODEL_TEST() +PVPNLX_TEST::PVPNLX_TEST() : PV_PANEL_MODEL_TEST() { - TEST_ADD(PVP0_TEST::test_get_model_name); - TEST_ADD(PVP0_TEST::test_set_get_parameters); + TEST_ADD(PVPNLX_TEST::test_get_model_name); + TEST_ADD(PVPNLX_TEST::test_set_get_parameters); } -void PVP0_TEST::setup() +void PVPNLX_TEST::setup() { PV_PANEL_MODEL_TEST::setup(); } -void PVP0_TEST::tear_down() +void PVPNLX_TEST::tear_down() { PV_PANEL_MODEL_TEST::tear_down(); @@ -30,22 +30,22 @@ void PVP0_TEST::tear_down() } -void PVP0_TEST::test_get_model_name() +void PVPNLX_TEST::test_get_model_name() { - show_test_information_for_function_of_class(__FUNCTION__,"PVP0_TEST"); + show_test_information_for_function_of_class(__FUNCTION__,"PVPNLX_TEST"); PV_PANEL_MODEL* model = get_test_pv_panel_model(); if(model!=NULL) { - TEST_ASSERT(model->get_model_name()=="PVP0"); + TEST_ASSERT(model->get_model_name()=="PVPNLX"); } else TEST_ASSERT(false); } -void PVP0_TEST::test_set_get_parameters() +void PVPNLX_TEST::test_set_get_parameters() { - show_test_information_for_function_of_class(__FUNCTION__,"PVP0_TEST"); + show_test_information_for_function_of_class(__FUNCTION__,"PVPNLX_TEST"); } diff --git a/code/steps/source/model/pvu_models/pv_relay_model/pv_relay_model.cpp b/code/steps/source/model/pvu_models/pv_relay_model/pv_relay_model.cpp index 45cf732b..62483fb5 100644 --- a/code/steps/source/model/pvu_models/pv_relay_model/pv_relay_model.cpp +++ b/code/steps/source/model/pvu_models/pv_relay_model/pv_relay_model.cpp @@ -16,7 +16,6 @@ PV_RELAY_MODEL::~PV_RELAY_MODEL() void PV_RELAY_MODEL::common_constructor() { - set_allowed_device_type_CAN_ONLY_BE_CALLED_BY_SPECIFIC_MODEL_CONSTRUCTOR(STEPS_PV_UNIT); } string PV_RELAY_MODEL::get_model_type() const diff --git a/code/steps/source/model/sg_models/compensator_model/compensator_model.cpp b/code/steps/source/model/sg_models/compensator_model/compensator_model.cpp index a0af46d6..992e23a9 100644 --- a/code/steps/source/model/sg_models/compensator_model/compensator_model.cpp +++ b/code/steps/source/model/sg_models/compensator_model/compensator_model.cpp @@ -10,7 +10,6 @@ using namespace std; COMPENSATOR_MODEL::COMPENSATOR_MODEL(STEPS& toolkit) : SG_MODEL(toolkit) { - set_allowed_device_type_CAN_ONLY_BE_CALLED_BY_SPECIFIC_MODEL_CONSTRUCTOR(STEPS_GENERATOR); } COMPENSATOR_MODEL::~COMPENSATOR_MODEL() diff --git a/code/steps/source/model/sg_models/exciter_model/exciter_model.cpp b/code/steps/source/model/sg_models/exciter_model/exciter_model.cpp index 653e3285..d2500307 100644 --- a/code/steps/source/model/sg_models/exciter_model/exciter_model.cpp +++ b/code/steps/source/model/sg_models/exciter_model/exciter_model.cpp @@ -11,7 +11,6 @@ using namespace std; EXCITER_MODEL::EXCITER_MODEL(STEPS& toolkit) : SG_MODEL(toolkit) { - set_allowed_device_type_CAN_ONLY_BE_CALLED_BY_SPECIFIC_MODEL_CONSTRUCTOR(STEPS_GENERATOR); } EXCITER_MODEL::~EXCITER_MODEL() diff --git a/code/steps/source/model/sg_models/stabilizer_model/stabilizer_model.cpp b/code/steps/source/model/sg_models/stabilizer_model/stabilizer_model.cpp index a86bf5eb..b8be4305 100644 --- a/code/steps/source/model/sg_models/stabilizer_model/stabilizer_model.cpp +++ b/code/steps/source/model/sg_models/stabilizer_model/stabilizer_model.cpp @@ -10,7 +10,6 @@ STABILIZER_MODEL::STABILIZER_MODEL(STEPS& toolkit) : SG_MODEL(toolkit), signal_2(toolkit),signal_3(toolkit), signal_4(toolkit) { - set_allowed_device_type_CAN_ONLY_BE_CALLED_BY_SPECIFIC_MODEL_CONSTRUCTOR(STEPS_GENERATOR); for(unsigned int slot=0; slotget_power_system_database(); + vector pv_units = psdb.get_all_pv_units(); + + unsigned int n= pv_units.size(); + + for(unsigned int i=0; i!=n; ++i) + add_pv_unit_to_dynamic_network(*(pv_units[i])); +} + +void NETWORK_MATRIX::add_pv_unit_to_dynamic_network(PV_UNIT& pv_unit) +{ + if(pv_unit.get_status()==true) + { + PV_CONVERTER_MODEL* pvconmodel = pv_unit.get_pv_converter_model(); + if(pvconmodel!=NULL) + { + if(pvconmodel->is_voltage_source()) + { + POWER_SYSTEM_DATABASE& psdb = toolkit->get_power_system_database(); + complex Z = pv_unit.get_source_impedance_in_pu(); + double one_over_mbase = pv_unit.get_one_over_mbase_in_one_over_MVA(); + double sbase = psdb.get_system_base_power_in_MVA(); + Z *= (one_over_mbase*sbase); + + unsigned int bus = pv_unit.get_unit_bus(); + unsigned int i = inphno.get_internal_bus_number_of_physical_bus_number(bus); + this_Y_matrix_pointer->add_entry(i,i,1.0/Z); + } + //else // is current source + // return; + } + else + { + ostringstream osstream; + osstream<<"Error. No PV_CONVERTER_MODEL is provided for "<show_information_with_leading_time_stamp(osstream); + return; + } + } +} + +void NETWORK_MATRIX::add_energy_storages_to_dynamic_network() +{ + POWER_SYSTEM_DATABASE& psdb = toolkit->get_power_system_database(); + vector eses = psdb.get_all_energy_storages(); + + unsigned int n= eses.size(); + + for(unsigned int i=0; i!=n; ++i) + add_energy_storage_to_dynamic_network(*(eses[i])); +} + +void NETWORK_MATRIX::add_energy_storage_to_dynamic_network(ENERGY_STORAGE& es) +{ + if(es.get_status()==true) + { + return; + } +} void NETWORK_MATRIX::add_motor_loads_to_dynamic_network() { @@ -3000,6 +3067,7 @@ void NETWORK_MATRIX::add_sources_to_positive_sequence_network() add_generators_to_positive_sequence_network(); add_wt_generators_to_positive_sequence_network(); add_pv_units_to_positive_sequence_network(); + add_energy_storages_to_positive_sequence_network(); } void NETWORK_MATRIX::add_generators_to_positive_sequence_network() @@ -3171,6 +3239,21 @@ void NETWORK_MATRIX::add_pv_unit_to_positive_sequence_network(const PV_UNIT& pv_ } } +void NETWORK_MATRIX::add_energy_storages_to_positive_sequence_network() +{ + POWER_SYSTEM_DATABASE& psdb = toolkit->get_power_system_database(); + vector eses = psdb.get_all_energy_storages(); + + unsigned int n= eses.size(); + for(unsigned int i=0; i!=n; ++i) + add_energy_storage_to_positive_sequence_network(*(eses[i])); +} + +void NETWORK_MATRIX::add_energy_storage_to_positive_sequence_network(const ENERGY_STORAGE& es) +{ + return; +} + void NETWORK_MATRIX::add_fixed_shunts_to_positive_sequence_network() { add_fixed_shunts_to_network(); @@ -3365,6 +3448,7 @@ void NETWORK_MATRIX::add_sources_to_negative_sequence_network() add_generators_to_negative_sequence_network(); add_wt_generators_to_negative_sequence_network(); add_pv_units_to_negative_sequence_network(); + add_energy_storages_to_negative_sequence_network(); } void NETWORK_MATRIX::add_generators_to_negative_sequence_network() @@ -3461,6 +3545,21 @@ void NETWORK_MATRIX::add_pv_unit_to_negative_sequence_network(const PV_UNIT& pv_ } } +void NETWORK_MATRIX::add_energy_storages_to_negative_sequence_network() +{ + POWER_SYSTEM_DATABASE& psdb = toolkit->get_power_system_database(); + vector eses = psdb.get_all_energy_storages(); + + unsigned int n= eses.size(); + for(unsigned int i=0; i!=n; ++i) + add_energy_storage_to_negative_sequence_network(*(eses[i])); +} + +void NETWORK_MATRIX::add_energy_storage_to_negative_sequence_network(const ENERGY_STORAGE& es) +{ + return; +} + void NETWORK_MATRIX::add_fixed_shunts_to_negative_sequence_network() { add_fixed_shunts_to_network(); @@ -4185,6 +4284,7 @@ void NETWORK_MATRIX::add_sources_to_zero_sequence_network() add_generators_to_zero_sequence_network(); add_wt_generators_to_zero_sequence_network(); add_pv_units_to_zero_sequence_network(); + add_energy_storages_to_zero_sequence_network(); } void NETWORK_MATRIX::add_generators_to_zero_sequence_network() @@ -4286,6 +4386,21 @@ void NETWORK_MATRIX::add_pv_unit_to_zero_sequence_network(const PV_UNIT& pv_unit } } +void NETWORK_MATRIX::add_energy_storages_to_zero_sequence_network() +{ + POWER_SYSTEM_DATABASE& psdb = toolkit->get_power_system_database(); + vector eses = psdb.get_all_energy_storages(); + + unsigned int n = eses.size(); + for(unsigned int i=0; i!=n; ++i) + add_energy_storage_to_zero_sequence_network(*(eses[i])); +} + +void NETWORK_MATRIX::add_energy_storage_to_zero_sequence_network(const ENERGY_STORAGE& es) +{ + return; +} + void NETWORK_MATRIX::add_fixed_shunts_to_zero_sequence_network() { POWER_SYSTEM_DATABASE& psdb = toolkit->get_power_system_database();