-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement model to calculate edge impurity conc.
- Loading branch information
Showing
13 changed files
with
239 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
"""Run the two point model with a fixed sheath entrance temperature.""" | ||
|
||
|
||
from ..atomic_data import read_atomic_data | ||
from ..formulas.scrape_off_layer_model import build_L_int_integrator, calc_required_edge_impurity_concentration | ||
from ..named_options import Impurity | ||
from ..unit_handling import Unitfull, convert_to_default_units, ureg | ||
from .algorithm_class import Algorithm | ||
|
||
RETURN_KEYS = [ | ||
"edge_impurity_concentration", | ||
] | ||
|
||
|
||
def run_calc_edge_impurity_concentration( | ||
edge_impurity_species: Impurity, | ||
q_parallel: Unitfull, | ||
SOL_power_loss_fraction: Unitfull, | ||
target_electron_temp: Unitfull, | ||
upstream_electron_temp: Unitfull, | ||
upstream_electron_density: Unitfull, | ||
kappa_e0: Unitfull, | ||
lengyel_overestimation_factor: Unitfull, | ||
reference_electron_density: Unitfull = 1.0 * ureg.n20, | ||
reference_ne_tau: Unitfull = 1.0 * ureg.n20 * ureg.ms, | ||
) -> dict[str, Unitfull]: | ||
"""Calculate the impurity concentration required to cool the scrape-off-layer using the Lengyel model. | ||
Args: | ||
edge_impurity_species: :term:`glossary link<edge_impurity_species>` | ||
reference_electron_density: :term:`glossary link<reference_electron_density>` | ||
reference_ne_tau: :term:`glossary link<reference_ne_tau>` | ||
q_parallel: :term:`glossary link<q_parallel>` | ||
SOL_power_loss_fraction: :term:`glossary link<SOL_power_loss_fraction>` | ||
target_electron_temp: :term:`glossary link<target_electron_temp>` | ||
upstream_electron_temp: :term:`glossary link<upstream_electron_temp>` | ||
upstream_electron_density: :term:`glossary link<upstream_electron_density>` | ||
kappa_e0: :term:`glossary link<kappa_e0>` | ||
lengyel_overestimation_factor: :term:`glossary link<lengyel_overestimation_factor>` | ||
Returns: | ||
:term:`edge_impurity_concentration` | ||
""" | ||
atomic_data = read_atomic_data() | ||
|
||
L_int_integrator = build_L_int_integrator( | ||
atomic_data=atomic_data, | ||
impurity_species=edge_impurity_species, | ||
reference_electron_density=reference_electron_density, | ||
reference_ne_tau=reference_ne_tau, | ||
) | ||
|
||
edge_impurity_concentration = calc_required_edge_impurity_concentration( | ||
L_int_integrator=L_int_integrator, | ||
q_parallel=q_parallel, | ||
SOL_power_loss_fraction=SOL_power_loss_fraction, | ||
target_electron_temp=target_electron_temp, | ||
upstream_electron_temp=upstream_electron_temp, | ||
upstream_electron_density=upstream_electron_density, | ||
kappa_e0=kappa_e0, | ||
lengyel_overestimation_factor=lengyel_overestimation_factor, | ||
) | ||
|
||
local_vars = locals() | ||
return {key: convert_to_default_units(local_vars[key], key) for key in RETURN_KEYS} | ||
|
||
|
||
calc_edge_impurity_concentration = Algorithm( | ||
function=run_calc_edge_impurity_concentration, | ||
return_keys=RETURN_KEYS, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
cfspopcon/formulas/scrape_off_layer_model/edge_impurity_concentration.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
"""Lengyel model to compute the edge impurity concentration.""" | ||
from typing import Callable | ||
|
||
import numpy as np | ||
import xarray as xr | ||
from scipy.interpolate import InterpolatedUnivariateSpline | ||
|
||
from ...named_options import Impurity | ||
from ...unit_handling import Unitfull, convert_units, magnitude, ureg, wraps_ufunc | ||
|
||
|
||
def build_L_int_integrator( | ||
atomic_data: dict[Impurity, Unitfull], | ||
impurity_species: Impurity, | ||
reference_electron_density: Unitfull, | ||
reference_ne_tau: Unitfull, | ||
) -> Callable[[Unitfull, Unitfull], Unitfull]: | ||
r"""Build an interpolator to calculate L_{int}$ between arbitrary temperature points. | ||
$L_int = \int_a^b L_z(T_e) sqrt(T_e) dT_e$ where $L_z$ is a cooling curve for an impurity species. | ||
This is used in the calculation of the radiated power associated with a given impurity. | ||
Args: | ||
atomic_data: :term:`glossary link<atomic_data>` | ||
impurity_species: [] :term:`glossary link<impurity_species>` | ||
reference_electron_density: [n20] :term:`glossary link<reference_electron_density>` | ||
reference_ne_tau: [n20 * ms] :term:`glossary link<reference_ne_tau>` | ||
Returns: | ||
:term:`L_int_interpolator` | ||
""" | ||
if isinstance(impurity_species, xr.DataArray): | ||
impurity_species = impurity_species.item() | ||
|
||
Lz_curve = atomic_data[impurity_species].noncoronal_electron_emission_prefactor.sel( | ||
dim_log_electron_density=np.log10(magnitude(convert_units(reference_electron_density, ureg.m**-3))), | ||
dim_log_ne_tau=np.log10(magnitude(convert_units(reference_ne_tau, ureg.m**-3 * ureg.s))), | ||
) | ||
|
||
log_electron_temp = Lz_curve.dim_log_electron_temperature | ||
electron_temp = np.power(10, log_electron_temp) | ||
Lz_sqrt_Te = Lz_curve * np.sqrt(electron_temp) | ||
|
||
interpolator = InterpolatedUnivariateSpline(electron_temp, magnitude(Lz_sqrt_Te)) | ||
def L_int(start_temp, stop_temp): | ||
return interpolator.integral(start_temp, stop_temp) | ||
|
||
return wraps_ufunc( | ||
input_units=dict(start_temp=ureg.eV, stop_temp=ureg.eV), return_units=dict(L_int=ureg.W * ureg.m**3 * ureg.eV**1.5) | ||
)(L_int) | ||
|
||
|
||
def calc_required_edge_impurity_concentration( | ||
L_int_integrator: Callable[[Unitfull, Unitfull], Unitfull], | ||
q_parallel: Unitfull, | ||
SOL_power_loss_fraction: Unitfull, | ||
target_electron_temp: Unitfull, | ||
upstream_electron_temp: Unitfull, | ||
upstream_electron_density: Unitfull, | ||
kappa_e0: Unitfull, | ||
lengyel_overestimation_factor: Unitfull, | ||
) -> Unitfull: | ||
"""Calculate the relative concentration of an edge impurity required to achieve a given SOL power loss fraction. | ||
N.b. this function does not ensure consistency of the calculated impurity concentration | ||
with the parallel temperature profile. You may wish to implement an iterative solver | ||
to find a consistent set of L_parallel, T_t and T_u. | ||
Args: | ||
L_int_integrator: :term:`glossary link<L_int_integrator>` | ||
q_parallel: :term:`glossary link<q_parallel>` | ||
SOL_power_loss_fraction: :term:`glossary link<SOL_power_loss_fraction>` | ||
target_electron_temp: :term:`glossary link<target_electron_temp>` | ||
upstream_electron_temp: :term:`glossary link<upstream_electron_temp>` | ||
upstream_electron_density: :term:`glossary link<upstream_electron_density>` | ||
kappa_e0: :term:`glossary link<kappa_e0>` | ||
lengyel_overestimation_factor: :term:`glossary link<lengyel_overestimation_factor>` | ||
Returns: | ||
:term:`impurity_concentration` | ||
""" | ||
L_int = L_int_integrator(target_electron_temp, upstream_electron_temp) | ||
|
||
numerator = q_parallel**2 - ((1.0 - SOL_power_loss_fraction) * q_parallel) ** 2 | ||
denominator = 2.0 * kappa_e0 * (upstream_electron_density * upstream_electron_temp) ** 2 * L_int | ||
|
||
return numerator / denominator / lengyel_overestimation_factor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.