1515"""Implementation of extended_lengyel instance of EdgeModel."""
1616
1717import dataclasses
18- import enum
1918import logging
2019from typing import Mapping
2120import jax
3231from torax ._src .edge .extended_lengyel import divertor_sol_1d as divertor_sol_1d_lib
3332from torax ._src .edge .extended_lengyel import extended_lengyel_defaults
3433from torax ._src .edge .extended_lengyel import extended_lengyel_enums
34+ from torax ._src .edge .extended_lengyel import extended_lengyel_formulas
3535from torax ._src .edge .extended_lengyel import extended_lengyel_solvers
3636from torax ._src .edge .extended_lengyel import extended_lengyel_standalone
3737from torax ._src .geometry import geometry
4242
4343
4444# pylint: disable=invalid-name
45- class FixedImpuritySourceOfTruth (enum .StrEnum ):
46- """Source of truth for fixed impurity concentrations when using an edge model.
47-
48- Determines how impurity concentrations are handled between the core plasma
49- simulation and the edge model.
50-
51- Attributes:
52- CORE: * The core impurity profiles are the source of truth. * The edge
53- model's impurity concentrations are derived from the core values at the
54- last closed flux surface: `c_edge = c_core_face[-1] * enrichment_factor`.
55- EDGE: * The edge model's `fixed_impurity_concentrations` are the source of
56- truth. * The core impurity profiles (n_e_ratios) are scaled to match the
57- values determined by the edge model. runtime_params still sets the profile
58- shape: `c_core = c_core / c_core_face[-1] * c_edge / enrichment_factor`.
59-
60- Note: For seeded impurities in the extended Lengyel edge model, the source of
61- truth is always the edge model, regardless of this setting. This enum only
62- controls the behavior for fixed impurities in that case.
63- """
64-
65- CORE = 'core'
66- EDGE = 'edge'
6745
6846
6947@jax .tree_util .register_dataclass
@@ -87,7 +65,7 @@ class InitialGuessRuntimeParams:
8765
8866
8967@jax .tree_util .register_dataclass
90- @dataclasses .dataclass (frozen = True )
68+ @dataclasses .dataclass (frozen = True , kw_only = True )
9169class RuntimeParams (edge_runtime_params .RuntimeParams ):
9270 """Runtime parameters for the extended Lengyel edge model."""
9371
@@ -100,11 +78,12 @@ class RuntimeParams(edge_runtime_params.RuntimeParams):
10078 solver_mode : extended_lengyel_enums .SolverMode = dataclasses .field (
10179 metadata = {'static' : True }
10280 )
103- impurity_sot : FixedImpuritySourceOfTruth = dataclasses . field (
104- metadata = {'static' : True }
81+ impurity_sot : extended_lengyel_enums . FixedImpuritySourceOfTruth = (
82+ dataclasses . field ( metadata = {'static' : True })
10583 )
10684 # Not static to allow rapid sensitivity checking of edge-model impact.
10785 update_temperatures : array_typing .BoolScalar
86+ update_density : array_typing .BoolScalar
10887 update_impurities : array_typing .BoolScalar
10988 fixed_point_iterations : int
11089 newton_raphson_iterations : int
@@ -139,7 +118,7 @@ class RuntimeParams(edge_runtime_params.RuntimeParams):
139118 # --- Impurity parameters ---
140119 seed_impurity_weights : Mapping [str , array_typing .FloatScalar ] | None
141120 fixed_impurity_concentrations : Mapping [str , array_typing .FloatScalar ]
142- enrichment_factor : Mapping [str , array_typing .FloatScalar ]
121+ enrichment_factor : Mapping [str , array_typing .FloatScalar ] | None
143122 use_enrichment_model : bool = dataclasses .field (metadata = {'static' : True })
144123 enrichment_model_multiplier : array_typing .FloatScalar
145124
@@ -238,7 +217,10 @@ def __call__(
238217 fixed_impurity_concentrations = edge_params .fixed_impurity_concentrations
239218 # If the source of truth for fixed impurities is the core, calculate the
240219 # edge concentrations from the core ratios.
241- if edge_params .impurity_sot == FixedImpuritySourceOfTruth .CORE :
220+ if (
221+ edge_params .impurity_sot
222+ == extended_lengyel_enums .FixedImpuritySourceOfTruth .CORE
223+ ):
242224 # Initialization
243225 fixed_impurity_concentrations = {}
244226 impurity_params = runtime_params .plasma_composition .impurity
@@ -255,10 +237,26 @@ def __call__(
255237 continue
256238
257239 # Calculate edge concentration: c_edge = c_core_lcfs * enrichment_factor
258- # Enrichment factor exists for all species (validated in config)
259- fixed_impurity_concentrations [species ] = (
260- ratio_face [- 1 ] * edge_params .enrichment_factor [species ]
261- )
240+ if edge_params .use_enrichment_model :
241+ if previous_edge_outputs is not None :
242+ assert isinstance (
243+ previous_edge_outputs ,
244+ extended_lengyel_standalone .ExtendedLengyelOutputs ,
245+ )
246+ enrichment = previous_edge_outputs .calculated_enrichment [species ]
247+ else :
248+ # For initial timestep when previous_edge_outputs is None
249+ enrichment = extended_lengyel_formulas .calc_enrichment_kallenbach (
250+ 1.0 , species , edge_params .enrichment_model_multiplier
251+ )
252+ elif edge_params .enrichment_factor is not None :
253+ enrichment = edge_params .enrichment_factor [species ]
254+ else :
255+ raise ValueError (
256+ 'enrichment_factor must be provided when use_enrichment_model is'
257+ ' False.'
258+ )
259+ fixed_impurity_concentrations [species ] = ratio_face [- 1 ] * enrichment
262260
263261 # Determine initial guesses
264262 initial_guess = _get_initial_guess (edge_params , previous_edge_outputs )
@@ -308,6 +306,9 @@ def __call__(
308306 multistart_num_guesses = edge_params .multistart_num_guesses ,
309307 enrichment_model_multiplier = edge_params .enrichment_model_multiplier ,
310308 diverted = diverted ,
309+ use_enrichment_model = edge_params .use_enrichment_model ,
310+ enrichment_factor = edge_params .enrichment_factor ,
311+ impurity_sot = edge_params .impurity_sot ,
311312 initial_guess = initial_guess ,
312313 )
313314
0 commit comments