Source code for cfspopcon.formulas.energy_confinement.switch_confinement_scaling_on_threshold

"""Switch the confinement scaling used if below a threshold power or density."""

import xarray as xr

from ...algorithm_class import Algorithm
from ...unit_handling import Unitfull
from .solve_for_input_power import solve_energy_confinement_scaling_for_input_power


[docs] @Algorithm.register_algorithm(return_keys=["energy_confinement_time", "P_in", "SOC_LOC_ratio"]) def switch_to_linearised_ohmic_confinement_below_threshold( plasma_stored_energy: Unitfull, energy_confinement_time: Unitfull, P_in: Unitfull, average_electron_density: Unitfull, confinement_time_scalar: Unitfull, plasma_current: Unitfull, magnetic_field_on_axis: Unitfull, major_radius: Unitfull, areal_elongation: Unitfull, separatrix_elongation: Unitfull, inverse_aspect_ratio: Unitfull, average_ion_mass: Unitfull, triangularity_psi95: Unitfull, separatrix_triangularity: Unitfull, q_star: Unitfull, ) -> tuple[Unitfull, ...]: """Switch to the LOC scaling if it predicts a worse energy confinement than our selected tau_e scaling. Args: plasma_stored_energy: :term:`glossary link<plasma_stored_energy>` energy_confinement_time: :term:`glossary link<energy_confinement_time>` P_in: :term:`glossary link<P_in>` average_electron_density: :term:`glossary link<average_electron_density>` confinement_time_scalar: :term:`glossary link<confinement_time_scalar>` plasma_current: :term:`glossary link<plasma_current>` magnetic_field_on_axis: :term:`glossary link<magnetic_field_on_axis>` major_radius: :term:`glossary link<major_radius>` areal_elongation: :term:`glossary link<areal_elongation>` separatrix_elongation: :term:`glossary link<separatrix_elongation>` inverse_aspect_ratio: :term:`glossary link<inverse_aspect_ratio>` average_ion_mass: :term:`glossary link<average_ion_mass>` triangularity_psi95: :term:`glossary link<triangularity_psi95>` separatrix_triangularity: :term:`glossary link<separatrix_triangularity>` q_star: :term:`glossary link<q_star>` Returns: :term:`energy_confinement_time`, :term:`P_in`, :term:`SOC_LOC_ratio` """ tau_e_LOC, P_in_LOC = solve_energy_confinement_scaling_for_input_power( confinement_time_scalar=confinement_time_scalar, plasma_current=plasma_current, magnetic_field_on_axis=magnetic_field_on_axis, average_electron_density=average_electron_density, major_radius=major_radius, areal_elongation=areal_elongation, separatrix_elongation=separatrix_elongation, inverse_aspect_ratio=inverse_aspect_ratio, average_ion_mass=average_ion_mass, triangularity_psi95=triangularity_psi95, separatrix_triangularity=separatrix_triangularity, plasma_stored_energy=plasma_stored_energy, q_star=q_star, energy_confinement_scaling="LOC", ) # Use Linearized Ohmic Confinement if it gives worse energy confinement. SOC_LOC_ratio = energy_confinement_time / tau_e_LOC energy_confinement_time = xr.where(SOC_LOC_ratio > 1.0, tau_e_LOC, energy_confinement_time) # type:ignore[no-untyped-call] P_in = xr.where(SOC_LOC_ratio > 1.0, P_in_LOC, P_in) # type:ignore[no-untyped-call] return (energy_confinement_time, P_in, SOC_LOC_ratio)
[docs] @Algorithm.register_algorithm(return_keys=["energy_confinement_time", "P_in"]) def switch_to_L_mode_confinement_below_threshold( plasma_stored_energy: Unitfull, energy_confinement_time: Unitfull, P_in: Unitfull, average_electron_density: Unitfull, confinement_time_scalar: Unitfull, plasma_current: Unitfull, magnetic_field_on_axis: Unitfull, major_radius: Unitfull, areal_elongation: Unitfull, separatrix_elongation: Unitfull, inverse_aspect_ratio: Unitfull, average_ion_mass: Unitfull, triangularity_psi95: Unitfull, separatrix_triangularity: Unitfull, q_star: Unitfull, ratio_of_P_SOL_to_P_LH: Unitfull, energy_confinement_scaling_for_L_mode: Unitfull, ) -> tuple[Unitfull, ...]: """Switch to the L-mode scaling if Psol < PLH. Args: plasma_stored_energy: :term:`glossary link<plasma_stored_energy>` energy_confinement_time: :term:`glossary link<energy_confinement_time>` P_in: :term:`glossary link<P_in>` average_electron_density: :term:`glossary link<average_electron_density>` confinement_time_scalar: :term:`glossary link<confinement_time_scalar>` plasma_current: :term:`glossary link<plasma_current>` magnetic_field_on_axis: :term:`glossary link<magnetic_field_on_axis>` major_radius: :term:`glossary link<major_radius>` areal_elongation: :term:`glossary link<areal_elongation>` separatrix_elongation: :term:`glossary link<separatrix_elongation>` inverse_aspect_ratio: :term:`glossary link<inverse_aspect_ratio>` average_ion_mass: :term:`glossary link<average_ion_mass>` triangularity_psi95: :term:`glossary link<triangularity_psi95>` separatrix_triangularity: :term:`glossary link<separatrix_triangularity>` q_star: :term:`glossary link<q_star>` ratio_of_P_SOL_to_P_LH: :term:`glossary link<ratio_of_P_SOL_to_P_LH>` energy_confinement_scaling_for_L_mode: :term:`glossary link<energy_confinement_scaling_for_L_mode>` Returns: :term:`energy_confinement_time`, :term:`P_in` """ tau_e_L_mode, P_in_L_mode = solve_energy_confinement_scaling_for_input_power( confinement_time_scalar=confinement_time_scalar, plasma_current=plasma_current, magnetic_field_on_axis=magnetic_field_on_axis, average_electron_density=average_electron_density, major_radius=major_radius, areal_elongation=areal_elongation, separatrix_elongation=separatrix_elongation, inverse_aspect_ratio=inverse_aspect_ratio, average_ion_mass=average_ion_mass, triangularity_psi95=triangularity_psi95, separatrix_triangularity=separatrix_triangularity, plasma_stored_energy=plasma_stored_energy, q_star=q_star, energy_confinement_scaling=energy_confinement_scaling_for_L_mode, ) # Use L-mode confinement if Psol < PLH energy_confinement_time = xr.where(ratio_of_P_SOL_to_P_LH < 1.0, tau_e_L_mode, energy_confinement_time) # type:ignore[no-untyped-call] P_in = xr.where(ratio_of_P_SOL_to_P_LH < 1.0, P_in_L_mode, P_in) # type:ignore[no-untyped-call] return energy_confinement_time, P_in