From 137859f67de2618aaf4229fb1c82c055b62d06a8 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Tue, 6 Aug 2024 14:20:41 -0600 Subject: [PATCH 01/24] initial commit of HeatingPower objective --- desc/objectives/_confinement.py | 267 ++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 desc/objectives/_confinement.py diff --git a/desc/objectives/_confinement.py b/desc/objectives/_confinement.py new file mode 100644 index 0000000000..67a0cb6517 --- /dev/null +++ b/desc/objectives/_confinement.py @@ -0,0 +1,267 @@ +"""Objectives for targeting energy confinement.""" + +import numpy as np + +from desc.backend import jnp +from desc.compute.utils import _compute as compute_fun +from desc.compute.utils import get_profiles, get_transforms +from desc.grid import LinearGrid, QuadratureGrid +from desc.utils import Timer, errorif + +from .objective_funs import _Objective + + +class HeatingPower(_Objective): + """Heating power required by the ISS04 energy confinement time scaling. + + tau_E^ISS04 = 0.134 a^2.28 R^0.64 P^-0.61 n_e^0.54 B^0.84 iota^0.41 (s) + + Parameters + ---------- + eq : Equilibrium + Equilibrium that will be optimized to satisfy the Objective. + target : {float, ndarray}, optional + Target value(s) of the objective. Only used if bounds is None. + Must be broadcastable to Objective.dim_f. Defaults to ``target=0``. + bounds : tuple of {float, ndarray}, optional + Lower and upper bounds on the objective. Overrides target. + Both bounds must be broadcastable to to Objective.dim_f. + Defaults to ``target=0``. + weight : {float, ndarray}, optional + Weighting to apply to the Objective, relative to other Objectives. + Must be broadcastable to to Objective.dim_f + normalize : bool, optional + Whether to compute the error in physical units or non-dimensionalize. + Has no effect for this objective. + normalize_target : bool, optional + Whether target and bounds should be normalized before comparing to computed + values. If `normalize` is `True` and the target is in physical units, + this should also be set to True. Note: Has no effect for this objective. + loss_function : {None, 'mean', 'min', 'max'}, optional + Loss function to apply to the objective values once computed. This loss function + is called on the raw compute value, before any shifting, scaling, or + normalization. Note: Has no effect for this objective. + deriv_mode : {"auto", "fwd", "rev"} + Specify how to compute jacobian matrix, either forward mode or reverse mode AD. + "auto" selects forward or reverse mode based on the size of the input and output + of the objective. Has no effect on self.grad or self.hess which always use + reverse mode and forward over reverse mode respectively. + f_ren : float, optional + Renormalization or confinement enhancement factor. Defaults = 1. + gamma : float, optional + Adiabatic (compressional) index. Default = 0. + grid_geometry : Grid, optional + Collocation grid used to compute the major and minor radii. + Defaults to ``QuadratureGrid(eq.L_grid, eq.M_grid, eq.N_grid)``. + grid_density : Grid, optional + Collocation grid used to compute the line-averaged density. + Defaults to ``QuadratureGrid(eq.L_grid, eq.M_grid, eq.N_grid)``. + grid_B : Grid, optional + Collocation grid used to compute the magnetic field strength. + Defaults to ``QuadratureGrid(eq.L_grid, eq.M_grid, eq.N_grid)``. + grid_iota : Grid, optional + Collocation grid used to compute the rotational transform. + Defaults to ``QuadratureGrid(eq.L_grid, eq.M_grid, eq.N_grid)``. + name : str, optional + Name of the objective function. + + """ + + _scalar = True + _units = "(W)" + _print_value_fmt = "Heating power: {:10.3e} " + + def __init__( + self, + eq, + target=None, + bounds=None, + weight=1, + normalize=True, + normalize_target=True, + loss_function=None, + deriv_mode="auto", + f_ren=1, + gamma=0, + grid_geometry=None, + grid_density=None, + grid_B=None, + grid_iota=None, + name="heating power", + ): + if target is None and bounds is None: + target = 2 + self._f_ren = f_ren + self._gamma = gamma + self._grid_geometry = grid_geometry + self._grid_density = grid_density + self._grid_B = grid_B + self._grid_iota = grid_iota + super().__init__( + things=eq, + target=target, + bounds=bounds, + weight=weight, + normalize=normalize, + normalize_target=normalize_target, + loss_function=loss_function, + deriv_mode=deriv_mode, + name=name, + ) + + def build(self, use_jit=True, verbose=1): + """Build constant arrays. + + Parameters + ---------- + use_jit : bool, optional + Whether to just-in-time compile the objective and derivatives. + verbose : int, optional + Level of output. + + """ + eq = self.things[0] + errorif( + eq.electron_density is None, + ValueError, + "Equilibrium must have an electron density profile.", + ) + + if self._grid_geometry is None: + self._grid_geometry = QuadratureGrid( + L=eq.L_grid, + M=eq.M_grid, + N=eq.N_grid, + NFP=eq.NFP, + ) + if self._grid_density is None: + self._grid_density = LinearGrid(L=eq.L_grid, M=0, N=0) + if self._grid_B is None: + self._grid_B = LinearGrid(rho=np.array([0]), N=eq.N_grid, NFP=eq.NFP) + if self._grid_iota is None: + self._grid_iota = LinearGrid( + rho=np.array([2 / 3.0]), M=eq.M_grid, N=eq.N_grid, NFP=eq.NFP + ) + + self._dim_f = 1 + self._data_keys_geometry = ["a", "R0", "W_p"] + self._data_keys_density = ["ne"] + self._data_keys_B = ["|B|"] + self._data_keys_iota = ["iota"] + + timer = Timer() + if verbose > 0: + print("Precomputing transforms") + timer.start("Precomputing transforms") + + self._constants = { + "profiles_geometry": get_profiles( + self._data_keys_geometry, obj=eq, grid=self._grid_geometry + ), + "transforms_geometry": get_transforms( + self._data_keys_geometry, obj=eq, grid=self._grid_geometry + ), + "profiles_density": get_profiles( + self._data_keys_density, obj=eq, grid=self._grid_density + ), + "transforms_density": get_transforms( + self._data_keys_density, obj=eq, grid=self._grid_density + ), + "profiles_B": get_profiles(self._data_keys_B, obj=eq, grid=self._grid_B), + "transforms_B": get_transforms( + self._data_keys_B, obj=eq, grid=self._grid_B + ), + "profiles_iota": get_profiles( + self._data_keys_iota, obj=eq, grid=self._grid_iota + ), + "transforms_iota": get_transforms( + self._data_keys_iota, obj=eq, grid=self._grid_iota + ), + "f_ren": self._f_ren, + "gamma": self._gamma, + } + + timer.stop("Precomputing transforms") + if verbose > 1: + timer.disp("Precomputing transforms") + + super().build(use_jit=use_jit, verbose=verbose) + + def compute(self, params, constants=None): + """Compute heating power. + + Parameters + ---------- + params : dict + Dictionary of equilibrium or surface degrees of freedom, eg + Equilibrium.params_dict + constants : dict + Dictionary of constant data, eg transforms, profiles etc. Defaults to + self.constants + + Returns + ------- + P : float + Heating power required by the ISS04 energy confinement time scaling (W). + + """ + if constants is None: + constants = self.constants + data_geometry = compute_fun( + "desc.equilibrium.equilibrium.Equilibrium", + self._data_keys_geometry, + params=params, + transforms=constants["transforms_geometry"], + profiles=constants["profiles_geometry"], + gamma=constants["gamma"], + ) + data_density = compute_fun( + "desc.equilibrium.equilibrium.Equilibrium", + self._data_keys_density, + params=params, + transforms=constants["transforms_density"], + profiles=constants["profiles_density"], + ) + data_B = compute_fun( + "desc.equilibrium.equilibrium.Equilibrium", + self._data_keys_B, + params=params, + transforms=constants["transforms_B"], + profiles=constants["profiles_B"], + ) + data_iota = compute_fun( + "desc.equilibrium.equilibrium.Equilibrium", + self._data_keys_iota, + params=params, + transforms=constants["transforms_iota"], + profiles=constants["profiles_iota"], + ) + + P = (data_geometry["W_p"] / 1e6) / ( # MJ + 0.134 + * data_geometry["a"] ** 2.28 # m + * data_geometry["R0"] ** 0.64 # m + * (jnp.mean(data_density["n_e"]) ** 0.54 / 1e19) # 1e19/m^3 + * jnp.mean(data_B["|B|"]) ** 0.84 # T + * jnp.mean(data_iota["iota"]) ** 0.41 + * constants["f_ren"] + ) ** -0.39 + return P + + @property + def f_ren(self): + """float: Confinement enhancement factor.""" + return self._f_ren + + @f_ren.setter + def f_ren(self, new): + self._f_ren = new + + @property + def gamma(self): + """float: Adiabatic (compressional) index.""" + return self._gamma + + @gamma.setter + def gamma(self, new): + self._gamma = new From 551e9068828c058a2ead8cdbd131c31509f25b22 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Tue, 6 Aug 2024 14:37:12 -0600 Subject: [PATCH 02/24] compute quantity for ni --- desc/compute/_profiles.py | 49 ++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/desc/compute/_profiles.py b/desc/compute/_profiles.py index ccb701f072..00a12cb93a 100644 --- a/desc/compute/_profiles.py +++ b/desc/compute/_profiles.py @@ -354,6 +354,44 @@ def _Ti_rr(params, transforms, profiles, data, **kwargs): return data +@register_compute_fun( + name="ni", + label="n_i", + units="m^{-3}", + units_long="1 / cubic meters", + description="Ion density", + dim=1, + params=[], + transforms={"grid": []}, + profiles=[], + coordinates="r", + data=["ne", "Zeff"], +) +def _ni(params, transforms, profiles, data, **kwargs): + data["ni"] = data["ne"] / data["Zeff"] + return data + + +@register_compute_fun( + name="ni_r", + label="\\partial_{\\rho} n_i", + units="m^{-3}", + units_long="1 / cubic meters", + description="Ion density, first radial derivative", + dim=1, + params=[], + transforms={"grid": []}, + profiles=[], + coordinates="r", + data=["ne", "ne_r", "Zeff", "Zeff_r"], +) +def _ni_r(params, transforms, profiles, data, **kwargs): + data["ni_r"] = (data["ne_r"] * data["Zeff"] - data["ne"] * data["Zeff_r"]) / data[ + "Zeff" + ] ** 2 + return data + + @register_compute_fun( name="Zeff", label="Z_{eff}", @@ -411,7 +449,7 @@ def _Zeff_r(params, transforms, profiles, data, **kwargs): transforms={"grid": []}, profiles=["pressure"], coordinates="r", - data=["Te", "ne", "Ti", "Zeff"], + data=["ne", "ni", "Te", "Ti"], ) def _p(params, transforms, profiles, data, **kwargs): if profiles["pressure"] is not None: @@ -420,7 +458,7 @@ def _p(params, transforms, profiles, data, **kwargs): ) else: data["p"] = elementary_charge * ( - data["ne"] * data["Te"] + data["Ti"] * data["ne"] / data["Zeff"] + data["ne"] * data["Te"] + data["ni"] * data["Ti"] ) return data @@ -436,7 +474,7 @@ def _p(params, transforms, profiles, data, **kwargs): transforms={"grid": []}, profiles=["pressure"], coordinates="r", - data=["Te", "Te_r", "ne", "ne_r", "Ti", "Ti_r", "Zeff", "Zeff_r"], + data=["ne", "ne_r", "ni", "ni_r", "Te", "Te_r", "Ti", "Ti_r"], ) def _p_r(params, transforms, profiles, data, **kwargs): if profiles["pressure"] is not None: @@ -447,9 +485,8 @@ def _p_r(params, transforms, profiles, data, **kwargs): data["p_r"] = elementary_charge * ( data["ne_r"] * data["Te"] + data["ne"] * data["Te_r"] - + data["Ti_r"] * data["ne"] / data["Zeff"] - + data["Ti"] * data["ne_r"] / data["Zeff"] - - data["Ti"] * data["ne"] * data["Zeff_r"] / data["Zeff"] ** 2 + + data["ni_r"] * data["Ti"] + + data["ni"] * data["Ti_r"] ) return data From 04184af5f76aa60ce20a72f49348442a8215623a Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Tue, 6 Aug 2024 14:53:20 -0600 Subject: [PATCH 03/24] add _rho compute quantity --- desc/compute/_profiles.py | 20 ++++++++++++++++++++ tests/test_profiles.py | 15 +++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/desc/compute/_profiles.py b/desc/compute/_profiles.py index 00a12cb93a..8faeef5dbe 100644 --- a/desc/compute/_profiles.py +++ b/desc/compute/_profiles.py @@ -216,6 +216,26 @@ def _Te_rr(params, transforms, profiles, data, **kwargs): return data +@register_compute_fun( + name="_rho", + label="\\bar{n}_e", + units="m^{-3}", + units_long="1 / cubic meters", + description="Line-averaged electron density", + dim=0, + params=[], + transforms={"grid": []}, + profiles=[], + coordinates="", + data=["ne"], +) +def _bar_ne(params, transforms, profiles, data, **kwargs): + data["_rho"] = jnp.sum(data["ne"] * transforms["grid"].spacing[:, 0]) / jnp.sum( + transforms["grid"].spacing[:, 0] + ) + return data + + @register_compute_fun( name="ne", label="n_e", diff --git a/tests/test_profiles.py b/tests/test_profiles.py index 530fd5f765..f96834de00 100644 --- a/tests/test_profiles.py +++ b/tests/test_profiles.py @@ -408,7 +408,6 @@ def test_solve_with_combined(self): Te = PowerSeriesProfile(2.0e3 * np.array([1, -1]), modes=[0, 2]) Ti = Te pressure = elementary_charge * (ne * Te + ne * Ti) - print("pressure params:", pressure.params) LM_resolution = 6 eq1 = Equilibrium( @@ -461,7 +460,6 @@ def test_kinetic_pressure(self): Te = PowerSeriesProfile(2.0e3 * np.array([1, -1]), modes=[0, 2]) Ti = Te pressure = elementary_charge * (ne * Te + ne * Ti) - print("pressure params:", pressure.params) LM_resolution = 6 eq1 = Equilibrium( @@ -507,3 +505,16 @@ def test_kinetic_pressure(self): assert np.all(data2["Te_r"] == data2["Ti_r"]) np.testing.assert_allclose(data1["p"], data2["p"]) np.testing.assert_allclose(data1["p_r"], data2["p_r"]) + + @pytest.mark.unit + def test_line_average(self): + """Test that line-averaged profiles are correct.""" + ne0 = 3e19 + Te0 = 2e3 + ne = PowerSeriesProfile(2 * ne0 * np.array([1, -1]), modes=[0, 1]) + Te = PowerSeriesProfile(2 * Te0 * np.array([1, -1]), modes=[0, 1]) + + with pytest.raises(UserWarning): + eq = Equilibrium(electron_density=ne, electron_temperature=Te) + data = eq.compute("_rho") + np.testing.assert_allclose(data["_rho"], ne0) From 5609439624c1ae35dc9d39806f28afea66e53f91 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Tue, 6 Aug 2024 15:06:49 -0600 Subject: [PATCH 04/24] add iota_23 compute quantity --- desc/compute/_profiles.py | 22 ++++++++++++++++++++++ tests/test_profiles.py | 12 ++++++++++++ 2 files changed, 34 insertions(+) diff --git a/desc/compute/_profiles.py b/desc/compute/_profiles.py index 8faeef5dbe..951128c17c 100644 --- a/desc/compute/_profiles.py +++ b/desc/compute/_profiles.py @@ -9,6 +9,7 @@ expensive computations. """ +from interpax import interp1d from scipy.constants import elementary_charge, mu_0 from desc.backend import cond, jnp @@ -743,6 +744,27 @@ def _gradbeta_a(params, transforms, profiles, data, **kwargs): return data +@register_compute_fun( + name="iota_23", + label="\\iota_{2/3}", + units="~", + units_long="None", + description="Rotational transform (normalized by 2pi) at rho=2/3", + dim=0, + params=[], + transforms={"grid": []}, + profiles=[], + coordinates="", + data=["rho", "iota"], + method="str: Interpolation method. Default 'cubic'.", +) +def _iota_23(params, transforms, profiles, data, **kwargs): + rho = transforms["grid"].compress(data["rho"], surface_label="rho") + iota = transforms["grid"].compress(data["iota"], surface_label="rho") + data["iota_23"] = interp1d(2 / 3, rho, iota, method=kwargs.get("method", "cubic")) + return data + + @register_compute_fun( name="iota", label="\\iota", diff --git a/tests/test_profiles.py b/tests/test_profiles.py index f96834de00..46fd76c099 100644 --- a/tests/test_profiles.py +++ b/tests/test_profiles.py @@ -518,3 +518,15 @@ def test_line_average(self): eq = Equilibrium(electron_density=ne, electron_temperature=Te) data = eq.compute("_rho") np.testing.assert_allclose(data["_rho"], ne0) + + @pytest.mark.unit + def test_interpolation(self): + """Test that interpolated profile values are correct.""" + iota0 = 0.2 + diota = 1.2 + iota = PowerSeriesProfile(np.array([iota0, diota]), modes=[0, 1]) + + with pytest.raises(UserWarning): + eq = Equilibrium(iota=iota) + data = eq.compute("iota_23") + np.testing.assert_allclose(data["iota_23"], iota0 + diota * (2 / 3)) From 515850f0e83e1a7e69734ffad4354742eecb6c67 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Tue, 6 Aug 2024 15:21:50 -0600 Subject: [PATCH 05/24] rename 'B0' to 'psi_r/sqrt(g)' --- desc/compute/_field.py | 336 +++++++++++++++++++++--------------- desc/compute/_omnigenity.py | 18 +- tests/test_axis_limits.py | 2 +- tests/test_plotting.py | 2 +- 4 files changed, 214 insertions(+), 144 deletions(-) diff --git a/desc/compute/_field.py b/desc/compute/_field.py index c3c95d86a7..36f13da8bf 100644 --- a/desc/compute/_field.py +++ b/desc/compute/_field.py @@ -27,7 +27,7 @@ @register_compute_fun( - name="B0", + name="psi_r/sqrt(g)", label="\\psi' / \\sqrt{g}", units="T \\cdot m^{-1}", units_long="Tesla / meter", @@ -40,8 +40,8 @@ data=["psi_r", "sqrt(g)"], axis_limit_data=["psi_rr", "sqrt(g)_r"], ) -def _B0(params, transforms, profiles, data, **kwargs): - data["B0"] = transforms["grid"].replace_at_axis( +def _psi_r_over_sqrtg(params, transforms, profiles, data, **kwargs): + data["psi_r/sqrt(g)"] = transforms["grid"].replace_at_axis( safediv(data["psi_r"], data["sqrt(g)"]), lambda: safediv(data["psi_rr"], data["sqrt(g)_r"]), ) @@ -77,10 +77,10 @@ def _B_sup_rho(params, transforms, profiles, data, **kwargs): transforms={}, profiles=[], coordinates="rtz", - data=["B0", "iota", "lambda_z", "omega_z"], + data=["psi_r/sqrt(g)", "iota", "lambda_z", "omega_z"], ) def _B_sup_theta(params, transforms, profiles, data, **kwargs): - data["B^theta"] = data["B0"] * ( + data["B^theta"] = data["psi_r/sqrt(g)"] * ( data["iota"] * data["omega_z"] + data["iota"] - data["lambda_z"] ) return data @@ -97,10 +97,10 @@ def _B_sup_theta(params, transforms, profiles, data, **kwargs): transforms={}, profiles=[], coordinates="rtz", - data=["B0", "iota", "lambda_t", "omega_t"], + data=["psi_r/sqrt(g)", "iota", "lambda_t", "omega_t"], ) def _B_sup_zeta(params, transforms, profiles, data, **kwargs): - data["B^zeta"] = data["B0"] * ( + data["B^zeta"] = data["psi_r/sqrt(g)"] * ( -data["iota"] * data["omega_t"] + data["lambda_t"] + 1 ) return data @@ -181,7 +181,7 @@ def _B_Z(params, transforms, profiles, data, **kwargs): @register_compute_fun( - name="B0_r", + name="(psi_r/sqrt(g))_r", label="\\partial_{\\rho} (\\psi' / \\sqrt{g})", units="T \\cdot m^{-1}", units_long="Tesla / meter", @@ -194,8 +194,8 @@ def _B_Z(params, transforms, profiles, data, **kwargs): data=["psi_r", "psi_rr", "sqrt(g)", "sqrt(g)_r"], axis_limit_data=["psi_rrr", "sqrt(g)_rr"], ) -def _B0_r(params, transforms, profiles, data, **kwargs): - data["B0_r"] = transforms["grid"].replace_at_axis( +def _psi_r_over_sqrtg_r(params, transforms, profiles, data, **kwargs): + data["(psi_r/sqrt(g))_r"] = transforms["grid"].replace_at_axis( safediv( data["psi_rr"] * data["sqrt(g)"] - data["psi_r"] * data["sqrt(g)_r"], data["sqrt(g)"] ** 2, @@ -223,8 +223,8 @@ def _B0_r(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_r", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_r", "iota", "iota_r", "lambda_rz", @@ -234,12 +234,12 @@ def _B0_r(params, transforms, profiles, data, **kwargs): ], ) def _B_sup_theta_r(params, transforms, profiles, data, **kwargs): - data["B^theta_r"] = data["B0"] * ( + data["B^theta_r"] = data["psi_r/sqrt(g)"] * ( data["iota"] * data["omega_rz"] + data["iota_r"] * data["omega_z"] + data["iota_r"] - data["lambda_rz"] - ) + data["B0_r"] * ( + ) + data["(psi_r/sqrt(g))_r"] * ( data["iota"] * data["omega_z"] + data["iota"] - data["lambda_z"] ) return data @@ -260,8 +260,8 @@ def _B_sup_theta_r(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_r", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_r", "iota", "iota_r", "lambda_rt", @@ -271,11 +271,13 @@ def _B_sup_theta_r(params, transforms, profiles, data, **kwargs): ], ) def _B_sup_zeta_r(params, transforms, profiles, data, **kwargs): - data["B^zeta_r"] = data["B0"] * ( + data["B^zeta_r"] = data["psi_r/sqrt(g)"] * ( -data["iota"] * data["omega_rt"] - data["iota_r"] * data["omega_t"] + data["lambda_rt"] - ) + data["B0_r"] * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) + ) + data["(psi_r/sqrt(g))_r"] * ( + -data["iota"] * data["omega_t"] + data["lambda_t"] + 1 + ) return data @@ -312,7 +314,7 @@ def _B_r(params, transforms, profiles, data, **kwargs): @register_compute_fun( - name="B0_t", + name="(psi_r/sqrt(g))_t", label="\\partial_{\\theta} (\\psi' / \\sqrt{g})", units="T \\cdot m^{-1}", units_long="Tesla / meter", @@ -325,8 +327,8 @@ def _B_r(params, transforms, profiles, data, **kwargs): data=["psi_r", "sqrt(g)", "sqrt(g)_t"], axis_limit_data=["psi_rr", "sqrt(g)_r", "sqrt(g)_rt"], ) -def _B0_t(params, transforms, profiles, data, **kwargs): - data["B0_t"] = transforms["grid"].replace_at_axis( +def _psi_r_over_sqrtg_t(params, transforms, profiles, data, **kwargs): + data["(psi_r/sqrt(g))_t"] = transforms["grid"].replace_at_axis( safediv(-data["psi_r"] * data["sqrt(g)_t"], data["sqrt(g)"] ** 2), lambda: safediv(-data["psi_rr"] * data["sqrt(g)_rt"], data["sqrt(g)_r"] ** 2), ) @@ -347,12 +349,20 @@ def _B0_t(params, transforms, profiles, data, **kwargs): transforms={}, profiles=[], coordinates="rtz", - data=["B0", "B0_t", "iota", "lambda_tz", "lambda_z", "omega_tz", "omega_z"], + data=[ + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_t", + "iota", + "lambda_tz", + "lambda_z", + "omega_tz", + "omega_z", + ], ) def _B_sup_theta_t(params, transforms, profiles, data, **kwargs): - data["B^theta_t"] = data["B0"] * ( + data["B^theta_t"] = data["psi_r/sqrt(g)"] * ( data["iota"] * data["omega_tz"] - data["lambda_tz"] - ) + data["B0_t"] * ( + ) + data["(psi_r/sqrt(g))_t"] * ( data["iota"] * data["omega_z"] + data["iota"] - data["lambda_z"] ) return data @@ -372,12 +382,22 @@ def _B_sup_theta_t(params, transforms, profiles, data, **kwargs): transforms={}, profiles=[], coordinates="rtz", - data=["B0", "B0_t", "iota", "lambda_t", "lambda_tt", "omega_t", "omega_tt"], + data=[ + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_t", + "iota", + "lambda_t", + "lambda_tt", + "omega_t", + "omega_tt", + ], ) def _B_sup_zeta_t(params, transforms, profiles, data, **kwargs): - data["B^zeta_t"] = data["B0"] * ( + data["B^zeta_t"] = data["psi_r/sqrt(g)"] * ( -data["iota"] * data["omega_tt"] + data["lambda_tt"] - ) + data["B0_t"] * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) + ) + data["(psi_r/sqrt(g))_t"] * ( + -data["iota"] * data["omega_t"] + data["lambda_t"] + 1 + ) return data @@ -414,7 +434,7 @@ def _B_t(params, transforms, profiles, data, **kwargs): @register_compute_fun( - name="B0_z", + name="(psi_r/sqrt(g))_z", label="\\partial_{\\zeta} (\\psi' / \\sqrt{g})", units="T \\cdot m^{-1}", units_long="Tesla / meter", @@ -427,8 +447,8 @@ def _B_t(params, transforms, profiles, data, **kwargs): data=["psi_r", "sqrt(g)", "sqrt(g)_z"], axis_limit_data=["psi_rr", "sqrt(g)_r", "sqrt(g)_rz"], ) -def _B0_z(params, transforms, profiles, data, **kwargs): - data["B0_z"] = transforms["grid"].replace_at_axis( +def _psi_r_over_sqrtg_z(params, transforms, profiles, data, **kwargs): + data["(psi_r/sqrt(g))_z"] = transforms["grid"].replace_at_axis( safediv(-data["psi_r"] * data["sqrt(g)_z"], data["sqrt(g)"] ** 2), lambda: safediv(-data["psi_rr"] * data["sqrt(g)_rz"], data["sqrt(g)_r"] ** 2), ) @@ -449,12 +469,20 @@ def _B0_z(params, transforms, profiles, data, **kwargs): transforms={}, profiles=[], coordinates="rtz", - data=["B0", "B0_z", "iota", "lambda_z", "lambda_zz", "omega_z", "omega_zz"], + data=[ + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_z", + "iota", + "lambda_z", + "lambda_zz", + "omega_z", + "omega_zz", + ], ) def _B_sup_theta_z(params, transforms, profiles, data, **kwargs): - data["B^theta_z"] = data["B0"] * ( + data["B^theta_z"] = data["psi_r/sqrt(g)"] * ( data["iota"] * data["omega_zz"] - data["lambda_zz"] - ) + data["B0_z"] * ( + ) + data["(psi_r/sqrt(g))_z"] * ( data["iota"] * data["omega_z"] + data["iota"] - data["lambda_z"] ) return data @@ -474,12 +502,22 @@ def _B_sup_theta_z(params, transforms, profiles, data, **kwargs): transforms={}, profiles=[], coordinates="rtz", - data=["B0", "B0_z", "iota", "lambda_t", "lambda_tz", "omega_t", "omega_tz"], + data=[ + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_z", + "iota", + "lambda_t", + "lambda_tz", + "omega_t", + "omega_tz", + ], ) def _B_sup_zeta_z(params, transforms, profiles, data, **kwargs): - data["B^zeta_z"] = data["B0"] * ( + data["B^zeta_z"] = data["psi_r/sqrt(g)"] * ( -data["iota"] * data["omega_tz"] + data["lambda_tz"] - ) + data["B0_z"] * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) + ) + data["(psi_r/sqrt(g))_z"] * ( + -data["iota"] * data["omega_t"] + data["lambda_t"] + 1 + ) return data @@ -516,7 +554,7 @@ def _B_z(params, transforms, profiles, data, **kwargs): @register_compute_fun( - name="B0_rr", + name="(psi_r/sqrt(g))_rr", label="\\partial_{\\rho \\rho} (\\psi' / \\sqrt{g})", units="T \\cdot m^{-1}", units_long="Tesla / meters", @@ -529,8 +567,8 @@ def _B_z(params, transforms, profiles, data, **kwargs): data=["psi_r", "psi_rr", "psi_rrr", "sqrt(g)", "sqrt(g)_r", "sqrt(g)_rr"], axis_limit_data=["sqrt(g)_rrr"], ) -def _B0_rr(params, transforms, profiles, data, **kwargs): - data["B0_rr"] = transforms["grid"].replace_at_axis( +def _psi_r_over_sqrtg_rr(params, transforms, profiles, data, **kwargs): + data["(psi_r/sqrt(g))_rr"] = transforms["grid"].replace_at_axis( safediv( data["psi_rrr"] * data["sqrt(g)"] ** 2 - 2 * data["psi_rr"] * data["sqrt(g)_r"] * data["sqrt(g)"] @@ -563,9 +601,9 @@ def _B0_rr(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_r", - "B0_rr", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_r", + "(psi_r/sqrt(g))_rr", "iota", "iota_r", "iota_rr", @@ -579,7 +617,7 @@ def _B0_rr(params, transforms, profiles, data, **kwargs): ) def _B_sup_theta_rr(params, transforms, profiles, data, **kwargs): data["B^theta_rr"] = ( - data["B0"] + data["psi_r/sqrt(g)"] * ( data["iota"] * data["omega_rrz"] + 2 * data["iota_r"] * data["omega_rz"] @@ -588,14 +626,14 @@ def _B_sup_theta_rr(params, transforms, profiles, data, **kwargs): - data["lambda_rrz"] ) + 2 - * data["B0_r"] + * data["(psi_r/sqrt(g))_r"] * ( data["iota"] * data["omega_rz"] + data["iota_r"] * data["omega_z"] + data["iota_r"] - data["lambda_rz"] ) - + data["B0_rr"] + + data["(psi_r/sqrt(g))_rr"] * (data["iota"] * data["omega_z"] + data["iota"] - data["lambda_z"]) ) return data @@ -616,9 +654,9 @@ def _B_sup_theta_rr(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_r", - "B0_rr", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_r", + "(psi_r/sqrt(g))_rr", "iota", "iota_r", "iota_rr", @@ -632,7 +670,7 @@ def _B_sup_theta_rr(params, transforms, profiles, data, **kwargs): ) def _B_sup_zeta_rr(params, transforms, profiles, data, **kwargs): data["B^zeta_rr"] = ( - -data["B0"] + -data["psi_r/sqrt(g)"] * ( data["iota"] * data["omega_rrt"] + 2 * data["iota_r"] * data["omega_rt"] @@ -640,13 +678,14 @@ def _B_sup_zeta_rr(params, transforms, profiles, data, **kwargs): - data["lambda_rrt"] ) - 2 - * data["B0_r"] + * data["(psi_r/sqrt(g))_r"] * ( data["iota"] * data["omega_rt"] + data["iota_r"] * data["omega_t"] - data["lambda_rt"] ) - + data["B0_rr"] * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) + + data["(psi_r/sqrt(g))_rr"] + * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) ) return data @@ -690,7 +729,7 @@ def _B_rr(params, transforms, profiles, data, **kwargs): @register_compute_fun( - name="B0_tt", + name="(psi_r/sqrt(g))_tt", label="\\partial_{\\theta \\theta} (\\psi' / \\sqrt{g})", units="T \\cdot m^{-1}", units_long="Tesla / meter", @@ -703,8 +742,8 @@ def _B_rr(params, transforms, profiles, data, **kwargs): data=["psi_r", "sqrt(g)", "sqrt(g)_t", "sqrt(g)_tt"], axis_limit_data=["psi_rr", "sqrt(g)_r", "sqrt(g)_rt", "sqrt(g)_rtt"], ) -def _B0_tt(params, transforms, profiles, data, **kwargs): - data["B0_tt"] = transforms["grid"].replace_at_axis( +def _psi_r_over_sqrtg_tt(params, transforms, profiles, data, **kwargs): + data["(psi_r/sqrt(g))_tt"] = transforms["grid"].replace_at_axis( safediv( data["psi_r"] * (2 * data["sqrt(g)_t"] ** 2 - data["sqrt(g)"] * data["sqrt(g)_tt"]), @@ -734,9 +773,9 @@ def _B0_tt(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_t", - "B0_tt", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_t", + "(psi_r/sqrt(g))_tt", "iota", "lambda_ttz", "lambda_tz", @@ -748,9 +787,11 @@ def _B0_tt(params, transforms, profiles, data, **kwargs): ) def _B_sup_theta_tt(params, transforms, profiles, data, **kwargs): data["B^theta_tt"] = ( - data["B0"] * (data["iota"] * data["omega_ttz"] - data["lambda_ttz"]) - + 2 * data["B0_t"] * (data["iota"] * data["omega_tz"] - data["lambda_tz"]) - + data["B0_tt"] + data["psi_r/sqrt(g)"] * (data["iota"] * data["omega_ttz"] - data["lambda_ttz"]) + + 2 + * data["(psi_r/sqrt(g))_t"] + * (data["iota"] * data["omega_tz"] - data["lambda_tz"]) + + data["(psi_r/sqrt(g))_tt"] * (data["iota"] * data["omega_z"] + data["iota"] - data["lambda_z"]) ) return data @@ -771,9 +812,9 @@ def _B_sup_theta_tt(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_t", - "B0_tt", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_t", + "(psi_r/sqrt(g))_tt", "iota", "lambda_t", "lambda_tt", @@ -785,9 +826,12 @@ def _B_sup_theta_tt(params, transforms, profiles, data, **kwargs): ) def _B_sup_zeta_tt(params, transforms, profiles, data, **kwargs): data["B^zeta_tt"] = ( - -data["B0"] * (data["iota"] * data["omega_ttt"] - data["lambda_ttt"]) - - 2 * data["B0_t"] * (data["iota"] * data["omega_tt"] - data["lambda_tt"]) - + data["B0_tt"] * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) + -data["psi_r/sqrt(g)"] * (data["iota"] * data["omega_ttt"] - data["lambda_ttt"]) + - 2 + * data["(psi_r/sqrt(g))_t"] + * (data["iota"] * data["omega_tt"] - data["lambda_tt"]) + + data["(psi_r/sqrt(g))_tt"] + * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) ) return data @@ -831,7 +875,7 @@ def _B_tt(params, transforms, profiles, data, **kwargs): @register_compute_fun( - name="B0_zz", + name="(psi_r/sqrt(g))_zz", label="\\partial_{\\zeta \\zeta} (\\psi' / \\sqrt{g})", units="T \\cdot m^{-1}", units_long="Tesla / meter", @@ -844,8 +888,8 @@ def _B_tt(params, transforms, profiles, data, **kwargs): data=["psi_r", "sqrt(g)", "sqrt(g)_z", "sqrt(g)_zz"], axis_limit_data=["psi_rr", "sqrt(g)_r", "sqrt(g)_rz", "sqrt(g)_rzz"], ) -def _B0_zz(params, transforms, profiles, data, **kwargs): - data["B0_zz"] = transforms["grid"].replace_at_axis( +def _psi_r_over_sqrtg_zz(params, transforms, profiles, data, **kwargs): + data["(psi_r/sqrt(g))_zz"] = transforms["grid"].replace_at_axis( safediv( data["psi_r"] * (2 * data["sqrt(g)_z"] ** 2 - data["sqrt(g)"] * data["sqrt(g)_zz"]), @@ -875,9 +919,9 @@ def _B0_zz(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_z", - "B0_zz", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_z", + "(psi_r/sqrt(g))_zz", "iota", "lambda_z", "lambda_zz", @@ -889,9 +933,11 @@ def _B0_zz(params, transforms, profiles, data, **kwargs): ) def _B_sup_theta_zz(params, transforms, profiles, data, **kwargs): data["B^theta_zz"] = ( - data["B0"] * (data["iota"] * data["omega_zzz"] - data["lambda_zzz"]) - + 2 * data["B0_z"] * (data["iota"] * data["omega_zz"] - data["lambda_zz"]) - + data["B0_zz"] + data["psi_r/sqrt(g)"] * (data["iota"] * data["omega_zzz"] - data["lambda_zzz"]) + + 2 + * data["(psi_r/sqrt(g))_z"] + * (data["iota"] * data["omega_zz"] - data["lambda_zz"]) + + data["(psi_r/sqrt(g))_zz"] * (data["iota"] * data["omega_z"] + data["iota"] - data["lambda_z"]) ) return data @@ -912,9 +958,9 @@ def _B_sup_theta_zz(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_z", - "B0_zz", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_z", + "(psi_r/sqrt(g))_zz", "iota", "lambda_t", "lambda_tz", @@ -926,9 +972,12 @@ def _B_sup_theta_zz(params, transforms, profiles, data, **kwargs): ) def _B_sup_zeta_zz(params, transforms, profiles, data, **kwargs): data["B^zeta_zz"] = ( - -data["B0"] * (data["iota"] * data["omega_tzz"] - data["lambda_tzz"]) - - 2 * data["B0_z"] * (data["iota"] * data["omega_tz"] - data["lambda_tz"]) - + data["B0_zz"] * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) + -data["psi_r/sqrt(g)"] * (data["iota"] * data["omega_tzz"] - data["lambda_tzz"]) + - 2 + * data["(psi_r/sqrt(g))_z"] + * (data["iota"] * data["omega_tz"] - data["lambda_tz"]) + + data["(psi_r/sqrt(g))_zz"] + * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) ) return data @@ -972,7 +1021,7 @@ def _B_zz(params, transforms, profiles, data, **kwargs): @register_compute_fun( - name="B0_rt", + name="(psi_r/sqrt(g))_rt", label="\\partial_{\\rho\\theta} (\\psi' / \\sqrt{g})", units="T \\cdot m^{-1}", units_long="Tesla / meters", @@ -985,8 +1034,8 @@ def _B_zz(params, transforms, profiles, data, **kwargs): data=["psi_r", "psi_rr", "sqrt(g)", "sqrt(g)_r", "sqrt(g)_t", "sqrt(g)_rt"], axis_limit_data=["psi_rrr", "sqrt(g)_rr", "sqrt(g)_rrt"], ) -def _B0_rt(params, transforms, profiles, data, **kwargs): - data["B0_rt"] = transforms["grid"].replace_at_axis( +def _psi_r_over_sqrtg_rt(params, transforms, profiles, data, **kwargs): + data["(psi_r/sqrt(g))_rt"] = transforms["grid"].replace_at_axis( safediv( -data["sqrt(g)"] * (data["psi_rr"] * data["sqrt(g)_t"] + data["psi_r"] * data["sqrt(g)_rt"]) @@ -1021,10 +1070,10 @@ def _B0_rt(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_r", - "B0_rt", - "B0_t", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_r", + "(psi_r/sqrt(g))_rt", + "(psi_r/sqrt(g))_t", "iota", "iota_r", "lambda_rtz", @@ -1039,21 +1088,22 @@ def _B0_rt(params, transforms, profiles, data, **kwargs): ) def _B_sup_theta_rt(params, transforms, profiles, data, **kwargs): data["B^theta_rt"] = ( - data["B0"] + data["psi_r/sqrt(g)"] * ( data["iota"] * data["omega_rtz"] + data["iota_r"] * data["omega_tz"] - data["lambda_rtz"] ) - + data["B0_r"] * (data["iota"] * data["omega_tz"] - data["lambda_tz"]) - + data["B0_t"] + + data["(psi_r/sqrt(g))_r"] + * (data["iota"] * data["omega_tz"] - data["lambda_tz"]) + + data["(psi_r/sqrt(g))_t"] * ( data["iota"] * data["omega_rz"] + data["iota_r"] * data["omega_z"] + data["iota_r"] - data["lambda_rz"] ) - + data["B0_rt"] + + data["(psi_r/sqrt(g))_rt"] * (data["iota"] * data["omega_z"] + data["iota"] - data["lambda_z"]) ) return data @@ -1074,10 +1124,10 @@ def _B_sup_theta_rt(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_r", - "B0_rt", - "B0_t", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_r", + "(psi_r/sqrt(g))_rt", + "(psi_r/sqrt(g))_t", "iota", "iota_r", "lambda_rt", @@ -1092,20 +1142,22 @@ def _B_sup_theta_rt(params, transforms, profiles, data, **kwargs): ) def _B_sup_zeta_rt(params, transforms, profiles, data, **kwargs): data["B^zeta_rt"] = ( - -data["B0"] + -data["psi_r/sqrt(g)"] * ( data["iota"] * data["omega_rtt"] + data["iota_r"] * data["omega_tt"] - data["lambda_rtt"] ) - - data["B0_r"] * (data["iota"] * data["omega_tt"] - data["lambda_tt"]) - - data["B0_t"] + - data["(psi_r/sqrt(g))_r"] + * (data["iota"] * data["omega_tt"] - data["lambda_tt"]) + - data["(psi_r/sqrt(g))_t"] * ( data["iota"] * data["omega_rt"] + data["iota_r"] * data["omega_t"] - data["lambda_rt"] ) - + data["B0_rt"] * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) + + data["(psi_r/sqrt(g))_rt"] + * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) ) return data @@ -1156,7 +1208,7 @@ def _B_rt(params, transforms, profiles, data, **kwargs): @register_compute_fun( - name="B0_tz", + name="(psi_r/sqrt(g))_tz", label="\\partial_{\\theta\\zeta} (\\psi' / \\sqrt{g})", units="T \\cdot m^{-1}", units_long="Tesla / meter", @@ -1169,8 +1221,8 @@ def _B_rt(params, transforms, profiles, data, **kwargs): data=["psi_r", "sqrt(g)", "sqrt(g)_t", "sqrt(g)_z", "sqrt(g)_tz"], axis_limit_data=["psi_rr", "sqrt(g)_r", "sqrt(g)_rt", "sqrt(g)_rz", "sqrt(g)_rtz"], ) -def _B0_tz(params, transforms, profiles, data, **kwargs): - data["B0_tz"] = transforms["grid"].replace_at_axis( +def _psi_r_over_sqrtg_tz(params, transforms, profiles, data, **kwargs): + data["(psi_r/sqrt(g))_tz"] = transforms["grid"].replace_at_axis( safediv( data["psi_r"] * ( @@ -1206,10 +1258,10 @@ def _B0_tz(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_t", - "B0_tz", - "B0_z", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_t", + "(psi_r/sqrt(g))_tz", + "(psi_r/sqrt(g))_z", "iota", "lambda_tz", "lambda_tzz", @@ -1223,10 +1275,12 @@ def _B0_tz(params, transforms, profiles, data, **kwargs): ) def _B_sup_theta_tz(params, transforms, profiles, data, **kwargs): data["B^theta_tz"] = ( - data["B0"] * (data["iota"] * data["omega_tzz"] - data["lambda_tzz"]) - + data["B0_t"] * (data["iota"] * data["omega_zz"] - data["lambda_zz"]) - + data["B0_z"] * (data["iota"] * data["omega_tz"] - data["lambda_tz"]) - + data["B0_tz"] + data["psi_r/sqrt(g)"] * (data["iota"] * data["omega_tzz"] - data["lambda_tzz"]) + + data["(psi_r/sqrt(g))_t"] + * (data["iota"] * data["omega_zz"] - data["lambda_zz"]) + + data["(psi_r/sqrt(g))_z"] + * (data["iota"] * data["omega_tz"] - data["lambda_tz"]) + + data["(psi_r/sqrt(g))_tz"] * (data["iota"] * data["omega_z"] + data["iota"] - data["lambda_z"]) ) return data @@ -1247,10 +1301,10 @@ def _B_sup_theta_tz(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_t", - "B0_tz", - "B0_z", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_t", + "(psi_r/sqrt(g))_tz", + "(psi_r/sqrt(g))_z", "iota", "lambda_t", "lambda_tt", @@ -1264,10 +1318,13 @@ def _B_sup_theta_tz(params, transforms, profiles, data, **kwargs): ) def _B_sup_zeta_tz(params, transforms, profiles, data, **kwargs): data["B^zeta_tz"] = ( - -data["B0"] * (data["iota"] * data["omega_ttz"] - data["lambda_ttz"]) - - data["B0_t"] * (data["iota"] * data["omega_tz"] - data["lambda_tz"]) - - data["B0_z"] * (data["iota"] * data["omega_tt"] - data["lambda_tt"]) - + data["B0_tz"] * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) + -data["psi_r/sqrt(g)"] * (data["iota"] * data["omega_ttz"] - data["lambda_ttz"]) + - data["(psi_r/sqrt(g))_t"] + * (data["iota"] * data["omega_tz"] - data["lambda_tz"]) + - data["(psi_r/sqrt(g))_z"] + * (data["iota"] * data["omega_tt"] - data["lambda_tt"]) + + data["(psi_r/sqrt(g))_tz"] + * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) ) return data @@ -1317,7 +1374,7 @@ def _B_tz(params, transforms, profiles, data, **kwargs): @register_compute_fun( - name="B0_rz", + name="(psi_r/sqrt(g))_rz", label="\\partial_{\\rho\\zeta} (\\psi' / \\sqrt{g})", units="T \\cdot m^{-1}", units_long="Tesla / meters", @@ -1330,8 +1387,8 @@ def _B_tz(params, transforms, profiles, data, **kwargs): data=["psi_r", "psi_rr", "sqrt(g)", "sqrt(g)_r", "sqrt(g)_z", "sqrt(g)_rz"], axis_limit_data=["psi_rrr", "sqrt(g)_rr", "sqrt(g)_rrz"], ) -def _B0_rz(params, transforms, profiles, data, **kwargs): - data["B0_rz"] = transforms["grid"].replace_at_axis( +def _psi_r_over_sqrtg_rz(params, transforms, profiles, data, **kwargs): + data["(psi_r/sqrt(g))_rz"] = transforms["grid"].replace_at_axis( safediv( -data["sqrt(g)"] * (data["psi_rr"] * data["sqrt(g)_z"] + data["psi_r"] * data["sqrt(g)_rz"]) @@ -1366,10 +1423,10 @@ def _B0_rz(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_r", - "B0_rz", - "B0_z", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_r", + "(psi_r/sqrt(g))_rz", + "(psi_r/sqrt(g))_z", "iota", "iota_r", "lambda_rz", @@ -1384,21 +1441,22 @@ def _B0_rz(params, transforms, profiles, data, **kwargs): ) def _B_sup_theta_rz(params, transforms, profiles, data, **kwargs): data["B^theta_rz"] = ( - data["B0"] + data["psi_r/sqrt(g)"] * ( data["iota"] * data["omega_rzz"] + data["iota_r"] * data["omega_zz"] - data["lambda_rzz"] ) - + data["B0_r"] * (data["iota"] * data["omega_zz"] - data["lambda_zz"]) - + data["B0_z"] + + data["(psi_r/sqrt(g))_r"] + * (data["iota"] * data["omega_zz"] - data["lambda_zz"]) + + data["(psi_r/sqrt(g))_z"] * ( data["iota"] * data["omega_rz"] + data["iota_r"] * data["omega_z"] + data["iota_r"] - data["lambda_rz"] ) - + data["B0_rz"] + + data["(psi_r/sqrt(g))_rz"] * (data["iota"] * data["omega_z"] + data["iota"] - data["lambda_z"]) ) return data @@ -1419,10 +1477,10 @@ def _B_sup_theta_rz(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="rtz", data=[ - "B0", - "B0_r", - "B0_rz", - "B0_z", + "psi_r/sqrt(g)", + "(psi_r/sqrt(g))_r", + "(psi_r/sqrt(g))_rz", + "(psi_r/sqrt(g))_z", "iota", "iota_r", "lambda_rt", @@ -1437,20 +1495,22 @@ def _B_sup_theta_rz(params, transforms, profiles, data, **kwargs): ) def _B_sup_zeta_rz(params, transforms, profiles, data, **kwargs): data["B^zeta_rz"] = ( - -data["B0"] + -data["psi_r/sqrt(g)"] * ( data["iota"] * data["omega_rtz"] + data["iota_r"] * data["omega_tz"] - data["lambda_rtz"] ) - - data["B0_r"] * (data["iota"] * data["omega_tz"] - data["lambda_tz"]) - - data["B0_z"] + - data["(psi_r/sqrt(g))_r"] + * (data["iota"] * data["omega_tz"] - data["lambda_tz"]) + - data["(psi_r/sqrt(g))_z"] * ( data["iota"] * data["omega_rt"] + data["iota_r"] * data["omega_t"] - data["lambda_rt"] ) - + data["B0_rz"] * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) + + data["(psi_r/sqrt(g))_rz"] + * (-data["iota"] * data["omega_t"] + data["lambda_t"] + 1) ) return data diff --git a/desc/compute/_omnigenity.py b/desc/compute/_omnigenity.py index 469beae364..1d5f44b583 100644 --- a/desc/compute/_omnigenity.py +++ b/desc/compute/_omnigenity.py @@ -336,12 +336,22 @@ def _B_modes(params, transforms, profiles, data, **kwargs): transforms={}, profiles=[], coordinates="rtz", - data=["iota", "B0", "B_theta", "B_zeta", "|B|_t", "|B|_z", "G", "I", "B*grad(|B|)"], + data=[ + "iota", + "psi_r/sqrt(g)", + "B_theta", + "B_zeta", + "|B|_t", + "|B|_z", + "G", + "I", + "B*grad(|B|)", + ], helicity="tuple: Type of quasisymmetry, (M,N). Default (1,0)", ) def _f_C(params, transforms, profiles, data, **kwargs): M, N = kwargs.get("helicity", (1, 0)) - data["f_C"] = (M * data["iota"] - N) * data["B0"] * ( + data["f_C"] = (M * data["iota"] - N) * data["psi_r/sqrt(g)"] * ( data["B_zeta"] * data["|B|_t"] - data["B_theta"] * data["|B|_z"] ) - (M * data["G"] + N * data["I"]) * data["B*grad(|B|)"] return data @@ -359,10 +369,10 @@ def _f_C(params, transforms, profiles, data, **kwargs): transforms={}, profiles=[], coordinates="rtz", - data=["B0", "|B|_t", "|B|_z", "(B*grad(|B|))_t", "(B*grad(|B|))_z"], + data=["psi_r/sqrt(g)", "|B|_t", "|B|_z", "(B*grad(|B|))_t", "(B*grad(|B|))_z"], ) def _f_T(params, transforms, profiles, data, **kwargs): - data["f_T"] = data["B0"] * ( + data["f_T"] = data["psi_r/sqrt(g)"] * ( data["|B|_t"] * data["(B*grad(|B|))_z"] - data["|B|_z"] * data["(B*grad(|B|))_t"] ) diff --git a/tests/test_axis_limits.py b/tests/test_axis_limits.py index af5ae38823..a120994828 100644 --- a/tests/test_axis_limits.py +++ b/tests/test_axis_limits.py @@ -252,7 +252,7 @@ class TestAxisLimits: @pytest.mark.unit def test_axis_limit_api(self): """Test that axis limit dependencies are computed only when necessary.""" - name = "B0" + name = "psi_r/sqrt(g)" deps = {"psi_r", "sqrt(g)"} axis_limit_deps = {"psi_rr", "sqrt(g)_r"} eq = Equilibrium() diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 843e125319..7f02813087 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -335,7 +335,7 @@ def test_plot_fsa_axis_limit(self): plot_data["<" + name + ">"], desired, equal_nan=False ) - name = "B0" + name = "psi_r/sqrt(g)" assert ( "<" + name + ">" not in data_index["desc.equilibrium.equilibrium.Equilibrium"] From e09710d5ec48f6d4e0a82eba3d3ce1468a74ed04 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Tue, 6 Aug 2024 15:37:23 -0600 Subject: [PATCH 06/24] add new B0 compute quantity --- desc/compute/_field.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/desc/compute/_field.py b/desc/compute/_field.py index 36f13da8bf..b6abbc903c 100644 --- a/desc/compute/_field.py +++ b/desc/compute/_field.py @@ -2220,6 +2220,28 @@ def _B_sub_zeta_rz(params, transforms, profiles, data, **kwargs): return data +@register_compute_fun( + name="B0", + label="B_0", + units="T", + units_long="Tesla", + description="Average magnitude of magnetic field on the magnetic axis", + dim=0, + params=[], + transforms={"grid": []}, + profiles=[], + coordinates="", + data=["|B|", "sqrt(g)"], +) +def _B0(params, transforms, profiles, data, **kwargs): + # indices of the innermost flux surface + idx = jnp.where(transforms["grid"].inverse_rho_idx == 0)[0] + data["B0"] = jnp.sum( + data["|B|"][idx] * data["sqrt(g)"][idx] * transforms["grid"].weights[idx] + ) / jnp.sum(data["sqrt(g)"][idx] * transforms["grid"].weights[idx]) + return data + + @register_compute_fun( name="|B|^2", label="|\\mathbf{B}|^{2}", From a4a5184cfa6848d08636446f3718cc551cd0d09a Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Tue, 6 Aug 2024 17:15:49 -0600 Subject: [PATCH 07/24] update HeatingPower objective --- desc/objectives/__init__.py | 1 + desc/objectives/_confinement.py | 142 ++++++++++---------------------- 2 files changed, 44 insertions(+), 99 deletions(-) diff --git a/desc/objectives/__init__.py b/desc/objectives/__init__.py index 3ae2e59af0..e845e1e216 100644 --- a/desc/objectives/__init__.py +++ b/desc/objectives/__init__.py @@ -11,6 +11,7 @@ QuadraticFlux, ToroidalFlux, ) +from ._confinement import HeatingPower from ._equilibrium import ( CurrentDensity, Energy, diff --git a/desc/objectives/_confinement.py b/desc/objectives/_confinement.py index 67a0cb6517..271f200f3b 100644 --- a/desc/objectives/_confinement.py +++ b/desc/objectives/_confinement.py @@ -1,11 +1,8 @@ """Objectives for targeting energy confinement.""" -import numpy as np - -from desc.backend import jnp from desc.compute.utils import _compute as compute_fun from desc.compute.utils import get_profiles, get_transforms -from desc.grid import LinearGrid, QuadratureGrid +from desc.grid import QuadratureGrid from desc.utils import Timer, errorif from .objective_funs import _Objective @@ -16,6 +13,13 @@ class HeatingPower(_Objective): tau_E^ISS04 = 0.134 a^2.28 R^0.64 P^-0.61 n_e^0.54 B^0.84 iota^0.41 (s) + References + ---------- + https://doi.org/10.1088/0029-5515/45/12/024. + Characterization of energy confinement in net-current free plasmas using the + extended International Stellarator Database. + H. Yamada et al. Nucl. Fusion 29 November 2005; 45 (12): 1684–1693. + Parameters ---------- eq : Equilibrium @@ -47,21 +51,14 @@ class HeatingPower(_Objective): of the objective. Has no effect on self.grad or self.hess which always use reverse mode and forward over reverse mode respectively. f_ren : float, optional - Renormalization or confinement enhancement factor. Defaults = 1. + ISS04 renormalization factor. Default = 1. + H_ISS04 : float, optional + ISS04 confinement enhancement factor. Default = 1. gamma : float, optional Adiabatic (compressional) index. Default = 0. - grid_geometry : Grid, optional - Collocation grid used to compute the major and minor radii. - Defaults to ``QuadratureGrid(eq.L_grid, eq.M_grid, eq.N_grid)``. - grid_density : Grid, optional - Collocation grid used to compute the line-averaged density. - Defaults to ``QuadratureGrid(eq.L_grid, eq.M_grid, eq.N_grid)``. - grid_B : Grid, optional - Collocation grid used to compute the magnetic field strength. - Defaults to ``QuadratureGrid(eq.L_grid, eq.M_grid, eq.N_grid)``. - grid_iota : Grid, optional - Collocation grid used to compute the rotational transform. - Defaults to ``QuadratureGrid(eq.L_grid, eq.M_grid, eq.N_grid)``. + grid : Grid, optional + Collocation grid used to compute the intermediate quantities. + Defaults to ``QuadratureGrid(eq.L_grid, eq.M_grid, eq.N_grid, eq.NFP)``. name : str, optional Name of the objective function. @@ -82,21 +79,17 @@ def __init__( loss_function=None, deriv_mode="auto", f_ren=1, + H_ISS04=1, gamma=0, - grid_geometry=None, - grid_density=None, - grid_B=None, - grid_iota=None, + grid=None, name="heating power", ): if target is None and bounds is None: - target = 2 + target = 0 self._f_ren = f_ren + self._H_ISS04 = H_ISS04 self._gamma = gamma - self._grid_geometry = grid_geometry - self._grid_density = grid_density - self._grid_B = grid_B - self._grid_iota = grid_iota + self._grid = grid super().__init__( things=eq, target=target, @@ -126,28 +119,15 @@ def build(self, use_jit=True, verbose=1): ValueError, "Equilibrium must have an electron density profile.", ) - - if self._grid_geometry is None: - self._grid_geometry = QuadratureGrid( + if self._grid is None: + self._grid = QuadratureGrid( L=eq.L_grid, M=eq.M_grid, N=eq.N_grid, NFP=eq.NFP, ) - if self._grid_density is None: - self._grid_density = LinearGrid(L=eq.L_grid, M=0, N=0) - if self._grid_B is None: - self._grid_B = LinearGrid(rho=np.array([0]), N=eq.N_grid, NFP=eq.NFP) - if self._grid_iota is None: - self._grid_iota = LinearGrid( - rho=np.array([2 / 3.0]), M=eq.M_grid, N=eq.N_grid, NFP=eq.NFP - ) - self._dim_f = 1 - self._data_keys_geometry = ["a", "R0", "W_p"] - self._data_keys_density = ["ne"] - self._data_keys_B = ["|B|"] - self._data_keys_iota = ["iota"] + self._data_keys = ["W_p", "a", "R0", "_rho", "B0", "iota_23"] timer = Timer() if verbose > 0: @@ -155,29 +135,10 @@ def build(self, use_jit=True, verbose=1): timer.start("Precomputing transforms") self._constants = { - "profiles_geometry": get_profiles( - self._data_keys_geometry, obj=eq, grid=self._grid_geometry - ), - "transforms_geometry": get_transforms( - self._data_keys_geometry, obj=eq, grid=self._grid_geometry - ), - "profiles_density": get_profiles( - self._data_keys_density, obj=eq, grid=self._grid_density - ), - "transforms_density": get_transforms( - self._data_keys_density, obj=eq, grid=self._grid_density - ), - "profiles_B": get_profiles(self._data_keys_B, obj=eq, grid=self._grid_B), - "transforms_B": get_transforms( - self._data_keys_B, obj=eq, grid=self._grid_B - ), - "profiles_iota": get_profiles( - self._data_keys_iota, obj=eq, grid=self._grid_iota - ), - "transforms_iota": get_transforms( - self._data_keys_iota, obj=eq, grid=self._grid_iota - ), + "profiles": get_profiles(self._data_keys, obj=eq, grid=self._grid), + "transforms": get_transforms(self._data_keys, obj=eq, grid=self._grid), "f_ren": self._f_ren, + "H_ISS04": self._H_ISS04, "gamma": self._gamma, } @@ -207,46 +168,29 @@ def compute(self, params, constants=None): """ if constants is None: constants = self.constants - data_geometry = compute_fun( + data = compute_fun( "desc.equilibrium.equilibrium.Equilibrium", - self._data_keys_geometry, + self._data_keys, params=params, - transforms=constants["transforms_geometry"], - profiles=constants["profiles_geometry"], + transforms=constants["transforms"], + profiles=constants["profiles"], gamma=constants["gamma"], ) - data_density = compute_fun( - "desc.equilibrium.equilibrium.Equilibrium", - self._data_keys_density, - params=params, - transforms=constants["transforms_density"], - profiles=constants["profiles_density"], - ) - data_B = compute_fun( - "desc.equilibrium.equilibrium.Equilibrium", - self._data_keys_B, - params=params, - transforms=constants["transforms_B"], - profiles=constants["profiles_B"], - ) - data_iota = compute_fun( - "desc.equilibrium.equilibrium.Equilibrium", - self._data_keys_iota, - params=params, - transforms=constants["transforms_iota"], - profiles=constants["profiles_iota"], - ) - P = (data_geometry["W_p"] / 1e6) / ( # MJ - 0.134 - * data_geometry["a"] ** 2.28 # m - * data_geometry["R0"] ** 0.64 # m - * (jnp.mean(data_density["n_e"]) ** 0.54 / 1e19) # 1e19/m^3 - * jnp.mean(data_B["|B|"]) ** 0.84 # T - * jnp.mean(data_iota["iota"]) ** 0.41 - * constants["f_ren"] - ) ** -0.39 - return P + P = ( + (data["W_p"] / -1e6) # MJ + / ( + 0.134 + * data["a"] ** 2.28 # m + * data["R0"] ** 0.64 # m + * (data["_rho"] / 1e19) ** 0.54 # 1e19/m^3 + * data["B0"] ** 0.84 # T + * data["iota_23"] ** 0.41 + * constants["f_ren"] + * constants["H_ISS04"] + ) + ) ** (1 / 0.39) + return P * 1e6 # W @property def f_ren(self): From d97ecfe0108cbabc025e5426361392783fdc8441 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Thu, 15 Aug 2024 14:40:30 -0600 Subject: [PATCH 08/24] rename 'B0' to '<|B|>_axis' --- desc/compute/_field.py | 6 +++--- desc/objectives/_confinement.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/desc/compute/_field.py b/desc/compute/_field.py index 876c6ceae6..f728033c59 100644 --- a/desc/compute/_field.py +++ b/desc/compute/_field.py @@ -2264,8 +2264,8 @@ def _B_sub_zeta_rz(params, transforms, profiles, data, **kwargs): @register_compute_fun( - name="B0", - label="B_0", + name="<|B|>_axis", + label="\\lange |\\mathbf{B}| \\rangle_{axis}", units="T", units_long="Tesla", description="Average magnitude of magnetic field on the magnetic axis", @@ -2279,7 +2279,7 @@ def _B_sub_zeta_rz(params, transforms, profiles, data, **kwargs): def _B0(params, transforms, profiles, data, **kwargs): # indices of the innermost flux surface idx = jnp.where(transforms["grid"].inverse_rho_idx == 0)[0] - data["B0"] = jnp.sum( + data["<|B|>_axis"] = jnp.sum( data["|B|"][idx] * data["sqrt(g)"][idx] * transforms["grid"].weights[idx] ) / jnp.sum(data["sqrt(g)"][idx] * transforms["grid"].weights[idx]) return data diff --git a/desc/objectives/_confinement.py b/desc/objectives/_confinement.py index 271f200f3b..5c72f5db88 100644 --- a/desc/objectives/_confinement.py +++ b/desc/objectives/_confinement.py @@ -127,7 +127,7 @@ def build(self, use_jit=True, verbose=1): NFP=eq.NFP, ) self._dim_f = 1 - self._data_keys = ["W_p", "a", "R0", "_rho", "B0", "iota_23"] + self._data_keys = ["W_p", "a", "R0", "_rho", "<|B|>_axis", "iota_23"] timer = Timer() if verbose > 0: @@ -184,7 +184,7 @@ def compute(self, params, constants=None): * data["a"] ** 2.28 # m * data["R0"] ** 0.64 # m * (data["_rho"] / 1e19) ** 0.54 # 1e19/m^3 - * data["B0"] ** 0.84 # T + * data["<|B|>_axis"] ** 0.84 # T * data["iota_23"] ** 0.41 * constants["f_ren"] * constants["H_ISS04"] From b228a5af9247a52e88e3e7a409107dea43adae61 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Thu, 15 Aug 2024 14:59:59 -0600 Subject: [PATCH 09/24] make it JAX compatible --- desc/compute/_field.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/desc/compute/_field.py b/desc/compute/_field.py index f728033c59..0a849c535d 100644 --- a/desc/compute/_field.py +++ b/desc/compute/_field.py @@ -2276,12 +2276,12 @@ def _B_sub_zeta_rz(params, transforms, profiles, data, **kwargs): coordinates="", data=["|B|", "sqrt(g)"], ) -def _B0(params, transforms, profiles, data, **kwargs): - # indices of the innermost flux surface - idx = jnp.where(transforms["grid"].inverse_rho_idx == 0)[0] +def _B_mag_axis(params, transforms, profiles, data, **kwargs): + # mask of indices of the innermost flux surface + mask = transforms["grid"].inverse_rho_idx == 0 data["<|B|>_axis"] = jnp.sum( - data["|B|"][idx] * data["sqrt(g)"][idx] * transforms["grid"].weights[idx] - ) / jnp.sum(data["sqrt(g)"][idx] * transforms["grid"].weights[idx]) + mask * data["|B|"] * data["sqrt(g)"] * transforms["grid"].weights + ) / jnp.sum(mask * data["sqrt(g)"] * transforms["grid"].weights) return data From e51aba1f6e2156d55d91f592bf602b56eb558fba Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Thu, 15 Aug 2024 15:00:12 -0600 Subject: [PATCH 10/24] add normalization --- desc/objectives/_confinement.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/desc/objectives/_confinement.py b/desc/objectives/_confinement.py index 5c72f5db88..034b6c2ed8 100644 --- a/desc/objectives/_confinement.py +++ b/desc/objectives/_confinement.py @@ -5,6 +5,7 @@ from desc.grid import QuadratureGrid from desc.utils import Timer, errorif +from .normalization import compute_scaling_factors from .objective_funs import _Objective @@ -146,6 +147,10 @@ def build(self, use_jit=True, verbose=1): if verbose > 1: timer.disp("Precomputing transforms") + if self._normalize: + scales = compute_scaling_factors(eq) + self._normalization = scales["W"] + super().build(use_jit=use_jit, verbose=verbose) def compute(self, params, constants=None): From 039e854e7f76440b14d25244d2b61bd9f2e44aeb Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Thu, 15 Aug 2024 18:18:01 -0600 Subject: [PATCH 11/24] repair tests --- desc/compute/_field.py | 8 +++++-- desc/plotting.py | 2 ++ tests/test_axis_limits.py | 2 ++ tests/test_objective_funs.py | 44 ++++++++++++++++++++++++++++++++++-- tests/test_plotting.py | 2 +- 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/desc/compute/_field.py b/desc/compute/_field.py index 0a849c535d..9215df3f61 100644 --- a/desc/compute/_field.py +++ b/desc/compute/_field.py @@ -2275,13 +2275,17 @@ def _B_sub_zeta_rz(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="", data=["|B|", "sqrt(g)"], + axis_limit_data=["sqrt(g)_r"], ) def _B_mag_axis(params, transforms, profiles, data, **kwargs): # mask of indices of the innermost flux surface mask = transforms["grid"].inverse_rho_idx == 0 + sqrt_g = transforms["grid"].replace_at_axis( + data["sqrt(g)"], lambda: data["sqrt(g)_r"], copy=True + ) data["<|B|>_axis"] = jnp.sum( - mask * data["|B|"] * data["sqrt(g)"] * transforms["grid"].weights - ) / jnp.sum(mask * data["sqrt(g)"] * transforms["grid"].weights) + mask * data["|B|"] * sqrt_g * transforms["grid"].weights + ) / jnp.sum(mask * sqrt_g * transforms["grid"].weights) return data diff --git a/desc/plotting.py b/desc/plotting.py index ba822a5b2b..3175e51d72 100644 --- a/desc/plotting.py +++ b/desc/plotting.py @@ -1199,10 +1199,12 @@ def plot_fsa( # noqa: C901 # Attempt to compute the magnetic axis limit. # Compute derivative depending on various naming schemes. # e.g. B -> B_r, V(r) -> V_r(r), S_r(r) -> S_rr(r) + # psi_r/sqrt(g) -> (psi_r/sqrt(g))_r schemes = ( name + "_r", name[:-3] + "_r" + name[-3:], name[:-3] + "r" + name[-3:], + "(" + name + ")_r", ) values_r = next( ( diff --git a/tests/test_axis_limits.py b/tests/test_axis_limits.py index a120994828..2c31a6fdba 100644 --- a/tests/test_axis_limits.py +++ b/tests/test_axis_limits.py @@ -91,6 +91,7 @@ "K_vc", # only defined on surface "iota_num_rrr", "iota_den_rrr", + "iota_23", # only defined at rho=2/3 "cvdrift0", } @@ -128,6 +129,7 @@ def _skip_this(eq, name): or (eq.electron_temperature is None and "Te" in name) or (eq.electron_density is None and "ne" in name) or (eq.ion_temperature is None and "Ti" in name) + or (eq.electron_density is None and "ni" in name) or (eq.anisotropy is None and "beta_a" in name) or (eq.pressure is not None and " Redl" in name) or (eq.current is None and "iota_num" in name) diff --git a/tests/test_objective_funs.py b/tests/test_objective_funs.py index d6f67a5ffc..3ad50d846e 100644 --- a/tests/test_objective_funs.py +++ b/tests/test_objective_funs.py @@ -49,6 +49,7 @@ ForceBalance, ForceBalanceAnisotropic, GenericObjective, + HeatingPower, Isodynamicity, LinearObjectiveFromUser, MagneticWell, @@ -2031,6 +2032,7 @@ class TestComputeScalarResolution: CoilSetMinDistance, CoilTorsion, GenericObjective, + HeatingPower, Omnigenity, PlasmaCoilSetMinDistance, PlasmaVesselDistance, @@ -2090,6 +2092,28 @@ def test_compute_scalar_resolution_bootstrap(self): f[i] = obj.compute_scalar(obj.x()) np.testing.assert_allclose(f, f[-1], rtol=5e-2) + @pytest.mark.regression + def test_compute_scalar_resolution_heating_power(self): + """HeatingPower.""" + eq = self.eq.copy() + eq.electron_density = PowerSeriesProfile([1e19, 0, -1e19]) + eq.electron_temperature = PowerSeriesProfile([1e3, 0, -1e3]) + eq.ion_temperature = PowerSeriesProfile([1e3, 0, -1e3]) + eq.atomic_number = 1.0 + + f = np.zeros_like(self.res_array, dtype=float) + for i, res in enumerate(self.res_array): + grid = QuadratureGrid( + L=int(self.eq.L * res), + M=int(self.eq.M * res), + N=int(self.eq.N * res), + NFP=self.eq.NFP, + ) + obj = ObjectiveFunction(HeatingPower(eq=eq, grid=grid)) + obj.build(verbose=0) + f[i] = obj.compute_scalar(obj.x()) + np.testing.assert_allclose(f, f[-1], rtol=5e-2) + @pytest.mark.regression def test_compute_scalar_resolution_boundary_error(self): """BoundaryError.""" @@ -2359,6 +2383,8 @@ class TestObjectiveNaNGrad: CoilSetMinDistance, CoilTorsion, ForceBalanceAnisotropic, + HeatingPower, + Omnigenity, PlasmaCoilSetMinDistance, PlasmaVesselDistance, QuadraticFlux, @@ -2368,8 +2394,6 @@ class TestObjectiveNaNGrad: GenericObjective, LinearObjectiveFromUser, ObjectiveFromUser, - # TODO: add Omnigenity objective (see GH issue #943) - Omnigenity, ] other_objectives = list(set(objectives) - set(specials)) @@ -2408,6 +2432,22 @@ def test_objective_no_nangrad_bootstrap(self): g = obj.grad(obj.x(eq)) assert not np.any(np.isnan(g)), "redl bootstrap" + @pytest.mark.unit + def test_objective_no_nangrad_heating_power(self): + """HeatingPower.""" + eq = Equilibrium( + L=2, + M=2, + N=2, + electron_density=PowerSeriesProfile([1e19, 0, -1e19]), + electron_temperature=PowerSeriesProfile([1e3, 0, -1e3]), + current=PowerSeriesProfile([1, 0, -1]), + ) + obj = ObjectiveFunction(HeatingPower(eq)) + obj.build() + g = obj.grad(obj.x(eq)) + assert not np.any(np.isnan(g)), "heating power" + @pytest.mark.unit def test_objective_no_nangrad_boundary_error(self): """BoundaryError.""" diff --git a/tests/test_plotting.py b/tests/test_plotting.py index c54d6ab465..bc8e302b7f 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -371,7 +371,7 @@ def test_plot_fsa_axis_limit(self): rho=rho, M=eq.M_grid, N=eq.N_grid, - with_sqrt_g=False, # Test that does not compute data_index["<|B|>"] + with_sqrt_g=False, # test that does not compute data_index["<|B|>"] return_data=True, ) data = eq.compute(names=name, grid=grid) From efde8bcb45a11da1f7d46d4aa42ef9cf8a44c0f4 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Fri, 16 Aug 2024 10:23:15 -0600 Subject: [PATCH 12/24] making Rory's requested changes --- desc/compute/_equil.py | 35 +++++++++++++++++++++++++++++++++ desc/compute/_field.py | 1 + desc/compute/_profiles.py | 22 --------------------- desc/objectives/_confinement.py | 34 ++++++++------------------------ tests/test_profiles.py | 12 ----------- 5 files changed, 44 insertions(+), 60 deletions(-) diff --git a/desc/compute/_equil.py b/desc/compute/_equil.py index d1ac38f637..848b3a73d1 100644 --- a/desc/compute/_equil.py +++ b/desc/compute/_equil.py @@ -9,6 +9,7 @@ expensive computations. """ +from interpax import interp1d from scipy.constants import mu_0 from desc.backend import jnp @@ -802,3 +803,37 @@ def _beta_volpol(params, transforms, profiles, data, **kwargs): def _beta_voltor(params, transforms, profiles, data, **kwargs): data["_vol"] = jnp.abs(data["W_p"] / data["W_Btor"]) return data + + +@register_compute_fun( + name="P_ISS04", + label="P_{ISS04}", + units="W", + units_long="Watts", + description="Heating power required by the ISS04 energy confinement time scaling", + dim=0, + params=[], + transforms={"grid": []}, + profiles=[], + coordinates="", + data=["a", "iota", "rho", "R0", "W_p", "_rho", "<|B|>_axis"], + method="str: Interpolation method. Default 'cubic'.", + H_ISS04="float: ISS04 confinement enhancement factor. Default 1.", +) +def _P_ISS04(params, transforms, profiles, data, **kwargs): + rho = transforms["grid"].compress(data["rho"], surface_label="rho") + iota = transforms["grid"].compress(data["iota"], surface_label="rho") + iota_23 = interp1d(2 / 3, rho, iota, method=kwargs.get("method", "cubic")) + data["P_ISS04"] = 1e6 * ( # MW -> W + jnp.abs(data["W_p"] / 1e6) # J -> MJ + / ( + 0.134 + * data["a"] ** 2.28 # m + * data["R0"] ** 0.64 # m + * (data["_rho"] / 1e19) ** 0.54 # 1/m^3 -> 1e19/m^3 + * data["<|B|>_axis"] ** 0.84 # T + * iota_23**0.41 + * kwargs.get("H_ISS04", 1) + ) + ) ** (1 / 0.39) + return data diff --git a/desc/compute/_field.py b/desc/compute/_field.py index 9215df3f61..3a5184dae0 100644 --- a/desc/compute/_field.py +++ b/desc/compute/_field.py @@ -2276,6 +2276,7 @@ def _B_sub_zeta_rz(params, transforms, profiles, data, **kwargs): coordinates="", data=["|B|", "sqrt(g)"], axis_limit_data=["sqrt(g)_r"], + resolution_requirement="z", ) def _B_mag_axis(params, transforms, profiles, data, **kwargs): # mask of indices of the innermost flux surface diff --git a/desc/compute/_profiles.py b/desc/compute/_profiles.py index 1f88242864..1433f96e20 100644 --- a/desc/compute/_profiles.py +++ b/desc/compute/_profiles.py @@ -9,7 +9,6 @@ expensive computations. """ -from interpax import interp1d from scipy.constants import elementary_charge, mu_0 from desc.backend import cond, jnp @@ -744,27 +743,6 @@ def _gradbeta_a(params, transforms, profiles, data, **kwargs): return data -@register_compute_fun( - name="iota_23", - label="\\iota_{2/3}", - units="~", - units_long="None", - description="Rotational transform (normalized by 2pi) at rho=2/3", - dim=0, - params=[], - transforms={"grid": []}, - profiles=[], - coordinates="", - data=["rho", "iota"], - method="str: Interpolation method. Default 'cubic'.", -) -def _iota_23(params, transforms, profiles, data, **kwargs): - rho = transforms["grid"].compress(data["rho"], surface_label="rho") - iota = transforms["grid"].compress(data["iota"], surface_label="rho") - data["iota_23"] = interp1d(2 / 3, rho, iota, method=kwargs.get("method", "cubic")) - return data - - @register_compute_fun( name="iota", label="\\iota", diff --git a/desc/objectives/_confinement.py b/desc/objectives/_confinement.py index 034b6c2ed8..5cba508923 100644 --- a/desc/objectives/_confinement.py +++ b/desc/objectives/_confinement.py @@ -51,8 +51,6 @@ class HeatingPower(_Objective): "auto" selects forward or reverse mode based on the size of the input and output of the objective. Has no effect on self.grad or self.hess which always use reverse mode and forward over reverse mode respectively. - f_ren : float, optional - ISS04 renormalization factor. Default = 1. H_ISS04 : float, optional ISS04 confinement enhancement factor. Default = 1. gamma : float, optional @@ -79,7 +77,6 @@ def __init__( normalize_target=True, loss_function=None, deriv_mode="auto", - f_ren=1, H_ISS04=1, gamma=0, grid=None, @@ -87,7 +84,6 @@ def __init__( ): if target is None and bounds is None: target = 0 - self._f_ren = f_ren self._H_ISS04 = H_ISS04 self._gamma = gamma self._grid = grid @@ -128,7 +124,7 @@ def build(self, use_jit=True, verbose=1): NFP=eq.NFP, ) self._dim_f = 1 - self._data_keys = ["W_p", "a", "R0", "_rho", "<|B|>_axis", "iota_23"] + self._data_keys = ["P_ISS04"] timer = Timer() if verbose > 0: @@ -138,7 +134,6 @@ def build(self, use_jit=True, verbose=1): self._constants = { "profiles": get_profiles(self._data_keys, obj=eq, grid=self._grid), "transforms": get_transforms(self._data_keys, obj=eq, grid=self._grid), - "f_ren": self._f_ren, "H_ISS04": self._H_ISS04, "gamma": self._gamma, } @@ -180,31 +175,18 @@ def compute(self, params, constants=None): transforms=constants["transforms"], profiles=constants["profiles"], gamma=constants["gamma"], + H_ISS04=constants["H_ISS04"], ) - - P = ( - (data["W_p"] / -1e6) # MJ - / ( - 0.134 - * data["a"] ** 2.28 # m - * data["R0"] ** 0.64 # m - * (data["_rho"] / 1e19) ** 0.54 # 1e19/m^3 - * data["<|B|>_axis"] ** 0.84 # T - * data["iota_23"] ** 0.41 - * constants["f_ren"] - * constants["H_ISS04"] - ) - ) ** (1 / 0.39) - return P * 1e6 # W + return data["P_ISS04"] @property - def f_ren(self): + def H_ISS04(self): """float: Confinement enhancement factor.""" - return self._f_ren + return self._H_ISS04 - @f_ren.setter - def f_ren(self, new): - self._f_ren = new + @H_ISS04.setter + def H_ISS04(self, new): + self._H_ISS04 = new @property def gamma(self): diff --git a/tests/test_profiles.py b/tests/test_profiles.py index 46fd76c099..f96834de00 100644 --- a/tests/test_profiles.py +++ b/tests/test_profiles.py @@ -518,15 +518,3 @@ def test_line_average(self): eq = Equilibrium(electron_density=ne, electron_temperature=Te) data = eq.compute("_rho") np.testing.assert_allclose(data["_rho"], ne0) - - @pytest.mark.unit - def test_interpolation(self): - """Test that interpolated profile values are correct.""" - iota0 = 0.2 - diota = 1.2 - iota = PowerSeriesProfile(np.array([iota0, diota]), modes=[0, 1]) - - with pytest.raises(UserWarning): - eq = Equilibrium(iota=iota) - data = eq.compute("iota_23") - np.testing.assert_allclose(data["iota_23"], iota0 + diota * (2 / 3)) From 05047e7340b661e3570a9dacbe2b5537a9ebf05f Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Fri, 16 Aug 2024 10:28:14 -0600 Subject: [PATCH 13/24] remove unneeded line from test --- tests/test_axis_limits.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_axis_limits.py b/tests/test_axis_limits.py index 2c31a6fdba..1d6c1f983d 100644 --- a/tests/test_axis_limits.py +++ b/tests/test_axis_limits.py @@ -91,7 +91,6 @@ "K_vc", # only defined on surface "iota_num_rrr", "iota_den_rrr", - "iota_23", # only defined at rho=2/3 "cvdrift0", } From bf9c683becfbf9dbb45fce3376fe3e524efd4228 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Fri, 16 Aug 2024 11:30:43 -0600 Subject: [PATCH 14/24] exclude P_ISS04 from axis limit tests --- tests/test_axis_limits.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_axis_limits.py b/tests/test_axis_limits.py index 1d6c1f983d..9ac4db81ea 100644 --- a/tests/test_axis_limits.py +++ b/tests/test_axis_limits.py @@ -24,9 +24,9 @@ # d²ψ/(dρ)² and 𝜕√𝑔/𝜕𝜌 are both finite nonzero at the magnetic axis. # Also, dⁿψ/(dρ)ⁿ for n > 3 is assumed zero everywhere. zero_limits = {"rho", "psi", "psi_r", "e_theta", "sqrt(g)", "B_t"} -# "current Redl" needs special treatment because it is generally not defined for all -# configurations (giving NaN values), except it is always 0 at the magnetic axis -not_continuous_limits = {"current Redl"} +# "current Redl" and "P_ISS04" need special treatment because they are not defined for +# all configurations (giving NaN values) +not_continuous_limits = {"current Redl", "P_ISS04"} not_finite_limits = { "D_Mercier", "D_geodesic", From 3fa64df043f5bccb43e13bd0cd045195bc743484 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Fri, 16 Aug 2024 12:18:58 -0600 Subject: [PATCH 15/24] more requested changes --- desc/compute/_equil.py | 7 ++++++- desc/compute/_field.py | 2 +- desc/objectives/__init__.py | 2 +- desc/objectives/_confinement.py | 7 +++---- tests/test_objective_funs.py | 14 +++++++------- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/desc/compute/_equil.py b/desc/compute/_equil.py index 848b3a73d1..37dd0294a4 100644 --- a/desc/compute/_equil.py +++ b/desc/compute/_equil.py @@ -823,7 +823,12 @@ def _beta_voltor(params, transforms, profiles, data, **kwargs): def _P_ISS04(params, transforms, profiles, data, **kwargs): rho = transforms["grid"].compress(data["rho"], surface_label="rho") iota = transforms["grid"].compress(data["iota"], surface_label="rho") - iota_23 = interp1d(2 / 3, rho, iota, method=kwargs.get("method", "cubic")) + kwargs = {} + if "iota_r" in data: + kwargs["fx"] = transforms["grid"].compress( + data["iota_r"] + ) # noqa: unused dependency + iota_23 = interp1d(2 / 3, rho, iota, method=kwargs.get("method", "cubic"), **kwargs) data["P_ISS04"] = 1e6 * ( # MW -> W jnp.abs(data["W_p"] / 1e6) # J -> MJ / ( diff --git a/desc/compute/_field.py b/desc/compute/_field.py index 3a5184dae0..06cd51a869 100644 --- a/desc/compute/_field.py +++ b/desc/compute/_field.py @@ -2276,7 +2276,7 @@ def _B_sub_zeta_rz(params, transforms, profiles, data, **kwargs): coordinates="", data=["|B|", "sqrt(g)"], axis_limit_data=["sqrt(g)_r"], - resolution_requirement="z", + resolution_requirement="tz", ) def _B_mag_axis(params, transforms, profiles, data, **kwargs): # mask of indices of the innermost flux surface diff --git a/desc/objectives/__init__.py b/desc/objectives/__init__.py index e845e1e216..0443a8a504 100644 --- a/desc/objectives/__init__.py +++ b/desc/objectives/__init__.py @@ -11,7 +11,7 @@ QuadraticFlux, ToroidalFlux, ) -from ._confinement import HeatingPower +from ._confinement import HeatingPowerISS04 from ._equilibrium import ( CurrentDensity, Energy, diff --git a/desc/objectives/_confinement.py b/desc/objectives/_confinement.py index 5cba508923..746a1e3896 100644 --- a/desc/objectives/_confinement.py +++ b/desc/objectives/_confinement.py @@ -9,10 +9,10 @@ from .objective_funs import _Objective -class HeatingPower(_Objective): +class HeatingPowerISS04(_Objective): """Heating power required by the ISS04 energy confinement time scaling. - tau_E^ISS04 = 0.134 a^2.28 R^0.64 P^-0.61 n_e^0.54 B^0.84 iota^0.41 (s) + tau_E = W_p / P = 0.134 a^2.28 R^0.64 P^-0.61 n_e^0.54 B^0.84 iota^0.41 (s) References ---------- @@ -37,11 +37,10 @@ class HeatingPower(_Objective): Must be broadcastable to to Objective.dim_f normalize : bool, optional Whether to compute the error in physical units or non-dimensionalize. - Has no effect for this objective. normalize_target : bool, optional Whether target and bounds should be normalized before comparing to computed values. If `normalize` is `True` and the target is in physical units, - this should also be set to True. Note: Has no effect for this objective. + this should also be set to True. loss_function : {None, 'mean', 'min', 'max'}, optional Loss function to apply to the objective values once computed. This loss function is called on the raw compute value, before any shifting, scaling, or diff --git a/tests/test_objective_funs.py b/tests/test_objective_funs.py index 3ad50d846e..a95980599a 100644 --- a/tests/test_objective_funs.py +++ b/tests/test_objective_funs.py @@ -49,7 +49,7 @@ ForceBalance, ForceBalanceAnisotropic, GenericObjective, - HeatingPower, + HeatingPowerISS04, Isodynamicity, LinearObjectiveFromUser, MagneticWell, @@ -2032,7 +2032,7 @@ class TestComputeScalarResolution: CoilSetMinDistance, CoilTorsion, GenericObjective, - HeatingPower, + HeatingPowerISS04, Omnigenity, PlasmaCoilSetMinDistance, PlasmaVesselDistance, @@ -2094,7 +2094,7 @@ def test_compute_scalar_resolution_bootstrap(self): @pytest.mark.regression def test_compute_scalar_resolution_heating_power(self): - """HeatingPower.""" + """HeatingPowerISS04.""" eq = self.eq.copy() eq.electron_density = PowerSeriesProfile([1e19, 0, -1e19]) eq.electron_temperature = PowerSeriesProfile([1e3, 0, -1e3]) @@ -2109,7 +2109,7 @@ def test_compute_scalar_resolution_heating_power(self): N=int(self.eq.N * res), NFP=self.eq.NFP, ) - obj = ObjectiveFunction(HeatingPower(eq=eq, grid=grid)) + obj = ObjectiveFunction(HeatingPowerISS04(eq=eq, grid=grid)) obj.build(verbose=0) f[i] = obj.compute_scalar(obj.x()) np.testing.assert_allclose(f, f[-1], rtol=5e-2) @@ -2383,7 +2383,7 @@ class TestObjectiveNaNGrad: CoilSetMinDistance, CoilTorsion, ForceBalanceAnisotropic, - HeatingPower, + HeatingPowerISS04, Omnigenity, PlasmaCoilSetMinDistance, PlasmaVesselDistance, @@ -2434,7 +2434,7 @@ def test_objective_no_nangrad_bootstrap(self): @pytest.mark.unit def test_objective_no_nangrad_heating_power(self): - """HeatingPower.""" + """HeatingPowerISS04.""" eq = Equilibrium( L=2, M=2, @@ -2443,7 +2443,7 @@ def test_objective_no_nangrad_heating_power(self): electron_temperature=PowerSeriesProfile([1e3, 0, -1e3]), current=PowerSeriesProfile([1, 0, -1]), ) - obj = ObjectiveFunction(HeatingPower(eq)) + obj = ObjectiveFunction(HeatingPowerISS04(eq)) obj.build() g = obj.grad(obj.x(eq)) assert not np.any(np.isnan(g)), "heating power" From d4e292e4ca6f44efc916d89770e19ac378f53d80 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Fri, 16 Aug 2024 12:28:32 -0600 Subject: [PATCH 16/24] update label for '_rho' --- desc/compute/_profiles.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/desc/compute/_profiles.py b/desc/compute/_profiles.py index 1433f96e20..a2d7ac700e 100644 --- a/desc/compute/_profiles.py +++ b/desc/compute/_profiles.py @@ -218,7 +218,7 @@ def _Te_rr(params, transforms, profiles, data, **kwargs): @register_compute_fun( name="_rho", - label="\\bar{n}_e", + label="\\bar{n}_e = \\int n_e d\\rho", # simple radial average〈nₑ〉ᵨ = ∫ nₑ dρ units="m^{-3}", units_long="1 / cubic meters", description="Line-averaged electron density", @@ -228,6 +228,7 @@ def _Te_rr(params, transforms, profiles, data, **kwargs): profiles=[], coordinates="", data=["ne"], + resolution_requirement="r", ) def _bar_ne(params, transforms, profiles, data, **kwargs): data["_rho"] = jnp.sum(data["ne"] * transforms["grid"].spacing[:, 0]) / jnp.sum( From 9017d478507dcae7f5cf9fd5df870b014d20a603 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Fri, 16 Aug 2024 16:13:40 -0600 Subject: [PATCH 17/24] update line-average to work with 3D profile --- desc/compute/_profiles.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/desc/compute/_profiles.py b/desc/compute/_profiles.py index a2d7ac700e..57761be1cf 100644 --- a/desc/compute/_profiles.py +++ b/desc/compute/_profiles.py @@ -227,12 +227,15 @@ def _Te_rr(params, transforms, profiles, data, **kwargs): transforms={"grid": []}, profiles=[], coordinates="", - data=["ne"], + data=["ne", "|e_theta x e_zeta|"], resolution_requirement="r", ) def _bar_ne(params, transforms, profiles, data, **kwargs): - data["_rho"] = jnp.sum(data["ne"] * transforms["grid"].spacing[:, 0]) / jnp.sum( - transforms["grid"].spacing[:, 0] + data["_rho"] = jnp.dot( + surface_averages( + transforms["grid"], data["ne"], data["|e_theta x e_zeta|"], expand_out=False + ), + transforms["grid"].compress(transforms["grid"].spacing[:, 0]), ) return data From 7e48df58ca43df87c28a3275583d650b0bb6a9f6 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Fri, 16 Aug 2024 16:31:35 -0600 Subject: [PATCH 18/24] rename fx kwarg --- desc/compute/_equil.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/desc/compute/_equil.py b/desc/compute/_equil.py index 37dd0294a4..f7f5dae22c 100644 --- a/desc/compute/_equil.py +++ b/desc/compute/_equil.py @@ -823,12 +823,12 @@ def _beta_voltor(params, transforms, profiles, data, **kwargs): def _P_ISS04(params, transforms, profiles, data, **kwargs): rho = transforms["grid"].compress(data["rho"], surface_label="rho") iota = transforms["grid"].compress(data["iota"], surface_label="rho") - kwargs = {} + fx = {} if "iota_r" in data: - kwargs["fx"] = transforms["grid"].compress( + fx["fx"] = transforms["grid"].compress( data["iota_r"] ) # noqa: unused dependency - iota_23 = interp1d(2 / 3, rho, iota, method=kwargs.get("method", "cubic"), **kwargs) + iota_23 = interp1d(2 / 3, rho, iota, method=kwargs.get("method", "cubic"), **fx) data["P_ISS04"] = 1e6 * ( # MW -> W jnp.abs(data["W_p"] / 1e6) # J -> MJ / ( From 5a959f6c71b07be6dee381aca511ba0ffdf4af02 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Mon, 19 Aug 2024 09:58:42 -0600 Subject: [PATCH 19/24] update formula and normalization --- desc/objectives/_confinement.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/desc/objectives/_confinement.py b/desc/objectives/_confinement.py index 746a1e3896..588b9accd5 100644 --- a/desc/objectives/_confinement.py +++ b/desc/objectives/_confinement.py @@ -12,7 +12,7 @@ class HeatingPowerISS04(_Objective): """Heating power required by the ISS04 energy confinement time scaling. - tau_E = W_p / P = 0.134 a^2.28 R^0.64 P^-0.61 n_e^0.54 B^0.84 iota^0.41 (s) + 𝜏_E = W_p / P = 0.134 H_ISS04 a^2.28 R^0.64 P^-0.61 n_e^0.54 B^0.84 𝜄^0.41 (s) References ---------- @@ -143,7 +143,7 @@ def build(self, use_jit=True, verbose=1): if self._normalize: scales = compute_scaling_factors(eq) - self._normalization = scales["W"] + self._normalization = scales["W_p"] super().build(use_jit=use_jit, verbose=verbose) From 1975d73b7dbe972731b48eb2cf574ea2edb2fe7b Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Wed, 21 Aug 2024 21:31:09 -0600 Subject: [PATCH 20/24] switch to volume average density --- desc/compute/_equil.py | 4 ++-- desc/compute/_profiles.py | 17 +++++++---------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/desc/compute/_equil.py b/desc/compute/_equil.py index f7f5dae22c..e5c7736dbc 100644 --- a/desc/compute/_equil.py +++ b/desc/compute/_equil.py @@ -816,7 +816,7 @@ def _beta_voltor(params, transforms, profiles, data, **kwargs): transforms={"grid": []}, profiles=[], coordinates="", - data=["a", "iota", "rho", "R0", "W_p", "_rho", "<|B|>_axis"], + data=["a", "iota", "rho", "R0", "W_p", "_vol", "<|B|>_axis"], method="str: Interpolation method. Default 'cubic'.", H_ISS04="float: ISS04 confinement enhancement factor. Default 1.", ) @@ -835,7 +835,7 @@ def _P_ISS04(params, transforms, profiles, data, **kwargs): 0.134 * data["a"] ** 2.28 # m * data["R0"] ** 0.64 # m - * (data["_rho"] / 1e19) ** 0.54 # 1/m^3 -> 1e19/m^3 + * (data["_vol"] / 1e19) ** 0.54 # 1/m^3 -> 1e19/m^3 * data["<|B|>_axis"] ** 0.84 # T * iota_23**0.41 * kwargs.get("H_ISS04", 1) diff --git a/desc/compute/_profiles.py b/desc/compute/_profiles.py index 57761be1cf..4952677a09 100644 --- a/desc/compute/_profiles.py +++ b/desc/compute/_profiles.py @@ -217,25 +217,22 @@ def _Te_rr(params, transforms, profiles, data, **kwargs): @register_compute_fun( - name="_rho", - label="\\bar{n}_e = \\int n_e d\\rho", # simple radial average〈nₑ〉ᵨ = ∫ nₑ dρ + name="_vol", + label="\\lange n_e \\rangle_{vol}", units="m^{-3}", units_long="1 / cubic meters", - description="Line-averaged electron density", + description="Volume average electron density", dim=0, params=[], transforms={"grid": []}, profiles=[], coordinates="", - data=["ne", "|e_theta x e_zeta|"], - resolution_requirement="r", + data=["ne", "sqrt(g)", "V"], + resolution_requirement="rtz", ) def _bar_ne(params, transforms, profiles, data, **kwargs): - data["_rho"] = jnp.dot( - surface_averages( - transforms["grid"], data["ne"], data["|e_theta x e_zeta|"], expand_out=False - ), - transforms["grid"].compress(transforms["grid"].spacing[:, 0]), + data["_vol"] = ( + jnp.sum(data["ne"] * data["sqrt(g)"] * transforms["grid"].weights) / data["V"] ) return data From 19c3d317389c35748b66ba2de7a56cafc58c7d5c Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Wed, 21 Aug 2024 21:34:30 -0600 Subject: [PATCH 21/24] update master_compute_data --- tests/inputs/master_compute_data_rpz.pkl | Bin 9315427 -> 8240192 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/inputs/master_compute_data_rpz.pkl b/tests/inputs/master_compute_data_rpz.pkl index 8a9086d237b4ba94e03209b8fead9406c04acd9e..5e54166e05138cf75a6e0a775a95b493c3bd244a 100644 GIT binary patch delta 111412 zcmdRXcUTlj*KdL-&ZTIbc9hQ7~sk#ju9$Syx>HD#muzb;mWa z!n&Af!`MBhl{JD9#W3cCiekXHx4O<5((e0x_q)%%f86(Ze4U!AI-%->U)8v$?&a*a zHkQ1zvesFzUccNr($b>$@;2%A$5&nURb7kHE`JkjZLb+WY~>M4UtxLwAUDBK9PZ$t znH4jOO&m0RlyIl#Se0PRZ*1#6e#4Yj^Y++iSEa0)y((yA&4nYqN7h}r%c`|w-6<)n zdaO#d>XVo(9I>-1bnR?;T^ab- z6rzL8=!Qi0Jr8%#ueL9;yr*=Xzh|K^-qZbSZUuq*q*+{3`jhrr(sk4R1p<2BvP=&a zvv*pp5B6QnRjs%hqo0yC8c097isHomHkm4?vhOXz#9f+*(<;HVaGITMs@;Tf!$t@b z>#)J1@sag5m4&V7d)CH>RV+yyns1e>vV3YGMmyT(t31ny&{=~LQ&x?3wPYC4S8eOT zT6l>Iuc>O3323jVHHer5VIbamXl5mAH_Lv30L2{WcO5sZO0)kM42cK4#) zD-3~^C&F!VbF3rAxHa0WDjQHHoOM4KuuQhgRH@6pHw#TxWgB6bYBwx#(#Q!ytAVzj zYl>{0#0i(|3ZoqrStz5?yM)>i_38+^zs9!^lP=l4j&@tUr%ol6yhKB+{Vi};`&8%T z$)ge{g$lp?+`raJV@wq>XPEsSl{h2ZYJafJ=wfBToA$SQpt7{H61|hHZmTSdEyd4s ztxPI$<_!BYD#ucFiBa@lW?!HZe&1L7FLLtQXR7)#TA206D2ED0 zGHC0JHo}Ba{`SJgR*O9Z?OB@|qJHA28^m11e{7HVtcEq&L9)F^iX5*0D`&El_KJBT z=b|M8>x#KHRVtb0tKVyLWn9IudaXVwyVrJhRgdeZUQnpU^F#~4^F59ct z1zG`lgqBkoTdNp_5x7_*t6ZccZt5yj@uGg>SKA>|spX>nUac+S_o=W)QKHQ<4)!GoNH5yfQ#0f9j{p$u#GFvPzGYKhP zGzyH1alIeyqx;9snU|D=1!c!q`+RFJsIBIBlrFv3D%{z6bE;fd)htuSY^I7ficN`C zget^&|J5awZ7n4Yfv~wyt3ttoRy$Wj+s8K9Bb#%KyE%xa^ zw*r+{*-}?A=cN=vHrz(MHQCLLb?Z=B9-?4#3;zlM!M2~EweYViMoYtK$`gv}`@54I zZ5!h6t7w*~wFZ{&(#bZL%hhIkr-B-a$uwBA)5B9R_L^ud=>5L6 z7K$#7^$zy}aD)_mQ{`C7z?|*=n%vPxOuQI;iH<%R=~auh zTHT_Ba3{{YhLz2*fkN_b&g6@K@kg{?cST*M0=-cGD=*2TxcvZbxqwSP~NfcjgC zP7NEHAcLu$QbrC-8I&0NP0wD5WNTU|q17gNP@_`8P#vHo3~k?OMjgsT6)P*oCUxD8orf&dg$ zMY3y68c+S4+$yE6<3($e$cRc3dx>L<-0qam zd6iv7&_1`SBhI!_!Rm(8RDq{Bg(@G2Pdsmp-<*qA!TRnTr}9?3{#1sFIMbK@qo_0O zHL4(YFTYGa)cKcHP_hbz4X_F{2Z6UV%ItM7y4LDt|1genc|}^Rlp1vHp6#h&qCIDGYUGtO zXOp<=CYe(XE!f2fw`1&lgtY8tj^eS`H8SY5WIGR7?Jhp#!@oq_N#L#8a1S@O)@sX2 z$3uFkFa!BAlY5zx2qt%Pf=4C0RF*7zr$;a=I8E%TSiPpucth2| zjznO9h|c9gv*N`)t%(=g(%6hA1u?5#%PaKIvLKH7}|hOFe;P zkylOohX{w4`q+!HVF~1{Uo5tW8FWqM80=7bt`c1vwfU;5wYpQ~Ei1K0GacTdv%QcT zG~REe+S*wZHj}fqvYh>I)Ow(@=qI*%Rm)HDl|iAtcT^Vr#nABDCa)%DHTa9m%M#&N+Guv3I-s3$be&1`Fd_hNuN+ZAh@-s|~Ri-;4?F8C`ZTB+#XH z7q%uV=z{$!dVK9J(?Z3aBV%u;No&OOqZ_aN`?nwHJT^F-zW%)ec z`}nbzVYZ_DeLQ^dn~*@RoQlOjK8k8DTCR%9Cp$KxvfX|%D@%5aEI0@FCan7mZ&-Rl zL)Eno1#N9rO#@l6#`g^gv>@l-6Za!L*)qLi9mGb1VoVin=}1PeDB-J3C;K%grh1e3 zRUGY>T3G_JAbwYTuc{nN7nO*zDK)f?_~CLJFShK0p!DRKYCS?A=eeHZv5$?&JyUN96Ko(Dv)Wm4@$KXa+{6x60;sz69f?D=yI%jnUvUTWVi0vJd!3i)^|2{IiN)gKI@NBY^+Zjpc2(s(+NO#*Ojso= zN4g+@{Fb(s;+Rab>Q1Gro@zZ_TrT+jsiKxyt=#whh7BLC+(QP6u~&SzmA8J&@uSLh zSlEcatNd=1A7D)e5Ns3#Gc9eZh`Z+aULluP3VCs%;Cl|(DXvxW)Hj!e);^WDfOIVm z_RFV{`TZMmqpAp>=g^wM`o;Qs>WWYg?tE@K5tRNH>nS7*8&O|Sw{MUpcH2}hq2l$B z#e=4;MVH2-$R%a5X!|JY3Sr+ovXZ-zaP_ypn%ET){?VtX0+nNF=!Ga(M=WyDJgx}E zT@yxy2*$Lg_JZm1bO?SowASR>wOC|Zhv%z=+&V)XDui8<;o1mU1vBci8E#h7U%41i>|&kiCGW>IybLofhxE(gr_1Fo>6-EHX}#+jlH<>kD9eA zE*WACmEiKOjrtb0M#e06Z;b6VM|nHPylK!LEMA^}MN zWl;FG(B@wthxu4&FX)P=dx*Jz*QGZ(XQBhiJ}N|u5%VS)e#mf4-6A) z^bDLuPlBsP1On)oGE4bDcDVQQz+2^$pf$OjA@^Anc@NtbcrV&-b>V;BpDHnl!Y?BN zg9LSoLztL-pRjQ*i!u(RchK^{dgAa8ftjkRWgWKUXBR4-*t%*x2tXgJHY3YPBGH>F zBm$D{lo}J$t6H{*1U1hPx|>3MsA#5kHR(;y)=i-_ff%0G{IB7da-Ae3n|eD6@oz&z z#Ru7;up&cFhbpeQ;-9-GwlRgmV%2>cT6v8Kxw>N0Dq$6GU+T9H1LJTS5C(v^aAFv! z^{iv!eTq-=5)(<7A#r^9@QCXw&;Dh(LxEMwr8)Tq44j^X0?MUL7bmyZOQ zy+yKv>7C2F?Ih(_ILK49yX<&SfS`2@Xe6Ewv>``U^5s9X7XP-+9CcZs{~8~C`Boi=@~gaL){ zSlv3hItoq}ppGBA44vf%G>K)P=)>#Fs_n#a-3tVl@&0RlB>v;gw7)}RcC|k3 z^HpUx!sQVHHQd;7Z7Lb=owPWu5c@+Xd%?wiRM3AiTm?Xj)rQ$ntmCk)z871oXV?+XqRopLq_*c16m7N-bw%I+D18q2pjyq1sLL$=vK){$jL8M zY-BN<9t@*???et+1fR7w^?s@nXBh_2--suE7;{@?4?jFB!S47E^c<&H$qtu)psUhT zrE>DDBM>a55`SLTlVY-KBgWKbJC#C>(Ywe-jdV@5iVKfewQ#|YM1KBGCVwWAKcmQ>MDk}6`4dY12&RdxeT2EiU0f7L41i0ea^_~$ zw-h8-u@t)o7_^V%b;}m6Sso0K9LhQQM5M3VFC!1Q)>n1Qu>I`{96}M zJ5+R*hTl+ml)5UM-^~b49Dh6VN(Da=%yG|J)NLF|eyvu1HiKhh-eK>XBv~d^&OhYR z=fDN;TJ)UQsv60fDZ)$z`i$z3O7Vi_dM9V`;7?8ZtN@)ipm+Fe(e1!t-q`$Y1sf=Jc`?`2>{59^ zM~7}Q5D!sp@q&Xv#6yW6MjI88+ILKbmH(qQl7;Ev~g06dq zs$x-ASVl#;HuYKDUT_Itg4Z7vWG1nb6MQbu#spUW2L_QGB|Y3Lj5bFz7jb-cv;2x& zi1*^vR)r~>5`O3?kk}C|l3(5{c?V6Q?JXQ5T4pjvKy zMB)Qg-OGM`EEcV=HMmv&?z{XiI|SL@bR!oOc7w(yj}(sFtWifC=-H4YUL~Q4!+SJ! zuW;idOqdhig#UF%xH#uVH;umDff~ZW*KDL_D(R@vG$Oa@u^K@m$2ZrL8}?A7j5%R!7zgw+VUvq z=X3|@cs3p8%e{dCR}xAY$Rn`b2K(FZhw&qDejSBg=Zh2N1@hX}7b3rjOq+k{H{*c5 zn#DiunbK-xtmfd0x@p7qwb%Uo`hCrWZ5=g>K*k^e83PV8%z$YI7RVTeW82)n7sqeF`3sQVLRe^n3fEyb>XDTJdigui zb>!s(YP!;#DF_zgD7KqB(*bh+7MQRR378jl9xSxR3l}~U`sMiF=y+)<%;$~+J$WtA z=PqNr5$)%Lxv=dpAsq?$Aijr%Un9h~1)YiFWXj-0VYG=UK<+Vm?>s)(mmqbus z;IeT1-#FhC4fL)n^!Xc{MjuJPVBf+3c>_$~?9o}0(3uth134AjPS~H0R z@{Z1j8@^bg;*NW^eHm3yPtM1-x-s4nS_=Z_asx(pA&3L?n%bLehKT| z9+mXGctdsl<12~zl#?=M?{O*pSi+J^OTV(FFVN1y{v>~xpl${P!rlNuU2BEG?n4YP zV2#kvYGFKUg!wE3^wCjeSiSusT<&!J(|X(AEY}0a$Gm zjGw-XD!^);{!$cR^K+;IlBp`R_hY}hIgHnv=ij6Bcvj~@HHeA@29mBWXsCq=QWg-9 z7$7L60|Sz2z%^;1awGn6=mS6G5!Wds)l}!*-yu_YM3uy2YTFGG}4Dknt)Q#CU-J$J*{mXFt0-VomnSGQe zfkE=64C-l^R0tF!F;L8g2^@oQpa=+ZrcV$j3bBm>$O~|MGR|joKyN#u25ln^L|nq99iS7~9taB%mvBXmAY1lB*zgW;i<~6F`0>Diqp*RXhJ2IO zC3%xy@)wp)P`K@oZPlRSfwA+WBhoUqFVR34B3;sGCA9CO$ zj5pkc@rGC!ZkP$f4Zl{|@Y*%Hron#D?@w17BMoWTo`L;saQqFN{|4!eL3mIT^__$A zh5_v1*>p_*zNjFB3I}038x_{>0)@vSfgmI}9N_`N1@2p1aTD%<6YfX|?odfX0D4ih zO@Q8BM1s@zz?Mx#0=S}_gz!Ke1}1V2(>p?8xha}dx)}~2JP5!etH3$dHP7{l5HTJK?@n)|xqSHKvu%cm1kj=x;Yg36A z^9nx59S7-uI>Z&u_z~P*Yi?tIdS$nF;VC@Gg|I^40c9Y?V%%8;}9#+%`R43XFP0pNiNvN3B8ta~x?Zo|lH!Zv1iStmlI*5iDw zkq3fpC<9l65g16ZFhEuV{*aO|HJIVRub4V600UWPP91Y*>epVRlKI8%n*rY(r-qDbaaXyRm zSRH0>Uhe|wJKvnXfdPxznN4~`8L*5Ozyp_u&^Fcw1`G!ba&`keNJ4lJe-hw<5#hmO z>{lb4ND86zc~)y?Pz&GzGLX~_03N7Yg2wqkK++*R2m=PJ9^pZ0zXryufq|rc04p>W zY{G? zGM^{s1dh=I!Bu8>Fbe`jJTNFt_vogw55@&8!ULB|abh_z;LPxXNdbBS!UGdt0{qo= z1y64kW@6+D#7Nc|BU>)QgIt6M*4S@8IAJK28H{v1!UG23K@o=91(@xt!~D`qgnT0p zN4d|47kqF4;t%;b5?~M>j6ir`zE$`Ra|Hv3ekljxfjQZ%g=EGx#pH7xb4?iLnvo-s zfcaKoFv0`#;TMw;r^j^P2;o5lX2)dAmL0Ht0kdT+WIxsnFX{;ESCLDAH;uM#ST!$D z*4)VXuC2cf7m?Os!Kv3rS&z&CF*9EVYM9NmExpO7{c;kF=Unm@&EUU{lpl_}F#m;J zimYB2^0&o%C;0}pbr+!jHyl5=0OxlAdLO&6@$ZU<^M?2>!0_=E5P)q60{H?1?k*7I zl7Ruo9G@~}>{p}o^xLGDy6rPKk752gTc=U-qW34}^zsVi?$kAHI27Q?UC2K4$yit{ zwb|}aE!`NY`MQ&~*?0c5UrzX-jOPR8=0JdZ4FqN8C}qID#P*A!lmXWp7|6yzAh16N z2!8u(_ZGLTrx+Fk1L=D|5a8%15GVu%EJT5sgP;Hty|?Zee*B+oz~;Yt^_b9{hVb(I$lnN z`CJ6hlPQDoe@fqATZjD*fxf(x%;yOMuFozYn0+g){pf>{2G_&Duwi2mpb9YHR-k|y z6qwNv4Tu8TrEA6e*F`q$*!@v!Z`@^7D|Y71yjGX1-@I-AQv<@}ON}qCoAjqQw=A*o z%YMxR<>h-unieNH8GcP{%qw4TwoT{&IUFW%owmW!yA@qwr_bn^HH*&ZJKcGh#hBq6~S!sFOm4(FFlR3s+X|w4>ycm zx&K~N1hl0h7{IDwf~*DttdXSzC8i@~ARz+4 zp0B9@ycA@Xs3}Ou00Wlk0va%FQ4{=L-vq|#fl;X@Es<~#D&m8RJVr%~D3}T6vszA3 zgnuLHz5z{iuvC%}2c%WfBnLG~LQOhX)I{2k0+|KWqQJU#pn&cY+SX~Xtq23LEuI*c z_5$o>FEp;#Xk0~^U|b*3xZ0p?81ukZv~5Rh|$prq>y{+@La{5=c%Rh9gG6cV&Te@{n-q3G{{C{Q*Es6&B` zz0lo*d5B;bBDtX$;R-PXpT!Wo1w-(248c1w1b@H~{2oKxXiVHC->M<*} z!>q{XU|QUWY4I#gi-EEhv*HVLR*Z$Lh*?a2k6G~qX2p@173W}9oQheoFJ{Gtm=zm; zhOF2E=sU_!%xST`aAs?`@BfE@#BVAEB&fGx(Yc!Wz|1(*IlF8wuJ`Wd+N*|_xEap|WcAgO}_;?{DEJ1C$_ zCbkqn^0_-2S0)n}!Aqun`1q?%hjq@@7 zEW&`g9|COBL4X@Z6J&%U%m`Hh4alZHAS0-hHb2INGnrEYOkfj$0LL7{lmHAQ9Wam@ zV88Y*qy)8*!U@R};fA&mzzq*%I12?Z-Ufl)MJ+3 zjSS;a038aHgaT?cAh0e1vvdL~qJ{61ngiTGK3sdG)9)n@z-d2fqCv*fQInBoO@IKa zjRDDZ{V4-U3k)QkxgW>J;`~B0+^_`TG!_-nqX5Y~YNAC6b*(^RW&miwxT^rm9tY!! z$84@W1$$}4Y<~mch8D5xJ%k5Y&@bt7z*b7(#!0X(o~c0@NC=jtAjBI+V8EJ?z(XWh zgjn_gGHj0mXn}#$83km30n2!R0>&2LElFp=-S2}p@!Y#+aK6}p{yq==T~o>55s%29 zVLbO7{n-Qr3F4y+2xR|#%BR>t#HI?6s6g3~bMGDj%`X%n_=mBiwj~EB_6yyc@23KZF|>=uVOQk04z7 z5?pF#EWnNT*uG<4`ge3|<)C_iS5D%}^SJUmaOIzwS03Sp9|~v|m>Gg_V;M>3%KgV6 zG_D(HY$a%XMuZ#7&>P;OH|WtDo}w|^;QfaQjeQatzfNI5@W^~@U&sDu=nPxQ{5Hz{ z#~k#A%LquK(HjB~kW@uL@)QO976sNV2SBoNmxW4T)5C-LuBdn(bK_-wh_`1gpD$7l zZS(Q6?jQ_caKi2Hfj|rr{H#(KEHyNSwpW1iFbQV=lUjQ*4X`xx6yF7%^7 zoV9trLNCF4gWM?ogWKcZ?jM-f<<_k&^==w+#%*2r!{cua>Mxm>Jdd6*EQn3)ecCa> z&_?a`esUF~!L-74M3-ef4N=(civ4|X{4dEcf32Y15$?gW6KGS@1iCdd`ciV5wlG~2 zyONUAw8HkA9?;(k$L|~u^V2{)%?&rY;D#7Ky5Mpl>XTH5E;z?rTdyp*&+$^ z4)lsB{oxwDLZ2s2g#%=qz~!UU=o(XkBzJ&QF%i)Ii2Wmh0k;$w$ZBA~X`}ymRZxGh zhMAr-X!s(I`|{1gj-i){t^05zTJ7z{<*q8UZSLP#)@6zkX(oUi!-) z?OJjRHZ}41{C$+HtqE;o5%lZc!ub6-pD_YGX0}4Vk%39)=@+sQ2FN%;*1e$wBxE25 zY^Dr2ttVw5qX3fe9c3WL;(TU5(9@j^Z(V;(Zv(^U?9*;*D4%HB)r0msTp=w8Bsa(Tx|2YU=|FABz&s99Y)ICBqBbP!3SrBb56TwvpCzpu z>}dcP5vNr_Tl*etK=&Lb7?A*z3j~?o)QE_Y(l(a^{UqXp(HTF15h8ug_$wHx(G`qT zTSEGIV#V4QFrmGf05ITmt*9Rxn3doa!@!R@tuJ*;x&2D&$DB?Ex6*$=HOG z4PZkO2Wh@!B*2F0jsP1rVgzGe(=5)*$*mDL6a$V(zyVn}p@uocX@Ou8WiZ@;3}h9? z*fba~*N6F>4(M^(_86nz18iu6{g3H*eu!*|1dJfD+zWBTXiW1R%~_@v;09eXWD)%- zzzy0akY%#4txJb~2FE``*f0s{b*A)}8m21kHYCm0#58B}!8}<&2}sF6kV~o$X)+9P zgHD2eJuu*01kc^%=g%!2F5k#II@&OI=laCU&-WR|UmN;YOk^iR=+lY^zs`h6MpG?uM&Yd_O*&5m!uTHdI^An8M482R~Yr=pY zuTiz33^XC|h2}~D4A_nne(VSY+9Sa~h)~$nn6OM0= z^UokXT}Olq5s=PhUo<6q2fzy|!~;5Kzz0cf!4`GZpnVB#F$l+p;e2%@wRKrf84$dn zFd%TDCG^V?FrM3hzM`u-_7tyxaAQYwCO5zfM{z(hP6$E*CM2k9j(DLDc<*-fX00bg z13knUnb`o|Z!AH$fbCdwzbB+~?!Gx3^ap}W1mcB62t4ngpVNClAhX9n#;k|HrTZHL z+0W3{V!sK;Kf?J8(3c?+6Sxoo>6}Z)d~Y;|;$jHJItcAtiWx7sLntoA6Bvo}aX#aT zcwsQ&1!&7fnC^8jUS{4ws?hS7JDdD&?8^|4aHRKD`?wee=G{* zXlAg!JcG6d-9p-yzaSt|!+6=6&gTiF`T_`wd5=qEOBu))%!mpnsDS~;qyj;vE8>L` zNbl2ei;PcU%NX232Dfw;!UYE51I3&qol9nbvB12?2tb&4#0&X=7xd82>7GIQXWpWb z0t3zmY)EFzc)@JMXw*SC9{~=>wEW{0PjJ7183S&%7TrW$6WmOPZlv1=ZpE1K0=C1< zZiwTrnB8mw(9=dyH`Xx8;MPx|U)Fg+oOryVkcWfCRtOY&@MBK59onA2KsMrp>qvkZ z4+PUX0c_B=gh=-eVM7)MuIuJVXA6OiG2b@WLwiFu57!ZoaYA*BbVej-q6~%`kbzti zLoJRc;1-T{Iv~jD@wP$d2%%bs{Y(`I?TBl*B%m+n@Q}?kUokl(V6ssAA#4}`$;1S1bcqZ&-45ta z!wG>%K#c^QR(^^4A^4U2xZN_bZ(<8>?VTFk?296~=g9#_KkNwO1|FFiRBwE3dDZ!D zUp38MNyU5DME+d7LSua1Non(JN$4zP05|QeeN01mzyi}`2jPy`d47W^*cad za8JsBYct^21tfx>`+8~_Zswy1#a*A3IUEpN#s_5E~s$AmuI z{gL928;1;%UkqKJ#Kn)~R-`t|A2F_-JUnNbAK(0Q74CEKrSXk(TWF-bX?~~g22XWpn&oHyT~P2gnE>iyk|f)U}7h@ zI$oM+K-NJkew?XtEy%UP4V`k&rKHqDM`RpeBt`lR^|M%dCi@ zk|J5q)?@!R9B--2=ch(+Q&1BvYVsp$(hmiQLQU41H9>)y&Y+1Fx5fpxss?VI25rkW z25f7+*|vs)ZT(H!JTW%zAsW|rXe{;7xRUkMS~&(7a3*ZuK;s&Yu@p!=xNog&b^oYCESqx-!t0)JnK{@w=tJq+Eq z0lM?|K#xQE@@8yT_v9fUxZ{Lu^!Fh2_onFYe;~tyD8Nz_$R7o4g97W$f&#j&5WwbR zK)Zke?iq&Q?HGcMJc+?d2rj}9T=N2iOnV5CToH!UJPfgVa|i|o@(OI9!v6C(einw{ z*fT&c4MVWsb>KG|Loi>05?w_Jksznr2^tK=r1Al?Viim}GcG|AdU_9%(is=Xif1t^ zu6+zyamQ6iYH|6HUM%@LL~JqH%xj~h?} zHy}u%&l4b}Hsg}-z@+M z`X0m7vL!qKrCKOq1WK&U!#MRE0OsoMX=BDVWWHfy^XBdoT8%#%x}Q zuw*bMbKNBhOL)U1%;s%TfF#W326Hwa2@*58sKJ}@0I)LQ`-oZqun;hDvyhGk6;TfY zMNFtj0xF`SeE2qU10Z0=IV@8`8OUb9rN;g|)T99tSY_741ORIbDzX3t7>0`Ypnwbt z%zQ=#Y~MG2#}m+N#JyU9Y5x`OJ z`uivp$Q#{#{7N3qA?Aq1T!#o|!icsKv%U!<-cJ~U4`2v(LReA_VaX?qpieQPu147L z6+^D>8l^9P!FC#t15V(CNl2hI;u4015bS}tq#uUh=P1y66!3*P1U~=;JTRw}AS|hd zNhbkeNk7brd_1PbUokBP;A!0#vtktDl2Moy-7zbAVpe>BSup{#;yQ#SOA(fg#jF^D zS+OZ*#a{uI@Z1GVi*YES59aY2sDb(V;r|U#;amJazCbAhDjHPC4iz*iD@N`&$rAB~G{{dIT!j2vlnH0;H%VTf!?B zC^v9Vjw4bjxDD9V7Pq7kO3a}K%rG#rA!u|yhy%<r*R zNT#LFzKh)ZjBWXTT~@wwl~&^_|_#eE2JDM#qWi+CH{2)T8>q-q#OryhSHV zwHaiS+aE>E#U<&eqU( ze&B?TwI3ha)&I}-_qy8{A{>XW=zG!9P_J(Ktf@Ec3>Rze_;u)3SHr$uQ%`z!`Mm#q z_S&0MqT0w<`$L90QE}X}TXcz8C?w?|$63%N=D8`0l{LO1*}xKWP>Je;G;|JKVzxId zF?So5SWbW?HmG2Uxofb*@`Mg_i6y9n^@P3bOP5&k8Ag|weLj#bvGiC&mza&4tSm8~ zA#GFEc&o3xW>2FToz4bvgK!V`OU1jdFnKH%h?1aSR5+ImRxd+ADOWD~IkkEzDT7)) zyA`Znf`U{QTr;qG`Gp6ydT#Si)as?>ic#{>HioDlsoAsR!0hFPVD=o8#CjzyJ58;g z?K+8Cz4Q{So?QY~FSQ4&=Z1sTONZZ5t7o^PTNOVYo?)4l%VM1<7V1XTkQ1L4h4Z~M zUbM7TM(QUid& zSJHqt=Pg<;N@4BOn;ji=;6;?`Q_7!h22GR}_N?-I)$vc*m$mElZyokVDxno|3fKs4 z(}qh|Pe_pyRaFmY_OQl?4F0UK0 zg`_S@m#_QJoZjv?2?|Z+N$bMw-p8fsrL3#b10xbIvE%nVNc!bB0sD_g_gi}Oh`pXB zHCgy6DZ2O%X@K?FGw;`DN=(0A^7JOtqc)D1RHtdPbXL^lkBYspja}!~Ewo|eTox*2 z?PB>(9SR0+n)L&laBBN(eefZvwS)VUITOBT&(LU49U{nznYI5YU>!PV5takxbL@M}` zD#Ei+vFZq$(V1$(Hkm**VLb}ZD4MWwe!%EN52}e&5KJ|ZGJ>ck5|qr^C3Wgc6_Gxi zql&PnJg6d4u{TvjI#xmzkp>v4B2w!xMG=0z6z2g;HM8m5Vb4dtldzDK1cjx(NUQUx zaY;}g#l$`XMKsP~&3X4yVS&s)0ciqkc5w z;MOZF7L<~pz*G&+k@!1tcNq#$ePR!%yzI^sf0shGQh#S(yrljvK?SR4Y)|laxhMEL zyE%jUyL53I_4h-&_E3LkAM~L9F6{t+XQ6~vf#k+ge`h1dQ-7DTTVyEi&i?+2y1Vo; z^c1i7JNq)7`n$9{mijwe1Pr1=;uamx47$!@VJQ|0O@+&e2t1$=m8(1)fyY}2!IBFC z52$2iA=gCU;g7(h?P35P1AKTu9#dxk@>q_@V+@2~8A@rrVmBi2*a9J#RUz=$gTSLP z0*^EV9$g;+@R)$WL#=;M+iq|7Qs4mvr{ZKC{|1l;RHSm?>Lc=awvuK=b|V50sA%

a1 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%0D3m{k2CKwfy!4O_`BK#LtpxZPsRN& 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

aOxKS=R-^(0Qq2eicm@3x&806)IHv(a$&A+UPx zeDiVM_TXOU>Qs9Ck+Y!L@34kKRw2~AvnfS_s|=V;5@zEZR}DLgrdLQsw}S5lIV(Na zH^a7^dGR?Xo4{@r%eLenC6Jx6(8|Fe7hXE8s>~a>9~xWFRH)ZD0z)O&{4f!^0pXAJ*&*k7l8m;ZZJ?j2fY`xP!%b`uz8#6zU><4L6sr3 ziR1iP*x!BlSsH!`9u~KS(xp1ku4Hc9tDai0vo841-7C$|?dT$hfUQq~QCdiMw9#uQ zUM06hYie~BY}0AKMyK3>uPsE1smro}-7D+ECNeK=J;P$ufo6FeP5_z)nX5>#xziaIL%?;z93czi)jBbi;1j;=8^;wdCC!KPSBg z9$3H*D4Fd%Ofur5gF-S|%sx7xiZJ>@!b2(>))m&|U)%}#Y&o`y5a zFJ8tXa=@Y-%gtFutOD&mVyPd4JHZSEJS=xr z3G_b~e>d0k5jdXUvt46qCZtAu)f1r{fKI#1$K7tAgG#yG)WV2ZAT=-WSE%|;xM7m= zGO2w%gBef5p&kf$Np zkFN3%xD?HP5WVU)jCib`uyp25nB6vgF;7+txZcF4A~CB67S8DU`qsSy3bvnWliwnI z5*(hLRDL@B3J4W{qgLBq19AmTvpL3J1iT;Oo^_-J!G?&IM#?f3-Vw*-?*@`ZB)yDXh z>^WKPfF8PKxjlTF%*Z3Q(7mj37`o1S%FrF_lQ9>4xx={0BZpBpJEKcw=VDW)uT;c; z9O6AEgbfJq64sntk}SY!l-CYVOgu#G0|(k3Mv9 z?cBe-^OwAgx83KE1ZG(~ds=ia7nN}bE^#X_rAlhb$PqGc=AQR}&bTJHMU#_pgRR`t z4O28^qJZkCgUyELK8$OZrH2R0b>prk)_a85O-0b71%T?ndbKyYVs>71hNuvOMW1#@dv3bq_4SRh36xy%be&?B&4< zSh~2?JS?MxgBxG)eEWIgR5kqo3xY)tj=p|;m{bngcv6@GhcIi~IBHvZ#1n#z=jQ#K zk8U#_P7Fl184po}6YFudnuj~TT{G&0HwO2g+n|V(*AI{Qc<5?iD#p)aFOQR_){QQp zfK9ly6Wtvw9w%B__h!^O z_INyWkFgEous<}Bx*Jy^bu@q*y|;Z%s3p;tnn;6ib1*f{@MPfn4r&b}CyJ!R={vf@ z8iG-Bqt%rdo@maG_>}d8LUgJhx?+6Vyy>KzKAbiFnL0MHUt;9#&!|NP&*2JO=A-6? z7$9*4^=Oii8gRrkkC+Z@B%dpC>7jMSYd+_7Z$ly zUhqT#8xPjD9YN1|e6}@06cv6Ja)&9*K#JX%2e(?G}?RZ_lnB-zO`8w*>Uc`)a5 zRu@m=@qpQ<#banb;q}vlmD+g8) zCpw3r&Pfo)Ngj`P**K~-#HA?M=W|BNOv^>;H-}RW-Q~`S>1k=BYCg}HhfC#(q%#hC z#3f|SkbNCsG25&Rfi4#B*}*UtOeSO#%gYmML{fmY&oEQtnK@+dT?>7TNc}sOCd^)< z`Z%$NK>^}_=qiq`o&PeDpu{ccM86rrpn~yrs!Kc?BSkDD7-D`-EJJ2cyj{%gM-h%J zR2Z?C%2aP;A;LPlG@Br$WyoSk8MzEbh8|6cwNman^XKC>;58Vt*pE;^o zG#%PF5}Q#Pf)uG^rSh_v;eI{FK$*hFCWiNj&L((;Z8WdEW;#Y#lF1S6=sUk<0_Oeo zB&(oFkjLL$+r_ZwucYmo2zEc1XXbDBnQl zfzMhD$mz2x3iK&3GjAi>ZG5o~eL0&KNBORdDg?#WBZEAAN-IOG6|gv^BRp84BwZX= zytOlbBr6Zg7Gh_lIGwE+vNb7E81eL((VCLQOTb7IvVNP&G!4WJZmf-VIZXg82*^EtNpYS zg)8~;wg@qJWww)EgAjW=8~)(Jx+f!T7TJaN(*06+;A#1MA-&-_b;w3@X(tfIVZ3nZ z$v7l#8yFbqt<~eywg7#~%H$M1S1S9|iOWL&ipe zZ8m1@sJ#fMPZv3dL}B;nd1q-4Lv)tM9CC~#hKDf+lU_S70-r=N*{IIsaTW^Wh{B^z z(j~n`Y2d_zyEtlBjhsp3bSq%sBah^c(*&`r$+XG%&SkVdHg+EhdQOwXjMQm4*yRik z9-Lo;rpS&7Y^JHP{leIOx`|+k>u5Ky_E2vgcCP7Ik{PXfLY3@b(_x%GmRS2n+6+8t zC5@Av{gy0Vw~@Ap_<>#9LVLmXj8TQla@q~5L+;RL4pmXs-XfT$39W#_e5i(1uk;nc zP}zytTvJ*GmHF!WB(h=3aKjFUn9LzBvTp?}Pq$$k><{YUOsy0oHon2)n-np8l&CdRO2FB(@t0vw&TTheVV86!a0o_UO~D zvM0;p))ur`?9@xcWJ9xs=sy#SvZAH4G>*$+sN{6q*&59O_119lB3Z0Di8d9}@}&t; z?hHR>PHO>`NzlQ$WqHypi)Zg3I>4;4bFd{b?~yINk!7&a$33)M%E#fBn6r;UaZB`y zIim~?KyyvL;lXzJ(b8F75Ap(HJ$`JZ|A^848+d_bZWOS{3N&r}YiJYjBpYIsDl>;d z1=X31=?M#@iD0o-w0O?#4uf37Qo~wC4TPlO6g%2aHVU(b4J@@UaUg0p9j<+l%UEi% zAxq<^CINPe!*D@IMkOTe%sgqiRFC0Th%re90bV0W_D^zWNB~WFBu}zXfM8Gt+wIs# z3}ghCk~+ot0O}ia#)r6cL-0u68RAm2xPOvM8NIj~I5qeM;r-yF%1 z4(({7rr)!rYs_f2TzKkVq%Rk;GZ;ph#XSAB9{VlRW+oG39m}-&sUxP5!L&2*xC=B6 zRz=u6$os$2iE73wNWYsSpARWW@sd9%NPes{WrPMCHj(^TSmB5_Os<=V?JD|r+esFE z#L$g+;YFm6#xfj>ie}z)aD5a^hah!-`n}VtN`3qtUudwb9gVC>3YDT5pg@LEkTlscxQl_4AUElXu_fTh z(^2N8_z#y^fk(O=n8!^9Wh{>owrg@^EzZ9%T#cK`ERB@+!Zq&G@t+S5%n-)nBAcFv zS)0&BG1N4Q9?tj{Vi74mS&U!gKmW! z%~6V#&cV(rI9f@rL4LYc^ksQa2A zaW;-Hl>pY#zE}sl*U<2o9Y(`5-|xU$Pz~E~fcBe$#GNw+IO>Ts_hKez?Hi9;3n!Z7 z9Uh|((G7B@y(vS#;yLm6aR(N&Hk6I8Xb2n8$NdcAAU04Grd%DSOX}|*BS^^4+Y&b{ za9qe*Itq6!aa+s~9Kv@;B$dZse|DpCQ<>aLL6Oi($62`Zq=50<)1rz-hlq-^hlEj* zLWmBUQfudF!Yq@ul?#&zah1ajZ#z@DF&7U>Zgz*WnDrqiQ5-S0qOdS?Ud_0MsGyIr z)uXTkb$J3VZRt2yn7xLL^fGbjNe8EJv)#o}42GoIuZ+geR!BrsGI+etKEw@3@$j%+ zWW-E}MJYI}C76VKoJ_`7=;?k0KnBNgvG8LyMlRnOI%-eBs(2g`!k8&9%9unJtpQni zgE_a^7@8n39N0@RWP?SmAn+JbH-^zFC&5(s$rQ)Uth2%BKr}~?1a^AG5lKS3jF?;L zKXDtv9R|6Lr9l)DkqyS}A%@AEP7)oo9n-&FQlMtx-xdc>O+R8fo0w#uZ5v z^SK2{2MkeC0OwV39wFH~hu={M(dWVUXa!PPW!xF9=`gt7g;5mEvLIfd8z>?ynZ`LP ztY7sjYz&a8T9De6*~^N4y@Q1GNES2b>Sy+P7F^bADoM=Ed8KTRP4 zb>R~AdjYE{G9Ij8(q5thgG;UiTN9cW3k*Ft8P8gEXacK3)&5iEB}LtOTm#sK#GJZUhjuqO~wnv-A6F=ck&fs0SHQS;f6jz(^!o~ zIbl2pnF;YKz%;Me^5pF~vSftmB-J{OvNEiY?}>1E7HdhexE8TSFqUd1!*fs0lQyve zKUQ{F=s+yvapGv%O^uaPaf0}R^F*$Gy!quf);eg2j5Ybg=12mIptwomi63awSha%- zg#o%Cb0~mieW1DFNY$U0TjM=tjQQf4{u=_4`in5-I9fg*F)Mk*tfuhLj&1Vi4?lHc@=)HrB~1m)}S*bmAMi|-M~#c%`@uk1sPAXAY%9b$7P1Cj!y zP2@Ll;?8%G*&H$JL+gcuO|ZPXH0(dhAuaoH^jZM3O;#as~CilfUX zwMO*-X+|utmAV8k+!ipBLO9~?5kC1~C7Q)yBPt;QZy8Ln<{&rW0#9HSVou55@GW5$ z@WM^M>q;I+ko~A>LWL2F$&RreBnOc?krQ`O^%zB2#CcjM6>(4%u@E+HI8;Jvn(5o0 zC&NzMP%dbM;Y2wb#JbJf_8Gs^jc6b?f5kocTko(@{Sqkl(;G9C=a_Vet2~2vEL~;L zn^?_9DLC!QznfLGkfu$F>sbCCUe3bNLh^`StS6Qs$gmE@`^5SVk(z>riKFGIQEG`W zoXBIJf=M^4p!AR_DB+C^8>Dkd>pzeEFRVY|mf^^I8o?}xT^|f7RThcjpUhPD_=G+e zZf?{k6z`JxIdWrZjH5)o5uqx%v@#f~vir+p2(6LEN<%y)*%%1Tw-8Tpbnqk!eAglv z;1mZY9q1{D+920pQPQ0hE*<9Cz(F~T){0r67ZKcWp;sFRTLR%(h~SFXJRfsV&JLG( zL#}cSK4yNp0z-(**wPF{21AI91mhDb^AiNi6wUOK$Dby9>QmU%aD>S8aIioxA{c60 z05{a}zRf{t9`3+r#xfgvXM`(G_d38q`r#BZ08dAy97rTb1dH(VK7b|OpjzPw<>2Lu zu6DJ;+Q0cy7;Za>!Y~RU;@st95Qju!n4cOBf9k?`KZufyrU^Mp+c7jDp^_n*Fvm@z zBnW#d_k6^G*@5k5y4U4w@|2`hR6Js4_|T8vwM&_B%A1tnLQE_8Js-^ z7$TsE$U!O%%ina41bi4nVRmjfV@qyK{nnU_A$@Q-bC_R{7)Sv@coO*_he0AASKxTu!U5seIq5R!a-Zv`yF&Ts~XWNi^1Vd@pf zAsIyFf_`|6=n{V zgki|9888gNW2O{_xRF@PP^U?lMGl{8?1S2L;9NMQ9ME70!#N5}8LdJnta^YsED~cG zQbR=2FjJwh;4C<@=6$RR=`ySKB0gi*h^}a7_j<#ad$w{sN!!brRbqT7gM7zS93;NM z+6QK3O+-72ggWs>GS=sbY{Yc0g_xl}Z34FY(jH#4w$GwQ3Boe_Pa+>AVLLI@3nPZk zz_T8E@~|-yq?wa2EM1&9N}>JEI#k3;-JWWkEF&EB7s+T{@tW5=4k>1b$?%(OlnlQ~ z@gx1NwKxjDN6-*yi@}UnDS`=+`#5TpWD+;C>TDtnNE-ty1yIJ?Dequh(ZtW17jscl z@Fsxd_vDyFm}4R%d$I$)q?SUm4v^kqSd_se1thBi1h*nZ&LkXKVquyLX8TLY$AoxK z9n)3jgsfzItV#3Q!YY1bj_9K3IE3(^TvL?C^t)P!0khblP%Z|m2s8UY1}`LeXEE9# z6*7yMXA_xaDA#y{pA6p1<+Yx|h(noF8QdO%_HoE#?>sCKu>UtmNrD<=vnb#u)h3lm zN))a!G%52D34M%~d6r(LGL#V_!eb7Wns$z@iNyE*N&sAb&)Y0EY7trMGmdFd0;AO% zv&U(Z@$4+0J`VOPgFlcz!pxFH4l*Z(bbus=XsY&Cg0!BI;X?8i(o_#P*hsub6t}wT z^@vrhW-@|7RB$qWL)#CjOTt)CNf?M^+T)}y-9@n4pd~?F8b)z&gyQtG)<@c2MhZ2C zQm9FhBK7+Dk)=>pD}xP@I2sUo|2zi^f05V|+58|NL=J=$5SCITAT(&hM*%{k)h<)9 zU_*)4gAUgSg@SrzL?{741}#|LIgrMEv{7aAU_AbVFU4wKNJ#1!!{H#U-h}k^q}BTy z3Wpi{BH&3HC;647Z=}mgP*ZZu^pfz`7zy|}>^Kb?Erf$DB^|;+Uym>)Oj+%~WTH`) z3o%IMdn&UM1eP%*uV+}VkzGPtYEV);e&&hiURE9S@~XA>8&+<3k9X|%9Wqq}0*27a z7s&XsSZ5OV8r0&$xEHQi>-UbeqQTK1;Oj3&lZ_+t&*5ZIaO^|2kST|xZ5f2g#_$r3 zQqt#evM?eEoDKF4iN+vsHs(8)B;}!e^+6_Nsf$F<2AP_`0&s+$^>MKD76E4rYBSZb zGu9D~h&Ecb8B9;?*Wkoa%KAuiO71+sh)i`{@iwxEEL|X%5;h~p2KmNAJ`IV;jTMqzqQY>;WYCFlwx7;}C9F6y1t$$P3&WE@;b5ynJMqx2l^*jMf3}n? zB1=YGMB4uEw8aoeNW~GbI7)!Xg%kM=ew!IOnT78V-Z+}?20bux=@7wLW7&h9fUE{X zA{GOSfWxs>5jKSY4lx8A{;}62a5z@5hCoHMv7~jft zm#6+$e#?+OBG5Y`{)jNt-|=p3n2%?sRR{~Wfkcts?tJA^JV%?pX@ zlJpS7nZ|?az!We<>nZ+Pd2zm;Be)MoPcwfL$Dm2G`Hf(cLFIfM6|^6x##@)6O<8)! z3gjY4cr3k$RbG@oG78*7+X#yNrjLw*i7nn3+TuNkSF)&VltzqH1&M>8$dbu>4DSp_ z-dXU7Au=Liw4DP@|DOWG5!DcajVqq_8A&O|>MRqZCY1$Cw@}&*>egUL!Gc_p!KniF zhWE^GjKjR=afE4Naj+nVYe0r=mKd7}h$x!7tc*Q7@Avf0|CKLO8RLDtiHkRb; zuggqTWXUIFrYj0k9X1bVRsDN27tuP4|8P@e`r3jWs{Sg&kyjOY)yxdX5erNI{b`OAszduQvHtBDk0dSr zX2v687}h1}zmxWe(o30Zd1UUR9YOs6+T2G0qDgY;g&Zxp0zm#ER{+Rg|6uMTvG%Js zIw6s{_WMs{Ln^aoNBoVHNR%wcB<$ZvfJ6x{4~CN}{wfKQB*&;E$Qi;D9GEE?zs-ka z?z?<5+zc~25^>Jw;m4y=B+MjKuAuzhf^4Bq{fE-ow=)iqjcGW80%Mnl&3SJ{_j(}Z6xg8iNB zOS1Ssk$p+_gG9i|U;jY%<;Y~6;c$`@`{!~k8TRsTq~FRg_oVnzr5tU8mNj? zMi{~WKrD(A*^0@OQSQj!L#Ie`{6BPR$c_GYp;OYVdqw`^u_%%${?%Aic`@Y`)Rp=DcLvgsK#@Il3;{%<-J#=0xnIH2P`+vs*RwRp%fEB53#{gC= zEk0Kp+{O5L<&c>5piU55u@QzPD=f^6kx9ggtnjZ8E3)msk64k#{|Us3><5Whk-z={ z#ERH2T=ehUFU+v2e+$E!ONib7d<<)l3;za&^-t^`9<2QT7PlIlwf}6~3hf?V_AlE# zJUHTi2*e`4AwewCV*D3^SnVs3sQm8%vHmCTBVNKY${S`ysfQBM{yiWTi{(q!U>w~t z?a1L1T+9VsCTjctU@mFaoSFXzYB6>j7k)$MIHUiD?>1rO-v2h3i`Z?Y1n9WUE;tmw0wFj4Ds%+WoZ2Upu0?!iOZG4!!R4X%1D+>w_9 z9pH>f)7PN`rHD3KgTu{u**vkVm~g4#gFK6`gg+QP|^Wj`Le{6UZ zJ30?IH9H}kjoc5+jt)N@E`+zA36EtTJbQ5}=6N$*eCPni-c#Y-N=Z{s)8tva~~Ox?)52(71@U=Q4mCnR&BIZ)~bTmA}xxSJF|`S zMH)fQxUyNLRtA+~1=%ejBQ%mMGmVN&NfVKjB8sG>>_6w8J9FQ~mY)BdnRCwk-gzkZ z9;aNZ@T5dYx$4y;@xika9!IB8T^s7YV5Bfs&qb{KwjQi0b*od1N2J3(MhYjKh=r%e zc6N(wzvYT9SU7yL`!=eMF$nQPc{(C_6kSJo-2C$J_W+)bNZRC0y&E3xL}5zefdqqM zm0qZ@$#Q?T3zzBepjfI*%Y8AcXP?1+le+UDqZW9(Bpwz&*Su8L!6S?c(p=)sZZ*;? zwivbsM?}453+NW8ihfk#_!ChZj+rh{r-yKV-A~0?nq{W}(<^Fsobb};%vJ$uWuv0OwMK@F92Q0qmz6LCHZx||#>}*tbRrTX2dN=q<+tKuRwj;W z?LO1B4vE8EB$XT%C-h|N|ArCp=c71h95=Bih8}JEWl(Rc#}n&Yjh)Zv(Zc+FRYx4< z9;nJoq?tXePO77C#RZ<3&6O^Emr*CoCl2>cDSfw*w3)=%u?!)sfkUFTT%8&hTMdb0 z-^4Xj3jB~%6(7YV&F22^=zAS=Xpcn`VwBi~X`Pz-B(9piXBXX@(u=|&#Y4Xgn-~9z z_OR{gO&@zrrhEX>?r?WTymq`gBLYY(zM0Py0p!L%qMtFu8A-JUfqCg#<4+Wl^7glA zbFC1NNJ`s+X!EQB5OsvEjWECuYda#w06Z8|D)+Z&jwk_qODPOs`y4*(UDLW&z%6zd zH#u5!?=up1=S?<2lk=g?5M*#IiJ#7pk$>3_oWZS)Qr-Dev}?NHxK1sb&&V5K#X<>i zS}KtMDJUI@rah|juh?v0I#M8?7?|EHirl7QN%OCF<;Y^c-I16Uk3U;JUPJ_6m&sn! z-AJFv(mDvbyk45A#f|wgrAk-HhXx^dPk42E!%rX(BJY+Ja!10eHg?cM_R6)Hc7Q|Y z-zb&?VH3k4NtK0wymZ=Z5HvB8UKYvaYG#A%ajnelEY$lvD}f>%q-%rZCKe{s6Op)y zL3$psaubVLnW1J!X8UDHRLj9XUsx2A5l2RdmN?l+-JLcW@%JQYhjMhW(X0?@iMpMK z+-$f!P<{PsS#G`^Dbe~hazHagPBn$HCz3T7ie=3$DV7AcBv|QUd+c4-)NK0)W|hlv delta 128799 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 z%0D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 Gm;VnHk`6Wi From 3434eab810f864f3ef316667cfcf679eddb54065 Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Wed, 21 Aug 2024 21:37:38 -0600 Subject: [PATCH 22/24] update ne_vol function name --- desc/compute/_profiles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desc/compute/_profiles.py b/desc/compute/_profiles.py index 4952677a09..dfbfe5c9d9 100644 --- a/desc/compute/_profiles.py +++ b/desc/compute/_profiles.py @@ -230,7 +230,7 @@ def _Te_rr(params, transforms, profiles, data, **kwargs): data=["ne", "sqrt(g)", "V"], resolution_requirement="rtz", ) -def _bar_ne(params, transforms, profiles, data, **kwargs): +def _ne_vol(params, transforms, profiles, data, **kwargs): data["_vol"] = ( jnp.sum(data["ne"] * data["sqrt(g)"] * transforms["grid"].weights) / data["V"] ) From ec972c4d6c01b571b32b8f38036d2ca062d3974f Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Thu, 22 Aug 2024 09:36:53 -0600 Subject: [PATCH 23/24] remove line average test --- desc/compute/_profiles.py | 2 +- tests/test_profiles.py | 15 +-------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/desc/compute/_profiles.py b/desc/compute/_profiles.py index dfbfe5c9d9..6ff0a84dd5 100644 --- a/desc/compute/_profiles.py +++ b/desc/compute/_profiles.py @@ -218,7 +218,7 @@ def _Te_rr(params, transforms, profiles, data, **kwargs): @register_compute_fun( name="_vol", - label="\\lange n_e \\rangle_{vol}", + label="\\langle n_e \\rangle_{vol}", units="m^{-3}", units_long="1 / cubic meters", description="Volume average electron density", diff --git a/tests/test_profiles.py b/tests/test_profiles.py index 8ee13b5f60..bf75489a6b 100644 --- a/tests/test_profiles.py +++ b/tests/test_profiles.py @@ -508,19 +508,6 @@ def test_kinetic_pressure(self): np.testing.assert_allclose(data1["p"], data2["p"]) np.testing.assert_allclose(data1["p_r"], data2["p_r"]) - @pytest.mark.unit - def test_line_average(self): - """Test that line-averaged profiles are correct.""" - ne0 = 3e19 - Te0 = 2e3 - ne = PowerSeriesProfile(2 * ne0 * np.array([1, -1]), modes=[0, 1]) - Te = PowerSeriesProfile(2 * Te0 * np.array([1, -1]), modes=[0, 1]) - - with pytest.raises(UserWarning): - eq = Equilibrium(electron_density=ne, electron_temperature=Te) - data = eq.compute("_rho") - np.testing.assert_allclose(data["_rho"], ne0) - @pytest.mark.unit def test_hermite_spline_solve(self): """Test that spline with double number of parameters is optimized.""" @@ -530,4 +517,4 @@ def test_hermite_spline_solve(self): eq.pressure(rho), eq.pressure(rho, dr=1), rho ) eq.solve() - assert eq.is_nested() \ No newline at end of file + assert eq.is_nested() From a0ce1e3bd320658560aa87986a3698b4b558b9aa Mon Sep 17 00:00:00 2001 From: daniel-dudt Date: Fri, 23 Aug 2024 16:33:44 -0600 Subject: [PATCH 24/24] improved formatting of equation --- desc/objectives/_confinement.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desc/objectives/_confinement.py b/desc/objectives/_confinement.py index 588b9accd5..b768fa5e35 100644 --- a/desc/objectives/_confinement.py +++ b/desc/objectives/_confinement.py @@ -12,7 +12,7 @@ class HeatingPowerISS04(_Objective): """Heating power required by the ISS04 energy confinement time scaling. - 𝜏_E = W_p / P = 0.134 H_ISS04 a^2.28 R^0.64 P^-0.61 n_e^0.54 B^0.84 𝜄^0.41 (s) + τ_E = Wₚ / P = 0.134 H_ISS04 a²ᐧ²⁸ R⁰ᐧ⁶⁴ P⁻⁰ᐧ⁶¹ nₑ⁰ᐧ⁵⁴ B⁰ᐧ⁸⁴ 𝜄⁰ᐧ⁴¹ (s) References ----------