diff --git a/CHANGELOG.md b/CHANGELOG.md index 67f80cdc6..f91081115 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ - Updated `commodity_sell_price` input to `ProFastNPV` to be per year of the plant life. Also updated `BasicProFASTParameterConfig.as_dict()` so explicitly input escalation values are not overwritten to the general inflation rate [PR 799](https://github.com/NatLabRockies/H2Integrate/pull/799) - Added `calc_azimuth_angle()` to `PYSAMSolarPlantPerformanceModel` to provide default azimuth angle based on whether the site is in the northern or southern hemisphere [PR 806](https://github.com/NatLabRockies/H2Integrate/pull/806) - Corrected water rate units in pipe feedstock from galUS to galUS/h [PR 813](https://github.com/NatLabRockies/H2Integrate/pull/813) +- Added a thermal-nuclear (light-water reactor) model and a high-temperature steam electrolysis model. [PR 807](https://github.com/NatLabRockies/H2Integrate/pull/807) ## 0.8 [April 15, 2026] diff --git a/docs/_static/class_hierarchy.html b/docs/_static/class_hierarchy.html index 99ed86a84..9c6751d65 100644 --- a/docs/_static/class_hierarchy.html +++ b/docs/_static/class_hierarchy.html @@ -380,8 +380,8 @@
// parsing and collecting nodes and edges from the python - nodes = new vis.DataSet([{"borderWidth": 5.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PyomoRuleBaseClass", "label": "PyomoRuleBaseClass", "shape": "hexagon", "size": 19.45945945945946, "title": "PyomoRuleBaseClass\ncontrol/control_rules/pyomo_rule_baseclass.py\n[Control / General]", "x": 654.0, "y": 0.0}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PyomoDispatchGenericConverter", "label": "PyomoDispatchGenericConverter", "shape": "dot", "size": 18.0, "title": "PyomoDispatchGenericConverter\ncontrol/control_rules/converters/generic_converter.py\n[Converter / Other]", "x": 428.09388111524015, "y": 469.0988894808179}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PyomoRuleStorageBaseclass", "label": "PyomoRuleStorageBaseclass", "shape": "diamond", "size": 18.0, "title": "PyomoRuleStorageBaseclass\ncontrol/control_rules/storage/pyomo_storage_rule_baseclass.py\n[Storage / General]", "x": 428.09388111524004, "y": -469.09888948081795}, {"borderWidth": 5.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PyomoStorageControllerBaseClass", "label": "PyomoStorageControllerBaseClass", "shape": "diamond", "size": 20.18918918918919, "title": "PyomoStorageControllerBaseClass\ncontrol/control_strategies/pyomo_storage_controller_baseclass.py\n[Storage / General]", "x": 455.6085661088584, "y": -385.16822684557377}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DemandOpenLoopStorageController", "label": "DemandOpenLoopStorageController", "shape": "diamond", "size": 18.0, "title": "DemandOpenLoopStorageController\ncontrol/control_strategies/storage/demand_openloop_storage_controller.py\n[Storage / General]", "x": 370.0643470376622, "y": -331.15773226109025}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HeuristicLoadFollowingStorageController", "label": "HeuristicLoadFollowingStorageController", "shape": "diamond", "size": 18.0, "title": "HeuristicLoadFollowingStorageController\ncontrol/control_strategies/storage/heuristic_pyomo_controller.py\n[Storage / General]", "x": 264.590914357365, "y": -368.7926071689721}, {"borderWidth": 5.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "StorageOpenLoopControlBase", "label": "StorageOpenLoopControlBase", "shape": "diamond", "size": 20.18918918918919, "title": "StorageOpenLoopControlBase\ncontrol/control_strategies/storage/openloop_storage_control_base.py\n[Storage / General]", "x": 219.55784982221226, "y": -478.13520688340736}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "OptimizedDispatchStorageController", "label": "OptimizedDispatchStorageController", "shape": "diamond", "size": 18.0, "title": "OptimizedDispatchStorageController\ncontrol/control_strategies/storage/optimized_pyomo_controller.py\n[Storage / General]", "x": 270.16454539792574, "y": -589.4304862347785}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PeakLoadManagementHeuristicOpenLoopStorageController", "label": "PeakLoadManagementHeuristicOpenLoopStorageController", "shape": "diamond", "size": 18.0, "title": "PeakLoadManagementHeuristicOpenLoopStorageController\ncontrol/control_strategies/storage/plm_openloop_storage_controller.py\n[Storage / General]", "x": 388.2687164324305, "y": -630.4775561122241}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PeakLoadManagementOptimizedStorageController", "label": "PeakLoadManagementOptimizedStorageController", "shape": "diamond", "size": 18.0, "title": "PeakLoadManagementOptimizedStorageController\ncontrol/control_strategies/storage/plm_optimized_storage_controller.py\n[Storage / General]", "x": 501.4805766605486, "y": -572.7844347513467}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleStorageOpenLoopController", "label": "SimpleStorageOpenLoopController", "shape": "diamond", "size": 18.0, "title": "SimpleStorageOpenLoopController\ncontrol/control_strategies/storage/simple_openloop_controller.py\n[Storage / General]", "x": 538.9625776291, "y": -449.75172147563603}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CostMinimizationControl", "label": "CostMinimizationControl", "shape": "hexagon", "size": 18.0, "title": "CostMinimizationControl\ncontrol/control_strategies/system_level/cost_minimization_control.py\n[Control / General]", "x": 681.5146849936184, "y": 83.93066263524416}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DemandFollowingControl", "label": "DemandFollowingControl", "shape": "hexagon", "size": 18.0, "title": "DemandFollowingControl\ncontrol/control_strategies/system_level/demand_following_control.py\n[Control / General]", "x": 595.9704659224221, "y": 137.9411572197277}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ProfitMaximizationControl", "label": "ProfitMaximizationControl", "shape": "hexagon", "size": 18.0, "title": "ProfitMaximizationControl\ncontrol/control_strategies/system_level/profit_maximization_control.py\n[Control / General]", "x": 490.497033242125, "y": 100.30628231184586}, {"borderWidth": 5.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SystemLevelControlBase", "label": "SystemLevelControlBase", "shape": "hexagon", "size": 20.18918918918919, "title": "SystemLevelControlBase\ncontrol/control_strategies/system_level/system_level_control_base.py\n[Control / General]", "x": 445.4639687069722, "y": -9.036317402589397}, {"borderWidth": 4.0, "color": {"background": "#F5C542", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GenericConverterCostModel", "label": "GenericConverterCostModel", "shape": "dot", "size": 18.0, "title": "GenericConverterCostModel\nconverters/generic_converter_cost.py\n[Converter / Other]", "x": 455.6085661088585, "y": 553.0295521160621}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "AmmoniaSynLoopCostModel", "label": "AmmoniaSynLoopCostModel", "shape": "dot", "size": 18.0, "title": "AmmoniaSynLoopCostModel\nconverters/ammonia/ammonia_synloop_cost.py\n[Converter / Ammonia]", "x": 370.0643470376623, "y": 607.0400467005456}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "AmmoniaSynLoopPerformanceModel", "label": "AmmoniaSynLoopPerformanceModel", "shape": "dot", "size": 18.0, "title": "AmmoniaSynLoopPerformanceModel\nconverters/ammonia/ammonia_synloop_performance.py\n[Converter / Ammonia]", "x": 264.59091435736514, "y": 569.4051717926637}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleAmmoniaPerformanceModel", "label": "SimpleAmmoniaPerformanceModel", "shape": "dot", "size": 18.0, "title": "SimpleAmmoniaPerformanceModel\nconverters/ammonia/simple_ammonia_model.py\n[Converter / Ammonia]", "x": 219.55784982221238, "y": 460.06257207822847}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleAmmoniaCostModel", "label": "SimpleAmmoniaCostModel", "shape": "dot", "size": 18.0, "title": "SimpleAmmoniaCostModel\nconverters/ammonia/simple_ammonia_model.py\n[Converter / Ammonia]", "x": 270.16454539792585, "y": 348.7672927268573}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DOCPerformanceModel", "label": "DOCPerformanceModel", "shape": "dot", "size": 18.0, "title": "DOCPerformanceModel\nconverters/co2/marine/direct_ocean_capture.py\n[Converter / CO2]", "x": 388.2687164324306, "y": 307.72022284941175}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DOCCostModel", "label": "DOCCostModel", "shape": "dot", "size": 18.0, "title": "DOCCostModel\nconverters/co2/marine/direct_ocean_capture.py\n[Converter / CO2]", "x": 501.4805766605487, "y": 365.4133442102892}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "OAEPerformanceModel", "label": "OAEPerformanceModel", "shape": "dot", "size": 18.0, "title": "OAEPerformanceModel\nconverters/co2/marine/ocean_alkalinity_enhancement.py\n[Converter / CO2]", "x": 538.9625776291001, "y": 488.44605748599986}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "OAECostModel", "label": "OAECostModel", "shape": "dot", "size": 18.0, "title": "OAECostModel\nconverters/co2/marine/ocean_alkalinity_enhancement.py\n[Converter / CO2]", "x": 475.93189116793957, "y": 601.9588898891661}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "OAECostAndFinancialModel", "label": "OAECostAndFinancialModel", "shape": "dot", "size": 18.0, "title": "OAECostAndFinancialModel\nconverters/co2/marine/ocean_alkalinity_enhancement.py\n[Converter / CO2]", "x": 349.5705117805884, "y": 635.8507248662497}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GridPerformanceModel", "label": "GridPerformanceModel", "shape": "dot", "size": 18.0, "title": "GridPerformanceModel\nconverters/grid/grid.py\n[Converter / Grid]", "x": 236.61361523178945, "y": 568.2423536759715}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GridCostModel", "label": "GridCostModel", "shape": "dot", "size": 18.0, "title": "GridCostModel\nconverters/grid/grid.py\n[Converter / Grid]", "x": 206.39396475153276, "y": 439.409697663304}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HOPPComponent", "label": "HOPPComponent", "shape": "dot", "size": 18.0, "title": "HOPPComponent\nconverters/hopp/hopp_wrapper.py\n[Converter / HOPP]", "x": 278.165573095184, "y": 327.54056326717114}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "BasicElectrolyzerCostModel", "label": "BasicElectrolyzerCostModel", "shape": "dot", "size": 18.0, "title": "BasicElectrolyzerCostModel\nconverters/hydrogen/basic_cost_model.py\n[Converter / Hydrogen]", "x": 408.929515746538, "y": 301.0719911584519}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CustomElectrolyzerCostModel", "label": "CustomElectrolyzerCostModel", "shape": "dot", "size": 18.0, "title": "CustomElectrolyzerCostModel\nconverters/hydrogen/custom_electrolyzer_cost_model.py\n[Converter / Hydrogen]", "x": 519.3422437620703, "y": 376.741275969993}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ElectrolyzerPerformanceBaseClass", "label": "ElectrolyzerPerformanceBaseClass", "shape": "dot", "size": 18.72972972972973, "title": "ElectrolyzerPerformanceBaseClass\nconverters/hydrogen/electrolyzer_baseclass.py\n[Converter / Hydrogen]", "x": 541.9933368656093, "y": 509.0547616483423}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ElectrolyzerCostBaseClass", "label": "ElectrolyzerCostBaseClass", "shape": "dot", "size": 20.18918918918919, "title": "ElectrolyzerCostBaseClass\nconverters/hydrogen/electrolyzer_baseclass.py\n[Converter / Hydrogen]", "x": 462.61867180963463, "y": 617.7338834509918}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "LinearH2FuelCellPerformanceModel", "label": "LinearH2FuelCellPerformanceModel", "shape": "dot", "size": 18.0, "title": "LinearH2FuelCellPerformanceModel\nconverters/hydrogen/h2_fuel_cell.py\n[Converter / Hydrogen]", "x": 329.04975630639217, "y": 636.513453478361}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "H2FuelCellCostModel", "label": "H2FuelCellCostModel", "shape": "dot", "size": 18.0, "title": "H2FuelCellCostModel\nconverters/hydrogen/h2_fuel_cell.py\n[Converter / Hydrogen]", "x": 222.32576716621537, "y": 553.5863417347226}, {"borderWidth": 2.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ECOElectrolyzerPerformanceModel", "label": "ECOElectrolyzerPerformanceModel", "shape": "dot", "size": 18.72972972972973, "title": "ECOElectrolyzerPerformanceModel\nconverters/hydrogen/pem_electrolyzer.py\n[Converter / Hydrogen]", "x": 207.46113153897124, "y": 419.00371238109653}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SingliticoCostModel", "label": "SingliticoCostModel", "shape": "dot", "size": 18.0, "title": "SingliticoCostModel\nconverters/hydrogen/singlitico_cost_model.py\n[Converter / Hydrogen]", "x": 293.81016729091453, "y": 314.4201619012048}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SteamMethaneReformerPerformanceModel", "label": "SteamMethaneReformerPerformanceModel", "shape": "dot", "size": 18.0, "title": "SteamMethaneReformerPerformanceModel\nconverters/hydrogen/steam_methane_reformer.py\n[Converter / Hydrogen]", "x": 429.1980303433203, "y": 303.5048975398027}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SteamMethaneReformerCostModel", "label": "SteamMethaneReformerCostModel", "shape": "dot", "size": 18.0, "title": "SteamMethaneReformerCostModel\nconverters/hydrogen/steam_methane_reformer.py\n[Converter / Hydrogen]", "x": 531.4807512394786, "y": 393.1585470237545}, {"borderWidth": 1, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "WOMBATElectrolyzerModel", "label": "WOMBATElectrolyzerModel", "shape": "dot", "size": 18.0, "title": "WOMBATElectrolyzerModel\nconverters/hydrogen/wombat_model.py\n[Converter / Hydrogen]", "x": 538.4198729733245, "y": 529.1652694271473}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "AspenGeoH2SurfacePerformanceModel", "label": "AspenGeoH2SurfacePerformanceModel", "shape": "dot", "size": 18.0, "title": "AspenGeoH2SurfacePerformanceModel\nconverters/hydrogen/geologic/aspen_surface_processing.py\n[Converter / Hydrogen]", "x": 445.5710237882473, "y": 629.0047614736493}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "AspenGeoH2SurfaceCostModel", "label": "AspenGeoH2SurfaceCostModel", "shape": "dot", "size": 18.0, "title": "AspenGeoH2SurfaceCostModel\nconverters/hydrogen/geologic/aspen_surface_processing.py\n[Converter / Hydrogen]", "x": 309.11651798504033, "y": 631.947653855694}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GeoH2SubsurfacePerformanceBaseClass", "label": "GeoH2SubsurfacePerformanceBaseClass", "shape": "dot", "size": 19.45945945945946, "title": "GeoH2SubsurfacePerformanceBaseClass\nconverters/hydrogen/geologic/h2_well_subsurface_baseclass.py\n[Converter / Hydrogen]", "x": 211.84908461781183, "y": 536.0083507662598}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GeoH2SubsurfaceCostBaseClass", "label": "GeoH2SubsurfaceCostBaseClass", "shape": "dot", "size": 18.72972972972973, "title": "GeoH2SubsurfaceCostBaseClass\nconverters/hydrogen/geologic/h2_well_subsurface_baseclass.py\n[Converter / Hydrogen]", "x": 212.91655044595416, "y": 399.26617741803875}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GeoH2SurfacePerformanceBaseClass", "label": "GeoH2SurfacePerformanceBaseClass", "shape": "dot", "size": 18.72972972972973, "title": "GeoH2SurfacePerformanceBaseClass\nconverters/hydrogen/geologic/h2_well_surface_baseclass.py\n[Converter / Hydrogen]", "x": 311.84419223616084, "y": 304.68898638961775}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GeoH2SurfaceCostBaseClass", "label": "GeoH2SurfaceCostBaseClass", "shape": "dot", "size": 18.72972972972973, "title": "GeoH2SurfaceCostBaseClass\nconverters/hydrogen/geologic/h2_well_surface_baseclass.py\n[Converter / Hydrogen]", "x": 448.7220200189815, "y": 309.77552217810415}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GeoH2SubsurfaceCostModel", "label": "GeoH2SubsurfaceCostModel", "shape": "dot", "size": 18.0, "title": "GeoH2SubsurfaceCostModel\nconverters/hydrogen/geologic/mathur_modified.py\n[Converter / Hydrogen]", "x": 540.4994435124524, "y": 411.5906925910052}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGeoH2PerformanceModel", "label": "NaturalGeoH2PerformanceModel", "shape": "dot", "size": 18.0, "title": "NaturalGeoH2PerformanceModel\nconverters/hydrogen/geologic/simple_natural_geoh2.py\n[Converter / Hydrogen]", "x": 531.3901362621964, "y": 548.4583323631547}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "StimulatedGeoH2PerformanceModel", "label": "StimulatedGeoH2PerformanceModel", "shape": "dot", "size": 18.0, "title": "StimulatedGeoH2PerformanceModel\nconverters/hydrogen/geologic/templeton_serpentinization.py\n[Converter / Hydrogen]", "x": 426.78782378431725, "y": 637.3337381981482}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HumbertEwinPerformanceComponent", "label": "HumbertEwinPerformanceComponent", "shape": "dot", "size": 18.0, "title": "HumbertEwinPerformanceComponent\nconverters/iron/humbert_ewin_perf.py\n[Converter / Iron]", "x": 290.0713774101109, "y": 624.2026575560053}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HumbertStinnEwinCostComponent", "label": "HumbertStinnEwinCostComponent", "shape": "dot", "size": 18.0, "title": "HumbertStinnEwinCostComponent\nconverters/iron/humbert_stinn_ewin_cost.py\n[Converter / Iron]", "x": 204.19394571089566, "y": 516.9137611171568}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "IronReductionPlantBasePerformanceComponent", "label": "IronReductionPlantBasePerformanceComponent", "shape": "dot", "size": 19.45945945945946, "title": "IronReductionPlantBasePerformanceComponent\nconverters/iron/iron_dri_base.py\n[Converter / Iron]", "x": 221.34134343018306, "y": 380.48561129518464}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "IronReductionPlantBaseCostComponent", "label": "IronReductionPlantBaseCostComponent", "shape": "dot", "size": 19.45945945945946, "title": "IronReductionPlantBaseCostComponent\nconverters/iron/iron_dri_base.py\n[Converter / Iron]", "x": 331.21568985008844, "y": 297.6965237937115}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HydrogenIronReductionPlantCostComponent", "label": "HydrogenIronReductionPlantCostComponent", "shape": "dot", "size": 18.0, "title": "HydrogenIronReductionPlantCostComponent\nconverters/iron/iron_dri_plant.py\n[Converter / Iron]", "x": 467.2216800346311, "y": 318.8505150630724}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGasIronReductionPlantCostComponent", "label": "NaturalGasIronReductionPlantCostComponent", "shape": "dot", "size": 18.0, "title": "NaturalGasIronReductionPlantCostComponent\nconverters/iron/iron_dri_plant.py\n[Converter / Iron]", "x": 546.8371236174256, "y": 431.20832772949075}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HydrogenIronReductionPlantPerformanceComponent", "label": "HydrogenIronReductionPlantPerformanceComponent", "shape": "dot", "size": 18.0, "title": "HydrogenIronReductionPlantPerformanceComponent\nconverters/iron/iron_dri_plant.py\n[Converter / Iron]", "x": 521.6903751911968, "y": 566.6610637668477}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGasIronReductionPlantPerformanceComponent", "label": "NaturalGasIronReductionPlantPerformanceComponent", "shape": "dot", "size": 18.0, "title": "NaturalGasIronReductionPlantPerformanceComponent\nconverters/iron/iron_dri_plant.py\n[Converter / Iron]", "x": 406.952112243024, "y": 643.0222537742708}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "IronTransportCostComponent", "label": "IronTransportCostComponent", "shape": "dot", "size": 18.0, "title": "IronTransportCostComponent\nconverters/iron/iron_transport.py\n[Converter / Iron]", "x": 272.18129178907674, "y": 613.9005699916162}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MartinIronMineCostComponent", "label": "MartinIronMineCostComponent", "shape": "dot", "size": 18.0, "title": "MartinIronMineCostComponent\nconverters/iron/martin_mine_cost_model.py\n[Converter / Iron]", "x": 199.15055717864382, "y": 496.88602197643854}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MartinIronMinePerformanceComponent", "label": "MartinIronMinePerformanceComponent", "shape": "dot", "size": 18.0, "title": "MartinIronMinePerformanceComponent\nconverters/iron/martin_mine_perf_model.py\n[Converter / Iron]", "x": 232.2254768075065, "y": 362.9235822800501}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CO2HMethanolPlantPerformanceModel", "label": "CO2HMethanolPlantPerformanceModel", "shape": "dot", "size": 18.0, "title": "CO2HMethanolPlantPerformanceModel\nconverters/methanol/co2h_methanol_plant.py\n[Converter / Methanol]", "x": 351.4109262191128, "y": 293.29530750309686}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CO2HMethanolPlantCostModel", "label": "CO2HMethanolPlantCostModel", "shape": "dot", "size": 18.0, "title": "CO2HMethanolPlantCostModel\nconverters/methanol/co2h_methanol_plant.py\n[Converter / Methanol]", "x": 484.44055215455836, "y": 330.297978929092}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CO2HMethanolPlantFinanceModel", "label": "CO2HMethanolPlantFinanceModel", "shape": "dot", "size": 18.0, "title": "CO2HMethanolPlantFinanceModel\nconverters/methanol/co2h_methanol_plant.py\n[Converter / Methanol]", "x": 550.5984027605526, "y": 451.5476939728353}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MethanolPerformanceBaseClass", "label": "MethanolPerformanceBaseClass", "shape": "dot", "size": 19.45945945945946, "title": "MethanolPerformanceBaseClass\nconverters/methanol/methanol_baseclass.py\n[Converter / Methanol]", "x": 509.69716559653716, "y": 583.5219955261796}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MethanolCostBaseClass", "label": "MethanolCostBaseClass", "shape": "dot", "size": 19.45945945945946, "title": "MethanolCostBaseClass\nconverters/methanol/methanol_baseclass.py\n[Converter / Methanol]", "x": 386.4910795111691, "y": 646.1453801885751}, {"borderWidth": 5.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MethanolFinanceBaseClass", "label": "MethanolFinanceBaseClass", "shape": "dot", "size": 19.45945945945946, "title": "MethanolFinanceBaseClass\nconverters/methanol/methanol_baseclass.py\n[Converter / Methanol]", "x": 255.69275934662096, "y": 601.3783905588575}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SMRMethanolPlantPerformanceModel", "label": "SMRMethanolPlantPerformanceModel", "shape": "dot", "size": 18.0, "title": "SMRMethanolPlantPerformanceModel\nconverters/methanol/smr_methanol_plant.py\n[Converter / Methanol]", "x": 196.66404742738186, "y": 476.325072910983}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SMRMethanolPlantCostModel", "label": "SMRMethanolPlantCostModel", "shape": "dot", "size": 18.0, "title": "SMRMethanolPlantCostModel\nconverters/methanol/smr_methanol_plant.py\n[Converter / Methanol]", "x": 245.26041830184303, "y": 346.82157500140227}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SMRMethanolPlantFinanceModel", "label": "SMRMethanolPlantFinanceModel", "shape": "dot", "size": 18.0, "title": "SMRMethanolPlantFinanceModel\nconverters/methanol/smr_methanol_plant.py\n[Converter / Methanol]", "x": 372.0506131909644, "y": 291.4439725755037}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleGasProducerPerformance", "label": "SimpleGasProducerPerformance", "shape": "dot", "size": 18.0, "title": "SimpleGasProducerPerformance\nconverters/natural_gas/dummy_gas_components.py\n[Converter / Natural Gas]", "x": 500.1422507144458, "y": 343.82986093378406}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleGasConsumerPerformance", "label": "SimpleGasConsumerPerformance", "shape": "dot", "size": 18.0, "title": "SimpleGasConsumerPerformance\nconverters/natural_gas/dummy_gas_components.py\n[Converter / Natural Gas]", "x": 551.8160292273673, "y": 472.2454066683052}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleGasProducerCost", "label": "SimpleGasProducerCost", "shape": "dot", "size": 18.0, "title": "SimpleGasProducerCost\nconverters/natural_gas/dummy_gas_components.py\n[Converter / Natural Gas]", "x": 495.6839168464708, "y": 598.8099536341376}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleGasConsumerCost", "label": "SimpleGasConsumerCost", "shape": "dot", "size": 18.0, "title": "SimpleGasConsumerCost\nconverters/natural_gas/dummy_gas_components.py\n[Converter / Natural Gas]", "x": 365.7556658010815, "y": 646.7308814798549}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGasPerformanceModel", "label": "NaturalGasPerformanceModel", "shape": "dot", "size": 18.0, "title": "NaturalGasPerformanceModel\nconverters/natural_gas/natural_gas_cc_ct.py\n[Converter / Natural Gas]", "x": 240.8316118946296, "y": 586.8992069729802}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGasCostModel", "label": "NaturalGasCostModel", "shape": "dot", "size": 18.0, "title": "NaturalGasCostModel\nconverters/natural_gas/natural_gas_cc_ct.py\n[Converter / Natural Gas]", "x": 196.70889860494393, "y": 455.57195413603677}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleASUPerformanceModel", "label": "SimpleASUPerformanceModel", "shape": "dot", "size": 18.0, "title": "SimpleASUPerformanceModel\nconverters/nitrogen/simple_ASU.py\n[Converter / Nitrogen]", "x": 260.1901653677206, "y": 332.3999371200461}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleASUCostModel", "label": "SimpleASUCostModel", "shape": "dot", "size": 18.0, "title": "SimpleASUCostModel\nconverters/nitrogen/simple_ASU.py\n[Converter / Nitrogen]", "x": 392.80172635379284, "y": 292.1171568185306}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "QuinnNuclearPerformanceModel", "label": "QuinnNuclearPerformanceModel", "shape": "dot", "size": 18.0, "title": "QuinnNuclearPerformanceModel\nconverters/nuclear/nuclear_plant.py\n[Converter / Nuclear]", "x": 514.1120611197007, "y": 359.1947982547017}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "QuinnNuclearCostModel", "label": "QuinnNuclearCostModel", "shape": "dot", "size": 18.0, "title": "QuinnNuclearCostModel\nconverters/nuclear/nuclear_plant.py\n[Converter / Nuclear]", "x": 550.5168235029448, "y": 492.97505700886006}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ATBResComPVCostModel", "label": "ATBResComPVCostModel", "shape": "dot", "size": 18.0, "title": "ATBResComPVCostModel\nconverters/solar/atb_res_com_pv_cost.py\n[Converter / Solar]", "x": 479.8992121579394, "y": 612.3160092753269}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ATBUtilityPVCostModel", "label": "ATBUtilityPVCostModel", "shape": "dot", "size": 18.0, "title": "ATBUtilityPVCostModel\nconverters/solar/atb_utility_pv_cost.py\n[Converter / Solar]", "x": 345.0667047898959, "y": 644.8082942814825}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SolarPerformanceBaseClass", "label": "SolarPerformanceBaseClass", "shape": "dot", "size": 18.72972972972973, "title": "SolarPerformanceBaseClass\nconverters/solar/solar_baseclass.py\n[Converter / Solar]", "x": 227.80083824635747, "y": 570.7102438066149}, {"borderWidth": 3.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PYSAMSolarPlantPerformanceModel", "label": "PYSAMSolarPlantPerformanceModel", "shape": "dot", "size": 18.0, "title": "PYSAMSolarPlantPerformanceModel\nconverters/solar/solar_pysam.py\n[Converter / Solar]", "x": 199.25186993001995, "y": 434.94269396402495}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CMUElectricArcFurnaceCostModel", "label": "CMUElectricArcFurnaceCostModel", "shape": "dot", "size": 18.0, "title": "CMUElectricArcFurnaceCostModel\nconverters/steel/cmu_eaf_cost.py\n[Converter / Steel]", "x": 276.76776483357787, "y": 319.8555634030555}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CMUElectricArcFurnaceDRIPerformanceComponent", "label": "CMUElectricArcFurnaceDRIPerformanceComponent", "shape": "dot", "size": 18.0, "title": "CMUElectricArcFurnaceDRIPerformanceComponent\nconverters/steel/cmu_electric_arc_furnace_dri.py\n[Converter / Steel]", "x": 413.3524790181906, "y": 295.27713454003253}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CMUElectricArcFurnaceScrapOnlyPerformanceComponent", "label": "CMUElectricArcFurnaceScrapOnlyPerformanceComponent", "shape": "dot", "size": 18.0, "title": "CMUElectricArcFurnaceScrapOnlyPerformanceComponent\nconverters/steel/cmu_electric_arc_furnace_scrap.py\n[Converter / Steel]", "x": 526.159335243713, "y": 376.14527848915895}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SteelPerformanceModel", "label": "SteelPerformanceModel", "shape": "dot", "size": 18.0, "title": "SteelPerformanceModel\nconverters/steel/steel.py\n[Converter / Steel]", "x": 546.743615781497, "y": 513.4286945748072}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SteelCostAndFinancialModel", "label": "SteelCostAndFinancialModel", "shape": "dot", "size": 18.0, "title": "SteelCostAndFinancialModel\nconverters/steel/steel.py\n[Converter / Steel]", "x": 462.5917542911312, "y": 623.8559111338152}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SteelPerformanceBaseClass", "label": "SteelPerformanceBaseClass", "shape": "dot", "size": 18.72972972972973, "title": "SteelPerformanceBaseClass\nconverters/steel/steel_baseclass.py\n[Converter / Steel]", "x": 324.72859310432364, "y": 640.4260460063381}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SteelCostBaseClass", "label": "SteelCostBaseClass", "shape": "dot", "size": 18.72972972972973, "title": "SteelCostBaseClass\nconverters/steel/steel_baseclass.py\n[Converter / Steel]", "x": 216.77814592164026, "y": 553.0618685876668}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ElectricArcFurnacePlantBasePerformanceComponent", "label": "ElectricArcFurnacePlantBasePerformanceComponent", "shape": "dot", "size": 19.45945945945946, "title": "ElectricArcFurnacePlantBasePerformanceComponent\nconverters/steel/steel_eaf_base.py\n[Converter / Steel]", "x": 204.23854510804242, "y": 414.73832160687783}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ElectricArcFurnacePlantBaseCostComponent", "label": "ElectricArcFurnacePlantBaseCostComponent", "shape": "dot", "size": 19.45945945945946, "title": "ElectricArcFurnacePlantBaseCostComponent\nconverters/steel/steel_eaf_base.py\n[Converter / Steel]", "x": 294.740834296002, "y": 309.3594743780847}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HydrogenEAFPlantCostComponent", "label": "HydrogenEAFPlantCostComponent", "shape": "dot", "size": 18.0, "title": "HydrogenEAFPlantCostComponent\nconverters/steel/steel_eaf_plant.py\n[Converter / Steel]", "x": 433.40509869823285, "y": 300.86319031224053}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGasEAFPlantCostComponent", "label": "NaturalGasEAFPlantCostComponent", "shape": "dot", "size": 18.0, "title": "NaturalGasEAFPlantCostComponent\nconverters/steel/steel_eaf_plant.py\n[Converter / Steel]", "x": 536.1198784691253, "y": 394.42665374762043}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HydrogenEAFPlantPerformanceComponent", "label": "HydrogenEAFPlantPerformanceComponent", "shape": "dot", "size": 18.0, "title": "HydrogenEAFPlantPerformanceComponent\nconverters/steel/steel_eaf_plant.py\n[Converter / Steel]", "x": 540.5636645511591, "y": 533.3117528946093}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGasEAFPlantPerformanceComponent", "label": "NaturalGasEAFPlantPerformanceComponent", "shape": "dot", "size": 18.0, "title": "NaturalGasEAFPlantPerformanceComponent\nconverters/steel/steel_eaf_plant.py\n[Converter / Steel]", "x": 444.01862690077985, "y": 633.2724247412675}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ReverseOsmosisPerformanceModel", "label": "ReverseOsmosisPerformanceModel", "shape": "dot", "size": 18.0, "title": "ReverseOsmosisPerformanceModel\nconverters/water/desal/desalination.py\n[Converter / Water]", "x": 305.03269414802736, "y": 633.6581275003193}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ReverseOsmosisCostModel", "label": "ReverseOsmosisCostModel", "shape": "dot", "size": 18.0, "title": "ReverseOsmosisCostModel\nconverters/water/desal/desalination.py\n[Converter / Water]", "x": 207.91368001519578, "y": 534.2137056268189}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DesalinationPerformanceBaseClass", "label": "DesalinationPerformanceBaseClass", "shape": "dot", "size": 18.72972972972973, "title": "DesalinationPerformanceBaseClass\nconverters/water/desal/desalination_baseclass.py\n[Converter / Water]", "x": 211.58805712431138, "y": 395.2469621597975}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DesalinationCostBaseClass", "label": "DesalinationCostBaseClass", "shape": "dot", "size": 18.72972972972973, "title": "DesalinationCostBaseClass\nconverters/water/desal/desalination_baseclass.py\n[Converter / Water]", "x": 313.84715753363025, "y": 301.0546018388401}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "RunOfRiverHydroPerformanceModel", "label": "RunOfRiverHydroPerformanceModel", "shape": "dot", "size": 18.0, "title": "RunOfRiverHydroPerformanceModel\nconverters/water_power/hydro_plant_run_of_river.py\n[Converter / Water Power]", "x": 452.67476445714954, "y": 308.7874754191507}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "RunOfRiverHydroCostModel", "label": "RunOfRiverHydroCostModel", "shape": "dot", "size": 18.0, "title": "RunOfRiverHydroCostModel\nconverters/water_power/hydro_plant_run_of_river.py\n[Converter / Water Power]", "x": 543.8580906910796, "y": 413.7741089596238}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PySAMMarineCostModel", "label": "PySAMMarineCostModel", "shape": "dot", "size": 18.0, "title": "PySAMMarineCostModel\nconverters/water_power/pysam_marine_cost.py\n[Converter / Water Power]", "x": 532.0718732102009, "y": 552.342805603834}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PySAMTidalPerformanceModel", "label": "PySAMTidalPerformanceModel", "shape": "dot", "size": 18.0, "title": "PySAMTidalPerformanceModel\nconverters/water_power/tidal_pysam.py\n[Converter / Water Power]", "x": 424.4472139785939, "y": 640.4373943201894}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ATBWindPlantCostModel", "label": "ATBWindPlantCostModel", "shape": "dot", "size": 18.0, "title": "ATBWindPlantCostModel\nconverters/wind/atb_wind_cost.py\n[Converter / Wind]", "x": 286.2569295976094, "y": 624.6065418587294}, {"borderWidth": 3.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "FlorisWindPlantPerformanceModel", "label": "FlorisWindPlantPerformanceModel", "shape": "dot", "size": 18.0, "title": "FlorisWindPlantPerformanceModel\nconverters/wind/floris.py\n[Converter / Wind]", "x": 201.3280452712436, "y": 514.4356470449293}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "WindArdPerformanceCompatibilityComponent", "label": "WindArdPerformanceCompatibilityComponent", "shape": "dot", "size": 18.0, "title": "WindArdPerformanceCompatibilityComponent\nconverters/wind/wind_plant_ard.py\n[Converter / Wind]", "x": 221.1912824391352, "y": 376.74290673623443}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "WindArdCostCompatibilityComponent", "label": "WindArdCostCompatibilityComponent", "shape": "dot", "size": 18.0, "title": "WindArdCostCompatibilityComponent\nconverters/wind/wind_plant_ard.py\n[Converter / Wind]", "x": 333.8144210804685, "y": 295.05389888426953}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "WindPerformanceBaseClass", "label": "WindPerformanceBaseClass", "shape": "dot", "size": 19.45945945945946, "title": "WindPerformanceBaseClass\nconverters/wind/wind_plant_baseclass.py\n[Converter / Wind]", "x": 470.89095415961566, "y": 318.9337463910879}, {"borderWidth": 3.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PYSAMWindPlantPerformanceModel", "label": "PYSAMWindPlantPerformanceModel", "shape": "dot", "size": 18.0, "title": "PYSAMWindPlantPerformanceModel\nconverters/wind/wind_pysam.py\n[Converter / Wind]", "x": 549.2687648311249, "y": 433.9130181048081}, {"borderWidth": 5.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PerformanceModelBaseClass", "label": "PerformanceModelBaseClass", "shape": "ellipse", "size": 40.62162162162162, "title": "PerformanceModelBaseClass\ncore/model_baseclasses.py\n[Core / General]", "x": -79.5125603737886, "y": 584.9567473090942}, {"borderWidth": 5.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CostModelBaseClass", "label": "CostModelBaseClass", "shape": "ellipse", "size": 45.0, "title": "CostModelBaseClass\ncore/model_baseclasses.py\n[Core / General]", "x": -51.99787538017026, "y": 668.8874099443384}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ResizeablePerformanceModelBaseClass", "label": "ResizeablePerformanceModelBaseClass", "shape": "ellipse", "size": 19.45945945945946, "title": "ResizeablePerformanceModelBaseClass\ncore/model_baseclasses.py\n[Core / General]", "x": -137.54209445136647, "y": 722.897904528822}, {"borderWidth": 5.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CacheBaseClass", "label": "CacheBaseClass", "shape": "ellipse", "size": 19.45945945945946, "title": "CacheBaseClass\ncore/model_baseclasses.py\n[Core / General]", "x": -243.0155271316636, "y": 685.2630296209401}, {"borderWidth": 5.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SiteBaseComponent", "label": "SiteBaseComponent", "shape": "ellipse", "size": 18.72972972972973, "title": "SiteBaseComponent\ncore/sites.py\n[Core / General]", "x": -288.0485916668164, "y": 575.9204299065049}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SiteLocationComponent", "label": "SiteLocationComponent", "shape": "ellipse", "size": 18.0, "title": "SiteLocationComponent\ncore/sites.py\n[Core / General]", "x": -237.4418960911029, "y": 464.62515055513364}, {"borderWidth": 4.0, "color": {"background": "#F5C542", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DemandComponentBase", "label": "DemandComponentBase", "shape": "dot", "size": 19.45945945945946, "title": "DemandComponentBase\ndemand/demand_base.py\n[Other / Other]", "x": -486.58132074145146, "y": -260.3302434705348}, {"borderWidth": 3.0, "color": {"background": "#F5C542", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "FlexibleDemandComponent", "label": "FlexibleDemandComponent", "shape": "dot", "size": 18.0, "title": "FlexibleDemandComponent\ndemand/flexible_demand.py\n[Other / Other]", "x": -459.0666357478331, "y": -176.39958083529064}, {"borderWidth": 3.0, "color": {"background": "#F5C542", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GenericDemandComponent", "label": "GenericDemandComponent", "shape": "dot", "size": 18.0, "title": "GenericDemandComponent\ndemand/generic_demand.py\n[Other / Other]", "x": -544.6108548190293, "y": -122.38908625080711}, {"borderWidth": 3.0, "color": {"background": "#F5C542", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "EIANaturalGasFeedstockCostModel", "label": "EIANaturalGasFeedstockCostModel", "shape": "dot", "size": 18.0, "title": "EIANaturalGasFeedstockCostModel\nfeedstocks/eia_ng_price.py\n[Other / Other]", "x": -650.0842874993265, "y": -160.02396115868896}, {"borderWidth": 4.0, "color": {"background": "#F5C542", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "FeedstockCostModel", "label": "FeedstockCostModel", "shape": "dot", "size": 18.72972972972973, "title": "FeedstockCostModel\nfeedstocks/feedstocks.py\n[Other / Other]", "x": -695.1173520344793, "y": -269.36656087312423}, {"borderWidth": 5.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ProFastBase", "label": "ProFastBase", "shape": "star", "size": 19.45945945945946, "title": "ProFastBase\nfinances/profast_base.py\n[Finance / General]", "x": -486.58132074145146, "y": 260.3302434705349}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ProFastLCO", "label": "ProFastLCO", "shape": "star", "size": 18.0, "title": "ProFastLCO\nfinances/profast_lco.py\n[Finance / General]", "x": -459.0666357478331, "y": 344.2609061057791}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ProFastNPV", "label": "ProFastNPV", "shape": "star", "size": 18.0, "title": "ProFastNPV\nfinances/profast_npv.py\n[Finance / General]", "x": -544.6108548190293, "y": 398.2714006902626}, {"borderWidth": 5.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ResourceBaseAPIModel", "label": "ResourceBaseAPIModel", "shape": "triangle", "size": 19.45945945945946, "title": "ResourceBaseAPIModel\nresource/resource_base.py\n[Resource / General]", "x": -79.51256037378874, "y": -584.9567473090942}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NLRDeveloperAPISolarResourceBase", "label": "NLRDeveloperAPISolarResourceBase", "shape": "triangle", "size": 24.56756756756757, "title": "NLRDeveloperAPISolarResourceBase\nresource/solar/nlr_developer_api_base.py\n[Resource / General]", "x": -51.9978753801704, "y": -501.02608467385005}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GOESAggregatedSolarAPI", "label": "GOESAggregatedSolarAPI", "shape": "triangle", "size": 18.0, "title": "GOESAggregatedSolarAPI\nresource/solar/nlr_developer_goes_api_models.py\n[Resource / General]", "x": -137.5420944513666, "y": -447.0155900893665}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GOESConusSolarAPI", "label": "GOESConusSolarAPI", "shape": "triangle", "size": 18.0, "title": "GOESConusSolarAPI\nresource/solar/nlr_developer_goes_api_models.py\n[Resource / General]", "x": -243.01552713166376, "y": -484.6504649972484}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GOESFullDiscSolarAPI", "label": "GOESFullDiscSolarAPI", "shape": "triangle", "size": 18.0, "title": "GOESFullDiscSolarAPI\nresource/solar/nlr_developer_goes_api_models.py\n[Resource / General]", "x": -288.0485916668165, "y": -593.9930647116836}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GOESTMYSolarAPI", "label": "GOESTMYSolarAPI", "shape": "triangle", "size": 18.0, "title": "GOESTMYSolarAPI\nresource/solar/nlr_developer_goes_api_models.py\n[Resource / General]", "x": -237.44189609110305, "y": -705.2883440630549}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "Himawari7SolarAPI", "label": "Himawari7SolarAPI", "shape": "triangle", "size": 18.0, "title": "Himawari7SolarAPI\nresource/solar/nlr_developer_himawari_api_models.py\n[Resource / General]", "x": -119.33772505659829, "y": -746.3354139405003}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "Himawari8SolarAPI", "label": "Himawari8SolarAPI", "shape": "triangle", "size": 18.0, "title": "Himawari8SolarAPI\nresource/solar/nlr_developer_himawari_api_models.py\n[Resource / General]", "x": -6.125864828480175, "y": -688.6422925796229}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HimawariTMYSolarAPI", "label": "HimawariTMYSolarAPI", "shape": "triangle", "size": 18.0, "title": "HimawariTMYSolarAPI\nresource/solar/nlr_developer_himawari_api_models.py\n[Resource / General]", "x": 31.356136140071186, "y": -565.6095793039123}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MeteosatPrimeMeridianSolarAPI", "label": "MeteosatPrimeMeridianSolarAPI", "shape": "triangle", "size": 18.0, "title": "MeteosatPrimeMeridianSolarAPI\nresource/solar/nlr_developer_meteosat_prime_meridian_models.py\n[Resource / General]", "x": -31.67455032108934, "y": -452.096746900746}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MeteosatPrimeMeridianTMYSolarAPI", "label": "MeteosatPrimeMeridianTMYSolarAPI", "shape": "triangle", "size": 18.0, "title": "MeteosatPrimeMeridianTMYSolarAPI\nresource/solar/nlr_developer_meteosat_prime_meridian_models.py\n[Resource / General]", "x": -158.0359297084405, "y": -418.2049119236624}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "OpenMeteoHistoricalSolarResource", "label": "OpenMeteoHistoricalSolarResource", "shape": "triangle", "size": 18.0, "title": "OpenMeteoHistoricalSolarResource\nresource/solar/openmeteo_solar.py\n[Resource / General]", "x": -270.99282625723947, "y": -485.8132831139406}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SolarResourceBaseAPIModel", "label": "SolarResourceBaseAPIModel", "shape": "triangle", "size": 19.45945945945946, "title": "SolarResourceBaseAPIModel\nresource/solar/solar_resource_base.py\n[Resource / General]", "x": -301.2124767374961, "y": -614.6459391266081}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "WTKNLRDeveloperAPIWindResource", "label": "WTKNLRDeveloperAPIWindResource", "shape": "triangle", "size": 18.0, "title": "WTKNLRDeveloperAPIWindResource\nresource/wind/nlr_developer_wtk_api.py\n[Resource / General]", "x": -229.44086839384488, "y": -726.515073522741}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "OpenMeteoHistoricalWindResource", "label": "OpenMeteoHistoricalWindResource", "shape": "triangle", "size": 18.0, "title": "OpenMeteoHistoricalWindResource\nresource/wind/openmeteo_wind.py\n[Resource / General]", "x": -98.67692574249088, "y": -752.9836456314601}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "WindResourceBaseAPIModel", "label": "WindResourceBaseAPIModel", "shape": "triangle", "size": 19.45945945945946, "title": "WindResourceBaseAPIModel\nresource/wind/wind_resource_base.py\n[Resource / General]", "x": 11.735802273041458, "y": -677.3143608199191}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GenericStorageCostModel", "label": "GenericStorageCostModel", "shape": "diamond", "size": 18.0, "title": "GenericStorageCostModel\nstorage/generic_storage_cost.py\n[Storage / General]", "x": 475.93189116793945, "y": -336.23888907246976}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "StorageAutoSizingModel", "label": "StorageAutoSizingModel", "shape": "diamond", "size": 18.0, "title": "StorageAutoSizingModel\nstorage/simple_storage_auto_sizing.py\n[Storage / General]", "x": 349.5705117805883, "y": -302.34705409538617}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "StoragePerformanceBase", "label": "StoragePerformanceBase", "shape": "diamond", "size": 20.18918918918919, "title": "StoragePerformanceBase\nstorage/storage_baseclass.py\n[Storage / General]", "x": 236.61361523178934, "y": -369.9554252856643}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "StoragePerformanceModel", "label": "StoragePerformanceModel", "shape": "diamond", "size": 18.0, "title": "StoragePerformanceModel\nstorage/storage_performance_model.py\n[Storage / General]", "x": 206.39396475153265, "y": -498.78808129833186}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ATBBatteryCostModel", "label": "ATBBatteryCostModel", "shape": "diamond", "size": 18.0, "title": "ATBBatteryCostModel\nstorage/battery/atb_battery_cost.py\n[Storage / General]", "x": 278.1655730951839, "y": -610.6572156944648}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PySAMBatteryPerformanceModel", "label": "PySAMBatteryPerformanceModel", "shape": "diamond", "size": 18.0, "title": "PySAMBatteryPerformanceModel\nstorage/battery/pysam_battery.py\n[Storage / General]", "x": 408.9295157465379, "y": -637.1257878031839}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HydrogenStorageBaseCostModel", "label": "HydrogenStorageBaseCostModel", "shape": "diamond", "size": 20.91891891891892, "title": "HydrogenStorageBaseCostModel\nstorage/hydrogen/h2_storage_cost.py\n[Storage / General]", "x": 519.3422437620702, "y": -561.4565029916428}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "LinedRockCavernStorageCostModel", "label": "LinedRockCavernStorageCostModel", "shape": "diamond", "size": 18.0, "title": "LinedRockCavernStorageCostModel\nstorage/hydrogen/h2_storage_cost.py\n[Storage / General]", "x": 541.9933368656092, "y": -429.1430173132935}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SaltCavernStorageCostModel", "label": "SaltCavernStorageCostModel", "shape": "diamond", "size": 18.0, "title": "SaltCavernStorageCostModel\nstorage/hydrogen/h2_storage_cost.py\n[Storage / General]", "x": 462.6186718096345, "y": -320.463895510644}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PipeStorageCostModel", "label": "PipeStorageCostModel", "shape": "diamond", "size": 18.0, "title": "PipeStorageCostModel\nstorage/hydrogen/h2_storage_cost.py\n[Storage / General]", "x": 329.04975630639206, "y": -301.68432548327485}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CompressedGasStorageCostModel", "label": "CompressedGasStorageCostModel", "shape": "diamond", "size": 18.0, "title": "CompressedGasStorageCostModel\nstorage/hydrogen/h2_storage_cost.py\n[Storage / General]", "x": 222.32576716621526, "y": -384.6114372269132}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MCHTOLStorageCostModel", "label": "MCHTOLStorageCostModel", "shape": "diamond", "size": 18.0, "title": "MCHTOLStorageCostModel\nstorage/hydrogen/mch_storage.py\n[Storage / General]", "x": 207.46113153897113, "y": -519.1940665805394}]); - edges = new vis.DataSet([{"arrows": "to", "from": "PyomoRuleBaseClass", "to": "PyomoDispatchGenericConverter"}, {"arrows": "to", "from": "PyomoRuleBaseClass", "to": "PyomoRuleStorageBaseclass"}, {"arrows": "to", "from": "PyomoStorageControllerBaseClass", "to": "HeuristicLoadFollowingStorageController"}, {"arrows": "to", "from": "PyomoStorageControllerBaseClass", "to": "OptimizedDispatchStorageController"}, {"arrows": "to", "from": "PyomoStorageControllerBaseClass", "to": "PeakLoadManagementOptimizedStorageController"}, {"arrows": "to", "from": "StorageOpenLoopControlBase", "to": "DemandOpenLoopStorageController"}, {"arrows": "to", "from": "StorageOpenLoopControlBase", "to": "PeakLoadManagementHeuristicOpenLoopStorageController"}, {"arrows": "to", "from": "StorageOpenLoopControlBase", "to": "SimpleStorageOpenLoopController"}, {"arrows": "to", "from": "SystemLevelControlBase", "to": "CostMinimizationControl"}, {"arrows": "to", "from": "SystemLevelControlBase", "to": "DemandFollowingControl"}, {"arrows": "to", "from": "SystemLevelControlBase", "to": "ProfitMaximizationControl"}, {"arrows": "to", "from": "ElectrolyzerPerformanceBaseClass", "to": "ECOElectrolyzerPerformanceModel"}, {"arrows": "to", "from": "ElectrolyzerCostBaseClass", "to": "BasicElectrolyzerCostModel"}, {"arrows": "to", "from": "ElectrolyzerCostBaseClass", "to": "CustomElectrolyzerCostModel"}, {"arrows": "to", "from": "ElectrolyzerCostBaseClass", "to": "SingliticoCostModel"}, {"arrows": "to", "from": "ECOElectrolyzerPerformanceModel", "to": "WOMBATElectrolyzerModel"}, {"arrows": "to", "from": "GeoH2SubsurfacePerformanceBaseClass", "to": "NaturalGeoH2PerformanceModel"}, {"arrows": "to", "from": "GeoH2SubsurfacePerformanceBaseClass", "to": "StimulatedGeoH2PerformanceModel"}, {"arrows": "to", "from": "GeoH2SubsurfaceCostBaseClass", "to": "GeoH2SubsurfaceCostModel"}, {"arrows": "to", "from": "GeoH2SurfacePerformanceBaseClass", "to": "AspenGeoH2SurfacePerformanceModel"}, {"arrows": "to", "from": "GeoH2SurfaceCostBaseClass", "to": "AspenGeoH2SurfaceCostModel"}, {"arrows": "to", "from": "IronReductionPlantBasePerformanceComponent", "to": "HydrogenIronReductionPlantPerformanceComponent"}, {"arrows": "to", "from": "IronReductionPlantBasePerformanceComponent", "to": "NaturalGasIronReductionPlantPerformanceComponent"}, {"arrows": "to", "from": "IronReductionPlantBaseCostComponent", "to": "HydrogenIronReductionPlantCostComponent"}, {"arrows": "to", "from": "IronReductionPlantBaseCostComponent", "to": "NaturalGasIronReductionPlantCostComponent"}, {"arrows": "to", "from": "MethanolPerformanceBaseClass", "to": "CO2HMethanolPlantPerformanceModel"}, {"arrows": "to", "from": "MethanolPerformanceBaseClass", "to": "SMRMethanolPlantPerformanceModel"}, {"arrows": "to", "from": "MethanolCostBaseClass", "to": "CO2HMethanolPlantCostModel"}, {"arrows": "to", "from": "MethanolCostBaseClass", "to": "SMRMethanolPlantCostModel"}, {"arrows": "to", "from": "MethanolFinanceBaseClass", "to": "CO2HMethanolPlantFinanceModel"}, {"arrows": "to", "from": "MethanolFinanceBaseClass", "to": "SMRMethanolPlantFinanceModel"}, {"arrows": "to", "from": "SolarPerformanceBaseClass", "to": "PYSAMSolarPlantPerformanceModel"}, {"arrows": "to", "from": "SteelPerformanceBaseClass", "to": "SteelPerformanceModel"}, {"arrows": "to", "from": "SteelCostBaseClass", "to": "SteelCostAndFinancialModel"}, {"arrows": "to", "from": "ElectricArcFurnacePlantBasePerformanceComponent", "to": "HydrogenEAFPlantPerformanceComponent"}, {"arrows": "to", "from": "ElectricArcFurnacePlantBasePerformanceComponent", "to": "NaturalGasEAFPlantPerformanceComponent"}, {"arrows": "to", "from": "ElectricArcFurnacePlantBaseCostComponent", "to": "HydrogenEAFPlantCostComponent"}, {"arrows": "to", "from": "ElectricArcFurnacePlantBaseCostComponent", "to": "NaturalGasEAFPlantCostComponent"}, {"arrows": "to", "from": "DesalinationPerformanceBaseClass", "to": "ReverseOsmosisPerformanceModel"}, {"arrows": "to", "from": "DesalinationCostBaseClass", "to": "ReverseOsmosisCostModel"}, {"arrows": "to", "from": "WindPerformanceBaseClass", "to": "FlorisWindPlantPerformanceModel"}, {"arrows": "to", "from": "WindPerformanceBaseClass", "to": "PYSAMWindPlantPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SimpleAmmoniaPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "DOCPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "OAEPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "GridPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "HOPPComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "LinearH2FuelCellPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SteamMethaneReformerPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "GeoH2SubsurfacePerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "GeoH2SurfacePerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "HumbertEwinPerformanceComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "IronReductionPlantBasePerformanceComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "MartinIronMinePerformanceComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "MethanolPerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SimpleGasProducerPerformance"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SimpleGasConsumerPerformance"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "NaturalGasPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SimpleASUPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "QuinnNuclearPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SolarPerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "CMUElectricArcFurnaceDRIPerformanceComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "CMUElectricArcFurnaceScrapOnlyPerformanceComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SteelPerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "ElectricArcFurnacePlantBasePerformanceComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "DesalinationPerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "RunOfRiverHydroPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "PySAMTidalPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "WindArdPerformanceCompatibilityComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "WindPerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "ResizeablePerformanceModelBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "DemandComponentBase"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "StoragePerformanceBase"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "GenericConverterCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "AmmoniaSynLoopCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SimpleAmmoniaCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "DOCCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "OAECostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "OAECostAndFinancialModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "GridCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "ElectrolyzerCostBaseClass"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "H2FuelCellCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SteamMethaneReformerCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "GeoH2SubsurfaceCostBaseClass"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "GeoH2SurfaceCostBaseClass"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "HumbertStinnEwinCostComponent"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "IronReductionPlantBaseCostComponent"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "IronTransportCostComponent"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "MartinIronMineCostComponent"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "MethanolCostBaseClass"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SimpleGasProducerCost"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SimpleGasConsumerCost"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "NaturalGasCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SimpleASUCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "QuinnNuclearCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "ATBResComPVCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "ATBUtilityPVCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "CMUElectricArcFurnaceCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SteelCostBaseClass"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "ElectricArcFurnacePlantBaseCostComponent"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "DesalinationCostBaseClass"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "RunOfRiverHydroCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "PySAMMarineCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "ATBWindPlantCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "WindArdCostCompatibilityComponent"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "FeedstockCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "GenericStorageCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "ATBBatteryCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "HydrogenStorageBaseCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "MCHTOLStorageCostModel"}, {"arrows": "to", "from": "ResizeablePerformanceModelBaseClass", "to": "AmmoniaSynLoopPerformanceModel"}, {"arrows": "to", "from": "ResizeablePerformanceModelBaseClass", "to": "ElectrolyzerPerformanceBaseClass"}, {"arrows": "to", "from": "CacheBaseClass", "to": "HOPPComponent"}, {"arrows": "to", "from": "CacheBaseClass", "to": "FlorisWindPlantPerformanceModel"}, {"arrows": "to", "from": "SiteBaseComponent", "to": "SiteLocationComponent"}, {"arrows": "to", "from": "DemandComponentBase", "to": "FlexibleDemandComponent"}, {"arrows": "to", "from": "DemandComponentBase", "to": "GenericDemandComponent"}, {"arrows": "to", "from": "FeedstockCostModel", "to": "EIANaturalGasFeedstockCostModel"}, {"arrows": "to", "from": "ProFastBase", "to": "ProFastLCO"}, {"arrows": "to", "from": "ProFastBase", "to": "ProFastNPV"}, {"arrows": "to", "from": "ResourceBaseAPIModel", "to": "SolarResourceBaseAPIModel"}, {"arrows": "to", "from": "ResourceBaseAPIModel", "to": "WindResourceBaseAPIModel"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "GOESAggregatedSolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "GOESConusSolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "GOESFullDiscSolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "GOESTMYSolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "Himawari7SolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "Himawari8SolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "HimawariTMYSolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "MeteosatPrimeMeridianSolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "MeteosatPrimeMeridianTMYSolarAPI"}, {"arrows": "to", "from": "SolarResourceBaseAPIModel", "to": "NLRDeveloperAPISolarResourceBase"}, {"arrows": "to", "from": "SolarResourceBaseAPIModel", "to": "OpenMeteoHistoricalSolarResource"}, {"arrows": "to", "from": "WindResourceBaseAPIModel", "to": "WTKNLRDeveloperAPIWindResource"}, {"arrows": "to", "from": "WindResourceBaseAPIModel", "to": "OpenMeteoHistoricalWindResource"}, {"arrows": "to", "from": "StoragePerformanceBase", "to": "StorageAutoSizingModel"}, {"arrows": "to", "from": "StoragePerformanceBase", "to": "StoragePerformanceModel"}, {"arrows": "to", "from": "StoragePerformanceBase", "to": "PySAMBatteryPerformanceModel"}, {"arrows": "to", "from": "HydrogenStorageBaseCostModel", "to": "LinedRockCavernStorageCostModel"}, {"arrows": "to", "from": "HydrogenStorageBaseCostModel", "to": "SaltCavernStorageCostModel"}, {"arrows": "to", "from": "HydrogenStorageBaseCostModel", "to": "PipeStorageCostModel"}, {"arrows": "to", "from": "HydrogenStorageBaseCostModel", "to": "CompressedGasStorageCostModel"}]); + nodes = new vis.DataSet([{"borderWidth": 5.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SiteBaseComponent", "label": "SiteBaseComponent", "shape": "ellipse", "size": 18.710526315789473, "title": "SiteBaseComponent\ncore/sites.py\n[Core / General]", "x": -79.5125603737886, "y": 584.9567473090942}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SiteLocationComponent", "label": "SiteLocationComponent", "shape": "ellipse", "size": 18.0, "title": "SiteLocationComponent\ncore/sites.py\n[Core / General]", "x": -51.99787538017026, "y": 668.8874099443384}, {"borderWidth": 5.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PerformanceModelBaseClass", "label": "PerformanceModelBaseClass", "shape": "ellipse", "size": 40.73684210526316, "title": "PerformanceModelBaseClass\ncore/model_baseclasses.py\n[Core / General]", "x": -137.54209445136647, "y": 722.897904528822}, {"borderWidth": 5.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CostModelBaseClass", "label": "CostModelBaseClass", "shape": "ellipse", "size": 45.0, "title": "CostModelBaseClass\ncore/model_baseclasses.py\n[Core / General]", "x": -243.0155271316636, "y": 685.2630296209401}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ResizeablePerformanceModelBaseClass", "label": "ResizeablePerformanceModelBaseClass", "shape": "ellipse", "size": 19.42105263157895, "title": "ResizeablePerformanceModelBaseClass\ncore/model_baseclasses.py\n[Core / General]", "x": -288.0485916668164, "y": 575.9204299065049}, {"borderWidth": 5.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CacheBaseClass", "label": "CacheBaseClass", "shape": "ellipse", "size": 19.42105263157895, "title": "CacheBaseClass\ncore/model_baseclasses.py\n[Core / General]", "x": -237.4418960911029, "y": 464.62515055513364}, {"borderWidth": 4.0, "color": {"background": "#F5C542", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GenericConverterCostModel", "label": "GenericConverterCostModel", "shape": "dot", "size": 18.0, "title": "GenericConverterCostModel\nconverters/generic_converter_cost.py\n[Converter / Other]", "x": 428.09388111524015, "y": 469.0988894808179}, {"borderWidth": 3.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PYSAMSolarPlantPerformanceModel", "label": "PYSAMSolarPlantPerformanceModel", "shape": "dot", "size": 18.0, "title": "PYSAMSolarPlantPerformanceModel\nconverters/solar/solar_pysam.py\n[Converter / Solar]", "x": 455.6085661088585, "y": 553.0295521160621}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ATBUtilityPVCostModel", "label": "ATBUtilityPVCostModel", "shape": "dot", "size": 18.0, "title": "ATBUtilityPVCostModel\nconverters/solar/atb_utility_pv_cost.py\n[Converter / Solar]", "x": 370.0643470376623, "y": 607.0400467005456}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ATBResComPVCostModel", "label": "ATBResComPVCostModel", "shape": "dot", "size": 18.0, "title": "ATBResComPVCostModel\nconverters/solar/atb_res_com_pv_cost.py\n[Converter / Solar]", "x": 264.59091435736514, "y": 569.4051717926637}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SolarPerformanceBaseClass", "label": "SolarPerformanceBaseClass", "shape": "dot", "size": 18.710526315789473, "title": "SolarPerformanceBaseClass\nconverters/solar/solar_baseclass.py\n[Converter / Solar]", "x": 219.55784982221238, "y": 460.06257207822847}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ElectrolyzerPerformanceBaseClass", "label": "ElectrolyzerPerformanceBaseClass", "shape": "dot", "size": 19.42105263157895, "title": "ElectrolyzerPerformanceBaseClass\nconverters/hydrogen/electrolyzer_baseclass.py\n[Converter / Hydrogen]", "x": 270.16454539792585, "y": 348.7672927268573}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ElectrolyzerCostBaseClass", "label": "ElectrolyzerCostBaseClass", "shape": "dot", "size": 20.842105263157894, "title": "ElectrolyzerCostBaseClass\nconverters/hydrogen/electrolyzer_baseclass.py\n[Converter / Hydrogen]", "x": 388.2687164324306, "y": 307.72022284941175}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SingliticoCostModel", "label": "SingliticoCostModel", "shape": "dot", "size": 18.0, "title": "SingliticoCostModel\nconverters/hydrogen/singlitico_cost_model.py\n[Converter / Hydrogen]", "x": 501.4805766605487, "y": 365.4133442102892}, {"borderWidth": 1, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "WOMBATElectrolyzerModel", "label": "WOMBATElectrolyzerModel", "shape": "dot", "size": 18.0, "title": "WOMBATElectrolyzerModel\nconverters/hydrogen/wombat_model.py\n[Converter / Hydrogen]", "x": 538.9625776291001, "y": 488.44605748599986}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "LinearH2FuelCellPerformanceModel", "label": "LinearH2FuelCellPerformanceModel", "shape": "dot", "size": 18.0, "title": "LinearH2FuelCellPerformanceModel\nconverters/hydrogen/h2_fuel_cell.py\n[Converter / Hydrogen]", "x": 475.93189116793957, "y": 601.9588898891661}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "H2FuelCellCostModel", "label": "H2FuelCellCostModel", "shape": "dot", "size": 18.0, "title": "H2FuelCellCostModel\nconverters/hydrogen/h2_fuel_cell.py\n[Converter / Hydrogen]", "x": 349.5705117805884, "y": 635.8507248662497}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SteamMethaneReformerPerformanceModel", "label": "SteamMethaneReformerPerformanceModel", "shape": "dot", "size": 18.0, "title": "SteamMethaneReformerPerformanceModel\nconverters/hydrogen/steam_methane_reformer.py\n[Converter / Hydrogen]", "x": 236.61361523178945, "y": 568.2423536759715}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SteamMethaneReformerCostModel", "label": "SteamMethaneReformerCostModel", "shape": "dot", "size": 18.0, "title": "SteamMethaneReformerCostModel\nconverters/hydrogen/steam_methane_reformer.py\n[Converter / Hydrogen]", "x": 206.39396475153276, "y": 439.409697663304}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "BasicElectrolyzerCostModel", "label": "BasicElectrolyzerCostModel", "shape": "dot", "size": 18.0, "title": "BasicElectrolyzerCostModel\nconverters/hydrogen/basic_cost_model.py\n[Converter / Hydrogen]", "x": 278.165573095184, "y": 327.54056326717114}, {"borderWidth": 2.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ECOElectrolyzerPerformanceModel", "label": "ECOElectrolyzerPerformanceModel", "shape": "dot", "size": 18.710526315789473, "title": "ECOElectrolyzerPerformanceModel\nconverters/hydrogen/pem_electrolyzer.py\n[Converter / Hydrogen]", "x": 408.929515746538, "y": 301.0719911584519}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CustomElectrolyzerCostModel", "label": "CustomElectrolyzerCostModel", "shape": "dot", "size": 18.0, "title": "CustomElectrolyzerCostModel\nconverters/hydrogen/custom_electrolyzer_cost_model.py\n[Converter / Hydrogen]", "x": 519.3422437620703, "y": 376.741275969993}, {"borderWidth": 2.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HTSEPerformanceModel", "label": "HTSEPerformanceModel", "shape": "dot", "size": 18.0, "title": "HTSEPerformanceModel\nconverters/hydrogen/htse_electrolyzer.py\n[Converter / Hydrogen]", "x": 541.9933368656093, "y": 509.0547616483423}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HTSECostModel", "label": "HTSECostModel", "shape": "dot", "size": 18.0, "title": "HTSECostModel\nconverters/hydrogen/htse_electrolyzer.py\n[Converter / Hydrogen]", "x": 462.61867180963463, "y": 617.7338834509918}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GeoH2SubsurfaceCostModel", "label": "GeoH2SubsurfaceCostModel", "shape": "dot", "size": 18.0, "title": "GeoH2SubsurfaceCostModel\nconverters/hydrogen/geologic/mathur_modified.py\n[Converter / Hydrogen]", "x": 329.04975630639217, "y": 636.513453478361}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GeoH2SubsurfacePerformanceBaseClass", "label": "GeoH2SubsurfacePerformanceBaseClass", "shape": "dot", "size": 19.42105263157895, "title": "GeoH2SubsurfacePerformanceBaseClass\nconverters/hydrogen/geologic/h2_well_subsurface_baseclass.py\n[Converter / Hydrogen]", "x": 222.32576716621537, "y": 553.5863417347226}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GeoH2SubsurfaceCostBaseClass", "label": "GeoH2SubsurfaceCostBaseClass", "shape": "dot", "size": 18.710526315789473, "title": "GeoH2SubsurfaceCostBaseClass\nconverters/hydrogen/geologic/h2_well_subsurface_baseclass.py\n[Converter / Hydrogen]", "x": 207.46113153897124, "y": 419.00371238109653}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "AspenGeoH2SurfacePerformanceModel", "label": "AspenGeoH2SurfacePerformanceModel", "shape": "dot", "size": 18.0, "title": "AspenGeoH2SurfacePerformanceModel\nconverters/hydrogen/geologic/aspen_surface_processing.py\n[Converter / Hydrogen]", "x": 293.81016729091453, "y": 314.4201619012048}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "AspenGeoH2SurfaceCostModel", "label": "AspenGeoH2SurfaceCostModel", "shape": "dot", "size": 18.0, "title": "AspenGeoH2SurfaceCostModel\nconverters/hydrogen/geologic/aspen_surface_processing.py\n[Converter / Hydrogen]", "x": 429.1980303433203, "y": 303.5048975398027}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGeoH2PerformanceModel", "label": "NaturalGeoH2PerformanceModel", "shape": "dot", "size": 18.0, "title": "NaturalGeoH2PerformanceModel\nconverters/hydrogen/geologic/simple_natural_geoh2.py\n[Converter / Hydrogen]", "x": 531.4807512394786, "y": 393.1585470237545}, {"borderWidth": 3.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "StimulatedGeoH2PerformanceModel", "label": "StimulatedGeoH2PerformanceModel", "shape": "dot", "size": 18.0, "title": "StimulatedGeoH2PerformanceModel\nconverters/hydrogen/geologic/templeton_serpentinization.py\n[Converter / Hydrogen]", "x": 538.4198729733245, "y": 529.1652694271473}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GeoH2SurfacePerformanceBaseClass", "label": "GeoH2SurfacePerformanceBaseClass", "shape": "dot", "size": 18.710526315789473, "title": "GeoH2SurfacePerformanceBaseClass\nconverters/hydrogen/geologic/h2_well_surface_baseclass.py\n[Converter / Hydrogen]", "x": 445.5710237882473, "y": 629.0047614736493}, {"borderWidth": 4.0, "color": {"background": "#2E7D32", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GeoH2SurfaceCostBaseClass", "label": "GeoH2SurfaceCostBaseClass", "shape": "dot", "size": 18.710526315789473, "title": "GeoH2SurfaceCostBaseClass\nconverters/hydrogen/geologic/h2_well_surface_baseclass.py\n[Converter / Hydrogen]", "x": 309.11651798504033, "y": 631.947653855694}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ReverseOsmosisPerformanceModel", "label": "ReverseOsmosisPerformanceModel", "shape": "dot", "size": 18.0, "title": "ReverseOsmosisPerformanceModel\nconverters/water/desal/desalination.py\n[Converter / Water]", "x": 211.84908461781183, "y": 536.0083507662598}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ReverseOsmosisCostModel", "label": "ReverseOsmosisCostModel", "shape": "dot", "size": 18.0, "title": "ReverseOsmosisCostModel\nconverters/water/desal/desalination.py\n[Converter / Water]", "x": 212.91655044595416, "y": 399.26617741803875}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DesalinationPerformanceBaseClass", "label": "DesalinationPerformanceBaseClass", "shape": "dot", "size": 18.710526315789473, "title": "DesalinationPerformanceBaseClass\nconverters/water/desal/desalination_baseclass.py\n[Converter / Water]", "x": 311.84419223616084, "y": 304.68898638961775}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DesalinationCostBaseClass", "label": "DesalinationCostBaseClass", "shape": "dot", "size": 18.710526315789473, "title": "DesalinationCostBaseClass\nconverters/water/desal/desalination_baseclass.py\n[Converter / Water]", "x": 448.7220200189815, "y": 309.77552217810415}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleThermalNuclearReactorPerformanceModel", "label": "SimpleThermalNuclearReactorPerformanceModel", "shape": "dot", "size": 18.0, "title": "SimpleThermalNuclearReactorPerformanceModel\nconverters/nuclear/nuclear_plant_thermal.py\n[Converter / Nuclear]", "x": 540.4994435124524, "y": 411.5906925910052}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleThermalNuclearReactorCostModel", "label": "SimpleThermalNuclearReactorCostModel", "shape": "dot", "size": 18.0, "title": "SimpleThermalNuclearReactorCostModel\nconverters/nuclear/nuclear_plant_thermal.py\n[Converter / Nuclear]", "x": 531.3901362621964, "y": 548.4583323631547}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "QuinnNuclearPerformanceModel", "label": "QuinnNuclearPerformanceModel", "shape": "dot", "size": 18.0, "title": "QuinnNuclearPerformanceModel\nconverters/nuclear/nuclear_plant.py\n[Converter / Nuclear]", "x": 426.78782378431725, "y": 637.3337381981482}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "QuinnNuclearCostModel", "label": "QuinnNuclearCostModel", "shape": "dot", "size": 18.0, "title": "QuinnNuclearCostModel\nconverters/nuclear/nuclear_plant.py\n[Converter / Nuclear]", "x": 290.0713774101109, "y": 624.2026575560053}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CMUElectricArcFurnaceCostModel", "label": "CMUElectricArcFurnaceCostModel", "shape": "dot", "size": 18.0, "title": "CMUElectricArcFurnaceCostModel\nconverters/steel/cmu_eaf_cost.py\n[Converter / Steel]", "x": 204.19394571089566, "y": 516.9137611171568}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HydrogenEAFPlantCostComponent", "label": "HydrogenEAFPlantCostComponent", "shape": "dot", "size": 18.0, "title": "HydrogenEAFPlantCostComponent\nconverters/steel/steel_eaf_plant.py\n[Converter / Steel]", "x": 221.34134343018306, "y": 380.48561129518464}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGasEAFPlantCostComponent", "label": "NaturalGasEAFPlantCostComponent", "shape": "dot", "size": 18.0, "title": "NaturalGasEAFPlantCostComponent\nconverters/steel/steel_eaf_plant.py\n[Converter / Steel]", "x": 331.21568985008844, "y": 297.6965237937115}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HydrogenEAFPlantPerformanceComponent", "label": "HydrogenEAFPlantPerformanceComponent", "shape": "dot", "size": 18.0, "title": "HydrogenEAFPlantPerformanceComponent\nconverters/steel/steel_eaf_plant.py\n[Converter / Steel]", "x": 467.2216800346311, "y": 318.8505150630724}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGasEAFPlantPerformanceComponent", "label": "NaturalGasEAFPlantPerformanceComponent", "shape": "dot", "size": 18.0, "title": "NaturalGasEAFPlantPerformanceComponent\nconverters/steel/steel_eaf_plant.py\n[Converter / Steel]", "x": 546.8371236174256, "y": 431.20832772949075}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CMUElectricArcFurnaceScrapOnlyPerformanceComponent", "label": "CMUElectricArcFurnaceScrapOnlyPerformanceComponent", "shape": "dot", "size": 18.0, "title": "CMUElectricArcFurnaceScrapOnlyPerformanceComponent\nconverters/steel/cmu_electric_arc_furnace_scrap.py\n[Converter / Steel]", "x": 521.6903751911968, "y": 566.6610637668477}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ElectricArcFurnacePlantBasePerformanceComponent", "label": "ElectricArcFurnacePlantBasePerformanceComponent", "shape": "dot", "size": 19.42105263157895, "title": "ElectricArcFurnacePlantBasePerformanceComponent\nconverters/steel/steel_eaf_base.py\n[Converter / Steel]", "x": 406.952112243024, "y": 643.0222537742708}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ElectricArcFurnacePlantBaseCostComponent", "label": "ElectricArcFurnacePlantBaseCostComponent", "shape": "dot", "size": 19.42105263157895, "title": "ElectricArcFurnacePlantBaseCostComponent\nconverters/steel/steel_eaf_base.py\n[Converter / Steel]", "x": 272.18129178907674, "y": 613.9005699916162}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CMUElectricArcFurnaceDRIPerformanceComponent", "label": "CMUElectricArcFurnaceDRIPerformanceComponent", "shape": "dot", "size": 18.0, "title": "CMUElectricArcFurnaceDRIPerformanceComponent\nconverters/steel/cmu_electric_arc_furnace_dri.py\n[Converter / Steel]", "x": 199.15055717864382, "y": 496.88602197643854}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SteelPerformanceBaseClass", "label": "SteelPerformanceBaseClass", "shape": "dot", "size": 18.710526315789473, "title": "SteelPerformanceBaseClass\nconverters/steel/steel_baseclass.py\n[Converter / Steel]", "x": 232.2254768075065, "y": 362.9235822800501}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SteelCostBaseClass", "label": "SteelCostBaseClass", "shape": "dot", "size": 18.710526315789473, "title": "SteelCostBaseClass\nconverters/steel/steel_baseclass.py\n[Converter / Steel]", "x": 351.4109262191128, "y": 293.29530750309686}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SteelPerformanceModel", "label": "SteelPerformanceModel", "shape": "dot", "size": 18.0, "title": "SteelPerformanceModel\nconverters/steel/steel.py\n[Converter / Steel]", "x": 484.44055215455836, "y": 330.297978929092}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SteelCostAndFinancialModel", "label": "SteelCostAndFinancialModel", "shape": "dot", "size": 18.0, "title": "SteelCostAndFinancialModel\nconverters/steel/steel.py\n[Converter / Steel]", "x": 550.5984027605526, "y": 451.5476939728353}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleASUPerformanceModel", "label": "SimpleASUPerformanceModel", "shape": "dot", "size": 18.0, "title": "SimpleASUPerformanceModel\nconverters/nitrogen/simple_ASU.py\n[Converter / Nitrogen]", "x": 509.69716559653716, "y": 583.5219955261796}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleASUCostModel", "label": "SimpleASUCostModel", "shape": "dot", "size": 18.0, "title": "SimpleASUCostModel\nconverters/nitrogen/simple_ASU.py\n[Converter / Nitrogen]", "x": 386.4910795111691, "y": 646.1453801885751}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ATBWindPlantCostModel", "label": "ATBWindPlantCostModel", "shape": "dot", "size": 18.0, "title": "ATBWindPlantCostModel\nconverters/wind/atb_wind_cost.py\n[Converter / Wind]", "x": 255.69275934662096, "y": 601.3783905588575}, {"borderWidth": 3.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PYSAMWindPlantPerformanceModel", "label": "PYSAMWindPlantPerformanceModel", "shape": "dot", "size": 18.0, "title": "PYSAMWindPlantPerformanceModel\nconverters/wind/wind_pysam.py\n[Converter / Wind]", "x": 196.66404742738186, "y": 476.325072910983}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "WindPerformanceBaseClass", "label": "WindPerformanceBaseClass", "shape": "dot", "size": 19.42105263157895, "title": "WindPerformanceBaseClass\nconverters/wind/wind_plant_baseclass.py\n[Converter / Wind]", "x": 245.26041830184303, "y": 346.82157500140227}, {"borderWidth": 3.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "FlorisWindPlantPerformanceModel", "label": "FlorisWindPlantPerformanceModel", "shape": "dot", "size": 18.0, "title": "FlorisWindPlantPerformanceModel\nconverters/wind/floris.py\n[Converter / Wind]", "x": 372.0506131909644, "y": 291.4439725755037}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "WindArdPerformanceCompatibilityComponent", "label": "WindArdPerformanceCompatibilityComponent", "shape": "dot", "size": 18.0, "title": "WindArdPerformanceCompatibilityComponent\nconverters/wind/wind_plant_ard.py\n[Converter / Wind]", "x": 500.1422507144458, "y": 343.82986093378406}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "WindArdCostCompatibilityComponent", "label": "WindArdCostCompatibilityComponent", "shape": "dot", "size": 18.0, "title": "WindArdCostCompatibilityComponent\nconverters/wind/wind_plant_ard.py\n[Converter / Wind]", "x": 551.8160292273673, "y": 472.2454066683052}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SMRMethanolPlantPerformanceModel", "label": "SMRMethanolPlantPerformanceModel", "shape": "dot", "size": 18.0, "title": "SMRMethanolPlantPerformanceModel\nconverters/methanol/smr_methanol_plant.py\n[Converter / Methanol]", "x": 495.6839168464708, "y": 598.8099536341376}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SMRMethanolPlantCostModel", "label": "SMRMethanolPlantCostModel", "shape": "dot", "size": 18.0, "title": "SMRMethanolPlantCostModel\nconverters/methanol/smr_methanol_plant.py\n[Converter / Methanol]", "x": 365.7556658010815, "y": 646.7308814798549}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SMRMethanolPlantFinanceModel", "label": "SMRMethanolPlantFinanceModel", "shape": "dot", "size": 18.0, "title": "SMRMethanolPlantFinanceModel\nconverters/methanol/smr_methanol_plant.py\n[Converter / Methanol]", "x": 240.8316118946296, "y": 586.8992069729802}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MethanolPerformanceBaseClass", "label": "MethanolPerformanceBaseClass", "shape": "dot", "size": 19.42105263157895, "title": "MethanolPerformanceBaseClass\nconverters/methanol/methanol_baseclass.py\n[Converter / Methanol]", "x": 196.70889860494393, "y": 455.57195413603677}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MethanolCostBaseClass", "label": "MethanolCostBaseClass", "shape": "dot", "size": 19.42105263157895, "title": "MethanolCostBaseClass\nconverters/methanol/methanol_baseclass.py\n[Converter / Methanol]", "x": 260.1901653677206, "y": 332.3999371200461}, {"borderWidth": 5.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MethanolFinanceBaseClass", "label": "MethanolFinanceBaseClass", "shape": "dot", "size": 19.42105263157895, "title": "MethanolFinanceBaseClass\nconverters/methanol/methanol_baseclass.py\n[Converter / Methanol]", "x": 392.80172635379284, "y": 292.1171568185306}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CO2HMethanolPlantPerformanceModel", "label": "CO2HMethanolPlantPerformanceModel", "shape": "dot", "size": 18.0, "title": "CO2HMethanolPlantPerformanceModel\nconverters/methanol/co2h_methanol_plant.py\n[Converter / Methanol]", "x": 514.1120611197007, "y": 359.1947982547017}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CO2HMethanolPlantCostModel", "label": "CO2HMethanolPlantCostModel", "shape": "dot", "size": 18.0, "title": "CO2HMethanolPlantCostModel\nconverters/methanol/co2h_methanol_plant.py\n[Converter / Methanol]", "x": 550.5168235029448, "y": 492.97505700886006}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CO2HMethanolPlantFinanceModel", "label": "CO2HMethanolPlantFinanceModel", "shape": "dot", "size": 18.0, "title": "CO2HMethanolPlantFinanceModel\nconverters/methanol/co2h_methanol_plant.py\n[Converter / Methanol]", "x": 479.8992121579394, "y": 612.3160092753269}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HydrogenIronReductionPlantCostComponent", "label": "HydrogenIronReductionPlantCostComponent", "shape": "dot", "size": 18.0, "title": "HydrogenIronReductionPlantCostComponent\nconverters/iron/iron_dri_plant.py\n[Converter / Iron]", "x": 345.0667047898959, "y": 644.8082942814825}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGasIronReductionPlantCostComponent", "label": "NaturalGasIronReductionPlantCostComponent", "shape": "dot", "size": 18.0, "title": "NaturalGasIronReductionPlantCostComponent\nconverters/iron/iron_dri_plant.py\n[Converter / Iron]", "x": 227.80083824635747, "y": 570.7102438066149}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HydrogenIronReductionPlantPerformanceComponent", "label": "HydrogenIronReductionPlantPerformanceComponent", "shape": "dot", "size": 18.0, "title": "HydrogenIronReductionPlantPerformanceComponent\nconverters/iron/iron_dri_plant.py\n[Converter / Iron]", "x": 199.25186993001995, "y": 434.94269396402495}, {"borderWidth": 3.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGasIronReductionPlantPerformanceComponent", "label": "NaturalGasIronReductionPlantPerformanceComponent", "shape": "dot", "size": 18.0, "title": "NaturalGasIronReductionPlantPerformanceComponent\nconverters/iron/iron_dri_plant.py\n[Converter / Iron]", "x": 276.76776483357787, "y": 319.8555634030555}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HumbertEwinPerformanceComponent", "label": "HumbertEwinPerformanceComponent", "shape": "dot", "size": 18.0, "title": "HumbertEwinPerformanceComponent\nconverters/iron/humbert_ewin_perf.py\n[Converter / Iron]", "x": 413.3524790181906, "y": 295.27713454003253}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MartinIronMineCostComponent", "label": "MartinIronMineCostComponent", "shape": "dot", "size": 18.0, "title": "MartinIronMineCostComponent\nconverters/iron/martin_mine_cost_model.py\n[Converter / Iron]", "x": 526.1593352437131, "y": 376.14527848915895}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "IronTransportCostComponent", "label": "IronTransportCostComponent", "shape": "dot", "size": 18.0, "title": "IronTransportCostComponent\nconverters/iron/iron_transport.py\n[Converter / Iron]", "x": 546.743615781497, "y": 513.4286945748072}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "IronReductionPlantBasePerformanceComponent", "label": "IronReductionPlantBasePerformanceComponent", "shape": "dot", "size": 19.42105263157895, "title": "IronReductionPlantBasePerformanceComponent\nconverters/iron/iron_dri_base.py\n[Converter / Iron]", "x": 462.5917542911312, "y": 623.8559111338152}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "IronReductionPlantBaseCostComponent", "label": "IronReductionPlantBaseCostComponent", "shape": "dot", "size": 19.42105263157895, "title": "IronReductionPlantBaseCostComponent\nconverters/iron/iron_dri_base.py\n[Converter / Iron]", "x": 324.72859310432364, "y": 640.4260460063381}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MartinIronMinePerformanceComponent", "label": "MartinIronMinePerformanceComponent", "shape": "dot", "size": 18.0, "title": "MartinIronMinePerformanceComponent\nconverters/iron/martin_mine_perf_model.py\n[Converter / Iron]", "x": 216.77814592164026, "y": 553.0618685876668}, {"borderWidth": 4.0, "color": {"background": "#D84315", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HumbertStinnEwinCostComponent", "label": "HumbertStinnEwinCostComponent", "shape": "dot", "size": 18.0, "title": "HumbertStinnEwinCostComponent\nconverters/iron/humbert_stinn_ewin_cost.py\n[Converter / Iron]", "x": 204.23854510804242, "y": 414.73832160687783}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HOPPComponent", "label": "HOPPComponent", "shape": "dot", "size": 18.0, "title": "HOPPComponent\nconverters/hopp/hopp_wrapper.py\n[Converter / HOPP]", "x": 294.740834296002, "y": 309.3594743780847}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PySAMTidalPerformanceModel", "label": "PySAMTidalPerformanceModel", "shape": "dot", "size": 18.0, "title": "PySAMTidalPerformanceModel\nconverters/water_power/tidal_pysam.py\n[Converter / Water Power]", "x": 433.40509869823285, "y": 300.86319031224053}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PySAMMarineCostModel", "label": "PySAMMarineCostModel", "shape": "dot", "size": 18.0, "title": "PySAMMarineCostModel\nconverters/water_power/pysam_marine_cost.py\n[Converter / Water Power]", "x": 536.1198784691253, "y": 394.42665374762043}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "RunOfRiverHydroPerformanceModel", "label": "RunOfRiverHydroPerformanceModel", "shape": "dot", "size": 18.0, "title": "RunOfRiverHydroPerformanceModel\nconverters/water_power/hydro_plant_run_of_river.py\n[Converter / Water Power]", "x": 540.5636645511591, "y": 533.3117528946093}, {"borderWidth": 4.0, "color": {"background": "#4A90D9", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "RunOfRiverHydroCostModel", "label": "RunOfRiverHydroCostModel", "shape": "dot", "size": 18.0, "title": "RunOfRiverHydroCostModel\nconverters/water_power/hydro_plant_run_of_river.py\n[Converter / Water Power]", "x": 444.01862690077985, "y": 633.2724247412674}, {"borderWidth": 3.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "AmmoniaSynLoopPerformanceModel", "label": "AmmoniaSynLoopPerformanceModel", "shape": "dot", "size": 18.0, "title": "AmmoniaSynLoopPerformanceModel\nconverters/ammonia/ammonia_synloop_performance.py\n[Converter / Ammonia]", "x": 305.03269414802736, "y": 633.6581275003193}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "AmmoniaSynLoopCostModel", "label": "AmmoniaSynLoopCostModel", "shape": "dot", "size": 18.0, "title": "AmmoniaSynLoopCostModel\nconverters/ammonia/ammonia_synloop_cost.py\n[Converter / Ammonia]", "x": 207.91368001519578, "y": 534.2137056268189}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleAmmoniaPerformanceModel", "label": "SimpleAmmoniaPerformanceModel", "shape": "dot", "size": 18.0, "title": "SimpleAmmoniaPerformanceModel\nconverters/ammonia/simple_ammonia_model.py\n[Converter / Ammonia]", "x": 211.58805712431138, "y": 395.2469621597975}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleAmmoniaCostModel", "label": "SimpleAmmoniaCostModel", "shape": "dot", "size": 18.0, "title": "SimpleAmmoniaCostModel\nconverters/ammonia/simple_ammonia_model.py\n[Converter / Ammonia]", "x": 313.84715753363025, "y": 301.0546018388401}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DOCPerformanceModel", "label": "DOCPerformanceModel", "shape": "dot", "size": 18.0, "title": "DOCPerformanceModel\nconverters/co2/marine/direct_ocean_capture.py\n[Converter / CO2]", "x": 452.67476445714954, "y": 308.7874754191507}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DOCCostModel", "label": "DOCCostModel", "shape": "dot", "size": 18.0, "title": "DOCCostModel\nconverters/co2/marine/direct_ocean_capture.py\n[Converter / CO2]", "x": 543.8580906910796, "y": 413.7741089596238}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "OAEPerformanceModel", "label": "OAEPerformanceModel", "shape": "dot", "size": 18.0, "title": "OAEPerformanceModel\nconverters/co2/marine/ocean_alkalinity_enhancement.py\n[Converter / CO2]", "x": 532.0718732102009, "y": 552.342805603834}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "OAECostModel", "label": "OAECostModel", "shape": "dot", "size": 18.0, "title": "OAECostModel\nconverters/co2/marine/ocean_alkalinity_enhancement.py\n[Converter / CO2]", "x": 424.4472139785939, "y": 640.4373943201894}, {"borderWidth": 4.0, "color": {"background": "#66BB6A", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "OAECostAndFinancialModel", "label": "OAECostAndFinancialModel", "shape": "dot", "size": 18.0, "title": "OAECostAndFinancialModel\nconverters/co2/marine/ocean_alkalinity_enhancement.py\n[Converter / CO2]", "x": 286.2569295976094, "y": 624.6065418587294}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GridPerformanceModel", "label": "GridPerformanceModel", "shape": "dot", "size": 18.0, "title": "GridPerformanceModel\nconverters/grid/grid.py\n[Converter / Grid]", "x": 201.3280452712436, "y": 514.4356470449293}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GridCostModel", "label": "GridCostModel", "shape": "dot", "size": 18.0, "title": "GridCostModel\nconverters/grid/grid.py\n[Converter / Grid]", "x": 221.19128243913522, "y": 376.74290673623443}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGasPerformanceModel", "label": "NaturalGasPerformanceModel", "shape": "dot", "size": 18.0, "title": "NaturalGasPerformanceModel\nconverters/natural_gas/natural_gas_cc_ct.py\n[Converter / Natural Gas]", "x": 333.8144210804685, "y": 295.05389888426953}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NaturalGasCostModel", "label": "NaturalGasCostModel", "shape": "dot", "size": 18.0, "title": "NaturalGasCostModel\nconverters/natural_gas/natural_gas_cc_ct.py\n[Converter / Natural Gas]", "x": 470.89095415961566, "y": 318.9337463910879}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleGasProducerPerformance", "label": "SimpleGasProducerPerformance", "shape": "dot", "size": 18.0, "title": "SimpleGasProducerPerformance\nconverters/natural_gas/dummy_gas_components.py\n[Converter / Natural Gas]", "x": 549.2687648311249, "y": 433.9130181048081}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleGasConsumerPerformance", "label": "SimpleGasConsumerPerformance", "shape": "dot", "size": 18.0, "title": "SimpleGasConsumerPerformance\nconverters/natural_gas/dummy_gas_components.py\n[Converter / Natural Gas]", "x": 521.3915858425219, "y": 570.2552478490614}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleGasProducerCost", "label": "SimpleGasProducerCost", "shape": "dot", "size": 18.0, "title": "SimpleGasProducerCost\nconverters/natural_gas/dummy_gas_components.py\n[Converter / Natural Gas]", "x": 404.1543265855715, "y": 645.2534468240677}, {"borderWidth": 4.0, "color": {"background": "#1B3A5C", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleGasConsumerCost", "label": "SimpleGasConsumerCost", "shape": "dot", "size": 18.0, "title": "SimpleGasConsumerCost\nconverters/natural_gas/dummy_gas_components.py\n[Converter / Natural Gas]", "x": 268.6638310304031, "y": 613.4016976914556}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "StoragePerformanceModel", "label": "StoragePerformanceModel", "shape": "diamond", "size": 18.0, "title": "StoragePerformanceModel\nstorage/storage_performance_model.py\n[Storage / General]", "x": 428.09388111524004, "y": -469.09888948081795}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "StoragePerformanceBase", "label": "StoragePerformanceBase", "shape": "diamond", "size": 20.13157894736842, "title": "StoragePerformanceBase\nstorage/storage_baseclass.py\n[Storage / General]", "x": 455.6085661088584, "y": -385.16822684557377}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "StorageAutoSizingModel", "label": "StorageAutoSizingModel", "shape": "diamond", "size": 18.0, "title": "StorageAutoSizingModel\nstorage/simple_storage_auto_sizing.py\n[Storage / General]", "x": 370.0643470376622, "y": -331.15773226109025}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GenericStorageCostModel", "label": "GenericStorageCostModel", "shape": "diamond", "size": 18.0, "title": "GenericStorageCostModel\nstorage/generic_storage_cost.py\n[Storage / General]", "x": 264.590914357365, "y": -368.7926071689721}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MCHTOLStorageCostModel", "label": "MCHTOLStorageCostModel", "shape": "diamond", "size": 18.0, "title": "MCHTOLStorageCostModel\nstorage/hydrogen/mch_storage.py\n[Storage / General]", "x": 219.55784982221226, "y": -478.13520688340736}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HydrogenStorageBaseCostModel", "label": "HydrogenStorageBaseCostModel", "shape": "diamond", "size": 20.842105263157894, "title": "HydrogenStorageBaseCostModel\nstorage/hydrogen/h2_storage_cost.py\n[Storage / General]", "x": 270.16454539792574, "y": -589.4304862347785}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "LinedRockCavernStorageCostModel", "label": "LinedRockCavernStorageCostModel", "shape": "diamond", "size": 18.0, "title": "LinedRockCavernStorageCostModel\nstorage/hydrogen/h2_storage_cost.py\n[Storage / General]", "x": 388.2687164324305, "y": -630.4775561122241}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SaltCavernStorageCostModel", "label": "SaltCavernStorageCostModel", "shape": "diamond", "size": 18.0, "title": "SaltCavernStorageCostModel\nstorage/hydrogen/h2_storage_cost.py\n[Storage / General]", "x": 501.4805766605486, "y": -572.7844347513467}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PipeStorageCostModel", "label": "PipeStorageCostModel", "shape": "diamond", "size": 18.0, "title": "PipeStorageCostModel\nstorage/hydrogen/h2_storage_cost.py\n[Storage / General]", "x": 538.9625776291, "y": -449.75172147563603}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CompressedGasStorageCostModel", "label": "CompressedGasStorageCostModel", "shape": "diamond", "size": 18.0, "title": "CompressedGasStorageCostModel\nstorage/hydrogen/h2_storage_cost.py\n[Storage / General]", "x": 475.93189116793945, "y": -336.23888907246976}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PySAMBatteryPerformanceModel", "label": "PySAMBatteryPerformanceModel", "shape": "diamond", "size": 18.0, "title": "PySAMBatteryPerformanceModel\nstorage/battery/pysam_battery.py\n[Storage / General]", "x": 349.5705117805883, "y": -302.34705409538617}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ATBBatteryCostModel", "label": "ATBBatteryCostModel", "shape": "diamond", "size": 18.0, "title": "ATBBatteryCostModel\nstorage/battery/atb_battery_cost.py\n[Storage / General]", "x": 236.61361523178934, "y": -369.9554252856643}, {"borderWidth": 4.0, "color": {"background": "#F5C542", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "FeedstockCostModel", "label": "FeedstockCostModel", "shape": "dot", "size": 18.710526315789473, "title": "FeedstockCostModel\nfeedstocks/feedstocks.py\n[Other / Other]", "x": -486.58132074145146, "y": -260.3302434705348}, {"borderWidth": 3.0, "color": {"background": "#F5C542", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "EIANaturalGasFeedstockCostModel", "label": "EIANaturalGasFeedstockCostModel", "shape": "dot", "size": 18.0, "title": "EIANaturalGasFeedstockCostModel\nfeedstocks/eia_ng_price.py\n[Other / Other]", "x": -459.0666357478331, "y": -176.39958083529064}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ProFastLCO", "label": "ProFastLCO", "shape": "star", "size": 18.0, "title": "ProFastLCO\nfinances/profast_lco.py\n[Finance / General]", "x": -486.58132074145146, "y": 260.3302434705349}, {"borderWidth": 5.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ProFastBase", "label": "ProFastBase", "shape": "star", "size": 19.42105263157895, "title": "ProFastBase\nfinances/profast_base.py\n[Finance / General]", "x": -459.0666357478331, "y": 344.2609061057791}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ProFastNPV", "label": "ProFastNPV", "shape": "star", "size": 18.0, "title": "ProFastNPV\nfinances/profast_npv.py\n[Finance / General]", "x": -544.6108548190293, "y": 398.2714006902626}, {"borderWidth": 5.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ResourceBaseAPIModel", "label": "ResourceBaseAPIModel", "shape": "triangle", "size": 19.42105263157895, "title": "ResourceBaseAPIModel\nresource/resource_base.py\n[Resource / General]", "x": -79.51256037378874, "y": -584.9567473090942}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MeteosatPrimeMeridianSolarAPI", "label": "MeteosatPrimeMeridianSolarAPI", "shape": "triangle", "size": 18.0, "title": "MeteosatPrimeMeridianSolarAPI\nresource/solar/nlr_developer_meteosat_prime_meridian_models.py\n[Resource / General]", "x": -51.9978753801704, "y": -501.02608467385005}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "MeteosatPrimeMeridianTMYSolarAPI", "label": "MeteosatPrimeMeridianTMYSolarAPI", "shape": "triangle", "size": 18.0, "title": "MeteosatPrimeMeridianTMYSolarAPI\nresource/solar/nlr_developer_meteosat_prime_meridian_models.py\n[Resource / General]", "x": -137.5420944513666, "y": -447.0155900893665}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SolarResourceBaseAPIModel", "label": "SolarResourceBaseAPIModel", "shape": "triangle", "size": 19.42105263157895, "title": "SolarResourceBaseAPIModel\nresource/solar/solar_resource_base.py\n[Resource / General]", "x": -243.01552713166376, "y": -484.6504649972484}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "OpenMeteoHistoricalSolarResource", "label": "OpenMeteoHistoricalSolarResource", "shape": "triangle", "size": 18.0, "title": "OpenMeteoHistoricalSolarResource\nresource/solar/openmeteo_solar.py\n[Resource / General]", "x": -288.0485916668165, "y": -593.9930647116836}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "Himawari7SolarAPI", "label": "Himawari7SolarAPI", "shape": "triangle", "size": 18.0, "title": "Himawari7SolarAPI\nresource/solar/nlr_developer_himawari_api_models.py\n[Resource / General]", "x": -237.44189609110305, "y": -705.2883440630549}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "Himawari8SolarAPI", "label": "Himawari8SolarAPI", "shape": "triangle", "size": 18.0, "title": "Himawari8SolarAPI\nresource/solar/nlr_developer_himawari_api_models.py\n[Resource / General]", "x": -119.33772505659829, "y": -746.3354139405003}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HimawariTMYSolarAPI", "label": "HimawariTMYSolarAPI", "shape": "triangle", "size": 18.0, "title": "HimawariTMYSolarAPI\nresource/solar/nlr_developer_himawari_api_models.py\n[Resource / General]", "x": -6.125864828480175, "y": -688.6422925796229}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "NLRDeveloperAPISolarResourceBase", "label": "NLRDeveloperAPISolarResourceBase", "shape": "triangle", "size": 24.394736842105264, "title": "NLRDeveloperAPISolarResourceBase\nresource/solar/nlr_developer_api_base.py\n[Resource / General]", "x": 31.356136140071186, "y": -565.6095793039123}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GOESAggregatedSolarAPI", "label": "GOESAggregatedSolarAPI", "shape": "triangle", "size": 18.0, "title": "GOESAggregatedSolarAPI\nresource/solar/nlr_developer_goes_api_models.py\n[Resource / General]", "x": -31.67455032108934, "y": -452.096746900746}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GOESConusSolarAPI", "label": "GOESConusSolarAPI", "shape": "triangle", "size": 18.0, "title": "GOESConusSolarAPI\nresource/solar/nlr_developer_goes_api_models.py\n[Resource / General]", "x": -158.0359297084405, "y": -418.2049119236624}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GOESFullDiscSolarAPI", "label": "GOESFullDiscSolarAPI", "shape": "triangle", "size": 18.0, "title": "GOESFullDiscSolarAPI\nresource/solar/nlr_developer_goes_api_models.py\n[Resource / General]", "x": -270.99282625723947, "y": -485.8132831139406}, {"borderWidth": 2.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GOESTMYSolarAPI", "label": "GOESTMYSolarAPI", "shape": "triangle", "size": 18.0, "title": "GOESTMYSolarAPI\nresource/solar/nlr_developer_goes_api_models.py\n[Resource / General]", "x": -301.2124767374961, "y": -614.6459391266081}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "OpenMeteoHistoricalWindResource", "label": "OpenMeteoHistoricalWindResource", "shape": "triangle", "size": 18.0, "title": "OpenMeteoHistoricalWindResource\nresource/wind/openmeteo_wind.py\n[Resource / General]", "x": -229.44086839384488, "y": -726.515073522741}, {"borderWidth": 4.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "WindResourceBaseAPIModel", "label": "WindResourceBaseAPIModel", "shape": "triangle", "size": 19.42105263157895, "title": "WindResourceBaseAPIModel\nresource/wind/wind_resource_base.py\n[Resource / General]", "x": -98.67692574249088, "y": -752.9836456314601}, {"borderWidth": 3.0, "color": {"background": "#555555", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "WTKNLRDeveloperAPIWindResource", "label": "WTKNLRDeveloperAPIWindResource", "shape": "triangle", "size": 18.0, "title": "WTKNLRDeveloperAPIWindResource\nresource/wind/nlr_developer_wtk_api.py\n[Resource / General]", "x": 11.735802273041458, "y": -677.3143608199191}, {"borderWidth": 3.0, "color": {"background": "#F5C542", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "GenericDemandComponent", "label": "GenericDemandComponent", "shape": "dot", "size": 18.0, "title": "GenericDemandComponent\ndemand/generic_demand.py\n[Other / Other]", "x": -544.6108548190293, "y": -122.38908625080711}, {"borderWidth": 4.0, "color": {"background": "#F5C542", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DemandComponentBase", "label": "DemandComponentBase", "shape": "dot", "size": 19.42105263157895, "title": "DemandComponentBase\ndemand/demand_base.py\n[Other / Other]", "x": -650.0842874993265, "y": -160.02396115868896}, {"borderWidth": 3.0, "color": {"background": "#F5C542", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "FlexibleDemandComponent", "label": "FlexibleDemandComponent", "shape": "dot", "size": 18.0, "title": "FlexibleDemandComponent\ndemand/flexible_demand.py\n[Other / Other]", "x": -695.1173520344793, "y": -269.36656087312423}, {"borderWidth": 5.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PyomoStorageControllerBaseClass", "label": "PyomoStorageControllerBaseClass", "shape": "diamond", "size": 20.13157894736842, "title": "PyomoStorageControllerBaseClass\ncontrol/control_strategies/pyomo_storage_controller_baseclass.py\n[Storage / General]", "x": 206.39396475153265, "y": -498.78808129833186}, {"borderWidth": 5.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SystemLevelControlBase", "label": "SystemLevelControlBase", "shape": "hexagon", "size": 20.13157894736842, "title": "SystemLevelControlBase\ncontrol/control_strategies/system_level/system_level_control_base.py\n[Control / General]", "x": 654.0, "y": 0.0}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "ProfitMaximizationControl", "label": "ProfitMaximizationControl", "shape": "hexagon", "size": 18.0, "title": "ProfitMaximizationControl\ncontrol/control_strategies/system_level/profit_maximization_control.py\n[Control / General]", "x": 681.5146849936184, "y": 83.93066263524416}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DemandFollowingControl", "label": "DemandFollowingControl", "shape": "hexagon", "size": 18.0, "title": "DemandFollowingControl\ncontrol/control_strategies/system_level/demand_following_control.py\n[Control / General]", "x": 595.9704659224221, "y": 137.9411572197277}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "CostMinimizationControl", "label": "CostMinimizationControl", "shape": "hexagon", "size": 18.0, "title": "CostMinimizationControl\ncontrol/control_strategies/system_level/cost_minimization_control.py\n[Control / General]", "x": 490.497033242125, "y": 100.30628231184586}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PeakLoadManagementOptimizedStorageController", "label": "PeakLoadManagementOptimizedStorageController", "shape": "diamond", "size": 18.0, "title": "PeakLoadManagementOptimizedStorageController\ncontrol/control_strategies/storage/plm_optimized_storage_controller.py\n[Storage / General]", "x": 278.1655730951839, "y": -610.6572156944648}, {"borderWidth": 5.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "StorageOpenLoopControlBase", "label": "StorageOpenLoopControlBase", "shape": "diamond", "size": 20.13157894736842, "title": "StorageOpenLoopControlBase\ncontrol/control_strategies/storage/openloop_storage_control_base.py\n[Storage / General]", "x": 408.9295157465379, "y": -637.1257878031839}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "DemandOpenLoopStorageController", "label": "DemandOpenLoopStorageController", "shape": "diamond", "size": 18.0, "title": "DemandOpenLoopStorageController\ncontrol/control_strategies/storage/demand_openloop_storage_controller.py\n[Storage / General]", "x": 519.3422437620702, "y": -561.4565029916428}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "HeuristicLoadFollowingStorageController", "label": "HeuristicLoadFollowingStorageController", "shape": "diamond", "size": 18.0, "title": "HeuristicLoadFollowingStorageController\ncontrol/control_strategies/storage/heuristic_pyomo_controller.py\n[Storage / General]", "x": 541.9933368656092, "y": -429.1430173132935}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "OptimizedDispatchStorageController", "label": "OptimizedDispatchStorageController", "shape": "diamond", "size": 18.0, "title": "OptimizedDispatchStorageController\ncontrol/control_strategies/storage/optimized_pyomo_controller.py\n[Storage / General]", "x": 462.6186718096345, "y": -320.4638955106441}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "SimpleStorageOpenLoopController", "label": "SimpleStorageOpenLoopController", "shape": "diamond", "size": 18.0, "title": "SimpleStorageOpenLoopController\ncontrol/control_strategies/storage/simple_openloop_controller.py\n[Storage / General]", "x": 329.04975630639206, "y": -301.68432548327485}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PeakLoadManagementHeuristicOpenLoopStorageController", "label": "PeakLoadManagementHeuristicOpenLoopStorageController", "shape": "diamond", "size": 18.0, "title": "PeakLoadManagementHeuristicOpenLoopStorageController\ncontrol/control_strategies/storage/plm_openloop_storage_controller.py\n[Storage / General]", "x": 222.32576716621526, "y": -384.6114372269132}, {"borderWidth": 5.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PyomoRuleBaseClass", "label": "PyomoRuleBaseClass", "shape": "hexagon", "size": 19.42105263157895, "title": "PyomoRuleBaseClass\ncontrol/control_rules/pyomo_rule_baseclass.py\n[Control / General]", "x": 445.4639687069722, "y": -9.036317402589397}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PyomoDispatchGenericConverter", "label": "PyomoDispatchGenericConverter", "shape": "dot", "size": 18.0, "title": "PyomoDispatchGenericConverter\ncontrol/control_rules/converters/generic_converter.py\n[Converter / Other]", "x": 197.11069916989607, "y": 494.00654543295764}, {"borderWidth": 4.0, "color": {"background": "#00ACC1", "border": "#555555", "highlight": {"background": "#FF6B6B", "border": "#FF0000"}, "hover": {"background": "#FFD700", "border": "#FF8C00"}}, "font": {"color": "#333333"}, "id": "PyomoRuleStorageBaseclass", "label": "PyomoRuleStorageBaseclass", "shape": "diamond", "size": 18.0, "title": "PyomoRuleStorageBaseclass\ncontrol/control_rules/storage/pyomo_storage_rule_baseclass.py\n[Storage / General]", "x": 207.46113153897113, "y": -519.1940665805394}]); + edges = new vis.DataSet([{"arrows": "to", "from": "SiteBaseComponent", "to": "SiteLocationComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "ResizeablePerformanceModelBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SolarPerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "LinearH2FuelCellPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SteamMethaneReformerPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "GeoH2SubsurfacePerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "GeoH2SurfacePerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "DesalinationPerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SimpleThermalNuclearReactorPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "QuinnNuclearPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "CMUElectricArcFurnaceScrapOnlyPerformanceComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "ElectricArcFurnacePlantBasePerformanceComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "CMUElectricArcFurnaceDRIPerformanceComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SteelPerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SimpleASUPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "WindPerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "WindArdPerformanceCompatibilityComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "MethanolPerformanceBaseClass"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "HumbertEwinPerformanceComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "IronReductionPlantBasePerformanceComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "MartinIronMinePerformanceComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "HOPPComponent"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "PySAMTidalPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "RunOfRiverHydroPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SimpleAmmoniaPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "DOCPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "OAEPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "GridPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "NaturalGasPerformanceModel"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SimpleGasProducerPerformance"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "SimpleGasConsumerPerformance"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "StoragePerformanceBase"}, {"arrows": "to", "from": "PerformanceModelBaseClass", "to": "DemandComponentBase"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "GenericConverterCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "ATBUtilityPVCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "ATBResComPVCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "ElectrolyzerCostBaseClass"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "H2FuelCellCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SteamMethaneReformerCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "GeoH2SubsurfaceCostBaseClass"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "GeoH2SurfaceCostBaseClass"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "DesalinationCostBaseClass"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SimpleThermalNuclearReactorCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "QuinnNuclearCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "CMUElectricArcFurnaceCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "ElectricArcFurnacePlantBaseCostComponent"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SteelCostBaseClass"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SimpleASUCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "ATBWindPlantCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "WindArdCostCompatibilityComponent"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "MethanolCostBaseClass"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "MartinIronMineCostComponent"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "IronTransportCostComponent"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "IronReductionPlantBaseCostComponent"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "HumbertStinnEwinCostComponent"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "PySAMMarineCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "RunOfRiverHydroCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "AmmoniaSynLoopCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SimpleAmmoniaCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "DOCCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "OAECostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "OAECostAndFinancialModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "GridCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "NaturalGasCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SimpleGasProducerCost"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "SimpleGasConsumerCost"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "GenericStorageCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "MCHTOLStorageCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "HydrogenStorageBaseCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "ATBBatteryCostModel"}, {"arrows": "to", "from": "CostModelBaseClass", "to": "FeedstockCostModel"}, {"arrows": "to", "from": "ResizeablePerformanceModelBaseClass", "to": "ElectrolyzerPerformanceBaseClass"}, {"arrows": "to", "from": "ResizeablePerformanceModelBaseClass", "to": "AmmoniaSynLoopPerformanceModel"}, {"arrows": "to", "from": "CacheBaseClass", "to": "FlorisWindPlantPerformanceModel"}, {"arrows": "to", "from": "CacheBaseClass", "to": "HOPPComponent"}, {"arrows": "to", "from": "SolarPerformanceBaseClass", "to": "PYSAMSolarPlantPerformanceModel"}, {"arrows": "to", "from": "ElectrolyzerPerformanceBaseClass", "to": "ECOElectrolyzerPerformanceModel"}, {"arrows": "to", "from": "ElectrolyzerPerformanceBaseClass", "to": "HTSEPerformanceModel"}, {"arrows": "to", "from": "ElectrolyzerCostBaseClass", "to": "SingliticoCostModel"}, {"arrows": "to", "from": "ElectrolyzerCostBaseClass", "to": "BasicElectrolyzerCostModel"}, {"arrows": "to", "from": "ElectrolyzerCostBaseClass", "to": "CustomElectrolyzerCostModel"}, {"arrows": "to", "from": "ElectrolyzerCostBaseClass", "to": "HTSECostModel"}, {"arrows": "to", "from": "ECOElectrolyzerPerformanceModel", "to": "WOMBATElectrolyzerModel"}, {"arrows": "to", "from": "GeoH2SubsurfacePerformanceBaseClass", "to": "NaturalGeoH2PerformanceModel"}, {"arrows": "to", "from": "GeoH2SubsurfacePerformanceBaseClass", "to": "StimulatedGeoH2PerformanceModel"}, {"arrows": "to", "from": "GeoH2SubsurfaceCostBaseClass", "to": "GeoH2SubsurfaceCostModel"}, {"arrows": "to", "from": "GeoH2SurfacePerformanceBaseClass", "to": "AspenGeoH2SurfacePerformanceModel"}, {"arrows": "to", "from": "GeoH2SurfaceCostBaseClass", "to": "AspenGeoH2SurfaceCostModel"}, {"arrows": "to", "from": "DesalinationPerformanceBaseClass", "to": "ReverseOsmosisPerformanceModel"}, {"arrows": "to", "from": "DesalinationCostBaseClass", "to": "ReverseOsmosisCostModel"}, {"arrows": "to", "from": "ElectricArcFurnacePlantBasePerformanceComponent", "to": "HydrogenEAFPlantPerformanceComponent"}, {"arrows": "to", "from": "ElectricArcFurnacePlantBasePerformanceComponent", "to": "NaturalGasEAFPlantPerformanceComponent"}, {"arrows": "to", "from": "ElectricArcFurnacePlantBaseCostComponent", "to": "HydrogenEAFPlantCostComponent"}, {"arrows": "to", "from": "ElectricArcFurnacePlantBaseCostComponent", "to": "NaturalGasEAFPlantCostComponent"}, {"arrows": "to", "from": "SteelPerformanceBaseClass", "to": "SteelPerformanceModel"}, {"arrows": "to", "from": "SteelCostBaseClass", "to": "SteelCostAndFinancialModel"}, {"arrows": "to", "from": "WindPerformanceBaseClass", "to": "PYSAMWindPlantPerformanceModel"}, {"arrows": "to", "from": "WindPerformanceBaseClass", "to": "FlorisWindPlantPerformanceModel"}, {"arrows": "to", "from": "MethanolPerformanceBaseClass", "to": "SMRMethanolPlantPerformanceModel"}, {"arrows": "to", "from": "MethanolPerformanceBaseClass", "to": "CO2HMethanolPlantPerformanceModel"}, {"arrows": "to", "from": "MethanolCostBaseClass", "to": "SMRMethanolPlantCostModel"}, {"arrows": "to", "from": "MethanolCostBaseClass", "to": "CO2HMethanolPlantCostModel"}, {"arrows": "to", "from": "MethanolFinanceBaseClass", "to": "SMRMethanolPlantFinanceModel"}, {"arrows": "to", "from": "MethanolFinanceBaseClass", "to": "CO2HMethanolPlantFinanceModel"}, {"arrows": "to", "from": "IronReductionPlantBasePerformanceComponent", "to": "HydrogenIronReductionPlantPerformanceComponent"}, {"arrows": "to", "from": "IronReductionPlantBasePerformanceComponent", "to": "NaturalGasIronReductionPlantPerformanceComponent"}, {"arrows": "to", "from": "IronReductionPlantBaseCostComponent", "to": "HydrogenIronReductionPlantCostComponent"}, {"arrows": "to", "from": "IronReductionPlantBaseCostComponent", "to": "NaturalGasIronReductionPlantCostComponent"}, {"arrows": "to", "from": "StoragePerformanceBase", "to": "StoragePerformanceModel"}, {"arrows": "to", "from": "StoragePerformanceBase", "to": "StorageAutoSizingModel"}, {"arrows": "to", "from": "StoragePerformanceBase", "to": "PySAMBatteryPerformanceModel"}, {"arrows": "to", "from": "HydrogenStorageBaseCostModel", "to": "LinedRockCavernStorageCostModel"}, {"arrows": "to", "from": "HydrogenStorageBaseCostModel", "to": "SaltCavernStorageCostModel"}, {"arrows": "to", "from": "HydrogenStorageBaseCostModel", "to": "PipeStorageCostModel"}, {"arrows": "to", "from": "HydrogenStorageBaseCostModel", "to": "CompressedGasStorageCostModel"}, {"arrows": "to", "from": "FeedstockCostModel", "to": "EIANaturalGasFeedstockCostModel"}, {"arrows": "to", "from": "ProFastBase", "to": "ProFastLCO"}, {"arrows": "to", "from": "ProFastBase", "to": "ProFastNPV"}, {"arrows": "to", "from": "ResourceBaseAPIModel", "to": "SolarResourceBaseAPIModel"}, {"arrows": "to", "from": "ResourceBaseAPIModel", "to": "WindResourceBaseAPIModel"}, {"arrows": "to", "from": "SolarResourceBaseAPIModel", "to": "OpenMeteoHistoricalSolarResource"}, {"arrows": "to", "from": "SolarResourceBaseAPIModel", "to": "NLRDeveloperAPISolarResourceBase"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "MeteosatPrimeMeridianSolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "MeteosatPrimeMeridianTMYSolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "Himawari7SolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "Himawari8SolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "HimawariTMYSolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "GOESAggregatedSolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "GOESConusSolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "GOESFullDiscSolarAPI"}, {"arrows": "to", "from": "NLRDeveloperAPISolarResourceBase", "to": "GOESTMYSolarAPI"}, {"arrows": "to", "from": "WindResourceBaseAPIModel", "to": "OpenMeteoHistoricalWindResource"}, {"arrows": "to", "from": "WindResourceBaseAPIModel", "to": "WTKNLRDeveloperAPIWindResource"}, {"arrows": "to", "from": "DemandComponentBase", "to": "GenericDemandComponent"}, {"arrows": "to", "from": "DemandComponentBase", "to": "FlexibleDemandComponent"}, {"arrows": "to", "from": "PyomoStorageControllerBaseClass", "to": "PeakLoadManagementOptimizedStorageController"}, {"arrows": "to", "from": "PyomoStorageControllerBaseClass", "to": "HeuristicLoadFollowingStorageController"}, {"arrows": "to", "from": "PyomoStorageControllerBaseClass", "to": "OptimizedDispatchStorageController"}, {"arrows": "to", "from": "SystemLevelControlBase", "to": "ProfitMaximizationControl"}, {"arrows": "to", "from": "SystemLevelControlBase", "to": "DemandFollowingControl"}, {"arrows": "to", "from": "SystemLevelControlBase", "to": "CostMinimizationControl"}, {"arrows": "to", "from": "StorageOpenLoopControlBase", "to": "DemandOpenLoopStorageController"}, {"arrows": "to", "from": "StorageOpenLoopControlBase", "to": "SimpleStorageOpenLoopController"}, {"arrows": "to", "from": "StorageOpenLoopControlBase", "to": "PeakLoadManagementHeuristicOpenLoopStorageController"}, {"arrows": "to", "from": "PyomoRuleBaseClass", "to": "PyomoDispatchGenericConverter"}, {"arrows": "to", "from": "PyomoRuleBaseClass", "to": "PyomoRuleStorageBaseclass"}]); nodeColors = {}; allNodes = nodes.get({ returnType: "Object" }); diff --git a/docs/technology_models/h2_htse.md b/docs/technology_models/h2_htse.md new file mode 100644 index 000000000..2e9c57ba0 --- /dev/null +++ b/docs/technology_models/h2_htse.md @@ -0,0 +1,103 @@ +# High-Temperature Steam Electrolysis (HTSE) Model + +The HTSE model in H2Integrate represents hydrogen production from high-temperature steam electrolysis using electricity and thermal input. It is implemented as two components: + +- `HTSEPerformanceModel` +- `HTSECostModel` + +The performance model converts electricity and heat into hydrogen, water demand, and operating signals for connected technologies. The cost model computes installed capital cost and fixed operating cost from installed HTSE size. + +## Model Overview + +This is a simplified HTSE representation with constant nominal specific energy requirements: + +- `nominal_electricity_required` in `kWh/kg` +- `nominal_heat_required` in `kWh/kg` + +At each timestep, hydrogen production is determined from: + +- installed HTSE size +- available `electricity_in` +- available `heat_in` +- optional `hydrogen_command_value` when system-level control is enabled +- turndown behavior + +The model also exposes internal operating signals that are useful for coupled systems, including: + +- `heat_demand` +- `electricity_demand` +- `electricity_consumed` +- `water_demand` + +```{note} +The current implementation uses `electricity_demand` to report installed electrical demand equal to nameplate size, while `electricity_consumed` reports the timestep electricity required by the energy balance. For coupled analyses, `electricity_consumed` is the more literal consumption signal. +``` + +## Performance Model + +Use this model by setting: + +- performance model: `HTSEPerformanceModel` + +The HTSE performance model inherits from the electrolyzer base classes, so it is treated as a hydrogen-producing, dispatchable technology with an `electricity_in` input and a `hydrogen_out` output. + +```{figure} images/HTSE.png +:alt: HTSE schematic +:width: 100% +:align: center +``` + +### Dispatch and sizing behavior + +Installed size is first inferred from: + +$$ +\text{electrolyzer\_size\_mw} = n_{clusters} \times cluster\_rating\_MW +$$ + +The model supports additional sizing modes inherited from the resizeable performance base class: + +- `normal` +- `resize_by_max_feedstock` +- `resize_by_max_commodity` + +In the current implementation: + +- `resize_by_max_feedstock` supports sizing from `electricity` +- `resize_by_max_commodity` supports sizing from `hydrogen` + +When system-level control is enabled, hydrogen demand is taken from `hydrogen_command_value`. Otherwise, the model assumes demand equal to rated hydrogen production implied by installed electrical size. + +### Energy balance behavior + +The model forms: + +$$ +\text{total\_specific\_energy} = nominal\_heat\_required + nominal\_electricity\_required +$$ + +and computes a nominal heat-to-electricity ratio: + +$$ +\text{ratio\_heat\_elec\_nom} = \frac{nominal\_heat\_required}{nominal\_electricity\_required} +$$ + +Available heat is used first up to the requested `heat_demand`. The remaining required energy is supplied electrically when possible. Hydrogen production is then limited by the combined energy available and by the turndown threshold. + +```{note} +The current implementation is intentionally simple and should be interpreted as a reduced-order plant representation, not a detailed SOEC stack model with thermal transients, degradation coupling, startup dynamics, or detailed balance-of-plant behavior. +``` + +### API details +For API details, see the [`HTSEPerformanceModel` and `HTSECostModel` API documentation](../_autosummary/h2integrate.converters.hydrogen.htse_electrolyzer). + +## Cost Model + +Use this model by setting: + +- cost model: `HTSECostModel` + +The cost model is size-based and currently depends only on installed HTSE size. + +### API details +For API details, see the [`HTSEPerformanceModel` and `HTSECostModel` API documentation](../_autosummary/h2integrate.converters.hydrogen.htse_electrolyzer). diff --git a/docs/technology_models/images/HTSE.png b/docs/technology_models/images/HTSE.png new file mode 100644 index 000000000..fb33470f5 Binary files /dev/null and b/docs/technology_models/images/HTSE.png differ diff --git a/docs/technology_models/images/ThermalNucReactor-H2I.png b/docs/technology_models/images/ThermalNucReactor-H2I.png new file mode 100644 index 000000000..63db37880 Binary files /dev/null and b/docs/technology_models/images/ThermalNucReactor-H2I.png differ diff --git a/docs/technology_models/nuclear.md b/docs/technology_models/nuclear.md index e793d1429..0036d679c 100644 --- a/docs/technology_models/nuclear.md +++ b/docs/technology_models/nuclear.md @@ -1,83 +1,33 @@ -# Nuclear power plant model - -The nuclear power plant model provides a simple, size-based performance model and a type-based cost model. -Cost defaults are intended to be populated from literature, such as Quinn et al. (2023) on SMR LWR techno-economic analysis. -See the paper here: [Quinn et al. (2023)](#references). - -To use this model, set the performance model to `QuinnNuclearPerformanceModel` and the cost model to `QuinnNuclearCostModel` in your `tech_config`. - -## Performance model - -The performance model limits electricity production by the rated capacity and an optional demand signal. - -**Inputs** -| Name | Shape | Units | Description | -| --- | --- | --- | --- | -| `system_capacity` | scalar | kW | Rated electrical capacity. | -| `electricity_set_point` | array[n_timesteps] | kW | Optional set point profile; defaults to rated capacity. | - -**Outputs** -| Name | Shape | Units | Description | -| --- | --- | --- | --- | -| `electricity_out` | array[n_timesteps] | kW | Electricity produced, capped at `system_capacity`. | -| `rated_electricity_production` | scalar | kW | Rated production (capacity). | -| `total_electricity_produced` | scalar | kW*h | Sum of production over the simulation. | -| `annual_electricity_produced` | array[plant_life] | kW*h/year | Annualized production. | -| `capacity_factor` | array[plant_life] | unitless | Ratio of actual to maximum production. | -| `replacement_schedule` | array[plant_life] | unitless | Placeholder replacement schedule (zeros). | -| `operational_life` | scalar | yr | Operational life (defaults to plant life). | - -## Cost model - -The cost model uses direct cost parameters to compute capital and operating costs. -It supports optional scaling of capex with size using a reference capacity and scaling exponent. - -**Inputs** -| Name | Shape | Units | Description | -| --- | --- | --- | --- | -| `system_capacity` | scalar | kW | Plant capacity used for cost scaling. | -| `electricity_out` | array[n_timesteps] | kW | Output from performance model. | - -**Cost parameters (tech_config)** -| Key | Type | Description | -| --- | --- | --- | -| `system_capacity_kw` | float | Rated electrical capacity (kW). | -| `capex_per_kw` | float | Capital cost per kW. | -| `fixed_opex_per_kw_year` | float | Fixed O&M per kW per year. | -| `variable_opex_per_mwh` | float | Variable O&M per MWh. | -| `reference_capacity_kw` | float | Reference capacity for capex scaling (defaults to `system_capacity_kw`). | -| `capex_scaling_exponent` | float | Capex scaling exponent (defaults to 1.0). | -| `cost_year` | int | Dollar year for the input costs. | - -The capex calculation follows: +# Nuclear power plant models -$$ -C_{\text{capex}} = (c_{\text{capex}} \cdot (P / P_{\text{ref}})^{(k-1)}) \cdot P -$$ +H2Integrate currently includes two nuclear converter options: + +- `QuinnNuclearPerformanceModel` with `QuinnNuclearCostModel` for an electricity-only nuclear plant +- `SimpleThermalNuclearReactorPerformanceModel` with `SimpleThermalNuclearReactorCostModel` for a thermal reactor that can trade off electricity production and process heat delivery + +The first model is based on Quinn et al. (2023). The second is a simplified thermal reactor representation intended for coupled workflows such as nuclear plus HTSE. -Where $c_{\text{capex}}$ is `capex_per_kw`, $P$ is plant capacity (kW), $P_{\text{ref}}$ is `reference_capacity_kw`, and $k$ is `capex_scaling_exponent`. +## Quinn electricity-only nuclear model -**Outputs** -| Name | Shape | Units | Description | -| --- | --- | --- | --- | -| `CapEx` | scalar | USD | Total capital expenditure. | -| `OpEx` | scalar | USD/year | Fixed plus variable O&M. | -| `VarOpEx` | array[plant_life] | USD/year | Variable O&M (repeated each year). | -| `cost_year` | scalar | year | Dollar year of costs. | +Use this model by setting: -## Example tech_config +- performance model: `QuinnNuclearPerformanceModel` +- cost model: `QuinnNuclearCostModel` + +This model produces electricity only and clips commanded output to rated plant capacity. + +### Example `tech_config` ```yaml technologies: nuclear: performance_model: - model: "QuinnNuclearPerformanceModel" + model: QuinnNuclearPerformanceModel cost_model: - model: "QuinnNuclearCostModel" + model: QuinnNuclearCostModel model_inputs: performance_parameters: system_capacity_kw: 300000.0 - capacity_factor: 0.9 cost_parameters: system_capacity_kw: 450000.0 capex_per_kw: 6000.0 @@ -88,7 +38,51 @@ technologies: cost_year: 2023 ``` -(references)= -## References +### API details +For API details, see the [`QuinnNuclearPerformanceModel` and `QuinnNuclearCostModel` API documentation](../_autosummary/h2integrate.converters.nuclear.nuclear_plant). +(references)= +### References - Quinn, J. et al., 2023. Small modular reactor light water reactor techno-economic analysis. Applied Energy 120669. https://doi.org/10.1016/j.apenergy.2023.120669 + +## Simple thermal nuclear reactor model + +Use this model by setting: + +- performance model: `SimpleThermalNuclearReactorPerformanceModel` +- cost model: `SimpleThermalNuclearReactorCostModel` + +This model represents a reactor with: + +- a high-pressure electric conversion stage +- a low-pressure electric conversion stage +- an extractable process heat stream, extracted upstream of the low-pressure turbine stages (dashed red arrow in the figure) + +It supports two operating modes: + +- `heat`: In `heat` mode, delivered heat is limited by available process heat and requested heat demand. Remaining low-pressure heat is converted to electricity. + +- `electricity`: In `electricity` mode, electricity is limited by the command value and rated capacity. Remaining process heat is then sent as `heat_out`. + +```{figure} images/ThermalNucReactor-H2I.png +:alt: Thermal nuclear reactor schematic +:width: 100% +:align: center +``` + +### Thermal reactor dispatch logic + +The model computes a combined electric efficiency: + +$$ +\eta_{combined} = \eta_{hp} + (1 - \eta_{hp}) \eta_{lp} +$$ + +Then infers thermal capacity from rated electrical capacity: + +$$ +P_{thermal} = \frac{P_{electric,rated}}{\eta_{combined}} +$$ + +### API details +For API details, see the [`SimpleThermalNuclearReactorPerformanceModel` and `SimpleThermalNuclearReactorCostModel` API documentation](../_autosummary/h2integrate.converters.nuclear.nuclear_plant_thermal). diff --git a/docs/user_guide/model_overview.md b/docs/user_guide/model_overview.md index 8c943e7a7..e2cee6f50 100644 --- a/docs/user_guide/model_overview.md +++ b/docs/user_guide/model_overview.md @@ -150,12 +150,14 @@ auto-generated API page. - `hydrogen`: hydrogen production - performance models: + {py:class}`~h2integrate.converters.hydrogen.pem_electrolyzer.ECOElectrolyzerPerformanceModel` - An OpenMDAO component that wraps the PEM electrolyzer model. + + {py:class}`~h2integrate.converters.hydrogen.htse_electrolyzer.HTSEPerformanceModel` - A simplified high-temperature steam electrolysis (HTSE) model. + {py:class}`~h2integrate.converters.hydrogen.h2_fuel_cell.LinearH2FuelCellPerformanceModel` - Performance model for a hydrogen fuel cell. + {py:class}`~h2integrate.converters.hydrogen.steam_methane_reformer.SteamMethaneReformerPerformanceModel` - Performance model for steam methane reforming (SMR) hydrogen production plants. - cost models: + {py:class}`~h2integrate.converters.hydrogen.basic_cost_model.BasicElectrolyzerCostModel` - An OpenMDAO component that computes the cost of a PEM electrolyzer. + {py:class}`~h2integrate.converters.hydrogen.custom_electrolyzer_cost_model.CustomElectrolyzerCostModel` - An OpenMDAO component that computes the cost of a PEM electrolyzer. + {py:class}`~h2integrate.converters.hydrogen.h2_fuel_cell.H2FuelCellCostModel` - Cost model for a hydrogen fuel cell system. + + {py:class}`~h2integrate.converters.hydrogen.htse_electrolyzer.HTSECostModel` - A simple size-based cost model for HTSE. + {py:class}`~h2integrate.converters.hydrogen.singlitico_cost_model.SingliticoCostModel` - An OpenMDAO component that computes the cost of a PEM electrolyzer. + {py:class}`~h2integrate.converters.hydrogen.steam_methane_reformer.SteamMethaneReformerCostModel` - Cost model for steam methane reforming hydrogen production plants. - combined performance and cost models: @@ -202,8 +204,10 @@ auto-generated API page. - `nuclear`: nuclear power plants - performance models: + {py:class}`~h2integrate.converters.nuclear.nuclear_plant.QuinnNuclearPerformanceModel` - Simple nuclear performance model producing electricity. + + {py:class}`~h2integrate.converters.nuclear.nuclear_plant_thermal.SimpleThermalNuclearReactorPerformanceModel` - Simple thermal nuclear reactor model with heat and electricity outputs. - cost models: + {py:class}`~h2integrate.converters.nuclear.nuclear_plant.QuinnNuclearCostModel` - Cost model for nuclear power plants. + + {py:class}`~h2integrate.converters.nuclear.nuclear_plant_thermal.SimpleThermalNuclearReactorCostModel` - Simple cost model for the thermal nuclear reactor. - `solar`: solar-PV panels - performance models: diff --git a/examples/36_nuclear_reactor_htse/driver_config.yaml b/examples/36_nuclear_reactor_htse/driver_config.yaml new file mode 100644 index 000000000..edf1a9391 --- /dev/null +++ b/examples/36_nuclear_reactor_htse/driver_config.yaml @@ -0,0 +1,52 @@ +name: driver_config +description: Runs a thermal nuclear plant with simple optimization +general: + folder_output: nuclear_thermal_plant +### Use This For Parameter Sweep +# driver: +# design_of_experiments: +# flag: true +# generator: "FullFact" #type of generator to use +# levels: 3 # input is specific to this generator +# debug_print: true +driver: + optimization: + flag: false + solver: COBYLA + tol: 0.1 + catol: 100000 + max_iter: 100 + rhobeg: 0.1 + disp: 3 + debug_print: true +design_variables: + nuclear: + electricity_command_value: + flag: true + lower: 1000 + upper: 500000 + units: kW + htse: + n_clusters: + flag: true + lower: 2.0 + upper: 40.0 + units: unitless +# Add constraints later to the code +# constraints: + # nuclear: + # electricity_out: + # flag: true + # upper: 5000.0 + # units: MW + # ramping_rate: + # flag: true + # upper: 500 + # units: kW/hr + # electrolyzer: + # total_hydrogen_produced: + # flag: false + # lower: 60500000. + # units: kg/year +objective: + name: finance_subgroup_hydrogen.LCOH diff --git a/examples/36_nuclear_reactor_htse/nuclear_reactor_thermal_htse.yaml b/examples/36_nuclear_reactor_htse/nuclear_reactor_thermal_htse.yaml new file mode 100644 index 000000000..874e6169f --- /dev/null +++ b/examples/36_nuclear_reactor_htse/nuclear_reactor_thermal_htse.yaml @@ -0,0 +1,6 @@ +name: H2Integrate_config +system_summary: This is an example plant with a nuclear plant capable of dispatching thermal and electrical energy to an HTSE + system +driver_config: driver_config.yaml +technology_config: tech_config.yaml +plant_config: plant_config.yaml diff --git a/examples/36_nuclear_reactor_htse/plant_config.yaml b/examples/36_nuclear_reactor_htse/plant_config.yaml new file mode 100644 index 000000000..e37f37a79 --- /dev/null +++ b/examples/36_nuclear_reactor_htse/plant_config.yaml @@ -0,0 +1,87 @@ +name: plant_config +description: This plant is located in CO, USA... +sites: + site: + latitude: 35.2018863 + longitude: -101.945027 +plant: + plant_life: 60 +# array of arrays containing left-to-right technology +# interconnections; can support bidirectional connections +# with the reverse definition. +# this will naturally grow as we mature the interconnected tech +technology_interconnections: + - [nuclear, htse, [heat_out, heat_in]] + - [nuclear, electrical_load_demand, electricity, cable] + - [htse, nuclear, [heat_demand, heat_command_value]] + - [htse, electrical_load_demand, [electricity_demand, electricity_demand]] + - [water_feedstock, htse, water, pipe] + - [htse_electricity_feedstock, htse, electricity, cable] + - [finance_subgroup_electricity, grid_sell, [LCOE, electricity_sell_price]] + - [finance_subgroup_electricity, htse_electricity_feedstock, [LCOE, price]] + - [electrical_load_demand, grid_sell, [unused_electricity_out, electricity_set_point]] + - [electrical_load_demand, grid_sell, [unused_electricity_out, electricity_in]] +tech_to_dispatch_connections: [] +resource_to_tech_connections: [] +finance_parameters: + finance_groups: + nuclear_finance: + commodity: electricity + finance_model: ProFastLCO + model_inputs: + params: + analysis_start_year: 2030 + installation_time: 84 # months - estimating 7 years for construction + inflation_rate: 0.0 # 0 for nominal analysis + discount_rate: 0.105 # nominal equity return based on 2024 ATB baseline workbook for nuclear + debt_equity_ratio: 2.26 # 2024 ATB uses 69.4% debt for nuclear + property_tax_and_insurance: 0.03 # percent of CAPEX estimated based on https://www.nrel.gov/docs/fy25osti/91775.pdf https://www.house.mn.gov/hrd/issinfo/clsrates.aspx + total_income_tax_rate: 0.257 # 0.257 tax rate in 2024 atb baseline workbook, value here is based on federal (21%) and state in MN (9.8) + capital_gains_tax_rate: 0.15 # H2FAST default + sales_tax_rate: 0.07375 # total state and local sales tax in St. Louis County https://taxmaps.state.mn.us/salestax/ + debt_interest_rate: 0.08 # based on 2024 ATB nominal interest rate for nuclear + debt_type: Revolving debt # can be "Revolving debt" or "One time loan". Revolving debt is H2FAST default and leads to much lower LCOH + loan_period_if_used: 0 # H2FAST default, not used for revolving debt + cash_onhand_months: 1 # H2FAST default + admin_expense: 0.00 # percent of sales H2FAST default + capital_items: + depr_type: MACRS # can be "MACRS" or "Straight line" + depr_period: 15 # 15 years is typical, some advanced nuclear facilities may be eligible for a 5 year MACRS + refurb: [0.] + htse_finance: + commodity: hydrogen + finance_model: ProFastLCO + model_inputs: + params: + analysis_start_year: 2036 # delayed so nuclear plant and HTSE plant come online the same year + installation_time: 12 # months - estimating 1 year for construction + inflation_rate: 0.0 # 0 for nominal analysis + discount_rate: 0.15 # nominal equity return based on 2024 ATB baseline workbook for nuclear + debt_equity_ratio: 2.26 # 2024 ATB uses 69.4% debt for nuclear + property_tax_and_insurance: 0.03 # percent of CAPEX estimated based on https://www.nrel.gov/docs/fy25osti/91775.pdf https://www.house.mn.gov/hrd/issinfo/clsrates.aspx + total_income_tax_rate: 0.257 # 0.257 tax rate in 2024 atb baseline workbook, value here is based on federal (21%) and state in MN (9.8) + capital_gains_tax_rate: 0.15 # H2FAST default + sales_tax_rate: 0.07375 # total state and local sales tax in St. Louis County https://taxmaps.state.mn.us/salestax/ + debt_interest_rate: 0.08 # based on 2024 ATB nominal interest rate for nuclear + debt_type: Revolving debt # can be "Revolving debt" or "One time loan". Revolving debt is H2FAST default and leads to much lower LCOH + loan_period_if_used: 0 # H2FAST default, not used for revolving debt + cash_onhand_months: 1 # H2FAST default + admin_expense: 0.00 # percent of sales H2FAST default + capital_items: + depr_type: MACRS # can be "MACRS" or "Straight line" + depr_period: 7 # 15 years is typical, some advanced nuclear facilities may be eligible for a 5 year MACRS + refurb: [0.] + cost_adjustment_parameters: + cost_year_adjustment_inflation: 0.025 # used to adjust modeled costs to target_dollar_year + target_dollar_year: 2022 + finance_subgroups: + electricity: + commodity: electricity + commodity_stream: nuclear + finance_groups: [nuclear_finance] + technologies: [nuclear] + hydrogen: + commodity: hydrogen + commodity_stream: htse + finance_groups: [htse_finance] + technologies: [htse_electricity_feedstock, water_feedstock, htse] diff --git a/examples/36_nuclear_reactor_htse/run_nuclear_reactor_thermal.py b/examples/36_nuclear_reactor_htse/run_nuclear_reactor_thermal.py new file mode 100644 index 000000000..620a0282b --- /dev/null +++ b/examples/36_nuclear_reactor_htse/run_nuclear_reactor_thermal.py @@ -0,0 +1,90 @@ +import numpy as np +import matplotlib.pyplot as plt + +from h2integrate.core.file_utils import load_yaml +from h2integrate.core.h2integrate_model import H2IntegrateModel + + +# load config and update htse refurb profile +config = load_yaml("nuclear_reactor_thermal_htse.yaml") +plant_config = load_yaml(config["plant_config"]) +plant_life = plant_config["plant"]["plant_life"] +tech_config = load_yaml(config["technology_config"]) + +refurb = np.zeros(plant_life) +refurb[3::4] = 1 +tech_config["technologies"]["htse"]["model_inputs"]["capital_items"]["refurb"] = refurb + +config["technology_config"] = tech_config + +# Create a GreenHEART model +h2i = H2IntegrateModel(config) + +# generate N2 diagram +# om.n2(h2i.prob) + +# Run and process the model +h2i.run() + +h2i.post_process() +# expected water kg/h 4,347.8261 +# generate plots of the output + +e_nuclear = h2i.prob.get_val("nuclear.annual_electricity_produced", units="TW*h/year")[0] +e_htse = h2i.prob.get_val("htse.electricity_demand", units="TW*h/year")[0] +e_sold = h2i.prob.get_val("grid_sell.annual_electricity_sold", units="TW*h/year")[0] + +heat_nuclear = np.sum(h2i.prob.get_val("nuclear.heat_out", units="GW")) +heat_htse = np.sum(h2i.prob.get_val("htse.heat_demand", units="GW")) + +h2_htse = h2i.prob.get_val("htse.annual_hydrogen_produced", units="kt/year")[0] + +# Print levelized cost outputs for each finance model/subgroup +lcoe_electricity = h2i.prob.get_val("finance_subgroup_electricity.LCOE", units="USD/(MW*h)")[0] +lcoh_hydrogen = h2i.prob.get_val("finance_subgroup_hydrogen.LCOH", units="USD/kg")[0] + +print(f"LCOE (electricity finance subgroup): {lcoe_electricity:.2f} USD/MWh") +print(f"LCOH (hydrogen finance subgroup): {lcoh_hydrogen:.4f} USD/kg") + +# Prepare data for bar charts +labels = ["Nuclear Plant", "HTSE Plant", "Grid Sold"] +electricity = [e_nuclear, e_htse, e_sold] + +heat_labels = ["Nuclear Plant", "HTSE Plant"] +heat = [heat_nuclear, heat_htse] + +h2_labels = ["HTSE Plant"] +h2 = [h2_htse] + +fig, axs = plt.subplots(1, 3, figsize=(15, 5)) + +# Electricity bar chart: Nuclear Generation (left), Stacked HTSE+Grid (right) +bar_width = 0.6 +x = np.arange(2) + +# Bar 0: Total Nuclear Generation +axs[0].bar([0], [e_nuclear], color="deepskyblue", width=bar_width, label="Nuclear generation") + +# Bar 1: Stacked HTSE + Grid Sold +axs[0].bar([1], [e_sold], color="green", width=bar_width, label="Sold to grid") +axs[0].bar([1], [e_htse], color="orange", width=bar_width, label="HTSE demand", bottom=e_sold) + +axs[0].set_xticks([0, 1]) +axs[0].set_xticklabels(["Produced", "Used"]) +axs[0].set_ylabel("Annual Energy (TW*h/year)") +axs[0].set_title("Electricity") +axs[0].set(ylim=[0, 10]) +axs[0].legend(ncol=2, frameon=False) + +# Heat bar chart +axs[1].bar(heat_labels, heat, color=["red", "purple"]) +axs[1].set_ylabel("Annual Heat (GWh/year)") +axs[1].set_title("Heat") + +# H2 bar chart +axs[2].bar(h2_labels, h2, color=["gold"]) +axs[2].set_ylabel("Annual Hydrogen (kt/year)") +axs[2].set_title("Hydrogen") + +plt.tight_layout() +plt.show() diff --git a/examples/36_nuclear_reactor_htse/tech_config.yaml b/examples/36_nuclear_reactor_htse/tech_config.yaml new file mode 100644 index 000000000..7116fb56c --- /dev/null +++ b/examples/36_nuclear_reactor_htse/tech_config.yaml @@ -0,0 +1,107 @@ +name: technology_config +description: This is a nuclear plant generating electricity and can also provide heat +general: + folder_output: nuclear_htse +technologies: + water_feedstock: + performance_model: + model: FeedstockPerformanceModel + cost_model: + model: FeedstockCostModel + model_inputs: + shared_parameters: + commodity: water + commodity_rate_units: galUS/h + performance_parameters: + rated_capacity: 2000.0 # gal water per hour + cost_parameters: + cost_year: 2021 + commodity_amount_units: galUS + price: 0.0035 # 3.5 USD/kgal + annual_cost: 0. + start_up_cost: 0.0 + nuclear: + performance_model: + model: SimpleThermalNuclearReactorPerformanceModel + cost_model: + model: SimpleThermalNuclearReactorCostModel + model_inputs: + performance_parameters: + operating_mode: heat + electricity_command_value: 500000 # kW + high_pressure_electrical_efficiency: 0.12 + low_pressure_electrical_efficiency: 0.22 + minimum_heat_extract: 1 # MW + cost_parameters: + cost_year: 2022 + nuclear_reactor_rated_capacity: 5000000.0 + nuclear_reactor_upfront_cost: 5750.0 # $/kWe # includes significant labor as per (Moneghan and Abou-Jaoude, 2024). + nuclear_reactor_fixed_om_cost: 2.64 # can adjust with labor # (Moneghan and Abou-Jaoude, 2024). + nuclear_reactor_variable_om_cost: 0.0145 + # Values from Table 38, Meta-Analysis of Advanced Nuclear Reactor Cost Estimations, + # slightly adjusted away from 93% capacity factor + shared_parameters: + rated_capacity: 1000000.0 + htse_electricity_feedstock: + performance_model: + model: FeedstockPerformanceModel + cost_model: + model: FeedstockCostModel + model_inputs: + shared_parameters: + commodity: electricity + commodity_rate_units: kW + performance_parameters: + rated_capacity: 30000.0 # kW + cost_parameters: + cost_year: 2022 + commodity_amount_units: kW*h + price: 0.0 # USD/(kW*h) + annual_cost: 0. + start_up_cost: 0.0 + htse: + performance_model: + model: HTSEPerformanceModel + cost_model: + model: HTSECostModel + model_inputs: + performance_parameters: + nominal_heat_required: 6.4 # kWh/kg + nominal_electricity_required: 36.8 # kWh/kg + # https://lwrs.inl.gov/content/uploads/11/2024/03/TechnicalEconomicAssessment-LWR-SupportedHydrogen.pdf # INL/RPT-23-75604 + cluster_rating_MW: 1 # Electric-only sizing component, so capacity = rating*clusters/nom_elec + n_clusters: 25 + turndown_ratio: 0.1 # minimum operating power + uptime_hours_until_eol: 35040 # 4 years as per Diaz et al. 2023 + cost_parameters: + cost_year: 2022 + unit_capex: 1417 # $/kW based on Diaz et al. 2023: Technical Economic Assessment of LWR-Supported Hydrogen Markets in Gulf Coast Regions + fixed_capex: 0.0 + capital_items: + depr_type: MACRS # can be "MACRS" or "Straight line" + depr_period: 7 + refurb: null # to be assigned at run rime + replacement_cost_percent: 0.1077 # based on table 2 in Diaz et al. 2023 + electrical_load_demand: + performance_model: + model: GenericDemandComponent + model_inputs: + performance_parameters: + commodity: electricity + commodity_rate_units: kW + demand_profile: 100000 # 100 MW + grid_sell: + performance_model: + model: GridPerformanceModel + cost_model: + model: GridCostModel + model_inputs: + shared_parameters: + interconnection_size: 5000000 # 5 GW + cost_parameters: + cost_year: 2022 + electricity_sell_price: 0.0 # $/kWh - only selling, no buying + sell_price_mode: constant + interconnection_capex_per_kw: 0.0 # $/kW capital cost + interconnection_opex_per_kw: 0.0 # $/kW/year O&M cost + fixed_interconnection_cost: 0.0 # $ one-time fixed cost diff --git a/examples/test/test_all_examples.py b/examples/test/test_all_examples.py index d02a1c52a..d113a9542 100644 --- a/examples/test/test_all_examples.py +++ b/examples/test/test_all_examples.py @@ -3050,3 +3050,56 @@ def test_plm_optimized_dispatch_example(subtests, temp_copy_of_example): battery_charge = model.prob.get_val("battery.storage_electricity_charge", units="kW") total_energy_charged = battery_charge.sum() * (1 / 60) # kWh, 1 min timestep assert pytest.approx(total_energy_charged, rel=1e-3) == -2663.0 + + +@pytest.mark.integration +@pytest.mark.parametrize( + "example_folder,resource_example_folder", [("36_nuclear_reactor_htse", None)] +) +def test_nuclear_reactor_htse_example(subtests, temp_copy_of_example): + example_folder = temp_copy_of_example + + model = H2IntegrateModel(example_folder / "nuclear_reactor_thermal_htse.yaml") + model.run() + annual_nuclear_electricity = model.prob.get_val( + "nuclear.annual_electricity_produced", units="TW*h/year" + )[0] + model.prob.get_val("htse.electricity_demand", units="TW*h/year")[0] + annual_htse_electricity = model.prob.get_val("htse.electricity_demand", units="TW*h/year")[0] + annual_grid_sell = model.prob.get_val("grid_sell.annual_electricity_sold", units="TW*h/year")[0] + annual_hydrogen = model.prob.get_val("htse.annual_hydrogen_produced", units="kt/year")[0] + + with subtests.test("Nuclear annual electricity is positive"): + assert annual_nuclear_electricity == pytest.approx(8.75162086757) + + with subtests.test("HTSE annual hydrogen production is positive"): + assert annual_hydrogen == pytest.approx(5.951086956521741) + + with subtests.test("Grid annual electricity sold is non-negative"): + assert annual_grid_sell == pytest.approx(8.53262086956522) + + with subtests.test("Electricity balance between HTSE demand and grid sales"): + assert pytest.approx(annual_nuclear_electricity, rel=1e-4) == ( + annual_htse_electricity + annual_grid_sell + ) + + high_pressure_heat = model.prob.get_val("nuclear.high_pressure_heat", units="MW") + low_pressure_heat = model.prob.get_val("nuclear.low_pressure_heat", units="MW") + extracted_heat = model.prob.get_val("nuclear.heat_out", units="MW") + + with subtests.test("Nuclear thermal split is conserved"): + assert np.allclose(high_pressure_heat, low_pressure_heat + extracted_heat, rtol=1e-6) + + rated_nuclear_output = model.prob.get_val("nuclear.rated_electricity_production", units="MW")[0] + nuclear_electricity_out = model.prob.get_val("nuclear.electricity_out", units="MW") + + with subtests.test("Nuclear electricity output is within rated limit"): + assert np.all(nuclear_electricity_out <= rated_nuclear_output + 1e-6) + + unused_electricity = model.prob.get_val( + "electrical_load_demand.unused_electricity_out", units="MW" + ) + grid_electricity_in = model.prob.get_val("grid_sell.electricity_in", units="MW") + + with subtests.test("Unused electricity is routed to grid sell"): + assert pytest.approx(unused_electricity.sum(), rel=1e-6) == grid_electricity_in.sum() diff --git a/h2integrate/converters/hydrogen/__init__.py b/h2integrate/converters/hydrogen/__init__.py index b39fb2556..0bf80327d 100644 --- a/h2integrate/converters/hydrogen/__init__.py +++ b/h2integrate/converters/hydrogen/__init__.py @@ -13,3 +13,7 @@ SteamMethaneReformerPerformanceModel, SteamMethaneReformerCostModel, ) +from h2integrate.converters.hydrogen.htse_electrolyzer import ( + HTSEPerformanceModel, + HTSECostModel, +) diff --git a/h2integrate/converters/hydrogen/htse_electrolyzer.py b/h2integrate/converters/hydrogen/htse_electrolyzer.py new file mode 100644 index 000000000..c0903dc9e --- /dev/null +++ b/h2integrate/converters/hydrogen/htse_electrolyzer.py @@ -0,0 +1,340 @@ +import numpy as np +from attrs import field, define +from CoolProp.CoolProp import PropsSI + +from h2integrate.core.utilities import merge_shared_inputs +from h2integrate.core.validators import gt_zero, contains +from h2integrate.core.model_baseclasses import ( + CostModelBaseConfig, + ResizeablePerformanceModelBaseConfig, +) +from h2integrate.converters.hydrogen.utilities import size_electrolyzer_for_hydrogen_demand +from h2integrate.converters.hydrogen.electrolyzer_baseclass import ( + ElectrolyzerCostBaseClass, + ElectrolyzerPerformanceBaseClass, +) + + +@define(kw_only=True) +class HTSEElectrolyzerPerformanceModelConfig(ResizeablePerformanceModelBaseConfig): + """Configuration class for the HTSE performance model. + + Args: + n_clusters (int): Number of HTSE clusters in the system. + nominal_heat_required (float): Nominal thermal energy required per kg of hydrogen + in kWh/kg. + nominal_electricity_required (float): Nominal electrical energy required per kg of + hydrogen in kWh/kg. + location (str): Deployment location, either ``"onshore"`` or ``"offshore"``. + Present in config but not used directly in the current performance calculation. + Defaults to ``"onshore"``. + cluster_rating_MW (float): Nameplate electrical rating per cluster in MW. + eol_eff_percent_loss (float): End-of-life efficiency loss in percent. Present in + config but not used directly in the current timestep energy balance. Defaults + to ``10.0``. + uptime_hours_until_eol (int): Hours of operation between replacement events. + Defaults to ``80000``. + include_degradation_penalty (bool): Whether to apply a degradation penalty. Present + in config but not used directly in the current timestep energy balance. Defaults + to ``False``. + turndown_ratio (float): Minimum fraction of rated hydrogen production required to + stay on (unitless). Defaults to ``0.1``. + pressure_H2 (float): Hydrogen pressure setting. Present in config but not used + directly in the current timestep energy balance. Defaults to ``1.0``. + """ + + n_clusters: int = field(validator=gt_zero) + nominal_heat_required: float = field(validator=gt_zero) + nominal_electricity_required: float = field(validator=gt_zero) + location: str = field(default="onshore", validator=contains(["onshore", "offshore"])) + cluster_rating_MW: float = field(validator=gt_zero) + eol_eff_percent_loss: float = field(default=10.0, validator=gt_zero) + uptime_hours_until_eol: int = field(default=80000, validator=gt_zero) + include_degradation_penalty: bool = field(default=False) + turndown_ratio: float = field(default=0.1, validator=gt_zero) + pressure_H2: float = field(default=1.0, validator=gt_zero) + + +class HTSEPerformanceModel(ElectrolyzerPerformanceBaseClass): + """A simplified high-temperature steam electrolysis (HTSE) model. + + This model represents hydrogen production from high-temperature steam electrolysis + using constant nominal specific energy requirements for electricity and heat. It + inherits from the electrolyzer base classes, so it is treated as a hydrogen-producing, + dispatchable technology with an ``electricity_in`` input and a ``hydrogen_out`` output. + + Installed size is inferred from ``n_clusters`` and ``cluster_rating_MW``, and the model + also supports the ``resize_by_max_feedstock`` (from electricity) and + ``resize_by_max_commodity`` (from hydrogen) sizing modes inherited from the resizeable + performance base class. At each timestep the model uses available heat first, supplies + the remaining required energy electrically when possible, and limits hydrogen + production by the combined available energy and the turndown threshold. It also exposes + operating signals useful for coupled systems, including ``heat_demand``, + ``electricity_demand``, ``electricity_consumed``, and ``water_consumed``. + + In the current implementation, ``electricity_demand`` reports installed electrical + demand equal to nameplate size, while ``electricity_consumed`` reports timestep + electricity required by the energy balance. + + The implementation is intentionally simple and should be interpreted as a reduced-order + plant representation, not a detailed SOEC stack model with thermal transients, + degradation coupling, startup dynamics, or detailed balance-of-plant behavior. + """ + + def setup(self) -> None: + self.config = HTSEElectrolyzerPerformanceModelConfig.from_dict( + merge_shared_inputs(self.options["tech_config"]["model_inputs"], "performance"), + strict=False, + additional_cls_name=self.__class__.__name__, + ) + super().setup() + + self.add_output( + "efficiency", + val=0.0, + units="unitless", + desc="Average first-law efficiency based on utilized input energy", + ) + self.add_output( + "time_until_replacement", + val=float(self.config.uptime_hours_until_eol), + units="h", + desc="Operating hours until replacement", + ) + self.add_input( + "n_clusters", + val=self.config.n_clusters, + units="unitless", + desc="Number of HTSE clusters in the system", + ) + self.add_input( + "heat_in", + val=0.0, + shape=self.n_timesteps, + units="kW", + desc="Thermal energy supplied to the HTSE system", + ) + self.add_output( + "electrolyzer_size_mw", + val=0.0, + units="MW", + desc="Installed HTSE nameplate capacity", + ) + self.add_input("cluster_size", val=1.0, units="MW") + self.add_input("max_hydrogen_capacity", val=1000.0, units="kg/h") + + self.add_input( + "water_in", + val=0.0, + shape=self.n_timesteps, + units="galUS/h", + desc="Water supply", + ) + + self.add_output( + "water_consumed", + val=0.0, + shape=self.n_timesteps, + units="galUS/h", + desc="Water consumption", + ) + self.add_output( + "heat_demand", + val=self.config.n_clusters + * self.config.cluster_rating_MW + * 1000 + * self.config.nominal_heat_required + / self.config.nominal_electricity_required, + shape=self.n_timesteps, + units="kW", + desc="Thermal demand by the HTSE system", + ) + self.add_output( + "electricity_demand", + val=0.0, + shape=self.n_timesteps, + units="kW", + desc="Electric demand by the HTSE system", + ) + self.add_output( + "electricity_consumed", + val=0.0, + shape=self.n_timesteps, + units="kW", + desc="Electricity consumed by the HTSE", + ) + + def compute(self, inputs, outputs, discrete_inputs, discrete_outputs): + electrolyzer_size_mw = float(inputs["n_clusters"][0]) * self.config.cluster_rating_MW + + size_mode = discrete_inputs["size_mode"] + if size_mode != "normal": + size_flow = discrete_inputs["flow_used_for_sizing"] + if size_mode == "resize_by_max_feedstock": + feed_ratio = max(float(inputs["max_feedstock_ratio"][0]), 1.0e-6) + if size_flow == "electricity": + electrolyzer_size_mw = np.max(inputs["electricity_in"]) / 1000.0 * feed_ratio + else: + raise ValueError(f"Cannot resize for '{size_flow}' feedstock") + elif size_mode == "resize_by_max_commodity": + comm_ratio = max(float(inputs["max_commodity_ratio"][0]), 1.0e-6) + if size_flow == "hydrogen": + electrolyzer_size_mw = size_electrolyzer_for_hydrogen_demand( + float(inputs["max_hydrogen_capacity"][0]) * comm_ratio + ) + else: + raise ValueError(f"Cannot resize for '{size_flow}' commodity") + else: + raise NotImplementedError(f"Sizing mode '{size_mode}' not implemented") + + n_clusters = inputs["n_clusters"] + electrolyzer_size_mw = n_clusters * self.config.cluster_rating_MW + electrolyzer_size_kw = electrolyzer_size_mw * 1000.0 + + if "system_level_control" in self.options["plant_config"]: + hydrogen_demand = inputs["hydrogen_command_value"] # kg/hr? + else: + hydrogen_demand = ( + electrolyzer_size_kw / self.config.nominal_electricity_required + ) # kW/(kWh/kg) = kg/hr + ratio_heat_elec_nom = ( + self.config.nominal_heat_required / self.config.nominal_electricity_required + ) + + heat_available_kw = inputs["heat_in"] + electricity_available_kw = inputs["electricity_in"] + # hydrogen_demand = inputs["hydrogen_command_value"] + + total_specific_energy = ( + self.config.nominal_heat_required + self.config.nominal_electricity_required + ) + rated_hydrogen_production = electrolyzer_size_kw / self.config.nominal_electricity_required + + # note here that the RATED production is based purely on the electrical requirement. + # The heat input is a bonus amount. Units here are kg/hr + heat_demand_kw = hydrogen_demand * self.config.nominal_heat_required + + actual_heat_kw = np.minimum(heat_demand_kw, heat_available_kw) + electricity_demand_kw = total_specific_energy * hydrogen_demand - actual_heat_kw + ratio_in = heat_available_kw / electricity_available_kw + hydrogen_produced = np.where( + electricity_available_kw < electricity_demand_kw, + np.where( + ratio_in > ratio_heat_elec_nom, + electricity_available_kw / self.config.nominal_electricity_required, + (heat_available_kw + electricity_available_kw) / total_specific_energy, + ), + (actual_heat_kw + electricity_demand_kw) / total_specific_energy, + ) + + actual_heat_kw / ratio_heat_elec_nom + + # in this case, the electricity is insufficient compared to the heat, so we'll use + # actual_electricity_kw = np.minimum(electricity_demand_kw, electricity_available_kw) + min_turn_down = self.config.turndown_ratio * rated_hydrogen_production + hydrogen_produced = np.where(hydrogen_produced >= min_turn_down, hydrogen_produced, 0.0) + + # Density of liquid water at 20°C (293.15 K) and 1 atm (101325 Pa) + PropsSI("D", "T", 293.15, "P", 101325, "Water") + kg_per_liter_water = 1.0 + water_demand_kg_per_h = hydrogen_produced * 18.015 / 2.016 + liters_per_galUS = 3.785411 + water_demand_gal_per_h = ( + water_demand_kg_per_h * (1.0 / kg_per_liter_water) * (1.0 / liters_per_galUS) + ) + + # heat_demand_kw = hydrogen_out * self.config.nominal_heat_required + # electricity_demand_kw = hydrogen_out * total_specific_energy - actual_heat_kw + # electricity_demand_kw = np.minimum(electricity_demand_kw, electricity_available_kw) + outputs["electricity_consumed"] = electricity_demand_kw + outputs["hydrogen_out"] = hydrogen_produced + # outputs["heat_demand"] = np.minimum(rated_hydrogen_production, + # inputs["hydrogen_command_value"]) * self.config.nominal_heat_required + outputs["heat_demand"] = hydrogen_demand * self.config.nominal_heat_required + outputs["electricity_demand"] = electrolyzer_size_kw + outputs["water_consumed"] = water_demand_gal_per_h + outputs["rated_hydrogen_production"] = rated_hydrogen_production + outputs["electrolyzer_size_mw"] = electrolyzer_size_mw + + total_hydrogen_produced = np.sum(hydrogen_produced) * (self.dt / 3600.0) + outputs["total_hydrogen_produced"] = total_hydrogen_produced + annual_hydrogen = total_hydrogen_produced / self.fraction_of_year_simulated + outputs["annual_hydrogen_produced"] = np.full(self.plant_life, annual_hydrogen) + + max_production = rated_hydrogen_production * self.n_timesteps * (self.dt / 3600.0) + capacity_factor = total_hydrogen_produced / max_production if max_production > 0 else 0.0 + outputs["capacity_factor"] = np.full(self.plant_life, capacity_factor) + + utilized_input_kw = actual_heat_kw + electricity_demand_kw + available_input_kw = heat_available_kw + electricity_available_kw + with np.errstate(divide="ignore", invalid="ignore"): + timestep_efficiency = np.divide( + utilized_input_kw, + available_input_kw, + out=np.zeros_like(utilized_input_kw), + where=available_input_kw > 0, + ) + outputs["efficiency"] = float(np.mean(timestep_efficiency)) + + refurb_schedule = np.zeros(self.plant_life) + refurb_period = max(1, round(self.config.uptime_hours_until_eol / 8760)) + refurb_schedule[refurb_period : self.plant_life : refurb_period] = 1.0 + outputs["replacement_schedule"] = refurb_schedule + outputs["time_until_replacement"] = float(self.config.uptime_hours_until_eol) + + +@define(kw_only=True) +class HTSECostModelConfig(CostModelBaseConfig): + """Configuration class for the HTSE cost model. + + Args: + unit_capex (float): Installed capital cost per kW of HTSE electrical size in USD/kW. + fixed_opex (float, optional): Fixed annual operating cost per kW in USD/(kW*year). + If omitted, it is populated from ``fixed_capex`` (or ``0.0`` when that is also + omitted). + fixed_capex (float, optional): Fallback value used to populate ``fixed_opex`` when + ``fixed_opex`` is not provided. + cost_year (int): Dollar year corresponding to the input costs. Defaults to ``2025``. + """ + + unit_capex: float = field(validator=gt_zero) + fixed_opex: float | None = field(default=None) + fixed_capex: float | None = field(default=None) + cost_year: int = field(default=2025, converter=int) + + def __attrs_post_init__(self) -> None: + if self.fixed_opex is None: + self.fixed_opex = 0.0 if self.fixed_capex is None else float(self.fixed_capex) + + +class HTSECostModel(ElectrolyzerCostBaseClass): + """A simple size-based cost model for HTSE. + + The model computes installed capital cost and fixed operating cost from the installed + HTSE electrical size reported by the performance model: + + - ``CapEx`` from ``unit_capex * electrolyzer_size_kw`` + - ``OpEx`` from ``fixed_opex * electrolyzer_size_kw`` + + The current model does not set a nonzero variable operating cost. + """ + + def setup(self) -> None: + self.config = HTSECostModelConfig.from_dict( + merge_shared_inputs(self.options["tech_config"]["model_inputs"], "cost"), + strict=False, + additional_cls_name=self.__class__.__name__, + ) + super().setup() + + self.add_input( + "electrolyzer_size_mw", + val=0.0, + units="MW", + desc="Installed HTSE nameplate capacity", + ) + + def compute(self, inputs, outputs, discrete_inputs, discrete_outputs): + electrolyzer_size_kw = float(inputs["electrolyzer_size_mw"][0]) * 1000.0 + outputs["CapEx"] = self.config.unit_capex * electrolyzer_size_kw + outputs["OpEx"] = self.config.fixed_opex * electrolyzer_size_kw diff --git a/h2integrate/converters/hydrogen/test/test_htse_electrolyzer.py b/h2integrate/converters/hydrogen/test/test_htse_electrolyzer.py new file mode 100644 index 000000000..eb1ed17df --- /dev/null +++ b/h2integrate/converters/hydrogen/test/test_htse_electrolyzer.py @@ -0,0 +1,242 @@ +import numpy as np +import pytest +import openmdao.api as om +from pytest import fixture + +from h2integrate.converters.hydrogen.htse_electrolyzer import HTSECostModel, HTSEPerformanceModel + + +@fixture +def plant_config(): + return { + "plant": { + "plant_life": 30, + "simulation": { + "n_timesteps": 8760, + "dt": 3600, + }, + }, + } + + +@fixture +def htse_performance_params(): + return { + "n_clusters": 25, + "cluster_rating_MW": 1.0, + "nominal_heat_required": 6.4, + "nominal_electricity_required": 36.8, + "turndown_ratio": 0.1, + "uptime_hours_until_eol": 35040, + } + + +@fixture +def htse_cost_params(): + return { + "unit_capex": 1417.0, + "cost_year": 2022, + } + + +def _build_performance_problem(plant_config, performance_params): + tech_config_dict = { + "model_inputs": { + "performance_parameters": performance_params, + } + } + + prob = om.Problem() + perf_comp = HTSEPerformanceModel( + plant_config=plant_config, + tech_config=tech_config_dict, + driver_config={}, + ) + prob.model.add_subsystem("htse_perf", perf_comp, promotes=["*"]) + prob.setup() + return prob + + +@pytest.mark.unit +def test_htse_performance_full_production(plant_config, htse_performance_params, subtests): + n_timesteps = plant_config["plant"]["simulation"]["n_timesteps"] + nom_elec = htse_performance_params["nominal_electricity_required"] + nom_heat = htse_performance_params["nominal_heat_required"] + + electrolyzer_size_kw = ( + htse_performance_params["n_clusters"] + * htse_performance_params["cluster_rating_MW"] + * 1000.0 + ) + rated_hydrogen_production = electrolyzer_size_kw / nom_elec + + # Supply exactly the heat and electricity demanded so the model runs at rated production + heat_demand_kw = rated_hydrogen_production * nom_heat + electricity_demand_kw = electrolyzer_size_kw + + prob = _build_performance_problem(plant_config, htse_performance_params) + prob.set_val("heat_in", np.full(n_timesteps, heat_demand_kw), units="kW") + prob.set_val("electricity_in", np.full(n_timesteps, electricity_demand_kw), units="kW") + prob.run_model() + + hydrogen_out = prob.get_val("hydrogen_out", units="kg/h") + + with subtests.test("Hydrogen produced at rated capacity"): + assert pytest.approx(hydrogen_out, rel=1e-6) == np.full( + n_timesteps, rated_hydrogen_production + ) + + with subtests.test("Rated hydrogen production reported"): + assert pytest.approx(prob.get_val("rated_hydrogen_production", units="kg/h")[0]) == ( + rated_hydrogen_production + ) + + with subtests.test("Installed HTSE size reported"): + assert pytest.approx(prob.get_val("electrolyzer_size_mw", units="MW")[0]) == 25.0 + + with subtests.test("Electricity demand equals installed electrical size"): + assert pytest.approx(prob.get_val("electricity_demand", units="kW")) == ( + np.full(n_timesteps, electrolyzer_size_kw) + ) + + with subtests.test("Heat demand based on hydrogen demand"): + assert pytest.approx(prob.get_val("heat_demand", units="kW")) == ( + np.full(n_timesteps, heat_demand_kw) + ) + + with subtests.test("Capacity factor is one at full production"): + assert pytest.approx(prob.get_val("capacity_factor")) == np.ones( + plant_config["plant"]["plant_life"] + ) + + with subtests.test("Efficiency is one when input matches demand"): + assert pytest.approx(prob.get_val("efficiency")[0], rel=1e-6) == 1.0 + + with subtests.test("Water consumption follows stoichiometry"): + expected_water_gal = rated_hydrogen_production * (18.015 / 2.016) / 3.785411 + assert pytest.approx(prob.get_val("water_consumed", units="galUS/h"), rel=1e-6) == ( + np.full(n_timesteps, expected_water_gal) + ) + + with subtests.test("Annual hydrogen production"): + assert pytest.approx(prob.get_val("annual_hydrogen_produced", units="kg/year")) == np.full( + plant_config["plant"]["plant_life"], rated_hydrogen_production * n_timesteps + ) + + +@pytest.mark.unit +def test_htse_performance_turndown_shutoff(plant_config, htse_performance_params, subtests): + n_timesteps = plant_config["plant"]["simulation"]["n_timesteps"] + + prob = _build_performance_problem(plant_config, htse_performance_params) + # Provide electricity well below the turndown threshold and no heat + prob.set_val("heat_in", np.zeros(n_timesteps), units="kW") + prob.set_val("electricity_in", np.full(n_timesteps, 100.0), units="kW") + prob.run_model() + + with subtests.test("Hydrogen production is zero below turndown"): + assert pytest.approx(prob.get_val("hydrogen_out", units="kg/h")) == np.zeros(n_timesteps) + + with subtests.test("Total hydrogen produced is zero"): + assert prob.get_val("total_hydrogen_produced", units="kg")[0] == pytest.approx(0.0) + + with subtests.test("Capacity factor is zero"): + assert pytest.approx(prob.get_val("capacity_factor")) == np.zeros( + plant_config["plant"]["plant_life"] + ) + + +@pytest.mark.unit +def test_htse_cost_model(plant_config, htse_cost_params, subtests): + tech_config_dict = { + "model_inputs": { + "cost_parameters": htse_cost_params, + } + } + + electrolyzer_size_mw = 25.0 + electrolyzer_size_kw = electrolyzer_size_mw * 1000.0 + + prob = om.Problem() + cost_comp = HTSECostModel( + plant_config=plant_config, + tech_config=tech_config_dict, + driver_config={}, + ) + prob.model.add_subsystem("htse_cost", cost_comp, promotes=["*"]) + prob.setup() + + prob.set_val("electrolyzer_size_mw", electrolyzer_size_mw, units="MW") + prob.run_model() + + with subtests.test("Capital cost scales with installed size"): + expected_capex = htse_cost_params["unit_capex"] * electrolyzer_size_kw + assert pytest.approx(prob.get_val("CapEx", units="USD")[0], rel=1e-6) == expected_capex + + with subtests.test("Operating cost defaults to zero when fixed_opex omitted"): + assert prob.get_val("OpEx", units="USD/year")[0] == pytest.approx(0.0) + + with subtests.test("Cost year is reported"): + assert prob.get_val("cost_year") == htse_cost_params["cost_year"] + + +@pytest.mark.unit +def test_htse_cost_model_fixed_opex(plant_config, subtests): + electrolyzer_size_mw = 25.0 + electrolyzer_size_kw = electrolyzer_size_mw * 1000.0 + + tech_config_dict = { + "model_inputs": { + "cost_parameters": { + "unit_capex": 1417.0, + "fixed_opex": 10.0, + }, + } + } + + prob = om.Problem() + cost_comp = HTSECostModel( + plant_config=plant_config, + tech_config=tech_config_dict, + driver_config={}, + ) + prob.model.add_subsystem("htse_cost", cost_comp, promotes=["*"]) + prob.setup() + prob.set_val("electrolyzer_size_mw", electrolyzer_size_mw, units="MW") + prob.run_model() + + with subtests.test("Operating cost uses provided fixed_opex"): + assert pytest.approx(prob.get_val("OpEx", units="USD/year")[0], rel=1e-6) == ( + 10.0 * electrolyzer_size_kw + ) + + +@pytest.mark.unit +def test_htse_cost_model_fixed_capex_fallback(plant_config, subtests): + electrolyzer_size_mw = 25.0 + electrolyzer_size_kw = electrolyzer_size_mw * 1000.0 + + tech_config_dict = { + "model_inputs": { + "cost_parameters": { + "unit_capex": 1417.0, + "fixed_capex": 5.0, + }, + } + } + + prob = om.Problem() + cost_comp = HTSECostModel( + plant_config=plant_config, + tech_config=tech_config_dict, + driver_config={}, + ) + prob.model.add_subsystem("htse_cost", cost_comp, promotes=["*"]) + prob.setup() + prob.set_val("electrolyzer_size_mw", electrolyzer_size_mw, units="MW") + prob.run_model() + + with subtests.test("fixed_capex populates fixed_opex when fixed_opex omitted"): + assert pytest.approx(prob.get_val("OpEx", units="USD/year")[0], rel=1e-6) == ( + 5.0 * electrolyzer_size_kw + ) diff --git a/h2integrate/converters/nuclear/__init__.py b/h2integrate/converters/nuclear/__init__.py index 3bab04d7e..409ebc15f 100644 --- a/h2integrate/converters/nuclear/__init__.py +++ b/h2integrate/converters/nuclear/__init__.py @@ -2,3 +2,7 @@ QuinnNuclearPerformanceModel, QuinnNuclearCostModel, ) +from h2integrate.converters.nuclear.nuclear_plant_thermal import ( + SimpleThermalNuclearReactorPerformanceModel, + SimpleThermalNuclearReactorCostModel, +) diff --git a/h2integrate/converters/nuclear/nuclear_plant_thermal.py b/h2integrate/converters/nuclear/nuclear_plant_thermal.py new file mode 100644 index 000000000..df9a2e414 --- /dev/null +++ b/h2integrate/converters/nuclear/nuclear_plant_thermal.py @@ -0,0 +1,270 @@ +import numpy as np +from attrs import field, define + +from h2integrate.core.utilities import BaseConfig, merge_shared_inputs +from h2integrate.core.validators import gt_zero, contains +from h2integrate.core.model_baseclasses import ( + CostModelBaseClass, + CostModelBaseConfig, + PerformanceModelBaseClass, +) + + +@define(kw_only=True) +class SimpleThermalNuclearReactorConfig(BaseConfig): + """Configuration class for the thermal nuclear reactor performance model. + + Args: + operating_mode (str): Dispatch mode of the reactor. Must be ``"heat"`` or + ``"electricity"``. In ``heat`` mode the reactor satisfies process heat demand + first and converts the remaining low-pressure heat to electricity; in + ``electricity`` mode it satisfies the electricity command first and delivers + the remaining available heat. + electricity_command_value (float): Requested electrical output in kW. + high_pressure_electrical_efficiency (float): Fraction of total thermal input + converted to electricity in the high-pressure stage (unitless). + low_pressure_electrical_efficiency (float): Efficiency applied to the remaining + low-pressure heat when generating electricity (unitless). + rated_capacity (float): Rated electrical capacity in kW, used to infer the reactor + thermal capacity. + minimum_heat_extract (float): Minimum process heat reserved for extraction in kW. + Defaults to ``0.0``. + """ + + operating_mode: str = field(validator=contains(["heat", "electricity"])) + electricity_command_value: float = field(validator=gt_zero) + high_pressure_electrical_efficiency: float = field(validator=gt_zero) + low_pressure_electrical_efficiency: float = field(validator=gt_zero) + rated_capacity: float = field(validator=gt_zero) + minimum_heat_extract: float = field(default=0.0) + + +class SimpleThermalNuclearReactorPerformanceModel(PerformanceModelBaseClass): + """Simple thermal nuclear reactor model with heat and electricity outputs. + + This model represents a reactor with a high-pressure electric conversion stage, a + low-pressure electric conversion stage, and an extractable process heat stream taken + upstream of the low-pressure turbine stages. It trades off electricity production and + process heat delivery according to the selected operating mode, making it suitable for + coupled workflows such as nuclear plus HTSE. + + The reactor infers its thermal capacity from the rated electrical capacity using a + combined electric efficiency and supports two operating modes: + + - ``heat``: satisfy heat demand first, then convert the remaining low-pressure heat to + electricity. + - ``electricity``: satisfy the electricity command first, then send the remaining + available process heat to ``heat_out``. + """ + + _time_step_bounds = (3600, 3600) + + def initialize(self) -> None: + super().initialize() + self.commodity = "electricity" + self.commodity_rate_units = "kW" + self.commodity_amount_units = "kW*h" + + def setup(self): + self.config = SimpleThermalNuclearReactorConfig.from_dict( + merge_shared_inputs(self.options["tech_config"]["model_inputs"], "performance"), + strict=False, + additional_cls_name=self.__class__.__name__, + ) + super().setup() + + self.add_discrete_input("operating_mode", val=self.config.operating_mode) + self.add_input( + f"{self.commodity}_command_value", + val=self.config.electricity_command_value, + shape=self.n_timesteps, + units=self.commodity_rate_units, + desc="Requested electric power setpoint", + ) + self.add_input( + "rated_capacity", + val=self.config.rated_capacity, + units=self.commodity_rate_units, + desc="Available reactor thermal capacity", + ) + self.add_input( + "high_pressure_electrical_efficiency", + val=self.config.high_pressure_electrical_efficiency, + units="unitless", + ) + self.add_input( + "low_pressure_electrical_efficiency", + val=self.config.low_pressure_electrical_efficiency, + units="unitless", + ) + self.add_input( + "minimum_heat_extract", + val=self.config.minimum_heat_extract, + units="kW", + desc="Minimum thermal output reserved for process heat extraction", + ) + self.add_input( + "heat_command_value", + val=6400, + shape=self.n_timesteps, + units="kW", + desc="Requested process heat demand from downstream technologies", + ) + + self.add_output("high_pressure_heat_demanded", val=0.0, shape=self.n_timesteps, units="kW") + self.add_output("high_pressure_heat", val=0.0, shape=self.n_timesteps, units="kW") + self.add_output("low_pressure_heat", val=0.0, shape=self.n_timesteps, units="kW") + self.add_output("heat_out", val=0.0, shape=self.n_timesteps, units="kW") + + def compute(self, inputs, outputs, discrete_inputs, discrete_outputs): + operating_mode = discrete_inputs["operating_mode"] + hp_eff = float(inputs["high_pressure_electrical_efficiency"][0]) + lp_eff = float(inputs["low_pressure_electrical_efficiency"][0]) + electric_capacity_mw = float(inputs["rated_capacity"][0]) * 1e-3 # convert kW to MW + minimum_heat_extract_kw = np.maximum( + inputs["minimum_heat_extract"], 0.0 + ) # maintain kW rating + requested_power_mw = ( + np.maximum(inputs["electricity_command_value"], 0.0) * 1e-3 + ) # convert kW to MW, fix >0 + external_heat_demand_kw = np.maximum( + inputs["heat_command_value"], 0.0 + ) # maintaining kW rating + + combined_efficiency = hp_eff + (1.0 - hp_eff) * lp_eff + if combined_efficiency <= 0.0: + raise ValueError("Combined nuclear electric efficiency must be greater than zero") + if lp_eff <= 0.0: + raise ValueError("Low-pressure electrical efficiency must be greater than zero") + + thermal_capacity_mw = electric_capacity_mw / combined_efficiency + high_pressure_electricity_mw = thermal_capacity_mw * hp_eff + available_process_heat_mw = thermal_capacity_mw * (1.0 - hp_eff) + heat_demand_mw = ( + np.maximum(external_heat_demand_kw, minimum_heat_extract_kw) * 1e-3 + ) # convert to MW from kW + + if operating_mode == "heat": + heat_out_mw = np.minimum(heat_demand_mw, available_process_heat_mw) + electricity_out_mw = ( + high_pressure_electricity_mw + (available_process_heat_mw - heat_out_mw) * lp_eff + ) + elif operating_mode == "electricity": + electricity_out_mw = np.minimum(requested_power_mw, electric_capacity_mw) + heat_out_mw = ( + available_process_heat_mw + - (electricity_out_mw - high_pressure_electricity_mw) / lp_eff + ) + heat_out_mw = np.clip(heat_out_mw, 0.0, available_process_heat_mw) + else: + raise NotImplementedError( + "The nuclear operating_mode must be either 'heat' or 'electricity'" + ) + + electricity_out_mw = np.clip(electricity_out_mw, 0.0, electric_capacity_mw) + low_pressure_heat_remaining_mw = available_process_heat_mw - heat_out_mw + + high_pressure_heat_kw = np.full(self.n_timesteps, available_process_heat_mw * 1000.0) + low_pressure_heat_kw = low_pressure_heat_remaining_mw * 1000.0 + electricity_out_kw = electricity_out_mw * 1000.0 + heat_out_kw = heat_out_mw * 1000.0 + + outputs["high_pressure_heat_demanded"] = heat_demand_mw * 1000.0 + outputs["high_pressure_heat"] = high_pressure_heat_kw + outputs["low_pressure_heat"] = low_pressure_heat_kw + outputs["heat_out"] = heat_out_kw + outputs["electricity_out"] = electricity_out_kw + outputs["rated_electricity_production"] = electric_capacity_mw * 1000.0 + + total_electricity = np.sum(electricity_out_kw) * (self.dt / 3600.0) + outputs["total_electricity_produced"] = total_electricity + annual_electricity = total_electricity / self.fraction_of_year_simulated + outputs["annual_electricity_produced"] = np.full(self.plant_life, annual_electricity) + + avg_electricity_out_mw = float(np.mean(electricity_out_mw)) + capacity_factor = ( + avg_electricity_out_mw / electric_capacity_mw if electric_capacity_mw > 0.0 else 0.0 + ) + outputs["capacity_factor"] = np.full(self.plant_life, capacity_factor) + outputs["replacement_schedule"] = np.zeros(self.plant_life) + + +@define(kw_only=True) +class SimpleThermalNuclearReactorCostConfig(CostModelBaseConfig): + """Configuration class for the thermal nuclear reactor cost model. + + Args: + rated_capacity (float): Rated capacity used for cost calculations in kW. + nuclear_reactor_upfront_cost (float): Capital cost per kW in USD/kW. + nuclear_reactor_fixed_om_cost (float): Fixed annual O&M in USD/(kW*year). + nuclear_reactor_variable_om_cost (float): Variable O&M applied to the simulated + electricity production in USD/(kW*h). + cost_year (int): Dollar year corresponding to the input costs. Defaults to ``2025``. + """ + + rated_capacity: float = field(validator=gt_zero) + nuclear_reactor_upfront_cost: float = field(validator=gt_zero) + nuclear_reactor_fixed_om_cost: float = field(validator=gt_zero) + nuclear_reactor_variable_om_cost: float = field(validator=gt_zero) + cost_year: int = field(default=2025, converter=int) + + +class SimpleThermalNuclearReactorCostModel(CostModelBaseClass): + """Simple cost model for the thermal nuclear reactor. + + The model applies capacity-based capital and fixed O&M costs and computes variable O&M + from the delivered electricity: + + - ``CapEx`` from ``rated_capacity * nuclear_reactor_upfront_cost`` + - ``OpEx`` from ``rated_capacity * nuclear_reactor_fixed_om_cost`` + - ``VarOpEx`` from ``nuclear_reactor_variable_om_cost`` applied to the simulated + electricity output, repeated across the plant life. + """ + + _time_step_bounds = (3600, 3600) + + def setup(self) -> None: + self.dt = self.options["plant_config"]["plant"]["simulation"]["dt"] + self.plant_life = int(self.options["plant_config"]["plant"]["plant_life"]) + n_timesteps = int(self.options["plant_config"]["plant"]["simulation"]["n_timesteps"]) + self.config = SimpleThermalNuclearReactorCostConfig.from_dict( + merge_shared_inputs(self.options["tech_config"]["model_inputs"], "cost"), + strict=False, + additional_cls_name=self.__class__.__name__, + ) + super().setup() + + self.add_input( + "rated_capacity", + val=self.config.rated_capacity, + units="kW", + ) + self.add_input( + "nuclear_reactor_upfront_cost", + val=self.config.nuclear_reactor_upfront_cost, + units="USD/kW", + ) + self.add_input( + "nuclear_reactor_fixed_om_cost", + val=self.config.nuclear_reactor_fixed_om_cost, + units="USD/(kW*year)", + ) + self.add_input( + "nuclear_reactor_variable_om_cost", + val=self.config.nuclear_reactor_variable_om_cost, + units="USD/(kW*h)", + ) + self.add_input("electricity_out", val=0.0, shape=n_timesteps, units="kW") + + def compute(self, inputs, outputs, discrete_inputs, discrete_outputs): + rated_capacity_kw = float(inputs["rated_capacity"][0]) + upfront_cost_per_kw = float(inputs["nuclear_reactor_upfront_cost"][0]) + fixed_om_per_kw_year = float(inputs["nuclear_reactor_fixed_om_cost"][0]) + variable_om_per_kwh = float(inputs["nuclear_reactor_variable_om_cost"][0]) + + outputs["CapEx"] = rated_capacity_kw * upfront_cost_per_kw + outputs["OpEx"] = fixed_om_per_kw_year * rated_capacity_kw + + delivered_electricity_kwh = np.sum(inputs["electricity_out"]) * (self.dt / 3600.0) + annual_variable_om = variable_om_per_kwh * delivered_electricity_kwh + outputs["VarOpEx"] = np.full(self.plant_life, annual_variable_om) diff --git a/h2integrate/converters/nuclear/test/test_nuclear_plant_thermal.py b/h2integrate/converters/nuclear/test/test_nuclear_plant_thermal.py new file mode 100644 index 000000000..05898741e --- /dev/null +++ b/h2integrate/converters/nuclear/test/test_nuclear_plant_thermal.py @@ -0,0 +1,223 @@ +import numpy as np +import pytest +import openmdao.api as om +from pytest import fixture + +from h2integrate.converters.nuclear.nuclear_plant_thermal import ( + SimpleThermalNuclearReactorCostModel, + SimpleThermalNuclearReactorPerformanceModel, +) + + +@fixture +def plant_config(): + return { + "plant": { + "plant_life": 30, + "simulation": { + "n_timesteps": 8760, + "dt": 3600, + }, + }, + } + + +@fixture +def thermal_performance_params(): + return { + "operating_mode": "heat", + "electricity_command_value": 500000.0, + "high_pressure_electrical_efficiency": 0.2, + "low_pressure_electrical_efficiency": 0.5, + "rated_capacity": 600000.0, + "minimum_heat_extract": 0.0, + } + + +@fixture +def thermal_cost_params(): + return { + "rated_capacity": 600000.0, + "nuclear_reactor_upfront_cost": 5750.0, + "nuclear_reactor_fixed_om_cost": 2.64, + "nuclear_reactor_variable_om_cost": 0.0145, + "cost_year": 2022, + } + + +def _build_performance_problem(plant_config, performance_params): + tech_config_dict = { + "model_inputs": { + "performance_parameters": performance_params, + } + } + + prob = om.Problem() + perf_comp = SimpleThermalNuclearReactorPerformanceModel( + plant_config=plant_config, + tech_config=tech_config_dict, + driver_config={}, + ) + prob.model.add_subsystem("nuc_thermal_perf", perf_comp, promotes=["*"]) + prob.setup() + return prob + + +@pytest.mark.unit +def test_thermal_performance_heat_mode(plant_config, thermal_performance_params, subtests): + n_timesteps = plant_config["plant"]["simulation"]["n_timesteps"] + plant_life = plant_config["plant"]["plant_life"] + + prob = _build_performance_problem(plant_config, thermal_performance_params) + prob.set_val("heat_command_value", np.full(n_timesteps, 400000.0), units="kW") + prob.run_model() + + # thermal_capacity = 600 / (0.2 + 0.8 * 0.5) = 1000 MW + # available process heat = 1000 * 0.8 = 800 MW + # heat_out = min(400, 800) = 400 MW + # electricity_out = 200 (HP) + (800 - 400) * 0.5 = 400 MW + with subtests.test("Delivered process heat matches demand"): + assert pytest.approx(prob.get_val("heat_out", units="kW")) == np.full(n_timesteps, 400000.0) + + with subtests.test("Electricity output in heat mode"): + assert pytest.approx(prob.get_val("electricity_out", units="kW")) == ( + np.full(n_timesteps, 400000.0) + ) + + with subtests.test("High-pressure heat stream"): + assert pytest.approx(prob.get_val("high_pressure_heat", units="kW")) == ( + np.full(n_timesteps, 800000.0) + ) + + with subtests.test("Low-pressure heat remaining"): + assert pytest.approx(prob.get_val("low_pressure_heat", units="kW")) == ( + np.full(n_timesteps, 400000.0) + ) + + with subtests.test("Thermal split is conserved"): + hp_heat = prob.get_val("high_pressure_heat", units="kW") + lp_heat = prob.get_val("low_pressure_heat", units="kW") + heat_out = prob.get_val("heat_out", units="kW") + assert np.allclose(hp_heat, lp_heat + heat_out, rtol=1e-6) + + with subtests.test("Rated electricity production"): + assert ( + pytest.approx(prob.get_val("rated_electricity_production", units="kW")[0]) == 600000.0 + ) + + with subtests.test("Capacity factor in heat mode"): + assert pytest.approx(prob.get_val("capacity_factor"), rel=1e-6) == np.full( + plant_life, 400.0 / 600.0 + ) + + with subtests.test("Annual electricity production"): + assert pytest.approx( + prob.get_val("annual_electricity_produced", units="kW*h/year") + ) == np.full(plant_life, 400000.0 * n_timesteps) + + +@pytest.mark.unit +def test_thermal_performance_electricity_mode(plant_config, thermal_performance_params, subtests): + n_timesteps = plant_config["plant"]["simulation"]["n_timesteps"] + plant_life = plant_config["plant"]["plant_life"] + + performance_params = dict(thermal_performance_params) + performance_params["operating_mode"] = "electricity" + + prob = _build_performance_problem(plant_config, performance_params) + prob.set_val("electricity_command_value", np.full(n_timesteps, 500000.0), units="kW") + prob.run_model() + + # electricity_out = min(500, 600) = 500 MW + # heat_out = 800 - (500 - 200) / 0.5 = 200 MW + with subtests.test("Electricity output tracks command"): + assert pytest.approx(prob.get_val("electricity_out", units="kW")) == ( + np.full(n_timesteps, 500000.0) + ) + + with subtests.test("Process heat after electricity dispatch"): + assert pytest.approx(prob.get_val("heat_out", units="kW")) == np.full(n_timesteps, 200000.0) + + with subtests.test("Thermal split is conserved"): + hp_heat = prob.get_val("high_pressure_heat", units="kW") + lp_heat = prob.get_val("low_pressure_heat", units="kW") + heat_out = prob.get_val("heat_out", units="kW") + assert np.allclose(hp_heat, lp_heat + heat_out, rtol=1e-6) + + with subtests.test("Capacity factor in electricity mode"): + assert pytest.approx(prob.get_val("capacity_factor"), rel=1e-6) == np.full( + plant_life, 500.0 / 600.0 + ) + + +@pytest.mark.unit +def test_thermal_performance_electricity_capped_at_capacity( + plant_config, thermal_performance_params, subtests +): + n_timesteps = plant_config["plant"]["simulation"]["n_timesteps"] + + performance_params = dict(thermal_performance_params) + performance_params["operating_mode"] = "electricity" + + prob = _build_performance_problem(plant_config, performance_params) + # Command more than the rated electrical capacity (600 MW) + prob.set_val("electricity_command_value", np.full(n_timesteps, 900000.0), units="kW") + prob.run_model() + + with subtests.test("Electricity output clipped to rated capacity"): + assert pytest.approx(prob.get_val("electricity_out", units="kW")) == ( + np.full(n_timesteps, 600000.0) + ) + + +@pytest.mark.unit +def test_thermal_cost_model(plant_config, thermal_cost_params, subtests): + n_timesteps = plant_config["plant"]["simulation"]["n_timesteps"] + plant_life = plant_config["plant"]["plant_life"] + + tech_config_dict = { + "model_inputs": { + "cost_parameters": thermal_cost_params, + } + } + + electricity_out = np.full(n_timesteps, 400000.0) + + prob = om.Problem() + cost_comp = SimpleThermalNuclearReactorCostModel( + plant_config=plant_config, + tech_config=tech_config_dict, + driver_config={}, + ) + prob.model.add_subsystem("nuc_thermal_cost", cost_comp, promotes=["*"]) + prob.setup() + + prob.set_val("electricity_out", electricity_out, units="kW") + prob.run_model() + + rated_capacity_kw = thermal_cost_params["rated_capacity"] + upfront_cost_per_kw = thermal_cost_params["nuclear_reactor_upfront_cost"] + fixed_om_per_kw_year = thermal_cost_params["nuclear_reactor_fixed_om_cost"] + variable_om_per_kwh = thermal_cost_params["nuclear_reactor_variable_om_cost"] + + dt = plant_config["plant"]["simulation"]["dt"] + delivered_electricity_kwh = electricity_out.sum() * (dt / 3600.0) + + with subtests.test("Thermal reactor capital cost"): + assert pytest.approx(prob.get_val("CapEx", units="USD")[0], rel=1e-6) == ( + rated_capacity_kw * upfront_cost_per_kw + ) + + with subtests.test("Thermal reactor fixed operating cost"): + assert pytest.approx(prob.get_val("OpEx", units="USD/year")[0], rel=1e-6) == ( + fixed_om_per_kw_year * rated_capacity_kw + ) + + with subtests.test("Thermal reactor variable operating cost"): + expected_varopex = variable_om_per_kwh * delivered_electricity_kwh + assert pytest.approx(prob.get_val("VarOpEx", units="USD/year"), rel=1e-6) == np.full( + plant_life, expected_varopex + ) + + with subtests.test("Thermal reactor cost year"): + assert prob.get_val("cost_year") == thermal_cost_params["cost_year"] diff --git a/h2integrate/core/supported_models.py b/h2integrate/core/supported_models.py index f9e43ce89..51fa624bd 100644 --- a/h2integrate/core/supported_models.py +++ b/h2integrate/core/supported_models.py @@ -75,6 +75,8 @@ def copy(self): "RunOfRiverHydroPerformanceModel": "converters.water_power:RunOfRiverHydroPerformanceModel", "RunOfRiverHydroCostModel": "converters.water_power:RunOfRiverHydroCostModel", "ECOElectrolyzerPerformanceModel": "converters.hydrogen:ECOElectrolyzerPerformanceModel", + "HTSEPerformanceModel": "converters.hydrogen:HTSEPerformanceModel", + "HTSECostModel": "converters.hydrogen:HTSECostModel", "SingliticoCostModel": "converters.hydrogen:SingliticoCostModel", "BasicElectrolyzerCostModel": "converters.hydrogen:BasicElectrolyzerCostModel", "CustomElectrolyzerCostModel": "converters.hydrogen:CustomElectrolyzerCostModel", @@ -128,6 +130,8 @@ def copy(self): "NaturalGasPerformanceModel": "converters.natural_gas:NaturalGasPerformanceModel", "QuinnNuclearPerformanceModel": "converters.nuclear:QuinnNuclearPerformanceModel", "QuinnNuclearCostModel": "converters.nuclear:QuinnNuclearCostModel", + "SimpleThermalNuclearReactorCostModel": "converters.nuclear:SimpleThermalNuclearReactorCostModel", + "SimpleThermalNuclearReactorPerformanceModel": "converters.nuclear:SimpleThermalNuclearReactorPerformanceModel", "NaturalGasCostModel": "converters.natural_gas:NaturalGasCostModel", # Transport "cable": "transporters:CablePerformanceModel", @@ -188,12 +192,10 @@ def copy(self): } ) - # This next section is to demarcate specific models that belong to certain categories that are # relevant for processing in the model stackup. Right now, these designations are # used in `h2integrate_model.py`. - # Model classes that do not contribute costs to the finance stackup because they are essentially # internal-only models that aren't categorized as a specific technology (e.g. a generic combiner # or splitter, or a model that is only used for performance modeling within another model and