-
Notifications
You must be signed in to change notification settings - Fork 41
Nuclear with thermal connection with HTSE #807
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
425d958
3d0af8e
902d1ee
6c8dd2a
3831202
5d148ee
13f00c2
7df8f82
9978339
fee9c51
6c4bd73
e123155
8c0d981
89c72e6
bcbbab0
520ff99
aee36a3
e254417
d3bdb24
a10669f
d357dca
5b7b812
6d6011a
cd7ec70
8bdbbe3
bba9f26
183b45e
0082741
f6829b4
4c5f108
f459eff
c7219b2
1cc6659
8f6e544
fbf293f
90378d8
d3580f9
ccb37ef
972519d
943bd3d
843f154
16f3780
c96ee17
2deb7c7
32b4647
6043d37
693c943
ec08b10
272ecf0
a084eb7
7252335
5ce232a
c2c49d2
f99290f
222e3cd
1247935
fbe572b
799f3aa
c425b65
4c5283d
b9ae46c
3147f2a
ef4a7c1
1751b8d
580ebdb
e1e52a2
a330d0c
79f3421
4c3344b
b0a0ede
cc247a7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -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: | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| $$ | ||||||
| \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 | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Specific energy has certain meaning in some contexts, like energy per mass (energy density). Is that the expected meaning here? If not, I'd suggest a different phrase, like |
||||||
| $$ | ||||||
|
|
||||||
| 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. | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For those unfamiliar with |
||||||
| ``` | ||||||
|
|
||||||
| ### 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: | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| - 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). | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be nice to have the pump and heat exchanger labeled for those not as familiar with the setup.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Label the heat exchanger? Also, what does the red dashed line represent?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. I also made a note in the doc page that the red dashed arrow represents the heat extraction (upstream of the LPT). |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -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` | ||||||||||||
|
Comment on lines
+12
to
+15
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
With the example |
||||||||||||
|
|
||||||||||||
| 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: | ||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
|
||||||||||||
| - 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). | ||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.