h2integrate.storage.storage_baseclass#

Classes

StoragePerformanceBase(**kwargs)

Baseclass for storage performance models

StoragePerformanceBaseConfig(*, ...)

Configuration class for the StoragePerformanceBase model.

class h2integrate.storage.storage_baseclass.StoragePerformanceBaseConfig(*, min_soc_fraction, max_soc_fraction, demand_profile)#

Configuration class for the StoragePerformanceBase model.

Attributes:

min_soc_fraction (float): Minimum allowable state of charge as a fraction (0 to 1). max_soc_fraction (float): Maximum allowable state of charge as a fraction (0 to 1). demand_profile (int | float | list): Demand values for each timestep, in

the same units as commodity_rate_units. May be a scalar for constant demand or a list/array for time-varying demand.

Parameters:
  • min_soc_fraction (float)

  • max_soc_fraction (float)

  • demand_profile (int | float | list)

min_soc_fraction: float#
max_soc_fraction: float#
demand_profile: int | float | list#
class h2integrate.storage.storage_baseclass.StoragePerformanceBase(**kwargs)#

Baseclass for storage performance models

config#

Configuration parameters for the storage performance model.

Type:

StoragePerformanceModelConfig

current_soc#

soc at the start of each interval that the simulate() method is called

Type:

float

dt_hr#

timestep in hours.

Type:

float

Notes

  • Default timestep is 1 hour (dt=3600.0).

  • State of charge (SOC) bounds are set using the configuration’s min_soc_fraction and max_soc_fraction.

  • If a Pyomo dispatch solver is provided, the storage will simulate dispatch decisions using solver inputs.

_time_step_bounds = (3600, 3600)#
setup()#

Set up the storage performance model in OpenMDAO.

Initializes the configuration and defines inputs/outputs for OpenMDAO. If dispatch connections are specified, it also sets up a discrete input for Pyomo solver integration.

compute(inputs, outputs, discrete_inputs=[], discrete_outputs=[])#

Run the storage model.

Configures the storage stateful model parameters (SOC limits, timestep, thermal properties, etc.), executes the simulation, and stores the results in OpenMDAO outputs.

Parameters:
  • inputs (dict) – Continuous input values (e.g., commodity_in, commodity_demand).

  • outputs (dict) – Dictionary where model outputs (SOC, unmet demand, etc.) are written.

  • discrete_inputs (dict) – Discrete inputs such as control mode or Pyomo solver.

  • discrete_outputs (dict) – Discrete outputs (unused in this component).

run_storage(charge_rate, discharge_rate, storage_capacity, inputs, outputs, discrete_inputs)#

Run the storage performance model and calculate the outputs. This method should be called in the compute() method of a subclass.

Example

>>> # In the `compute()` method:
>>> self.current_soc = self.config.init_soc_fraction
>>> charge_rate = inputs["max_charge_rate"][0]
>>> discharge_rate = inputs["max_discharge_rate"][0]
>>> storage_capacity = inputs["storage_capacity"]
>>> outputs = self.run_storage(
... charge_rate, discharge_rate, storage_capacity, inputs, outputs, discrete_inputs
>>> )
Parameters:
  • charge_rate (float) – storage charge rate in commodity_rate_units

  • discharge_rate (float) – storage discharge rate in commodity_rate_units

  • storage_capacity (float) – storage capacity in commodity_amount_units

  • inputs (om.vectors.default_vector.DefaultVector | dict) – OpenMDAO inputs to the compute() method. This should at least include the commodity demand profile and input commodity profile.

  • outputs (om.vectors.default_vector.DefaultVector) – OpenMDAO outputs from the compute() method

  • discrete_inputs (om.core.component._DictValues, optional) – OpenMDAO discrete inputs to the compute() method. This is only required if using a feedback control strategy and should contain the discrete input ‘pyomo_dispatch_solver’.

Returns:

om.vectors.default_vector.DefaultVector – calculated OpenMDAO outputs.

simulate(storage_dispatch_commands, charge_rate, discharge_rate, storage_capacity, sim_start_index=0)#

Run the storage model over a control window of n_control_window timesteps.

Iterates through storage_dispatch_commands one timestep at a time. A negative command requests charging; a positive command requests discharging. Each command is clipped to the most restrictive of three limits before it is applied:

  1. SOC headroom - the remaining capacity (charge) or remaining stored commodity (discharge), converted to a rate via storage_capacity / dt_hr.

  2. Hardware rate limit - charge_rate or discharge_rate, divided by the corresponding efficiency so the limit is expressed in pre-efficiency rate units.

  3. Commanded magnitude - the absolute value of the dispatch command itself (we never exceed what was asked for).

After clipping, the result is scaled by the charge or discharge efficiency to obtain the actual commodity flow into or out of the storage, and the SOC is updated accordingly.

This method is separated from compute() so the Pyomo dispatch controller can call it directly to evaluate candidate schedules.

Parameters:
  • storage_dispatch_commands (array_like[float]) – Dispatch set-points for each timestep in commodity_rate_units. Negative values command charging; positive values command discharging. Length must equal config.n_control_window.

  • charge_rate (float) – Maximum commodity input rate to storage in commodity_rate_units (before charge efficiency is applied).

  • discharge_rate (float) – Maximum commodity output rate from storage in commodity_rate_units (before discharge efficiency is applied).

  • storage_capacity (float) – Rated storage capacity in commodity_amount_units.

  • sim_start_index (int, optional) – Starting index for writing into persistent output arrays. Defaults to 0.

Returns:

tuple[np.ndarray, np.ndarray]
storage_commodity_out_timesteps :

Commodity flow per timestep in commodity_rate_units. Positive = discharge (commodity leaving storage), negative = charge (commodity entering storage).

soc_timesteps :

State of charge at the end of each timestep, in percent (0-100).