From 25f555dc6fdfe016611971c263627534c538aa13 Mon Sep 17 00:00:00 2001 From: Jared Thomas Date: Thu, 26 Mar 2026 10:28:11 -0600 Subject: [PATCH 01/10] move xdsm creation in H2IModel to a method so user has to call it if desired instead of having it be automatic --- h2integrate/core/h2integrate_model.py | 25 ++++++-- h2integrate/core/test/test_framework.py | 83 +++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 6 deletions(-) diff --git a/h2integrate/core/h2integrate_model.py b/h2integrate/core/h2integrate_model.py index b14ed0539..7cf6673aa 100644 --- a/h2integrate/core/h2integrate_model.py +++ b/h2integrate/core/h2integrate_model.py @@ -1219,12 +1219,6 @@ def connect_technologies(self): f"{dispatching_tech_name}.dispatch_block_rule_function_{tech_name}", ) - if (pyxdsm is not None) and (len(technology_interconnections) > 0): - try: - create_xdsm_from_config(self.plant_config) - except FileNotFoundError as e: - print(f"Unable to create system XDSM diagram. Error: {e}") - def create_driver_model(self): """ Add the driver to the OpenMDAO model and add recorder. @@ -1449,3 +1443,22 @@ def _structured(meta_list): "explicit_outputs": _structured(explicit_meta), "implicit_outputs": _structured(implicit_meta), } + + def create_xdsm(self): + """Generates an XDSM diagram for the plant configuration and saves it to a PDF file. + + Reads technology interconnections from the plant configuration and delegates + diagram creation to :func:`create_xdsm_from_config`. If ``pyxdsm`` is not + installed or no interconnections are defined, this method does nothing. A + :class:`FileNotFoundError` is caught and reported without raising. + + Raises: + None: All exceptions are caught internally; errors are printed to stdout. + """ + + technology_interconnections = self.plant_config.get("technology_interconnections", []) + if (pyxdsm is not None) and (len(technology_interconnections) > 0): + try: + create_xdsm_from_config(self.plant_config) + except FileNotFoundError as e: + print(f"Unable to create system XDSM diagram. Error: {e}") diff --git a/h2integrate/core/test/test_framework.py b/h2integrate/core/test/test_framework.py index 524968a64..cf8e53cae 100644 --- a/h2integrate/core/test/test_framework.py +++ b/h2integrate/core/test/test_framework.py @@ -1,11 +1,13 @@ import shutil from copy import deepcopy from pathlib import Path +from unittest.mock import MagicMock, patch import yaml import numpy as np import pytest +import h2integrate.core.h2integrate_model as h2i_model_module from h2integrate import EXAMPLE_DIR from h2integrate.core.h2integrate_model import H2IntegrateModel from h2integrate.core.inputs.validation import load_tech_yaml, load_plant_yaml, load_driver_yaml @@ -476,3 +478,84 @@ def test_system_order(subtests): with subtests.test("Test expected names are in the correct order"): assert names == expected_names + + +@pytest.mark.unit +def test_create_xdsm_calls_create_xdsm_from_config(): + plant_config = {"technology_interconnections": [("wind", "electrolyzer", "electricity")]} + model = object.__new__(H2IntegrateModel) + model.plant_config = plant_config + + with ( + patch.object(h2i_model_module, "pyxdsm", MagicMock()), + patch.object(h2i_model_module, "create_xdsm_from_config") as mock_fn, + ): + model.create_xdsm() + + mock_fn.assert_called_once_with(plant_config) + + +@pytest.mark.unit +def test_create_xdsm_skips_when_pyxdsm_none(): + plant_config = {"technology_interconnections": [("wind", "electrolyzer", "electricity")]} + model = object.__new__(H2IntegrateModel) + model.plant_config = plant_config + + with ( + patch.object(h2i_model_module, "pyxdsm", None), + patch.object(h2i_model_module, "create_xdsm_from_config") as mock_fn, + ): + model.create_xdsm() + + mock_fn.assert_not_called() + + +@pytest.mark.unit +def test_create_xdsm_skips_when_no_interconnections(): + plant_config = {"technology_interconnections": []} + model = object.__new__(H2IntegrateModel) + model.plant_config = plant_config + + with ( + patch.object(h2i_model_module, "pyxdsm", MagicMock()), + patch.object(h2i_model_module, "create_xdsm_from_config") as mock_fn, + ): + model.create_xdsm() + + mock_fn.assert_not_called() + + +@pytest.mark.unit +def test_create_xdsm_skips_when_interconnections_key_missing(): + plant_config = {} + model = object.__new__(H2IntegrateModel) + model.plant_config = plant_config + + with ( + patch.object(h2i_model_module, "pyxdsm", MagicMock()), + patch.object(h2i_model_module, "create_xdsm_from_config") as mock_fn, + ): + model.create_xdsm() + + mock_fn.assert_not_called() + + +@pytest.mark.unit +def test_create_xdsm_catches_file_not_found_error(capsys): + plant_config = {"technology_interconnections": [("wind", "electrolyzer", "electricity")]} + model = object.__new__(H2IntegrateModel) + model.plant_config = plant_config + + with ( + patch.object(h2i_model_module, "pyxdsm", MagicMock()), + patch.object( + h2i_model_module, + "create_xdsm_from_config", + side_effect=FileNotFoundError("latex not found"), + ), + ): + model.create_xdsm() + + captured = capsys.readouterr() + assert "Unable to create system XDSM diagram" in captured.out + assert "latex not found" in captured.out From 405607054f65e16979392fb67e55417c223052f7 Mon Sep 17 00:00:00 2001 From: Jared Thomas Date: Thu, 26 Mar 2026 15:46:53 -0600 Subject: [PATCH 02/10] update changelog and docs and adjust create_xdsm logic to reflect that it is an optional call --- CHANGELOG.md | 1 + docs/user_guide/how_to_set_up_an_analysis.md | 76 ++++++++++++++++++++ h2integrate/core/h2integrate_model.py | 31 ++++---- h2integrate/core/test/test_framework.py | 63 +++++++--------- 4 files changed, 120 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cf197f4c..41e5656e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ - Added base class (`StorageOpenLoopControlBase`) and base configuration class (`StorageOpenLoopControlBaseConfig`) for open-loop storage control strategies and updated the existing open-loop storage control strategies to inherit these [PR 619](https://github.com/NatLabRockies/H2Integrate/pull/619) - Added a generic cost model for converters [PR 622](https://github.com/NatLabRockies/H2Integrate/pull/622) - Updated the `StorageAutoSizingModel` model to be compatible with Pyomo control strategies [PR 621](https://github.com/NatLabRockies/H2Integrate/pull/621) +- Made generating an XDSM diagram from connections in a model optional. [PR 629](https://github.com/NatLabRockies/H2Integrate/pull/629) ## 0.7.1 [March 13, 2026] diff --git a/docs/user_guide/how_to_set_up_an_analysis.md b/docs/user_guide/how_to_set_up_an_analysis.md index 2995ad02d..a1ae5197f 100644 --- a/docs/user_guide/how_to_set_up_an_analysis.md +++ b/docs/user_guide/how_to_set_up_an_analysis.md @@ -121,6 +121,82 @@ The `resource_to_tech_connections` section defines how resources (like wind or s For more information on how to define and interpret technology interconnections, see the {ref}`connecting_technologies` page. ``` +## Visualizing the model structure +There are two basic methods for visualizing the model structure of your H2Integrate system model. You can generate a simplified [XDSM diagram](https://mdolab.engin.umich.edu/wiki/xdsm-overview) showing the technologies and connections specified in your config file, or you can generate an interactive [N2 diagram](https://openmdao.org/newdocs/versions/latest/features/model_visualization/n2_details/n2_details.html) of the full OpenMDAO model. The XDSM diagram is primarily useful for publications and presentations. The N2 diagram is primarily useful for debugging. Details for generating XDSM and N2 diagrams of you H2Integrate model are given below. + +### XDSM diagram (static and simplified) + +Use the built-in `create_xdsm()` method to generate a static system diagram from the +`technology_interconnections` section of your plant config. + +```{code-cell} ipython3 +from h2integrate.core.h2integrate_model import H2IntegrateModel +from pathlib import Path +import os + + +# Change to an example directory +os.chdir("../../examples/08_wind_electrolyzer/") + +# Build the model from the top-level config file +h2i_model = H2IntegrateModel("wind_plant_electrolyzer.yaml") + +# Write XDSM output to connections_xdsm.pdf +h2i_model.create_xdsm(outfile="connections_xdsm") + +# Confirm where the file was written +xdsm_pdf = Path("connections_xdsm.pdf") +``` + +This creates a PDF named `connections_xdsm.pdf` in your current working directory. + +```{code-cell} ipython3 +:tags: [remove-input] +from IPython.display import IFrame, display + +display(IFrame(src=str(xdsm_pdf), width="100%", height=500)) +``` + +*Figure: XDSM diagram generated from the technology interconnections.* + + +### N2 diagram (interactive and complete) + +Use OpenMDAO's `n2` utility to generate an interactive HTML diagram of the full model. + +```{code-cell} ipython3 +from h2integrate.core.h2integrate_model import H2IntegrateModel +from pathlib import Path +import openmdao.api as om +import os + + +# Change to an example directory +os.chdir("../../examples/08_wind_electrolyzer/") + +# Build and set up the model +h2i_model = H2IntegrateModel("wind_plant_electrolyzer.yaml") +h2i_model.setup() + +# Write interactive N2 HTML diagram +om.n2(h2i_model.prob, outfile="h2i_n2.html") + +# Confirm output file and display it inline +n2_html = Path("h2i_n2.html") +``` + +```{code-cell} ipython3 +:tags: [remove-input] +from IPython.display import IFrame, display + +display(IFrame(src=str(n2_html), width="100%", height=500)) +``` + +*Figure: OpenMDAO N2 diagram showing the full model structure and variable connections.* + +Open `h2i_n2.html` in a browser to explore model groups, components, and variable connections. + + ## Running the analysis Once you have the config files defined, you can run the analysis using a simple Python script that inputs the top-level config yaml. diff --git a/h2integrate/core/h2integrate_model.py b/h2integrate/core/h2integrate_model.py index 7cf6673aa..df5339c24 100644 --- a/h2integrate/core/h2integrate_model.py +++ b/h2integrate/core/h2integrate_model.py @@ -1444,21 +1444,28 @@ def _structured(meta_list): "implicit_outputs": _structured(implicit_meta), } - def create_xdsm(self): - """Generates an XDSM diagram for the plant configuration and saves it to a PDF file. + def create_xdsm(self, outfile="connections_xdsm"): + """Create an XDSM diagram from the plant technology interconnections. - Reads technology interconnections from the plant configuration and delegates - diagram creation to :func:`create_xdsm_from_config`. If ``pyxdsm`` is not - installed or no interconnections are defined, this method does nothing. A - :class:`FileNotFoundError` is caught and reported without raising. + This method reads ``technology_interconnections`` from ``self.plant_config`` + and delegates diagram generation to + :func:`h2integrate.core.utilities.create_xdsm_from_config`. + + Args: + outfile (str, optional): Base filename for the generated XDSM output. + The default is ``"connections_xdsm"``. Raises: - None: All exceptions are caught internally; errors are printed to stdout. + ValueError: If ``technology_interconnections`` is empty or missing from + the plant configuration. """ technology_interconnections = self.plant_config.get("technology_interconnections", []) - if (pyxdsm is not None) and (len(technology_interconnections) > 0): - try: - create_xdsm_from_config(self.plant_config) - except FileNotFoundError as e: - print(f"Unable to create system XDSM diagram. Error: {e}") + + if len(technology_interconnections) > 0: + create_xdsm_from_config(self.plant_config, output_file=outfile) + else: + raise ValueError( + "Generating an XDSM diagram requires technology interconnections, " + "but none were found." + ) diff --git a/h2integrate/core/test/test_framework.py b/h2integrate/core/test/test_framework.py index cf8e53cae..bd5a40aff 100644 --- a/h2integrate/core/test/test_framework.py +++ b/h2integrate/core/test/test_framework.py @@ -1,7 +1,7 @@ import shutil from copy import deepcopy from pathlib import Path -from unittest.mock import MagicMock, patch +from unittest.mock import patch import yaml import numpy as np @@ -481,81 +481,66 @@ def test_system_order(subtests): @pytest.mark.unit -def test_create_xdsm_calls_create_xdsm_from_config(): +def test_create_xdsm_calls_create_xdsm_from_config_default_outfile(): plant_config = {"technology_interconnections": [("wind", "electrolyzer", "electricity")]} model = object.__new__(H2IntegrateModel) model.plant_config = plant_config - with ( - patch.object(h2i_model_module, "pyxdsm", MagicMock()), - patch.object(h2i_model_module, "create_xdsm_from_config") as mock_fn, - ): + with patch.object(h2i_model_module, "create_xdsm_from_config") as mock_fn: model.create_xdsm() - mock_fn.assert_called_once_with(plant_config) + mock_fn.assert_called_once_with(plant_config, output_file="connections_xdsm") @pytest.mark.unit -def test_create_xdsm_skips_when_pyxdsm_none(): +def test_create_xdsm_calls_create_xdsm_from_config_custom_outfile(): plant_config = {"technology_interconnections": [("wind", "electrolyzer", "electricity")]} model = object.__new__(H2IntegrateModel) model.plant_config = plant_config + outfile = "my_custom_xdsm" - with ( - patch.object(h2i_model_module, "pyxdsm", None), - patch.object(h2i_model_module, "create_xdsm_from_config") as mock_fn, - ): - model.create_xdsm() + with patch.object(h2i_model_module, "create_xdsm_from_config") as mock_fn: + model.create_xdsm(outfile=outfile) - mock_fn.assert_not_called() + mock_fn.assert_called_once_with(plant_config, output_file=outfile) @pytest.mark.unit -def test_create_xdsm_skips_when_no_interconnections(): +def test_create_xdsm_raises_when_no_interconnections(): plant_config = {"technology_interconnections": []} model = object.__new__(H2IntegrateModel) model.plant_config = plant_config - with ( - patch.object(h2i_model_module, "pyxdsm", MagicMock()), - patch.object(h2i_model_module, "create_xdsm_from_config") as mock_fn, - ): - model.create_xdsm() + with patch.object(h2i_model_module, "create_xdsm_from_config") as mock_fn: + with pytest.raises(ValueError, match="requires technology interconnections"): + model.create_xdsm() mock_fn.assert_not_called() @pytest.mark.unit -def test_create_xdsm_skips_when_interconnections_key_missing(): +def test_create_xdsm_raises_when_interconnections_key_missing(): plant_config = {} model = object.__new__(H2IntegrateModel) model.plant_config = plant_config - with ( - patch.object(h2i_model_module, "pyxdsm", MagicMock()), - patch.object(h2i_model_module, "create_xdsm_from_config") as mock_fn, - ): - model.create_xdsm() + with patch.object(h2i_model_module, "create_xdsm_from_config") as mock_fn: + with pytest.raises(ValueError, match="requires technology interconnections"): + model.create_xdsm() mock_fn.assert_not_called() @pytest.mark.unit -def test_create_xdsm_catches_file_not_found_error(capsys): +def test_create_xdsm_propagates_file_not_found_error(): plant_config = {"technology_interconnections": [("wind", "electrolyzer", "electricity")]} model = object.__new__(H2IntegrateModel) model.plant_config = plant_config - with ( - patch.object(h2i_model_module, "pyxdsm", MagicMock()), - patch.object( - h2i_model_module, - "create_xdsm_from_config", - side_effect=FileNotFoundError("latex not found"), - ), + with patch.object( + h2i_model_module, + "create_xdsm_from_config", + side_effect=FileNotFoundError("latex not found"), ): - model.create_xdsm() - - captured = capsys.readouterr() - assert "Unable to create system XDSM diagram" in captured.out - assert "latex not found" in captured.out + with pytest.raises(FileNotFoundError, match="latex not found"): + model.create_xdsm() From 219d4ed72d7ea453a7d0d25bcec43958a91f1a71 Mon Sep 17 00:00:00 2001 From: Jared Thomas Date: Thu, 26 Mar 2026 17:15:10 -0600 Subject: [PATCH 03/10] update docs --- docs/user_guide/how_to_set_up_an_analysis.md | 57 ++++++++++++++------ 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/docs/user_guide/how_to_set_up_an_analysis.md b/docs/user_guide/how_to_set_up_an_analysis.md index a1ae5197f..25b95422b 100644 --- a/docs/user_guide/how_to_set_up_an_analysis.md +++ b/docs/user_guide/how_to_set_up_an_analysis.md @@ -131,7 +131,6 @@ Use the built-in `create_xdsm()` method to generate a static system diagram from ```{code-cell} ipython3 from h2integrate.core.h2integrate_model import H2IntegrateModel -from pathlib import Path import os @@ -143,18 +142,28 @@ h2i_model = H2IntegrateModel("wind_plant_electrolyzer.yaml") # Write XDSM output to connections_xdsm.pdf h2i_model.create_xdsm(outfile="connections_xdsm") - -# Confirm where the file was written -xdsm_pdf = Path("connections_xdsm.pdf") ``` This creates a PDF named `connections_xdsm.pdf` in your current working directory. ```{code-cell} ipython3 :tags: [remove-input] -from IPython.display import IFrame, display - -display(IFrame(src=str(xdsm_pdf), width="100%", height=500)) +import base64 +from pathlib import Path +from IPython.display import HTML, display + +xdsm_pdf = "connections_xdsm.pdf" + +pdf_data = base64.b64encode(Path(xdsm_pdf).read_bytes()).decode("utf-8") +display( + HTML( + f'
' + f'' + '
' + ) +) ``` *Figure: XDSM diagram generated from the technology interconnections.* @@ -166,7 +175,6 @@ Use OpenMDAO's `n2` utility to generate an interactive HTML diagram of the full ```{code-cell} ipython3 from h2integrate.core.h2integrate_model import H2IntegrateModel -from pathlib import Path import openmdao.api as om import os @@ -179,22 +187,37 @@ h2i_model = H2IntegrateModel("wind_plant_electrolyzer.yaml") h2i_model.setup() # Write interactive N2 HTML diagram -om.n2(h2i_model.prob, outfile="h2i_n2.html") - -# Confirm output file and display it inline -n2_html = Path("h2i_n2.html") +om.n2( + h2i_model.prob, + outfile="h2i_n2.html", + display_in_notebook=False, + show_browser=False, +) ``` +Open `h2i_n2.html` in a browser to explore model groups, components, and variable connections. + ```{code-cell} ipython3 :tags: [remove-input] -from IPython.display import IFrame, display - -display(IFrame(src=str(n2_html), width="100%", height=500)) +import html +from pathlib import Path +from IPython.display import HTML, display + +n2_html = "h2i_n2.html" +n2_srcdoc = html.escape(Path(n2_html).read_text(encoding="utf-8")) +display( + HTML( + f'
' + f'' + '
' + ) +) ``` -*Figure: OpenMDAO N2 diagram showing the full model structure and variable connections.* +*Figure: Interactive OpenMDAO N2 diagram showing the full model structure and variable connections.* -Open `h2i_n2.html` in a browser to explore model groups, components, and variable connections. ## Running the analysis From 189f13eb6fa089534e03dca29258ba40c9ff8bf6 Mon Sep 17 00:00:00 2001 From: Jared Thomas Date: Thu, 26 Mar 2026 17:15:15 -0600 Subject: [PATCH 04/10] update docs --- docs/user_guide/how_to_set_up_an_analysis.md | 42 ++++++++++++-------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/docs/user_guide/how_to_set_up_an_analysis.md b/docs/user_guide/how_to_set_up_an_analysis.md index 25b95422b..7ef50be8c 100644 --- a/docs/user_guide/how_to_set_up_an_analysis.md +++ b/docs/user_guide/how_to_set_up_an_analysis.md @@ -148,22 +148,32 @@ This creates a PDF named `connections_xdsm.pdf` in your current working director ```{code-cell} ipython3 :tags: [remove-input] -import base64 -from pathlib import Path -from IPython.display import HTML, display - -xdsm_pdf = "connections_xdsm.pdf" - -pdf_data = base64.b64encode(Path(xdsm_pdf).read_bytes()).decode("utf-8") -display( - HTML( - f'
' - f'' - '
' - ) -) +import matplotlib.pyplot as plt +import networkx as nx + +interconnections = h2i_model.plant_config.get("technology_interconnections", []) +G = nx.DiGraph() +edge_labels = {} +for conn in interconnections: + src, dst = conn[0], conn[1] + data = conn[2] + label = f"{data[0]} as {data[1]}" if isinstance(data, (list, tuple)) else str(data) + if len(conn) == 4: + label += f" via {conn[3]}" + G.add_edge(src, dst) + edge_labels[(src, dst)] = label.replace("_", " ") + +pos = nx.spring_layout(G, seed=0, k=2) +fig, ax = plt.subplots(figsize=(10, 5)) +nx.draw_networkx_nodes(G, pos, ax=ax, node_color="#90EE90", node_size=2500) +nx.draw_networkx_labels(G, pos, ax=ax, font_size=9) +nx.draw_networkx_edges(G, pos, ax=ax, arrows=True, arrowsize=20, + connectionstyle="arc3,rad=0.1") +nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, ax=ax, + font_size=8, bbox=dict(fc="white", ec="none")) +ax.axis("off") +plt.tight_layout() +plt.show() ``` *Figure: XDSM diagram generated from the technology interconnections.* From 359c1c362658257f197e8600bd0f88ee45d8a54d Mon Sep 17 00:00:00 2001 From: Jared Thomas Date: Fri, 27 Mar 2026 09:55:26 -0600 Subject: [PATCH 05/10] update docs for visualization --- docs/user_guide/figures/example_08_xdsm.pdf | Bin 0 -> 13297 bytes docs/user_guide/how_to_set_up_an_analysis.md | 38 +++--------------- .../run_wind_electrolyzer.py | 3 ++ 3 files changed, 8 insertions(+), 33 deletions(-) create mode 100644 docs/user_guide/figures/example_08_xdsm.pdf diff --git a/docs/user_guide/figures/example_08_xdsm.pdf b/docs/user_guide/figures/example_08_xdsm.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a02759a44df449f5e7787b86b25911915ff54c34 GIT binary patch literal 13297 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 literal 0 HcmV?d00001 diff --git a/docs/user_guide/how_to_set_up_an_analysis.md b/docs/user_guide/how_to_set_up_an_analysis.md index 7ef50be8c..ab3b2be2b 100644 --- a/docs/user_guide/how_to_set_up_an_analysis.md +++ b/docs/user_guide/how_to_set_up_an_analysis.md @@ -122,7 +122,7 @@ For more information on how to define and interpret technology interconnections, ``` ## Visualizing the model structure -There are two basic methods for visualizing the model structure of your H2Integrate system model. You can generate a simplified [XDSM diagram](https://mdolab.engin.umich.edu/wiki/xdsm-overview) showing the technologies and connections specified in your config file, or you can generate an interactive [N2 diagram](https://openmdao.org/newdocs/versions/latest/features/model_visualization/n2_details/n2_details.html) of the full OpenMDAO model. The XDSM diagram is primarily useful for publications and presentations. The N2 diagram is primarily useful for debugging. Details for generating XDSM and N2 diagrams of you H2Integrate model are given below. +There are two basic methods for visualizing the model structure of your H2Integrate system model. You can generate a simplified [XDSM diagram](https://mdolab.engin.umich.edu/wiki/xdsm-overview) showing the technologies and connections specified in your config file, or you can generate an interactive [N2 diagram](https://openmdao.org/newdocs/versions/latest/features/model_visualization/n2_details/n2_details.html) of the full OpenMDAO model. The XDSM diagram is primarily useful for publications and presentations. The N2 diagram is primarily useful for debugging. Details for generating XDSM and N2 diagrams of your H2Integrate model are given below. ### XDSM diagram (static and simplified) @@ -146,39 +146,12 @@ h2i_model.create_xdsm(outfile="connections_xdsm") This creates a PDF named `connections_xdsm.pdf` in your current working directory. -```{code-cell} ipython3 -:tags: [remove-input] -import matplotlib.pyplot as plt -import networkx as nx - -interconnections = h2i_model.plant_config.get("technology_interconnections", []) -G = nx.DiGraph() -edge_labels = {} -for conn in interconnections: - src, dst = conn[0], conn[1] - data = conn[2] - label = f"{data[0]} as {data[1]}" if isinstance(data, (list, tuple)) else str(data) - if len(conn) == 4: - label += f" via {conn[3]}" - G.add_edge(src, dst) - edge_labels[(src, dst)] = label.replace("_", " ") - -pos = nx.spring_layout(G, seed=0, k=2) -fig, ax = plt.subplots(figsize=(10, 5)) -nx.draw_networkx_nodes(G, pos, ax=ax, node_color="#90EE90", node_size=2500) -nx.draw_networkx_labels(G, pos, ax=ax, font_size=9) -nx.draw_networkx_edges(G, pos, ax=ax, arrows=True, arrowsize=20, - connectionstyle="arc3,rad=0.1") -nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, ax=ax, - font_size=8, bbox=dict(fc="white", ec="none")) -ax.axis("off") -plt.tight_layout() -plt.show() +```{figure} figures/example_08_xdsm.pdf +:width: 70% +:align: center ``` - *Figure: XDSM diagram generated from the technology interconnections.* - ### N2 diagram (interactive and complete) Use OpenMDAO's `n2` utility to generate an interactive HTML diagram of the full model. @@ -217,7 +190,7 @@ n2_html = "h2i_n2.html" n2_srcdoc = html.escape(Path(n2_html).read_text(encoding="utf-8")) display( HTML( - f'
' + f'
' f'' @@ -225,7 +198,6 @@ display( ) ) ``` - *Figure: Interactive OpenMDAO N2 diagram showing the full model structure and variable connections.* diff --git a/examples/08_wind_electrolyzer/run_wind_electrolyzer.py b/examples/08_wind_electrolyzer/run_wind_electrolyzer.py index 0c5a03835..fa354ea6f 100644 --- a/examples/08_wind_electrolyzer/run_wind_electrolyzer.py +++ b/examples/08_wind_electrolyzer/run_wind_electrolyzer.py @@ -14,6 +14,9 @@ # Create a GreenHEART model h2i_model = H2IntegrateModel(top_level_fpath) +# Generate XDSM diagram +h2i_model.create_xdsm() + # Run the model h2i_model.run() From 9f01edf7f97ac6913924df1a8fb46772a99ba7ff Mon Sep 17 00:00:00 2001 From: Jared Thomas Date: Fri, 27 Mar 2026 10:12:23 -0600 Subject: [PATCH 06/10] change xdsm code cell to not execute on build --- docs/user_guide/how_to_set_up_an_analysis.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user_guide/how_to_set_up_an_analysis.md b/docs/user_guide/how_to_set_up_an_analysis.md index ab3b2be2b..6feb63786 100644 --- a/docs/user_guide/how_to_set_up_an_analysis.md +++ b/docs/user_guide/how_to_set_up_an_analysis.md @@ -129,7 +129,7 @@ There are two basic methods for visualizing the model structure of your H2Integr Use the built-in `create_xdsm()` method to generate a static system diagram from the `technology_interconnections` section of your plant config. -```{code-cell} ipython3 +```python from h2integrate.core.h2integrate_model import H2IntegrateModel import os From ec869dd38951f6cf8ef33b4877e990910f5c6e13 Mon Sep 17 00:00:00 2001 From: Jared Thomas Date: Fri, 27 Mar 2026 10:49:26 -0600 Subject: [PATCH 07/10] switch pdf for png --- docs/user_guide/figures/example_08_xdsm.pdf | Bin 13297 -> 0 bytes docs/user_guide/figures/example_08_xdsm.png | Bin 0 -> 18280 bytes docs/user_guide/how_to_set_up_an_analysis.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 docs/user_guide/figures/example_08_xdsm.pdf create mode 100644 docs/user_guide/figures/example_08_xdsm.png diff --git a/docs/user_guide/figures/example_08_xdsm.pdf b/docs/user_guide/figures/example_08_xdsm.pdf deleted file mode 100644 index a02759a44df449f5e7787b86b25911915ff54c34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13297 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 diff --git a/docs/user_guide/figures/example_08_xdsm.png b/docs/user_guide/figures/example_08_xdsm.png new file mode 100644 index 0000000000000000000000000000000000000000..a9c6b930195d232be6681721d1292dac3180f8df GIT binary patch literal 18280 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 literal 0 HcmV?d00001 diff --git a/docs/user_guide/how_to_set_up_an_analysis.md b/docs/user_guide/how_to_set_up_an_analysis.md index 6feb63786..93772ea86 100644 --- a/docs/user_guide/how_to_set_up_an_analysis.md +++ b/docs/user_guide/how_to_set_up_an_analysis.md @@ -146,7 +146,7 @@ h2i_model.create_xdsm(outfile="connections_xdsm") This creates a PDF named `connections_xdsm.pdf` in your current working directory. -```{figure} figures/example_08_xdsm.pdf +```{figure} figures/example_08_xdsm.png :width: 70% :align: center ``` From f24957f2b6b02c15d92550eed48d1f0121e68f4d Mon Sep 17 00:00:00 2001 From: Jared Thomas Date: Fri, 27 Mar 2026 11:02:09 -0600 Subject: [PATCH 08/10] minor comments update in code example --- docs/user_guide/how_to_set_up_an_analysis.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user_guide/how_to_set_up_an_analysis.md b/docs/user_guide/how_to_set_up_an_analysis.md index 93772ea86..157b211b7 100644 --- a/docs/user_guide/how_to_set_up_an_analysis.md +++ b/docs/user_guide/how_to_set_up_an_analysis.md @@ -173,8 +173,8 @@ h2i_model.setup() om.n2( h2i_model.prob, outfile="h2i_n2.html", - display_in_notebook=False, - show_browser=False, + display_in_notebook=False, # set to True to display in-line in a notebook + show_browser=False, # set to True to open in a browser at run time ) ``` From 1ba941c587b5573b9891e988e93561f235a20102 Mon Sep 17 00:00:00 2001 From: Jared Thomas Date: Fri, 27 Mar 2026 11:54:41 -0600 Subject: [PATCH 09/10] remove xdsm call --- examples/08_wind_electrolyzer/run_wind_electrolyzer.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/08_wind_electrolyzer/run_wind_electrolyzer.py b/examples/08_wind_electrolyzer/run_wind_electrolyzer.py index fa354ea6f..0c5a03835 100644 --- a/examples/08_wind_electrolyzer/run_wind_electrolyzer.py +++ b/examples/08_wind_electrolyzer/run_wind_electrolyzer.py @@ -14,9 +14,6 @@ # Create a GreenHEART model h2i_model = H2IntegrateModel(top_level_fpath) -# Generate XDSM diagram -h2i_model.create_xdsm() - # Run the model h2i_model.run() From 7f939ae5975013b0977ec5d57aa81108b6e7ccd3 Mon Sep 17 00:00:00 2001 From: John Jasa Date: Fri, 27 Mar 2026 12:06:09 -0600 Subject: [PATCH 10/10] Updated XDSM explanation link --- docs/user_guide/how_to_set_up_an_analysis.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/user_guide/how_to_set_up_an_analysis.md b/docs/user_guide/how_to_set_up_an_analysis.md index 157b211b7..b64d4c7e3 100644 --- a/docs/user_guide/how_to_set_up_an_analysis.md +++ b/docs/user_guide/how_to_set_up_an_analysis.md @@ -122,7 +122,10 @@ For more information on how to define and interpret technology interconnections, ``` ## Visualizing the model structure -There are two basic methods for visualizing the model structure of your H2Integrate system model. You can generate a simplified [XDSM diagram](https://mdolab.engin.umich.edu/wiki/xdsm-overview) showing the technologies and connections specified in your config file, or you can generate an interactive [N2 diagram](https://openmdao.org/newdocs/versions/latest/features/model_visualization/n2_details/n2_details.html) of the full OpenMDAO model. The XDSM diagram is primarily useful for publications and presentations. The N2 diagram is primarily useful for debugging. Details for generating XDSM and N2 diagrams of your H2Integrate model are given below. +There are two basic methods for visualizing the model structure of your H2Integrate system model. +You can generate a simplified [XDSM diagram](https://openmdao.github.io/PracticalMDO/Notebooks/ModelConstruction/understanding_xdsm_diagrams.html) showing the technologies and connections specified in your config file, or you can generate an interactive [N2 diagram](https://openmdao.org/newdocs/versions/latest/features/model_visualization/n2_details/n2_details.html) of the full OpenMDAO model. +The XDSM diagram is primarily useful for publications and presentations. +The N2 diagram is primarily useful for debugging. Details for generating XDSM and N2 diagrams of your H2Integrate model are given below. ### XDSM diagram (static and simplified)