Skip to content

Commit fb132ff

Browse files
committed
Add draft postprocessed outputs
1 parent 409b139 commit fb132ff

File tree

2 files changed

+88
-22
lines changed

2 files changed

+88
-22
lines changed

torax/_src/output_tools/output.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@
1717
import dataclasses
1818
import inspect
1919
import itertools
20-
2120
import os
2221

2322
from absl import logging
2423
import chex
2524
import jax
2625
import numpy as np
27-
import os
2826
from torax._src import array_typing
2927
from torax._src import state
3028
from torax._src.geometry import geometry as geometry_lib
@@ -63,9 +61,12 @@
6361
IP = "Ip"
6462

6563
# Calculated or derived currents.
66-
J_OHMIC = "j_ohmic"
67-
J_EXTERNAL = "j_external"
68-
J_BOOTSTRAP = "j_bootstrap"
64+
J_TOR_OHMIC = "j_tor_ohmic"
65+
J_TOR_EXTERNAL = "j_tor_external"
66+
J_TOR_BOOTSTRAP = "j_tor_bootstrap"
67+
J_PARALLEL_OHMIC = "j_parallel_ohmic"
68+
J_PARALLEL_EXTERNAL = "j_parallel_external"
69+
J_PARALLEL_BOOTSTRAP = "j_parallel_bootstrap"
6970
I_BOOTSTRAP = "I_bootstrap"
7071

7172
# Core transport.
@@ -630,7 +631,7 @@ def _save_core_sources(
630631
else:
631632
xr_dict[f"p_{profile}_e"] = self._stacked_core_sources.T_e[profile]
632633
for profile in self._stacked_core_sources.psi:
633-
xr_dict[f"j_{profile}"] = self._stacked_core_sources.psi[profile]
634+
xr_dict[f"j_parallel_{profile}"] = self._stacked_core_sources.psi[profile]
634635
for profile in self._stacked_core_sources.n_e:
635636
xr_dict[f"s_{profile}"] = self._stacked_core_sources.n_e[profile]
636637

torax/_src/output_tools/post_processing.py

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,18 @@ class PostProcessedOutputs:
135135
rho_q_3_1_second: Second outermost rho_norm value that intercepts the q=3/1
136136
plane. If no intercept is found, set to -inf.
137137
I_bootstrap: Total bootstrap current [A].
138-
j_external: Total current density from psi sources which are external to the
139-
plasma (aka not bootstrap) [A m^-2]
140-
j_ohmic: Ohmic current density [A/m^2]
138+
j_parallel_external: Parallel current density from external psi sources
139+
(i.e., excluding bootstrap) [A m^-2]
140+
j_parallel_ohmic: Parallel ohmic current density [Am^-2]
141+
j_toroidal_total: Total toroidal current density [Am^-2]
142+
j_toroidal_bootstrap: Toroidal bootstrap current density [Am^-2]
143+
j_toroidal_ohmic: Toroidal ohmic current density [Am^-2]
144+
j_toroidal_external: Toroidal current density from external psi sources
145+
(i.e., excluding bootstrap) [A m^-2]
146+
j_toroidal_generic: Toroidal current density from generic current source
147+
[Am^-2]
148+
j_toroidal_ecrh: Toroidal current density from electron cyclotron heating
149+
and current source [Am^-2]
141150
S_gas_puff: Integrated gas puff source [s^-1]
142151
S_pellet: Integrated pellet source [s^-1]
143152
S_generic_particle: Integrated generic particle source [s^-1]
@@ -217,8 +226,14 @@ class PostProcessedOutputs:
217226
rho_q_3_1_first: array_typing.FloatScalar
218227
rho_q_3_1_second: array_typing.FloatScalar
219228
I_bootstrap: array_typing.FloatScalar
220-
j_external: array_typing.FloatVector
221-
j_ohmic: array_typing.FloatVector
229+
j_parallel_external: array_typing.FloatVector
230+
j_parallel_ohmic: array_typing.FloatVector
231+
j_toroidal_total: array_typing.FloatVector
232+
j_toroidal_bootstrap: array_typing.FloatVector
233+
j_toroidal_ohmic: array_typing.FloatVector
234+
j_toroidal_external: array_typing.FloatVector
235+
j_toroidal_generic: array_typing.FloatVector
236+
j_toroidal_ecrh: array_typing.FloatVector
222237
S_gas_puff: array_typing.FloatScalar
223238
S_pellet: array_typing.FloatScalar
224239
S_generic_particle: array_typing.FloatScalar
@@ -315,8 +330,14 @@ def zeros(cls, geo: geometry.Geometry) -> typing_extensions.Self:
315330
rho_q_2_1_second=jnp.array(0.0, dtype=jax_utils.get_dtype()),
316331
rho_q_3_1_second=jnp.array(0.0, dtype=jax_utils.get_dtype()),
317332
I_bootstrap=jnp.array(0.0, dtype=jax_utils.get_dtype()),
318-
j_external=jnp.zeros(geo.rho_face.shape),
319-
j_ohmic=jnp.zeros(geo.rho_face.shape),
333+
j_parallel_external=jnp.zeros(geo.rho_face.shape),
334+
j_parallel_ohmic=jnp.zeros(geo.rho_face.shape),
335+
j_toroidal_total=jnp.zeros(geo.rho_face.shape),
336+
j_toroidal_bootstrap=jnp.zeros(geo.rho_face.shape),
337+
j_toroidal_ohmic=jnp.zeros(geo.rho_face.shape),
338+
j_toroidal_external=jnp.zeros(geo.rho_face.shape),
339+
j_toroidal_generic=jnp.zeros(geo.rho_face.shape),
340+
j_toroidal_ecrh=jnp.zeros(geo.rho_face.shape),
320341
S_gas_puff=jnp.array(0.0, dtype=jax_utils.get_dtype()),
321342
S_pellet=jnp.array(0.0, dtype=jax_utils.get_dtype()),
322343
S_generic_particle=jnp.array(0.0, dtype=jax_utils.get_dtype()),
@@ -360,8 +381,8 @@ def check_for_errors(self):
360381
'icrh',
361382
]
362383
CURRENT_SOURCE_TRANSFORMATIONS = {
363-
'generic_current': 'I_aux_generic',
364-
'ecrh': 'I_ecrh',
384+
'generic_current': 'aux_generic',
385+
'ecrh': 'ecrh',
365386
}
366387
PARTICLE_SOURCE_TRANSFORMATIONS = {
367388
'gas_puff': 'S_gas_puff',
@@ -385,6 +406,20 @@ def _get_integrated_source_value(
385406
return jnp.array(0.0, dtype=jax_utils.get_dtype())
386407

387408

409+
def _get_source_toroidal_current_value(
410+
source_profiles_dict: dict[str, array_typing.FloatVector],
411+
internal_source_name: str,
412+
geo: geometry.Geometry,
413+
) -> jax.Array:
414+
"""Integrates a source profile if it exists, otherwise returns 0.0."""
415+
if internal_source_name in source_profiles_dict:
416+
return psi_calculations.j_parallel_to_j_tor(
417+
source_profiles_dict[internal_source_name], geo
418+
)
419+
else:
420+
return jnp.array(0.0, dtype=jax_utils.get_dtype())
421+
422+
388423
def _calculate_integrated_sources(
389424
geo: geometry.Geometry,
390425
core_profiles: state.CoreProfiles,
@@ -491,7 +526,7 @@ def _calculate_integrated_sources(
491526
integrated['P_external_injected'] += integrated[f'{value}']
492527

493528
for key, value in CURRENT_SOURCE_TRANSFORMATIONS.items():
494-
integrated[f'{value}'] = _get_integrated_source_value(
529+
integrated[f'I_{value}'] = _get_integrated_source_value(
495530
core_sources.psi, key, geo, math_utils.area_integration
496531
)
497532

@@ -703,11 +738,36 @@ def make_post_processed_outputs(
703738
sim_state.core_sources.bootstrap_current.j_bootstrap, sim_state.geometry
704739
)
705740

706-
j_external = sum(sim_state.core_sources.psi.values())
707-
psi_current = (
708-
j_external + sim_state.core_sources.bootstrap_current.j_bootstrap
741+
# Parallel current densities
742+
# Core sources psi are all <j.B>/B0
743+
j_parallel_external = sum(sim_state.core_sources.psi.values())
744+
j_parallel_ohmic = (
745+
sim_state.core_profiles.j_total # TODO: check whether j_total is parallel or toroidal
746+
- j_parallel_external
747+
- sim_state.core_sources.bootstrap_current.j_bootstrap # parallel by default
748+
)
749+
750+
# Toroidal current densities
751+
# TODO: check whether j_total is parallel or toroidal
752+
j_toroidal_total = psi_calculations.j_parallel_to_j_tor(
753+
sim_state.core_profiles.j_total, sim_state.geometry
754+
)
755+
j_toroidal_bootstrap = psi_calculations.j_parallel_to_j_tor(
756+
sim_state.core_sources.bootstrap_current.j_bootstrap, sim_state.geometry
757+
)
758+
j_toroidal_ohmic = psi_calculations.j_parallel_to_j_tor(
759+
j_parallel_ohmic, sim_state.geometry
760+
)
761+
j_toroidal_external = psi_calculations.j_parallel_to_j_tor(
762+
j_parallel_external, sim_state.geometry
709763
)
710-
j_ohmic = sim_state.core_profiles.j_total - psi_current
764+
j_toroidal_sources = {}
765+
for internal_name, external_name in CURRENT_SOURCE_TRANSFORMATIONS.items():
766+
j_toroidal_sources[f'j_toroidal_{external_name}'] = (
767+
_get_source_toroidal_current_value(
768+
core_sources.psi, internal_name, sim_state.geometry
769+
)
770+
)
711771

712772
beta_tor, beta_pol, beta_N = formulas.calculate_betas(
713773
sim_state.core_profiles, sim_state.geometry
@@ -757,8 +817,13 @@ def make_post_processed_outputs(
757817
rho_q_2_1_second=safety_factor_fit_outputs.rho_q_2_1_second,
758818
rho_q_3_1_second=safety_factor_fit_outputs.rho_q_3_1_second,
759819
I_bootstrap=I_bootstrap,
760-
j_external=j_external,
761-
j_ohmic=j_ohmic,
820+
j_parallel_external=j_parallel_external,
821+
j_parallel_ohmic=j_parallel_ohmic,
822+
j_toroidal_total=j_toroidal_total,
823+
j_toroidal_bootstrap=j_toroidal_bootstrap,
824+
j_toroidal_ohmic=j_toroidal_ohmic,
825+
j_toroidal_external=j_toroidal_external,
826+
**j_toroidal_sources,
762827
beta_tor=beta_tor,
763828
beta_pol=beta_pol,
764829
beta_N=beta_N,

0 commit comments

Comments
 (0)