@@ -21,11 +21,9 @@ class PySAMBatteryPerformanceModelConfig(StoragePerformanceBaseConfig):
2121 and reference module characteristics.
2222
2323 Attributes:
24- max_capacity (float):
25- Maximum battery energy capacity in kilowatt-hours (kWh).
24+ max_capacity (float): Maximum battery energy capacity in kilowatt-hours (kWh).
2625 Must be greater than zero.
27- max_charge_rate (float):
28- Rated power capacity of the battery in kilowatts (kW).
26+ max_charge_rate (float): Rated power capacity of the battery in kilowatts (kW).
2927 Must be greater than zero.
3028 demand_profile (int | float | list): Demand values for each timestep, in
3129 the same units as `commodity_rate_units`. May be a scalar for constant
@@ -36,20 +34,14 @@ class PySAMBatteryPerformanceModelConfig(StoragePerformanceBaseConfig):
3634
3735 - PySAM: ``"LFPGraphite"``, ``"LMOLTO"``, ``"LeadAcid"``, ``"NMCGraphite"``
3836
39- min_soc_fraction (float):
40- Minimum allowable state of charge as a fraction (0 to 1).
41- max_soc_fraction (float):
42- Maximum allowable state of charge as a fraction (0 to 1).
43- init_soc_fraction (float):
44- Initial state of charge as a fraction (0 to 1).
45- control_variable (str):
46- Control mode for the PySAM battery, either ``"input_power"``
37+ min_soc_fraction (float): Minimum allowable state of charge as a fraction (0 to 1).
38+ max_soc_fraction (float): Maximum allowable state of charge as a fraction (0 to 1).
39+ init_soc_fraction (float): Initial state of charge as a fraction (0 to 1).
40+ control_variable (str): Control mode for the PySAM battery, either ``"input_power"``
4741 or ``"input_current"``.
48- ref_module_capacity (int | float, optional):
49- Reference module capacity in kilowatt-hours (kWh).
42+ ref_module_capacity (int | float, optional): Reference module capacity in kWh.
5043 Defaults to 400.
51- ref_module_surface_area (int | float, optional):
52- Reference module surface area in square meters (m²).
44+ ref_module_surface_area (int | float, optional): Reference module surface area in m².
5345 Defaults to 30.
5446 Cp (int | float, optional): Battery specific heat capacity [J/kg*K].
5547 Defaults to 900.
@@ -61,12 +53,11 @@ class PySAMBatteryPerformanceModelConfig(StoragePerformanceBaseConfig):
6153
6254 max_capacity : float = field (validator = gt_zero )
6355 max_charge_rate : float = field (validator = gt_zero )
64- # demand_profile: int | float | list = field()
56+
6557 chemistry : str = field (
6658 validator = contains (["LFPGraphite" , "LMOLTO" , "LeadAcid" , "NMCGraphite" ]),
6759 )
68- # min_soc_fraction: float = field(validator=range_val(0, 1))
69- # max_soc_fraction: float = field(validator=range_val(0, 1))
60+
7061 init_soc_fraction : float = field (validator = range_val (0 , 1 ))
7162 control_variable : str = field (
7263 default = "input_power" , validator = contains (["input_power" , "input_current" ])
@@ -90,68 +81,18 @@ class PySAMBatteryPerformanceModel(StoragePerformanceBase):
9081 bounds set by the user. It may exceed the bounds by up to 5% SOC.
9182
9283 Attributes:
93- config (PySAMBatteryPerformanceModelConfig):
94- Configuration parameters for the battery performance model.
95- system_model (``BatteryStateful``):
96- Instance of the PySAM BatteryStateful model, initialized with
97- the selected chemistry and configuration parameters.
98- outputs (BatteryOutputs):
99- Container for simulation outputs such as SOC, chargeable/dischargeable
100- power, unmet demand, and unused commodities.
101- unmet_demand (float):
102- Tracks unmet demand during simulation (kW).
103- unused_commodity (float):
104- Tracks unused commodity during simulation (kW).
105-
106- Inputs:
107- max_charge_rate (float):
108- Battery charge rate in kilowatts per hour (kW).
109- storage_capacity (float):
110- Total energy storage capacity in kilowatt-hours (kWh).
111- electricity_demand (ndarray):
112- Power demand time series (kW).
113- electricity_in (ndarray):
114- Commanded input electricity (kW), typically from dispatch.
115-
116- Outputs:
117- unmet_demand_out (ndarray):
118- Remaining unmet demand after discharge (kW).
119- unused_commodity_out (ndarray):
120- Unused energy not absorbed by the battery (kW).
121- electricity_out (ndarray):
122- Dispatched electricity to meet demand (kW), including electricity from
123- electricity_in that was never used to charge the battery and
124- battery_electricity.
125- SOC (ndarray):
126- Battery state of charge (%).
127- battery_electricity (ndarray):
128- Electricity output from the battery model (kW).
84+ system_model (``BatteryStateful``): Instance of the PySAM BatteryStateful model, initialized
85+ with the selected chemistry and configuration parameters.
86+
12987
13088 Methods:
131- setup():
132- Defines model inputs, outputs, configuration, and connections
133- to plant-level dispatch (if applicable).
13489 compute(inputs, outputs, discrete_inputs, discrete_outputs):
13590 Runs the PySAM BatteryStateful model for a simulation timestep,
13691 updating outputs such as SOC, charge/discharge limits, unmet
13792 demand, and unused commodities.
138- simulate(electricity_in, electricity_demand, time_step_duration, control_variable,
139- sim_start_index=0):
140- Simulates the battery behavior across timesteps using either
141- input power or input current as control. This method is similar to what is
142- provided in typical compute methods in H2Integrate for running models, but
143- needs to be a separate method here to allow the dispatch function to call
144- and manage the performance model.
14593 _set_control_mode(control_mode=1.0, input_power=0.0, input_current=0.0,
14694 control_variable="input_power"):
14795 Sets the battery control mode (power or current).
148-
149- Notes:
150- - Default timestep is 1 hour (``dt=1.0``).
151- - State of charge (SOC) bounds are set using the configuration's
152- ``min_soc_fraction`` and ``max_soc_fraction``.
153- - If a Pyomo dispatch solver is provided, the battery will simulate
154- dispatch decisions using solver inputs.
15596 """
15697
15798 def initialize (self ):
@@ -179,29 +120,12 @@ def setup(self):
179120 # Initialize the PySAM BatteryStateful model with defaults
180121 self .system_model = BatteryStateful .default (self .config .chemistry )
181122
182- # Renaming outputs from battery to storage
183- # battery_electricity_discharge -> storage_electricity_discharge
184- # battery_electricity_charge -> storage_electricity_charge
185- # battery_electricity_out -> storage_electricity_out
186-
187123 def compute (self , inputs , outputs , discrete_inputs = [], discrete_outputs = []):
188124 """Run the PySAM Battery model for one simulation step.
189125
190126 Configures the battery stateful model parameters (SOC limits, timestep,
191127 thermal properties, etc.), executes the simulation, and stores the
192128 results in OpenMDAO outputs.
193-
194- Args:
195- inputs (dict):
196- Continuous input values (e.g., electricity_in, electricity_demand) or
197- battery design parameters.
198- outputs (dict):
199- Dictionary where model outputs (SOC, battery_discharge, unmet demand, etc.)
200- are written.
201- discrete_inputs (dict):
202- Discrete inputs such as control mode or Pyomo solver.
203- discrete_outputs (dict):
204- Discrete outputs (unused in this component).
205129 """
206130
207131 # Size the battery based on inputs -> method brought from HOPP
@@ -241,7 +165,7 @@ def compute(self, inputs, outputs, discrete_inputs=[], discrete_outputs=[]):
241165 self .system_model .value ("input_power" , 0.0 )
242166 self .system_model .execute (0 )
243167
244- self .run_storage (
168+ outputs = self .run_storage (
245169 inputs ["max_charge_rate" ][0 ],
246170 inputs ["max_charge_rate" ][0 ],
247171 inputs ["storage_capacity" ][0 ],
@@ -384,8 +308,3 @@ def _set_control_mode(
384308 self .system_model .value ("input_current" , input_current )
385309 # Either `input_power` or `input_current`; need to adjust `control_mode` above
386310 self .control_variable = control_variable
387-
388-
389- def dummy_function ():
390- # this function is required for initializing the pyomo control input and nothing else
391- pass
0 commit comments