Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
9210e9a
Add new plasma physics variables and update iteration variable count
chris-ashe Mar 17, 2026
9081e52
Add particle balance constraint equation and update constraint count
chris-ashe Mar 17, 2026
b28ffda
Add new plasma physics input variables for recycling and fuelling
chris-ashe Mar 17, 2026
64a10a3
Refactor particle balance constraint equation and update iteration va…
chris-ashe Mar 17, 2026
34947ac
Update particle balance constraints and increment equation count
chris-ashe Mar 17, 2026
ef39524
Update constraint limits
chris-ashe Mar 17, 2026
de9ac4e
Add new total D-T fusion rate variables
chris-ashe Mar 17, 2026
4f1b0e1
Update consistency equations for particle consistency
timothy-nunn Mar 18, 2026
209e824
Update molflow plasma fuelling variable ranges for consistency
chris-ashe Mar 20, 2026
966b457
Refine fusion power output formatting for improved precision in plot …
chris-ashe Mar 20, 2026
783f26b
Add D-D fusion reaction rate variables for helium and tritium branches
chris-ashe Mar 20, 2026
8b4e744
Add D-D fusion rate calculations for tritium and helium branches
chris-ashe Mar 20, 2026
6d974b4
Add plasma tritium flow rate calculations and contour plotting
chris-ashe Mar 20, 2026
89a29b6
Add total D-D fusion rate calculation and update output formatting
chris-ashe Mar 20, 2026
8cd99b6
Add deuterium and alpha particle flow rate calculations and contour p…
chris-ashe Mar 20, 2026
0c821db
Add plotting of fuelling efficiency and recycling fraction in plasma …
chris-ashe Mar 20, 2026
d259c03
Add plasma fuelling equations and documentation
chris-ashe Mar 22, 2026
54db27a
Add D-3He fusion rate and neutron production rate calculations
chris-ashe Mar 22, 2026
9e9aa5e
Add fuelling composition variables and constraints for deuterium, tri…
chris-ashe Mar 22, 2026
d78757c
Enhance plasma flow calculations by adding tritium and deuterium flow…
chris-ashe Mar 22, 2026
1b903ed
Rename burn-up fraction variable to f_plasma_fuel_burnup across multi…
chris-ashe Mar 22, 2026
55d08f1
Refactor fuel burn-up rate variable to fusrat_total across multiple f…
chris-ashe Mar 22, 2026
e06b0a9
Refactor plasma exhaust calculations to plasma fuelling, updating rel…
chris-ashe Mar 23, 2026
3ebde65
Refactor plasma fuelling plotting functions to improve organization a…
chris-ashe Mar 23, 2026
d8aec4d
Integrate PlasmaFuelling class into physics calculations and update f…
chris-ashe Mar 23, 2026
c88c865
Enhance plasma fuelling documentation with flow rate equations and ke…
chris-ashe Mar 23, 2026
6772cea
Refactor fuelling output logic to use dedicated method in PlasmaFuell…
chris-ashe Mar 23, 2026
32961f2
:fire: Remove tauratio variable from input variables and related test…
chris-ashe Mar 23, 2026
659fb1b
Add tritium and deuterium burnup calculations and update physics vari…
chris-ashe Mar 23, 2026
0760176
:fire: Refactor plasma fuelling variables: remove unused 'molflow_pla…
chris-ashe Mar 23, 2026
3a91922
Add Avogadro's number constant with reference documentation
chris-ashe Mar 23, 2026
ebc45c1
Add plasma fuelling loss calculations and update related variables in…
chris-ashe Mar 24, 2026
6aed3e6
Add helium-3 flow contour plotting and enhance existing contour plots…
chris-ashe Mar 24, 2026
b26a3e1
Refactor plotting indices in main_plot function to accommodate additi…
chris-ashe Mar 25, 2026
d594337
Enhance plasma fuelling documentation: add definitions for exhaust ef…
chris-ashe Mar 27, 2026
694d95b
Refactor Physics model and unit tests to integrate PlasmaFuelling cla…
chris-ashe Mar 31, 2026
6004cfb
Post rebase fixes
chris-ashe Jun 2, 2026
4789875
post rebase fixes
chris-ashe Jun 17, 2026
af1ecc7
Enhance plasma fuelling documentation and update constraint equations…
chris-ashe Jun 17, 2026
74eac1c
Enhance plasma fuelling documentation: add particle balance section, …
chris-ashe Jun 17, 2026
6b5fa2c
Update large tokamak input file: adjust number of equality constraint…
chris-ashe Jun 17, 2026
3e5c5fd
Fix bug in output caused by rebase
chris-ashe Jun 17, 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
9 changes: 9 additions & 0 deletions process/core/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,15 @@ def __post_init__(self):
"f_volflow_vac_pumps_impedance": InputVariable("vacuum", float, range=(1e-06, 1.0)),
"volflow_vac_pumps_max": InputVariable("vacuum", float, range=(1e-06, 1000.0)),
"molflow_vac_pumps": InputVariable("vacuum", float, range=(0.0, 1e30)),
"f_plasma_particles_lcfs_recycled": InputVariable(
data_structure.physics_variables, float, range=(0.0, 1.0)
),
"eta_plasma_fuelling": InputVariable(
data_structure.physics_variables, float, range=(0.0, 1.0)
),
"molflow_plasma_fuelling_vv_injected": InputVariable(
data_structure.physics_variables, float, range=(0.0, 1e24)
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fixup into previous commit where these were created.

"pflux_plant_floor_electric": InputVariable(
"heat_transport", float, range=(0.0, 1000.0)
),
Expand Down
73 changes: 73 additions & 0 deletions process/core/solver/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -1777,6 +1777,79 @@ def constraint_equation_92(constraint_registration, data):
)


@ConstraintManager.register_constraint(93, "particles/s", "=")
def constraint_equation_93():
"""
Particle balance
"""
# pscaling: total transport power per volume (MW/m3)
# NEED TO ADD PROPER FUSION RATES FOR EACH REACTION

# Numerator shall be the tritium particle balance
numerator = (
data_structure.physics_variables.eta_plasma_fuelling
* data_structure.physics_variables.molflow_plasma_fuelling_vv_injected
- data_structure.physics_variables.fusrat_total
) - (
(
data_structure.physics_variables.nd_plasma_fuel_ions_vol_avg
* data_structure.physics_variables.vol_plasma
* data_structure.physics_variables.f_plasma_fuel_tritium
)
/ (
data_structure.physics_variables.t_energy_confinement
/ (1 - data_structure.physics_variables.f_plasma_particles_lcfs_recycled)
)
)

# Alpha particle balance
denominator = data_structure.physics_variables.fusrat_total - (
data_structure.physics_variables.nd_plasma_alphas_vol_avg
* data_structure.physics_variables.vol_plasma
) / (data_structure.physics_variables.t_alpha_confinement)

cc = 1.0 - numerator / numerator

return ConstraintResult(cc, denominator * (1.0 - cc), denominator * cc)


@ConstraintManager.register_constraint(93, "particles/s", "=")
def constraint_equation_93():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be a copy of the previous constraint.

"""
Particle balance
"""
# pscaling: total transport power per volume (MW/m3)
# NEED TO ADD PROPER FUSION RATES FOR EACH REACTION

# Numerator shall be the tritium particle balance
numerator = (
data_structure.physics_variables.eta_plasma_fuelling
* data_structure.physics_variables.molflow_plasma_fuelling_vv_injected
- data_structure.physics_variables.fusrat_total
) - (
(
data_structure.physics_variables.nd_plasma_fuel_ions_vol_avg
* data_structure.physics_variables.vol_plasma
* data_structure.physics_variables.f_plasma_fuel_tritium
)
/ (
data_structure.physics_variables.t_energy_confinement
/ (1 - data_structure.physics_variables.f_plasma_particles_lcfs_recycled)
)
)

# Alpha particle balance
denominator = data_structure.physics_variables.fusrat_total - (
data_structure.physics_variables.nd_plasma_alphas_vol_avg
* data_structure.physics_variables.vol_plasma
) / (data_structure.physics_variables.t_alpha_confinement)

cc = 1.0 - numerator / numerator

return ConstraintResult(cc, denominator * (1.0 - cc), denominator * cc)



def constraint_eqns(m: int, ieqn: int, data: DataStructure):
"""Evaluates the constraints given the current state of PROCESS.

Expand Down
12 changes: 12 additions & 0 deletions process/core/solver/iteration_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,18 @@ class IterationVariable:
174: IterationVariable("triang", "physics", 0.00, 1.00),
175: IterationVariable("kappa", "physics", 0.00, 10.00),
176: IterationVariable("f_st_coil_aspect", "stellarator", 0.70, 1.30),
177: IterationVariable(
"f_plasma_particles_lcfs_recycled", "physics", 0.01, 1.0
),
178: IterationVariable(
"eta_plasma_fuelling", "physics", 0.01, 1.0
),
179: IterationVariable(
"molflow_plasma_fuelling_vv_injected",
"physics",
0.0,
1e24,
),
}


Expand Down
99 changes: 97 additions & 2 deletions process/data_structure/numerics.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,105 @@ def description(self):
return self._description_


ipnvars: int = 177
class PROCESSRunMode(IntEnum):
"""Enumeration of the available PROCESS run modes, which determine the behaviour
of the code in various places. This is controlled by the `ioptimz` variable
"""

EVALUATION = (-2, "Evaluation mode (no optimisation)")
"""In this mode, the code will not perform any optimisation, and will instead
simply evaluate the constraints for the given input parameters, which is useful
for testing and for evaluating the performance of a given design point without
trying to optimise it. Internally, PROCESS uses `fsolve` (a Newton-Krylov/hybrd
root-finding method from `scipy.optimize`) to seek a *consistent* solution by
varying a subset of the iteration variables until the consistency constraints
(equality constraints whose residuals must be driven to zero) are simultaneously
satisfied; no figure-of-merit is optimised, and the solver simply tries to find
a root of the constraint-residual vector.
"""
OPTIMISATION = (1, "Optimisation mode (e.g. via VMCON)")
"""In this mode, the code will perform optimisation using the VMCON solver
(or a custom solver if specified) to try to find a design point that optimises
the figure of merit while satisfying the constraints. This is the default mode
of operation for PROCESS.
"""

def __new__(cls, value: int, description: str):
"""Create a new PROCESSRunMode enum member with description.

Args:
value: The integer value of the enum member.
description: The description for this run mode.

Returns
-------
The new enum member with attached description.
"""
obj = int.__new__(cls, value)
obj._value_ = value
obj._description_ = description
return obj

@DynamicClassAttribute
def description(self):
"""Return the description for this run mode."""
return self._description_


class FiguresOfMerit(IntEnum):
"""Enumeration of the available figures of merit (FoM) that can be used as
objective functions for optimisation in PROCESS.
"""

MAJOR_RADIUS = (1, "Plasma major radius (R₀)")
NEUTRON_WALL_LOAD = (3, "Neutron wall load")
P_TF_PLUS_P_PF = (4, "TF & PF coil power")
FUSION_GAIN_Q = (5, "Fusion gain (Qₚₗₐₛₘₐ)")
COST_OF_ELECTRICITY = (6, "Cost of electricity")
CAPITAL_COST = (7, "Plant capital cost")
ASPECT_RATIO = (8, "Plasma aspect ratio")
DIVERTOR_HEAT_LOAD = (9, "Divertor heat load")
TOROIDAL_FIELD = (10, "Plasma toroidal field on axis (B₀)")
TOTAL_INJECTED_POWER = (11, "Plasma total injected power (Pᵢₙⱼ)")
PULSE_LENGTH = (14, "Pulse length")
PLANT_AVAILABILITY_FACTOR = (15, "Plant availability factor")
MIN_R0_MAX_TAU_BURN = (
16,
"Linear combination of major radius (minimised) and pulse length (maximised)",
)
NET_ELECTRICAL_OUTPUT = (17, "Plant net electrical output")
NULL_FIGURE_OF_MERIT = (18, "Null Figure of Merit")
MAX_Q_MAX_T_PLANT_PULSE_BURN = (
19,
"Linear combination of big Q and pulse length (maximised)",
)

def __new__(cls, value: int, description: str):
"""Create a new FiguresOfMerit enum member with description.

Args:
value: The integer value of the enum member.
description: The description for this figure of merit.

Returns
-------
The new enum member with attached description.
"""
obj = int.__new__(cls, value)
obj._value_ = value
obj._description_ = description
return obj

@DynamicClassAttribute
def description(self):
"""Return the description for this figure of merit."""
return self._description_


ipnvars: int = 180

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this belongs in this PR: it should be separate.

"""total number of variables available for iteration"""

ipeqns: int = 92
ipeqns: int = 93
"""number of constraint equations available"""

ipnfoms: int = 19
Expand Down
8 changes: 8 additions & 0 deletions process/data_structure/physics_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,14 @@ class PhysicsData:
molflow_plasma_fuelling_required: float = 0.0
"""plasma fuelling rate (nucleus-pairs/s)"""

f_plasma_particles_lcfs_recycled: float = None
"""fraction of plasma particles that are recycled at the LCFS. Recycling coefficent (R)"""

eta_plasma_fuelling: float = None
"""fuelling efficiency (fraction of fuel particles injected that become confined in the plasma)"""

molflow_plasma_fuelling_vv_injected: float = None
"""plasma fuelling rate into the vacuum vessel (nucleus-pairs/s)"""
tauratio: float = 1.0
"""tauratio /1.0/ : ratio of He and pellet particle confinement times"""

Expand Down