Skip to content

Commit

Permalink
Add regression testing (#129)
Browse files Browse the repository at this point in the history
* Regression test for FlorisStandin.

* floris already installed

* Add reg test for solarPySAM

* Ruff."

* Reg tests for SimpleBattery and LIB.

* Simplify inputs.

* Structure of reg test for electrolyzer added, but good input sequence still needed.

* Checkout develop branch of electrolyzer for testing.

* Electrolyzer reg tests with nonzero output.
  • Loading branch information
misi9170 authored Dec 3, 2024
1 parent dea73ef commit 879385c
Show file tree
Hide file tree
Showing 8 changed files with 1,717 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/continuous-integration-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -e ".[develop]"
pip install git+https://github.com/NREL/electrolyzer.git
pip install git+https://github.com/NREL/electrolyzer.git@develop
pip install https://github.com/NREL/SEAS/blob/main/SEAS.tar.gz?raw=true
# - uses: pre-commit/action@v3.0.0
- name: Run ruff
Expand Down
190 changes: 190 additions & 0 deletions tests/regression_tests/battery_regression_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
"""Regression tests for 'SolarPySAM'."""

import numpy as np
from hercules.python_simulators.battery import LIB, SimpleBattery

PRINT_VALUES = True

test_input_dict = {
"size": 20,
"energy_capacity": 80,
"charge_rate": 20,
"discharge_rate": 20,
"max_SOC": 0.9,
"min_SOC": 0.1,
"initial_conditions": {"SOC": 0.5},
}

np.random.seed(0)
powers_requested = np.concatenate(
(
np.linspace(0, 100000, 3), # Ramp up
np.linspace(100000, -5000, 6), # Ramp down
np.random.normal(-500, 100, 3) # Random fluctuations
)
)

powers_base_simple = np.array(
[
0.,
20000.,
20000.,
20000.,
20000.,
20000.,
20000.,
16000.,
-5000.,
-323.5947654,
-459.98427916,
]
)

reject_base_simple = np.array(
[
0. ,
30000.,
80000.,
80000.,
59000.,
38000.,
17000.,
0. ,
0. ,
0. ,
0.
]
)

soc_base_simple = np.array(
[
0.5 ,
0.50003472,
0.50006944,
0.50010417,
0.50013889,
0.50017361,
0.50020833,
0.50023611,
0.50022743,
0.50022687,
0.50022607,
]
)

powers_base_lib = np.array(
[
0. ,
20047.11229812,
20047.95046608,
20048.77886147,
20049.59760268,
20050.40680666,
20051.20658894,
15990.37116823,
-4983.52093018,
-323.83088639 ,
-459.97259284 ,
]
)

reject_base_lib = np.array(
[
0.00000000e+00,
2.99528877e+04,
7.99520495e+04,
7.99512211e+04,
5.89504024e+04,
3.79495932e+04,
1.69487934e+04,
9.62883177e+00,
-1.64790698e+01,
2.36120986e-01,
-1.16863220e-02,
]
)

soc_base_lib = np.array(
[
0.5 ,
0.50003472,
0.50006944,
0.50010417,
0.50013889,
0.50017361,
0.50020833,
0.50023604,
0.50022738,
0.50022681,
0.50022601,
]
)

def test_SimpleBattery_regression_():

dt = 0.5

battery = SimpleBattery(test_input_dict, dt)

times_test = np.arange(0, 5.5, dt)
powers_test = np.zeros_like(times_test)
reject_test = np.zeros_like(times_test)
soc_test = np.zeros_like(times_test)

for i, t in enumerate(times_test):
out = battery.step({
"time": t,
"py_sims": {
"inputs": {
"battery_signal": powers_requested[i],
"available_power": powers_requested[i]
}
}
})
powers_test[i] = out["power"]
reject_test[i] = out["reject"]
soc_test[i] = out["soc"]

if PRINT_VALUES:
print("Powers: ", powers_test)
print("Rejected: ", reject_test)
print("SOC: ", soc_test)

assert np.allclose(powers_base_simple, powers_test)
assert np.allclose(reject_base_simple, reject_test)
assert np.allclose(soc_base_simple, soc_test)

def test_LIB_regression_():


dt = 0.5

battery = LIB(test_input_dict, dt)

times_test = np.arange(0, 5.5, dt)
powers_test = np.zeros_like(times_test)
reject_test = np.zeros_like(times_test)
soc_test = np.zeros_like(times_test)

for i, t in enumerate(times_test):
out = battery.step({
"time": t,
"py_sims": {
"inputs": {
"battery_signal": powers_requested[i],
"available_power": powers_requested[i]
}
}
})
powers_test[i] = out["power"]
reject_test[i] = out["reject"]
soc_test[i] = out["soc"]

if PRINT_VALUES:
print("Powers: ", powers_test)
print("Rejected: ", reject_test)
print("SOC: ", soc_test)

assert np.allclose(powers_base_lib, powers_test)
assert np.allclose(reject_base_lib, reject_test)
assert np.allclose(soc_base_lib, soc_test)
116 changes: 116 additions & 0 deletions tests/regression_tests/electrolyzer_plant_regression_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
"""Regression tests for 'SolarPySAM'."""

import numpy as np
from hercules.python_simulators.electrolyzer_plant import ElectrolyzerPlant

PRINT_VALUES = True

test_input_dict = {
"general": {
"verbose": False
},
"electrolyzer": {
"initialize": True,
"initial_power_kW": 3000,
"supervisor": {
"n_stacks": 10,
},
"stack": {
"cell_type": "PEM",
"cell_area": 1000.0,
"max_current": 2000,
"temperature": 60,
"n_cells": 100,
"min_power": 50,
"stack_rating_kW": 500,
"include_degradation_penalty": True,
},
"controller": {
"n_stacks": 10,
"control_type": "DecisionControl",
"policy": {
"eager_on": False,
"eager_off": False,
"sequential": False,
"even_dist": False,
"baseline": True,
},
},
"costs": None,
"cell_params": {
"cell_type": "PEM",
"PEM_params": {
"cell_area": 1000,
"turndown_ratio": 0.1,
"max_current_density": 2,
},
},
"degradation": {
"PEM_params": {
"rate_steady": 1.41737929e-10,
"rate_fatigue": 3.33330244e-07,
"rate_onoff": 1.47821515e-04,
},
},
}
}

np.random.seed(0)
available_power_test = np.concatenate(
(
np.linspace(500, 1000, 3), # Ramp up
np.linspace(1000, 200, 3), # Ramp down
np.ones(3) * 200, # Constant
np.random.normal(500, 100, 3) # Random fluctuations
)
)

H2_output_base = np.array(
[
0.00071706,
0.00073655,
0.00079499,
0.00088781,
0.0009718 ,
0.00098348,
0.00092732,
0.00087651,
0.00083054,
0.00078894,
0.00083047,
0.00084576,
]
)

stacks_on_base = np.array([7., 7., 7., 7., 7., 7., 7., 7., 7., 7., 7., 7.])

def test_ElectrolyzerPlant_regression_():

dt = 0.5

electrolyzer = ElectrolyzerPlant(test_input_dict, dt)

times_test = np.arange(0, 6.0, dt)
H2_output_test = np.zeros_like(times_test)
stacks_on_test = np.zeros_like(times_test)

for i, t in enumerate(times_test):
out = electrolyzer.step({
"time": t,
"py_sims": {
"inputs": {
"available_power": available_power_test[i]
}
}
})
H2_output_test[i] = out["H2_output"]
stacks_on_test[i] = out["stacks_on"]

#print(out["H2_output"])

if PRINT_VALUES:
print("H2 output: ", H2_output_test)
print("Stacks on: ", stacks_on_test)

assert np.allclose(H2_output_base, H2_output_test)
assert np.allclose(stacks_on_base, stacks_on_test)
Loading

0 comments on commit 879385c

Please sign in to comment.