From 03ce2756bb53c52b90e04974b24f37618cfc9601 Mon Sep 17 00:00:00 2001 From: Jonathan Maddock <78556175+jonmaddock@users.noreply.github.com> Date: Fri, 14 Nov 2025 14:25:06 +0000 Subject: [PATCH 1/3] Add fuelling rate constraint --- process/core/input.py | 3 +++ process/core/solver/constraints.py | 8 ++++++++ process/models/physics/physics.py | 5 +---- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/process/core/input.py b/process/core/input.py index 31b6c6f6cd..8286bc587a 100644 --- a/process/core/input.py +++ b/process/core/input.py @@ -1186,6 +1186,9 @@ def bounds(self) -> tuple[NumberType | None, NumberType | None]: "f_len_sol_power_decay_inboard_outboard": InputVariable( "physics", float, range=(0.01, 2.0) ), + "molflow_plasma_fuelling_required": InputVariable( + "physics", float, range=(1.0e20, 1.0e23) + ), } diff --git a/process/core/solver/constraints.py b/process/core/solver/constraints.py index c5d786d0f8..b6152ddf2c 100644 --- a/process/core/solver/constraints.py +++ b/process/core/solver/constraints.py @@ -1981,6 +1981,14 @@ def constraint_equation_92(constraint_registration, data): ) +@ConstraintManager.register_constraint(93, "", "=") +def constraint_equation_93(constraint_registration, data): + num = data.physics.fusrat_total / data.physics.burnup + denom = data.physics.molflow_plasma_fuelling_required + + return eq(num, denom, constraint_registration) + + def constraint_eqns(m: int, ieqn: int, data: DataStructure): """Evaluates the constraints given the current state of PROCESS. diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index 43975e3f0e..b7dfe46d3c 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -1566,16 +1566,13 @@ def phyaux( # Fuel burnup rate (reactions/second) (previously Amps) rndfuel = fusrat - # Required fuelling rate (fuel ion pairs/second) (previously Amps) - molflow_plasma_fuelling_required = rndfuel / burnup - f_t_alpha_energy_confinement = t_alpha_confinement / t_energy_confinement return ( burnup, figmer, fusrat, - molflow_plasma_fuelling_required, + self.data.physics.molflow_plasma_fuelling_required, rndfuel, t_alpha_confinement, f_t_alpha_energy_confinement, From 80c5073aa960931bc3418f81bc0090af20f4e248 Mon Sep 17 00:00:00 2001 From: Jonathan Maddock <78556175+jonmaddock@users.noreply.github.com> Date: Tue, 23 Jun 2026 15:07:08 +0100 Subject: [PATCH 2/3] Add fuelling rate as optimisation parameter --- process/core/solver/iteration_variables.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/process/core/solver/iteration_variables.py b/process/core/solver/iteration_variables.py index fd468c5537..60ea812489 100644 --- a/process/core/solver/iteration_variables.py +++ b/process/core/solver/iteration_variables.py @@ -239,6 +239,12 @@ class IterationVariable: 175: IterationVariable("kappa", "physics", 0.00, 10.00), 176: IterationVariable("f_st_coil_aspect", "stellarator", 0.70, 1.30), 177: IterationVariable("f_a_tf_turn_cable_space_extra_void", "tfcoil", 0.01, 1.0), + 178: IterationVariable( + "molflow_plasma_fuelling_required", + "physics", + 1.0e20, + 1.0e23, + ), } From d7e934075bee703008d426af5415c3da05183516 Mon Sep 17 00:00:00 2001 From: ym1906 Date: Thu, 1 Oct 2026 13:22:14 +0100 Subject: [PATCH 3/3] Remove calculation from constraint 93 to phyaux. Rename variables, update associated outputs, labels and tests. --- process/core/input.py | 4 +- process/core/io/plot/summary.py | 2 +- process/core/solver/constraints.py | 12 +++- process/core/solver/iteration_variables.py | 2 +- process/data_structure/numerics.py | 2 + process/data_structure/physics_variables.py | 5 +- process/models/costs/costs.py | 4 +- process/models/physics/physics.py | 72 ++++++++++----------- process/models/stellarator/stellarator.py | 2 +- process/models/vacuum.py | 8 +-- tests/unit/models/physics/test_physics.py | 12 ++-- tests/unit/models/test_vacuum.py | 2 +- 12 files changed, 68 insertions(+), 59 deletions(-) diff --git a/process/core/input.py b/process/core/input.py index 8286bc587a..bd490eead0 100644 --- a/process/core/input.py +++ b/process/core/input.py @@ -1186,9 +1186,7 @@ def bounds(self) -> tuple[NumberType | None, NumberType | None]: "f_len_sol_power_decay_inboard_outboard": InputVariable( "physics", float, range=(0.01, 2.0) ), - "molflow_plasma_fuelling_required": InputVariable( - "physics", float, range=(1.0e20, 1.0e23) - ), + "molflow_plasma_fuelling": InputVariable("physics", float, range=(1.0e20, 1.0e23)), } diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index 212f2f1e94..3a27cce530 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -2976,7 +2976,7 @@ def plot_main_plasma_information( f" - Average mass of all plasma ions: {mfile.get('m_ions_total_amu', scan=scan):.3f} amu\n" f"Fuel mass: {mfile.get('m_plasma_fuel_ions', scan=scan) * 1000:.4f} g\n" f" - Average mass of all fuel ions: {mfile.get('m_fuel_amu', scan=scan):.3f} amu\n\n" - f"Fueling rate: {mfile.get('molflow_plasma_fuelling_required', scan=scan):.3e} nucleus-pairs/s\n" + f"Fueling rate: {mfile.get('molflow_plasma_fuelling', scan=scan):.3e} nucleus-pairs/s\n" f"Fuel burn-up rate: {mfile.get('rndfuel', scan=scan):.3e} reactions/s \n" f"Burn-up fraction: {mfile.get('burnup', scan=scan):.4f} \n" ) diff --git a/process/core/solver/constraints.py b/process/core/solver/constraints.py index b6152ddf2c..08792a461e 100644 --- a/process/core/solver/constraints.py +++ b/process/core/solver/constraints.py @@ -1983,10 +1983,16 @@ def constraint_equation_92(constraint_registration, data): @ConstraintManager.register_constraint(93, "", "=") def constraint_equation_93(constraint_registration, data): - num = data.physics.fusrat_total / data.physics.burnup - denom = data.physics.molflow_plasma_fuelling_required + """Fuel-ion equilibrium constraint. - return eq(num, denom, constraint_registration) + Requires the plasma fuelling rate to equal the fuelling rate required + for fuel-ion equilibrium. + """ + return eq( + data.physics.molflow_plasma_fuelling, + data.physics.molflow_plasma_fuelling_equilibrium, + constraint_registration, + ) def constraint_eqns(m: int, ieqn: int, data: DataStructure): diff --git a/process/core/solver/iteration_variables.py b/process/core/solver/iteration_variables.py index 60ea812489..5a2dc0ee68 100644 --- a/process/core/solver/iteration_variables.py +++ b/process/core/solver/iteration_variables.py @@ -240,7 +240,7 @@ class IterationVariable: 176: IterationVariable("f_st_coil_aspect", "stellarator", 0.70, 1.30), 177: IterationVariable("f_a_tf_turn_cable_space_extra_void", "tfcoil", 0.01, 1.0), 178: IterationVariable( - "molflow_plasma_fuelling_required", + "molflow_plasma_fuelling", "physics", 1.0e20, 1.0e23, diff --git a/process/data_structure/numerics.py b/process/data_structure/numerics.py index 85785576a4..cc2c175b03 100644 --- a/process/data_structure/numerics.py +++ b/process/data_structure/numerics.py @@ -292,6 +292,7 @@ class NumericsData: "CS achievable stress load cycles lower limit ", "ECRH ignitability ", # Stellarator constraint "Fuel composition consistency ", + "Fuel ion equilibrium ", ] ) """Labels describing constraint equations (corresponding itvs)