Skip to content

Commit ad7d7c8

Browse files
authored
Merge pull request #38 from NREL/develop
Release: v0.1.3
2 parents aa329cf + 6b40c6f commit ad7d7c8

12 files changed

Lines changed: 37 additions & 132 deletions

File tree

.github/workflows/ci.yml

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,44 @@ jobs:
66
build:
77

88
runs-on: ubuntu-latest
9+
defaults:
10+
run:
11+
shell: bash -el {0}
912
strategy:
1013
matrix:
1114
python-version: ["3.9", "3.10", "3.11"]
1215

1316
steps:
14-
- uses: actions/checkout@v3
15-
- name: Set up Python ${{ matrix.python-version }}
16-
uses: actions/setup-python@v3
17+
- uses: actions/checkout@v4
18+
- name: Set up Miniconda Python ${{ matrix.python-version }}
19+
uses: conda-incubator/setup-miniconda@v3
1720
with:
21+
auto-update-conda: true
1822
python-version: ${{ matrix.python-version }}
23+
channels: conda-forge
24+
activate-environment: greenheart-test-${{ matrix.python-version }}
1925
- name: Install dependencies
2026
env:
2127
SKLEARN_ALLOW_DEPRECATED_SKLEARN_PACKAGE_INSTALL: True
2228
run: |
2329
sudo apt-get update && sudo apt-get install -y libglpk-dev glpk-utils coinor-cbc
2430
python -m pip install --upgrade pip
2531
pip install electrolyzer@git+https://github.com/jaredthomas68/electrolyzer.git@smoothing
26-
pip install ProFAST@git+https://github.com/NREL/ProFAST.git
2732
pip install ".[develop]"
2833
- name: Create env file
2934
run: |
3035
touch .env
3136
# echo NREL_API_KEY=${{ secrets.NREL_API_KEY }} >> .env
3237
# cat .env
38+
- name: Save environment build details
39+
run: |
40+
mkdir ~/artifacts
41+
conda env export --file ~/artifacts/environment.yml
42+
- name: Upload build artifact
43+
uses: actions/upload-artifact@v4
44+
with:
45+
name: ${{ matrix.python-version }}-environment
46+
path: ~/artifacts/environment.yml
3347
- name: Run tests
3448
run: |
3549
PYTHONPATH=. pytest tests

CHANGELOG.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
11
# CHANGELOG
22

3-
## v0.1.1 [28 October 2024]
3+
## v0.1.3 [1 November 2024]
44

5-
- Minor updates to examples for NAWEA workshop
5+
- Replaces the git ProFAST installation with a PyPI installation.
6+
- Removed dependence on external electrolyzer repo
7+
- Updated CI to use conda environments with reproducible environment artifacts
8+
- Rename logger from "wisdem/weis" to "greenheart"
9+
- Remove unsupported optimization algorithms
10+
11+
## v0.1.2 [28 October 2024]
12+
13+
- Minor updates to examples for NAWEA workshop.
14+
- Adds `environment.yml` for easy environment creation and GreenHEART installation.
15+
16+
## v0.1.1 [22 October 2024]
17+
18+
- ?
619

720
## v0.1 [16 October 2024]
821

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ pip install -e ".[all]"
125125
```bash
126126
conda install -y -c conda-forge glpk
127127
pip install electrolyzer@git+https://github.com/jaredthomas68/electrolyzer.git@smoothing
128-
pip install ProFAST@git+https://github.com/NREL/ProFAST.git
129128
```
130129

131130
Note: Unix users should install Cbc via:

docs/install.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ pip install -e ".[all]"
109109
```bash
110110
conda install -y -c conda-forge glpk
111111
pip install electrolyzer@git+https://github.com/jaredthomas68/electrolyzer.git@smoothing
112-
pip install ProFAST@git+https://github.com/NREL/ProFAST.git
113112
```
114113

115114
````{note}

environment.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,4 @@ dependencies:
88
- pip
99
- pip:
1010
- electrolyzer@git+https://github.com/jaredthomas68/electrolyzer.git@smoothing
11-
- ProFAST@git+https://github.com/NREL/ProFAST.git
1211
- "."

greenheart/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11

2-
__version__ = "0.1.2"
2+
__version__ = "0.1.3"

greenheart/tools/eco/electrolysis.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131

3232
from greenheart.simulation.technologies.hydrogen.electrolysis.PEM_BOP.PEM_BOP import pem_bop
3333

34-
# from electrolyzer import run_electrolyzer
35-
3634

3735
def run_electrolyzer_physics(
3836
hopp_results,

greenheart/tools/optimization/gc_PoseOptimization.py

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,6 @@ def __init__(self, config: GreenHeartSimulationConfig):
2626

2727
self.config = config
2828

29-
self.nlopt_methods = [
30-
"GN_DIRECT",
31-
"GN_DIRECT_L",
32-
"GN_DIRECT_L_NOSCAL",
33-
"GN_ORIG_DIRECT",
34-
"GN_ORIG_DIRECT_L",
35-
"GN_AGS",
36-
"GN_ISRES",
37-
"LN_COBYLA",
38-
"LD_MMA",
39-
"LD_CCSAQ",
40-
"LD_SLSQP",
41-
]
42-
4329
self.scipy_methods = [
4430
"SLSQP",
4531
"Nelder-Mead",
@@ -265,20 +251,6 @@ def set_driver(self, opt_prob):
265251
]
266252
opt_prob = self._set_optimizer_properties(opt_prob, options_keys)
267253

268-
elif opt_options["solver"] in self.nlopt_methods:
269-
try:
270-
from wisdem.optimization_drivers.nlopt_driver import NLoptDriver
271-
except:
272-
raise ImportError(
273-
"You requested an optimization method from NLopt, but need to first install NLopt to use this method."
274-
)
275-
276-
opt_prob.driver = NLoptDriver()
277-
opt_prob.driver.options["optimizer"] = opt_options["solver"]
278-
options_keys = ["tol", "xtol", "max_iter", "max_time", "numgen"]
279-
mapped_keys = {"max_iter": "maxiter", "max_time": "maxtime"}
280-
opt_prob = self._set_optimizer_properties(opt_prob, options_keys, mapped_keys=mapped_keys)
281-
282254
else:
283255
raise ValueError(f"The {self.config.greenheart_config['opt_options']['driver']['optimization']['solver']} optimizer is not yet supported!")
284256

greenheart/tools/optimization/gc_run_greenheart.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def run_greenheart(config:GreenHeartSimulationConfig, overridden_values=None, ru
8282
os.makedirs(folder_output, exist_ok=True)
8383

8484
# create logger
85-
logger = logging.getLogger("wisdem/weis")
85+
logger = logging.getLogger("greenheart")
8686
logger.setLevel(logging.INFO)
8787

8888
# create handlers

greenheart/tools/optimization/openmdao.py

Lines changed: 0 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import numpy as np
22
import openmdao.api as om
33

4-
import electrolyzer.inputs.validation as val
5-
from electrolyzer import run_lcoh
6-
74
from shapely.geometry import Polygon, Point
85
from hopp.simulation import HoppInterface
96
from greenheart.simulation.greenheart_simulation import GreenHeartSimulationConfig, run_simulation
@@ -305,90 +302,3 @@ def compute(self, inputs, outputs):
305302

306303
def setup_partials(self):
307304
self.declare_partials('*', '*', method='fd', form='forward')
308-
309-
class ElectrolyzerComponent(om.ExplicitComponent):
310-
"""
311-
This is an OpenMDAO wrapper to the generic electrolyzer model.
312-
313-
It makes some assumptions about the number of electrolyzers, stack size, and
314-
how to distribute electricity across the different electrolyzers. These
315-
could be later made into modeling options to allow for more user configuration.
316-
"""
317-
def initialize(self):
318-
self.options.declare("h2_modeling_options")
319-
self.options.declare("h2_opt_options")
320-
self.options.declare("modeling_options")
321-
self.options.declare("design_variables",
322-
# ["electrolyzer_rating_kw"],
323-
types=list,
324-
desc="List of design variables that should be included",
325-
default=[],
326-
recordable=False)
327-
328-
def setup(self):
329-
self.add_input("power_signal", val=np.zeros(8760), units="W")
330-
self.add_input("lcoe_real", units="USD/kW/h")
331-
332-
if "electrolyzer_rating_kw" in self.options["design_variables"]:
333-
self.add_input("electrolyzer_rating_kw", val=15000, units="kW")
334-
335-
if self.options["h2_opt_options"]["control"]["system_rating_MW"]["flag"] \
336-
or self.options["modeling_options"]["rating_equals_turbine_rating"]:
337-
self.add_input("system_rating_MW", units="MW", val=self.options["h2_modeling_options"]["electrolyzer"]["control"]["system_rating_MW"])
338-
self.add_output("h2_produced", units="kg")
339-
self.add_output("max_curr_density", units="A/cm**2")
340-
self.add_output("electrolyzer_capex", units="USD")
341-
self.add_output("electrolyzer_opex", units="USD")
342-
self.add_output("lcoh", units="USD/kg")
343-
self.add_output("h2_produced_hourly", units="kg", val=np.zeros(8760))
344-
self.add_output("power_kW_curtailed", units="kW", val=np.zeros(8760))
345-
self.add_output("power_kW_avail", units="kW", val=np.zeros(8760))
346-
# self.add_output("deg_state", units="V", val=np.zeros(6)) # TODO we need a way to size this dynamically
347-
348-
def compute(self, inputs, outputs):
349-
# Set electrolyzer parameters from model inputs
350-
power_signal = inputs["power_signal"]
351-
lcoe_real = inputs["lcoe_real"][0]
352-
353-
if "electrolyzer_rating_kw" in inputs:
354-
self.options["h2_modeling_options"]["electrolyzer"]["control"]["system_rating_MW"] = inputs["electrolyzer_rating_kw"][0]*1E-3
355-
356-
elif self.options["h2_opt_options"]["control"]["system_rating_MW"]["flag"] \
357-
or self.options["modeling_options"]["rating_equals_turbine_rating"]:
358-
self.options["h2_modeling_options"]["electrolyzer"]["control"]["system_rating_MW"] = inputs["system_rating_MW"][0]
359-
360-
elif "electrolyzer_rating_MW" in self.options["modeling_options"]["overridden_values"]:
361-
electrolyzer_rating_MW = self.options["modeling_options"]["overridden_values"]["electrolyzer_rating_MW"]
362-
self.options["h2_modeling_options"]["electrolyzer"]["control"]["system_rating_MW"] = electrolyzer_rating_MW
363-
364-
h2_prod, max_curr_density, lcoh, lcoh_dict, lcoh_options_dict, = run_lcoh(
365-
self.options["h2_modeling_options"],
366-
power_signal,
367-
lcoe_real,
368-
optimize=True
369-
)
370-
371-
lt = lcoh_dict["LCOH Breakdown"]["Life Totals [$]"]
372-
capex = lt["CapEx"]
373-
opex = lt["OM"]
374-
375-
# msg = (
376-
# f"\n====== Electrolyzer ======\n"
377-
# f" - h2 produced (kg): {h2_prod}\n"
378-
# f" - max current density (A/cm^2): {max_curr_density}\n"
379-
# f" - LCOH ($/kg): {lcoh}\n"
380-
# )
381-
382-
# logger.info(msg)
383-
outputs["h2_produced"] = h2_prod
384-
outputs["max_curr_density"] = max_curr_density
385-
outputs["electrolyzer_capex"] = capex
386-
outputs["electrolyzer_opex"] = opex
387-
outputs["lcoh"] = lcoh
388-
outputs["h2_produced_hourly"] = lcoh_options_dict["kg_produced"]
389-
outputs["power_kW_curtailed"] = lcoh_options_dict["power_kW_curtailed"]
390-
outputs["power_kW_avail"] = lcoh_options_dict["power_kW_avail"]
391-
# outputs["deg_state"] = lcoh_options_dict["deg_state"] # TODO we need a way to size this dynamically
392-
393-
def setup_partials(self):
394-
self.declare_partials('lcoh', '*', method='fd', form='forward')

0 commit comments

Comments
 (0)