Skip to content

Commit 326a841

Browse files
theo-brownTorax team
authored andcommitted
Refactor Mavrin radiative cooling models to a new radiation subpackage.
Prerequisite to combining coronal and non-coronal Mavrin models for better modelling of radiative collapse. PiperOrigin-RevId: 861234999
1 parent 3e9f3c6 commit 326a841

File tree

12 files changed

+900
-482
lines changed

12 files changed

+900
-482
lines changed

torax/_src/edge/collisional_radiative_models.py

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,26 @@
1919
J Fusion Energ (2017) 36:161-172
2020
DOI 10.1007/s10894-017-0136-z
2121
"""
22-
import enum
22+
2323
from typing import Mapping
2424
import jax
2525
from jax import numpy as jnp
2626
from torax._src import array_typing
2727
from torax._src.edge import mavrin_2017_charge_states_data
28-
from torax._src.edge import mavrin_2017_cooling_rate_data
28+
from torax._src.physics.radiation import mavrin_fit
2929

3030
# pylint: disable=invalid-name
3131

3232
_NE_TAU_CORONAL_LIMIT = 1e19
3333

3434

35-
class MavrinVariable(enum.StrEnum):
36-
Z = 'Z'
37-
LZ = 'LZ'
38-
39-
40-
def calculate_mavrin_2017(
35+
# TODO(b/479521524): Similarly to radiation, create a new package for
36+
# charge_states and move this function, acommpanying data, and
37+
# physics/charge_states.py there.
38+
def calculate_mavrin_noncoronal_charge_state(
4139
T_e: array_typing.FloatVector,
4240
ne_tau: array_typing.FloatScalar,
4341
ion_symbol: str,
44-
variable: MavrinVariable,
4542
) -> jax.Array:
4643
"""Calculates the average charge state of an impurity based on a polynomial fit.
4744
@@ -55,32 +52,18 @@ def calculate_mavrin_2017(
5552
impurity residence time [m^-3 s]. High values of ne_tau correspond to the
5653
coronal limit.
5754
ion_symbol: Species to calculate average charge state for.
58-
variable: The variable to calculate, either 'Z' (charge states) or 'LZ'
59-
(radiative cooling rates).
6055
6156
Returns:
62-
Either average charge states or cooling rate, depending on the variable.
57+
Average charge state of the impurity.
6358
"""
6459

65-
match variable:
66-
case MavrinVariable.Z:
67-
cr_module = mavrin_2017_charge_states_data
68-
case MavrinVariable.LZ:
69-
cr_module = mavrin_2017_cooling_rate_data
70-
case _:
71-
allowed_variables = ', '.join([v.name for v in MavrinVariable])
72-
raise ValueError(
73-
f'Invalid fit variable: {variable}. Allowed variables are:'
74-
f' {allowed_variables}'
75-
)
76-
7760
# Alias He3 and He4 to He as they are chemically identical
7861
if ion_symbol in ('He3', 'He4'):
7962
ion_symbol_lookup = 'He'
8063
else:
8164
ion_symbol_lookup = ion_symbol
8265

83-
if ion_symbol_lookup not in cr_module.COEFFS.keys():
66+
if ion_symbol_lookup not in mavrin_2017_charge_states_data.COEFFS.keys():
8467
# If the ion is not supported by the edge radiation model, we assume it
8568
# negligibly contributes to the edge physics (radiation or Z_eff/dilution in
8669
# the divertor). This is a good assumption for heavy impurities like W,
@@ -91,18 +74,21 @@ def calculate_mavrin_2017(
9174
T_e_ev = T_e * 1e3
9275

9376
# Avoid extrapolating fitted polynomial out of bounds.
94-
min_temp = cr_module.MIN_TEMPERATURES[ion_symbol_lookup]
95-
max_temp = cr_module.MAX_TEMPERATURES[ion_symbol_lookup]
77+
min_temp = mavrin_2017_charge_states_data.MIN_TEMPERATURES[ion_symbol_lookup]
78+
max_temp = mavrin_2017_charge_states_data.MAX_TEMPERATURES[ion_symbol_lookup]
9679
T_e_ev = jnp.clip(T_e_ev, min_temp, max_temp)
9780
# Residence parameter capped at 10^19, which is the coronal limit.
9881
ne_tau = jnp.clip(ne_tau, a_max=_NE_TAU_CORONAL_LIMIT)
9982

10083
# Gather coefficients for each temperature
10184
interval_indices = jnp.searchsorted(
102-
cr_module.TEMPERATURE_INTERVALS[ion_symbol_lookup], T_e_ev
85+
mavrin_2017_charge_states_data.TEMPERATURE_INTERVALS[ion_symbol_lookup],
86+
T_e_ev,
10387
)
10488
coeffs_in_range = jnp.take(
105-
cr_module.COEFFS[ion_symbol_lookup], interval_indices, axis=1
89+
mavrin_2017_charge_states_data.COEFFS[ion_symbol_lookup],
90+
interval_indices,
91+
axis=1,
10692
)
10793

10894
X = jnp.log10(T_e_ev)
@@ -161,11 +147,11 @@ def _calculate_L_INT(
161147
electron_temp = electron_temp_ev / 1e3
162148

163149
# Calculate Lz at each temperature point on the grid
164-
Lz_values = calculate_mavrin_2017(
150+
Lz_values = mavrin_fit.calculate_mavrin_cooling_rate(
165151
T_e=electron_temp,
166-
ne_tau=ne_tau,
167152
ion_symbol=ion_symbol,
168-
variable=MavrinVariable.LZ,
153+
model_type=mavrin_fit.MavrinModelType.NONCORONAL,
154+
ne_tau=ne_tau,
169155
)
170156

171157
# The integrand is Lz * sqrt(Te)

torax/_src/edge/divertor_sol_1d.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class ExtendedLengyelParameters:
6464
main_ion_charge: array_typing.FloatScalar # [dimensionless]
6565
average_ion_mass: array_typing.FloatScalar # [amu]
6666
mean_ion_charge_state: array_typing.FloatScalar # [dimensionless]
67+
# TODO(b/XXXXXX): (v2) Rename to ne_tau for consistency.
6768
ne_tau: array_typing.FloatScalar # [s m^-3]
6869
fraction_of_P_SOL_to_divertor: array_typing.FloatScalar # [dimensionless]
6970
SOL_conduction_fraction: array_typing.FloatScalar # [dimensionless]

torax/_src/edge/extended_lengyel_formulas.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -267,21 +267,23 @@ def calc_Z_eff(
267267
dilution_factor = 0.0
268268
# Contribution from seeded impurities, with n_e_ratio = c_z*weight.
269269
for key, weight in seed_impurity_weights.items():
270-
Z_impurity_per_species = collisional_radiative_models.calculate_mavrin_2017(
271-
T_e=jnp.array([T_e]),
272-
ne_tau=ne_tau,
273-
ion_symbol=key,
274-
variable=collisional_radiative_models.MavrinVariable.Z,
270+
Z_impurity_per_species = (
271+
collisional_radiative_models.calculate_mavrin_noncoronal_charge_state(
272+
T_e=jnp.array([T_e]),
273+
ne_tau=ne_tau,
274+
ion_symbol=key,
275+
)
275276
)
276277
Z_eff += Z_impurity_per_species**2 * c_z * weight
277278
dilution_factor += Z_impurity_per_species * c_z * weight
278279
# Contribution from fixed impurities, with n_e_ratio=concentration
279280
for key, concentration in fixed_impurity_concentrations.items():
280-
Z_impurity_per_species = collisional_radiative_models.calculate_mavrin_2017(
281-
T_e=jnp.array([T_e]),
282-
ne_tau=ne_tau,
283-
ion_symbol=key,
284-
variable=collisional_radiative_models.MavrinVariable.Z,
281+
Z_impurity_per_species = (
282+
collisional_radiative_models.calculate_mavrin_noncoronal_charge_state(
283+
T_e=jnp.array([T_e]),
284+
ne_tau=ne_tau,
285+
ion_symbol=key,
286+
)
285287
)
286288
Z_eff += Z_impurity_per_species**2 * concentration
287289
dilution_factor += Z_impurity_per_species * concentration

0 commit comments

Comments
 (0)