Skip to content
Closed
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
ede81d1
Added new variables for efficiency of pf-coil power components
grmtrkngtn Feb 4, 2026
ef8d2e3
Updated the indices in loops to align with PROCESS style guide
grmtrkngtn Feb 4, 2026
c1b3831
updates the dosctring of new pf power variables
grmtrkngtn Feb 5, 2026
e9aaa12
Refactored pfpwr. Added new functions to calculate busbar, power supp…
grmtrkngtn Feb 5, 2026
b26b4cd
Added documentation for the changes to pf power accounting
grmtrkngtn Feb 10, 2026
91b22d0
Corrected unparsed variables
j-a-foster Feb 10, 2026
8f51ff7
Fixed subscripts in docs
j-a-foster Feb 10, 2026
5332df6
Removed unnecessary comments
grmtrkngtn Feb 11, 2026
42db87e
change ngrpt to n_pf_coil groups for clarity
grmtrkngtn Feb 11, 2026
0671d75
Updated index name for number of pf coils in each group
grmtrkngtn Feb 11, 2026
caeecef
Updated ii index to idx_circuit
grmtrkngtn Feb 11, 2026
8feead1
Updated jj index to idx_group
grmtrkngtn Feb 11, 2026
6c61b06
Updated jpf to idx_pf_coil, removed id_coil_in_group
grmtrkngtn Feb 11, 2026
6d5448c
Updated kk to idx_time
grmtrkngtn Feb 11, 2026
5d532b3
Updated ii to idx_time_interval
grmtrkngtn Feb 11, 2026
2032b8f
Updated ii to idx_circuit
grmtrkngtn Feb 11, 2026
1b908dd
Updated functions and calls to use the updated indexing
grmtrkngtn Feb 11, 2026
eb88315
Separate shield, vacuum vessel, and blanket calculations (#4064)
chris-ashe Feb 4, 2026
b6b401a
Move certain large test data to json files (#4084)
je-cook Feb 9, 2026
728a4b4
Move first wall geometry calculations into dedicated class (#4077)
chris-ashe Feb 10, 2026
230e386
Add plasma neutron surface power to output (#4087)
chris-ashe Feb 10, 2026
90edc92
Move beta calculations into separate class (#4053)
chris-ashe Feb 11, 2026
a9d1e0f
Fixed negativity in sqrt in costs.py by np.clip. (#4065)
OceanNuclear Feb 12, 2026
4afa759
Create physics inductance class (#4085)
chris-ashe Feb 12, 2026
a1b1796
Extend support for deuteron and triton in DetailedPlasma (#4088)
chris-ashe Feb 13, 2026
b511fe9
Merge remote-tracking branch 'origin/main' into 972-pf-power-supplies…
grmtrkngtn Feb 17, 2026
4364a98
reformatted total energy loss equation
grmtrkngtn Apr 9, 2026
07f212d
updated _pf_loss_storage_j to numpy docstring
grmtrkngtn Apr 9, 2026
55c3398
updated _pf_loss_powersupply_j to numpy docstring
grmtrkngtn Apr 9, 2026
8209454
updated _pf_loss_busbar_j to numpy docstring
grmtrkngtn Apr 9, 2026
0120116
updated _pf_loss_interval_total_j to numpy docstring
grmtrkngtn Apr 9, 2026
22e50bf
updated pfpwr docstring
grmtrkngtn Apr 9, 2026
5248478
updated pfpwr variables in line with style guide
grmtrkngtn Apr 9, 2026
1878e6d
updated pfbusr with res_pf_bus#
grmtrkngtn Apr 9, 2026
31a718f
Merge branch 'main' into 972-pf-power-supplies-accounting-2
grmtrkngtn Apr 9, 2026
88d8619
Tightened comments
grmtrkngtn Apr 9, 2026
095bc14
renamed index to a_pf_bus_cm
grmtrkngtn Apr 10, 2026
af71af8
Create diamagnetic current class (#4156)
chris-ashe Apr 9, 2026
defd5b8
Update CI regression docs (#4162)
clmould Apr 9, 2026
a135b59
Upgrade CLI to use click (#4105)
je-cook Apr 9, 2026
94a57f2
Use hatch run in CI for plotting summary (#4169)
timothy-nunn Apr 9, 2026
f112e24
Add FwBlktVVShape enum (#4167)
chris-ashe Apr 9, 2026
25a1184
Convert costs 2015 to new data structure (#4153)
clmould Apr 9, 2026
f4772c4
Move plot plasma current into summary.py (#4170)
timothy-nunn Apr 9, 2026
bdd92cc
Ensure njit is used in plasma fields (#4172)
chris-ashe Apr 10, 2026
ed24b3a
Remove unused configuration.py file (#4175)
je-cook Apr 10, 2026
79f831d
Fix stacked plots writing multiple files (#4068)
chris-ashe Apr 10, 2026
23266c6
Add `enum` for profile shape (#4180)
chris-ashe Apr 13, 2026
4755844
Upgrade pre-commit versions (#4178)
je-cook Apr 13, 2026
2a2e157
Corrected unparsed variables
j-a-foster Feb 10, 2026
7946050
Removed unnecessary comments
grmtrkngtn Feb 11, 2026
c61c6bd
Separate shield, vacuum vessel, and blanket calculations (#4064)
chris-ashe Feb 4, 2026
2303824
Move certain large test data to json files (#4084)
je-cook Feb 9, 2026
f81ac02
Move first wall geometry calculations into dedicated class (#4077)
chris-ashe Feb 10, 2026
e782901
Add plasma neutron surface power to output (#4087)
chris-ashe Feb 10, 2026
7af71e9
Move beta calculations into separate class (#4053)
chris-ashe Feb 11, 2026
08b8797
Fixed negativity in sqrt in costs.py by np.clip. (#4065)
OceanNuclear Feb 12, 2026
1b8b4fc
Create physics inductance class (#4085)
chris-ashe Feb 12, 2026
f71e108
Extend support for deuteron and triton in DetailedPlasma (#4088)
chris-ashe Feb 13, 2026
886e8c5
updated pfpwr docstring
grmtrkngtn Apr 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 145 additions & 38 deletions documentation/eng-models/power-requirements.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Power Requirements

The main power flow is controlled by `power.py`. The main class `Power` controls this.

## Power requirements | `Power`

### TF Coils
Expand All @@ -21,6 +22,133 @@ The main power flow is controlled by `power.py`. The main class `Power` controls

#### PF power | `pfpwr()`

#### PF coil power loss model – equations and derivation

PF coil currents are defined at discrete pulse times $t_0 \ldots t_5$.
All PF circuits (and plasma current) are coupled through the mutual inductance matrix $M_{ij}$.

---

##### 1. Magnetic energy stored in the poloidal field | `_pf_loss_storage_j()`

Magnetic energy in an inductive system is given by:

$$
E_{\text{PF}}(t_n) = \frac{1}{2} \sum_i I_i(t_n)\sum_j M_{ij} I_j(t_n)
$$

This is the standard inductive energy expression:

$$
E = \frac{1}{2} I^T M I
$$

---

##### 2. Energy moved between pulse phases

The change in stored magnetic energy between time points is:

$$
\Delta E_n = E_{\text{PF}}(t_{n+1}) - E_{\text{PF}}(t_n)
$$

This represents how much energy is charged into or discharged from the PF magnetic field.

---

##### 3. Storage system losses | `_pf_loss_storage_j()`

Assuming a fractional inefficiency $k_\text{s}$ in the energy storage system:

$$
E_{\text{loss},\text{s},n} = k_\text{s} \, \left| \Delta E_n \right|
$$

A fixed fraction of energy moved is lost each time energy flows in or out of storage.

---

##### 4. Power supply losses | `_pf_loss_power_supply_j()`

Electrical power delivered to each PF circuit is:

$$
P_i = V_i I_i
$$

Inductive voltage arises from changing currents:

$$
V_i = \sum_j M_{ij} \frac{dI_j}{dt}
$$

Approximating over a discrete time interval $\Delta t = t_{n+1}-t_n$:

$$
\frac{dI_j}{dt} \approx \frac{I_j(t_{n+1}) - I_j(t_n)}{\Delta t}
$$

and using the mean current:

$$
I_i \approx \frac{I_i(t_{n+1}) + I_i(t_n)}{2}
$$

gives:

$$
V_i \approx \frac{1}{\Delta t} \sum_j M_{ij}\left[I_j(t_{n+1}) - I_j(t_n)\right]
$$

The resulting energy loss in the power supplies over the interval is:

$$
E_{\text{loss},\text{ps},n} =
\frac{k_{\text{ps}}}{2}
\left|
\left[I_i(t_{n+1}) + I_i(t_n)\right]
\sum_j M_{ij}
\left[I_j(t_{n+1}) - I_j(t_n)\right]
\right|
$$

This represents inefficiency proportional to inductive power flow.

---

##### 5. Busbar resistive losses | `_pf_loss_busbar_j()`

Resistive heating follows Joule’s law:

$$
P = I^2 R
$$

Using the mean current over each interval:

$$
\bar{I}_i = \frac{I_i(t_{n+1}) + I_i(t_n)}{2}
$$

Energy dissipated in the busbars is:

$$
E_{\text{loss}, \text{bus},n} = \Delta t \sum_i \bar{I}_i^2 R_i
$$

---

##### 6. Total PF energy loss per pulse | `_pf_loss_interval_total_j()`

Summing losses over all pulse phases:

$$
EnergyLoss = \sum_n \left( E_{\text{loss},\text{s},n} + E_{\text{loss},\text{ps},n} + E_{\text{loss},\text{bus},n} \right)
Comment thread
grmtrkngtn marked this conversation as resolved.
Outdated
$$

The mean PF electrical power demand is obtained by dividing the total pulse energy loss by the flat-top duration.

---

#### AC power | `acpow()`
Expand Down Expand Up @@ -70,7 +198,7 @@ $$
P_{\text{blkt-breeder-heat}} = \left(P_{\text{blkt,nuclear}} \times \texttt{f_nuc_pow_bz_liq}\right) + P_{\text{pump,blkt-secondary}}
$$

6: If `i_blkt_dual_coolant == 1` the secondary breeder is only pumped for tritium extraction and not cooling so:
6: If `i_blkt_dual_coolant == 1` the secondary breeder is only pumped for tritium extraction and not cooling so:

$$
P_{\text{blkt-breeder-heat}} = P_{\text{pump,blkt-secondary}}
Expand All @@ -84,10 +212,9 @@ $$
+ \underbrace{\left[P_{\text{Blkt, nuclear}} + P_{\text{Blkt, pump}}\right]}_{\texttt{p_blkt_heat_deposited_mw}}
$$

- $P_{\text{FW, nuclear}}$ & $P_{\text{Blkt, nuclear}}$ is the nuclear heating from neutron interaction (which includes the energy multiplication (`f_p_blkt_multiplication`) for the blanket.)
- $P_{\text{FW,}\gamma}$ is the photon radiation incident on the FW (`p_fw_rad_total_mw`).
- $P_{\alpha,\text{loss}}$ is the plasma lost alpha power (`p_fw_alpha_mw`)

- $P_{\text{FW, nuclear}}$ & $P_{\text{Blkt, nuclear}}$ is the nuclear heating from neutron interaction (which includes the energy multiplication (`f_p_blkt_multiplication`) for the blanket.)
- $P_{\text{FW,}\gamma}$ is the photon radiation incident on the FW (`p_fw_rad_total_mw`).
- $P_{\alpha,\text{loss}}$ is the plasma lost alpha power (`p_fw_alpha_mw`)

8: The thermal power deposited in the shields is calculated:

Expand Down Expand Up @@ -142,7 +269,7 @@ $$
2: The electric demands of the plant core systems are calculated

$$
\overbrace{P_{\text{core systems}}}^\texttt{p_plant_core_systems_elec_mw} = P_{\text{base,total}}
\overbrace{P_{\text{core systems}}}^\texttt{p_plant_core_systems_elec_mw} = P_{\text{base,total}}
\\ + \overbrace{P_{\text{cryo plant}}}^\texttt{p_cryo_plant_electric_mw} + \overbrace{P_{\text{tritium plant}}}^\texttt{p_tritium_plant_electric_mw}
\\ + \overbrace{P_{\text{TF}}}^\texttt{p_tf_electric_supplies_mw} + \overbrace{P_{\text{PF}}}^\texttt{p_pf_electric_supplies_mw}
\\ + \overbrace{P_{\text{vacuum pumps}}}^\texttt{vachtmw} + \underbrace{\overbrace{P_{\text{CP pumps}}}}_{\text{If present}}^\texttt{p_cp_coolant_pump_elec_mw}
Expand Down Expand Up @@ -177,26 +304,23 @@ $$
\\ + \overbrace{P_{\text{HCD electric}}}^\texttt{p_hcd_electric_total_mw} + \overbrace{P_{\text{coolant pumps, electric}}}^\texttt{p_coolant_pump_elec_total_mw}
$$


7: The net-electric power is found by the different of gross and net

$$
\overbrace{P_{\text{net, electric}}}^\texttt{p_plant_electric_net_mw} = P_{\text{gross, electric}} - P_{\text{recirc, electric}}
$$


8: The recirculated power fraction is then quickly found as

$$
\overbrace{f_{\text{recirc}}}^\texttt{f_p_plant_electric_recirc} = \frac{P_{\text{gross, electric}} - P_{\text{net, electric}}}{P_{\text{gross, electric}}}
$$


---

#### Plant thermal efficiency | `plant_thermal_efficiency()`

`i_thermal_electric_conversion` : This switch controls the calculation of the thermal to electric conversion
`i_thermal_electric_conversion` : This switch controls the calculation of the thermal to electric conversion
efficiency in the secondary cycle.

----------------
Expand All @@ -207,9 +331,9 @@ This model is set with `i_thermal_electric_conversion = 0`.

It can be used with water or helium primary coolants.

The efficiency of the power generation cycle is set to a single value
obtained from previous cycle modelling studies. The heat deposited in the Toroidal Field coils
divertor coolant is assumed to be at such low temperature that it cannot be used for power
The efficiency of the power generation cycle is set to a single value
obtained from previous cycle modelling studies. The heat deposited in the Toroidal Field coils
divertor coolant is assumed to be at such low temperature that it cannot be used for power
generation and is dumped to the environment.

The resulting thermal efficiencies used are taken from studies that modelled Rankine cycles for
Expand All @@ -222,7 +346,6 @@ $$
\eta_{\text{turbine}} = 0.411
$$


-------------------

##### Use CCFE HCPB Model Value with divertor
Expand Down Expand Up @@ -262,7 +385,7 @@ It can be used with helium primary coolant.
$$
T_{\text{turbine,inlet}} = T_{\text{blkt,outlet}} - 20.0
$$

$$
\eta_{\text{turbine}} = 0.1802 \ln{(T_{\text{turbine,inlet}})}-0.7823 - \Delta \eta \\
\text{for} \quad 657.15 \le T_{\text{turbine,inlet}} \le 915.15 \text{K}
Expand All @@ -272,7 +395,6 @@ The peak divertor coolant temperature ($T_{\text{div,outlet}}$) is assumed to be

If the Rankine cycle is chosen and the primary coolant is water, it is assumed that the cycle is similar to that of pressurised water reactors currently in operation.


------------

##### Supercritical CO2 Brayton Cycle
Expand All @@ -281,48 +403,39 @@ This model is set with `i_thermal_electric_conversion = 4`.

It can be used with water or helium primary coolants.

A supercritical CO$_2$ Brayton cycle is assumed. The secondary cycle
efficiency (`eta_turbine`) is calculated from the coolant outlet temperature using simple relations
A supercritical CO$_2$ Brayton cycle is assumed. The secondary cycle
efficiency (`eta_turbine`) is calculated from the coolant outlet temperature using simple relations
between temperature and efficiency from :

$$
T_{\text{turbine,inlet}} = T_{\text{blkt,outlet}} - 20.0
$$

$$
\eta_{\text{turbine}} = 0.4347 \ln{(T_{\text{turbine,inlet}})}-2.5043 \\
\text{for} \quad 408.15 \le T_{\text{turbine,inlet}} \le 1023.15 \text{K}
$$

The peak divertor coolant temperature ($T_{\text{div,outlet}}$) is assumed to be the same as the turbine inlet ($T_{\text{turbine,inlet}}$).


The correlation of efficiency with temperature is derived from results of cycle modelling carried out by CCFE in collaboration with industry. The divertor heat is used in the main heat exchanger. The divertor heat is counted as primary heat, and is included in the calculation of the efficiency.


---

#### Liquid metal breeder plant thermal efficiency | `plant_thermal_efficiency_2()`

---




### Cryogenic power requirements | `cryo()`

---





Figure 1 shows a simplified description of the power flow.
Figure 1 shows a simplified description of the power flow.

<figure>
<center>
<img src="../../images/Overall-power-flow.png" alt="Overall power flow"
title="Power flows"
<img src="../../images/Overall-power-flow.png" alt="Overall power flow"
title="Power flows"
width="650" height="100" />
<br><br>
<figcaption><i>Figure 1: Power flows
Expand All @@ -338,17 +451,11 @@ Some details of the auxiliary systems are as follows.
The TF current is carried from the power supplies to the reactor by room-temperature aluminium busbars, organised in $N_{circuit}$ circuits. The total length of the busbars is (somehwat arbitrarily) given by

$$
L_bus = 8 \pi R_0 + (1 + N_{circuit}) (12 R_0 + 80)
L_bus = 8 \pi R_0 + (1 + N_{circuit}) (12 R_0 + 80)
$$

The resistivity of the busbar is 2.62e-8 ohm.m (0.0262 ohm.mm²/m) (hard-coded).

"TF coil resistive power" (`rpower`) includes the dissipation of the cryogenic current leads (assumed to be resistive).

The AC power required is determined by the efficiency of the coil power supply: `etatf` (default = 90%).






12 changes: 11 additions & 1 deletion process/data_structure/pf_power_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@
poloidalpower: list[float] = None
"""Poloidal power usage at time t (MW)"""

f_p_pf_energy_store_loss: float = None
"""Fraction of PF magnetic energy moved into/out of storage that is lost each time"""

f_p_pf_psu_loss: float = None
"""Fraction of inductive power flow lost in the PF power supplies/converters."""


def init_pf_power_variables():
"""Initialise PF coil power variables"""
Expand All @@ -56,7 +62,9 @@ def init_pf_power_variables():
vpfskv, \
peakpoloidalpower, \
maxpoloidalpower, \
poloidalpower
poloidalpower, \
f_p_pf_energy_store_loss, \
f_p_pf_psu_loss

acptmax = 0.0
ensxpfm = 0.0
Expand All @@ -69,3 +77,5 @@ def init_pf_power_variables():
peakpoloidalpower = 0.0
maxpoloidalpower = 1000.0
poloidalpower = np.zeros(5)
f_p_pf_energy_store_loss = 0.1
f_p_pf_psu_loss = 0.1
Loading
Loading