@@ -146,9 +146,18 @@ class PostProcessedOutputs:
146146 rho_q_3_1_second: Second outermost rho_norm value that intercepts the q=3/1
147147 plane. If no intercept is found, set to -inf.
148148 I_bootstrap: Total bootstrap current [A].
149- j_external: Total current density from psi sources which are external to the
150- plasma (aka not bootstrap) [A m^-2]
151- j_ohmic: Ohmic current density [A/m^2]
149+ j_parallel_external: Parallel current density from external psi sources
150+ (i.e., excluding bootstrap) [A m^-2]
151+ j_parallel_ohmic: Parallel ohmic current density [Am^-2]
152+ j_total: Total toroidal current density [Am^-2]
153+ j_bootstrap: Toroidal bootstrap current density [Am^-2]
154+ j_ohmic: Toroidal ohmic current density [Am^-2]
155+ j_external: Toroidal current density from external psi sources
156+ (i.e., excluding bootstrap) [A m^-2]
157+ j_generic_current: Toroidal current density from generic current source
158+ [Am^-2]
159+ j_ecrh: Toroidal current density from electron cyclotron heating
160+ and current source [Am^-2]
152161 S_gas_puff: Integrated gas puff source [s^-1]
153162 S_pellet: Integrated pellet source [s^-1]
154163 S_generic_particle: Integrated generic particle source [s^-1]
@@ -233,8 +242,14 @@ class PostProcessedOutputs:
233242 rho_q_3_1_first : array_typing .FloatScalar
234243 rho_q_3_1_second : array_typing .FloatScalar
235244 I_bootstrap : array_typing .FloatScalar
236- j_external : array_typing .FloatVector
245+ j_parallel_external : array_typing .FloatVector
246+ j_parallel_ohmic : array_typing .FloatVector
247+ j_total : array_typing .FloatVector
248+ j_bootstrap : array_typing .FloatVector
237249 j_ohmic : array_typing .FloatVector
250+ j_external : array_typing .FloatVector
251+ j_generic_current : array_typing .FloatVector
252+ j_ecrh : array_typing .FloatVector
238253 S_gas_puff : array_typing .FloatScalar
239254 S_pellet : array_typing .FloatScalar
240255 S_generic_particle : array_typing .FloatScalar
@@ -337,8 +352,15 @@ def zeros(cls, geo: geometry.Geometry) -> typing_extensions.Self:
337352 rho_q_2_1_second = jnp .array (0.0 , dtype = jax_utils .get_dtype ()),
338353 rho_q_3_1_second = jnp .array (0.0 , dtype = jax_utils .get_dtype ()),
339354 I_bootstrap = jnp .array (0.0 , dtype = jax_utils .get_dtype ()),
340- j_external = jnp .zeros (geo .rho_face .shape ),
355+ # TODO (v2): rename j_* to j_toroidal_* for clarity
356+ j_parallel_external = jnp .zeros (geo .rho_face .shape ),
357+ j_parallel_ohmic = jnp .zeros (geo .rho_face .shape ),
358+ j_total = jnp .zeros (geo .rho_face .shape ),
359+ j_bootstrap = jnp .zeros (geo .rho_face .shape ),
341360 j_ohmic = jnp .zeros (geo .rho_face .shape ),
361+ j_external = jnp .zeros (geo .rho_face .shape ),
362+ j_generic_current = jnp .zeros (geo .rho_face .shape ),
363+ j_ecrh = jnp .zeros (geo .rho_face .shape ),
342364 S_gas_puff = jnp .array (0.0 , dtype = jax_utils .get_dtype ()),
343365 S_pellet = jnp .array (0.0 , dtype = jax_utils .get_dtype ()),
344366 S_generic_particle = jnp .array (0.0 , dtype = jax_utils .get_dtype ()),
@@ -514,7 +536,7 @@ def _calculate_integrated_sources(
514536 integrated ['P_external_injected' ] += integrated [f'{ value } ' ]
515537
516538 for key , value in CURRENT_SOURCE_TRANSFORMATIONS .items ():
517- integrated [f' { value } ' ] = _get_integrated_source_value (
539+ integrated [value ] = _get_integrated_source_value (
518540 core_sources .psi , key , geo , math_utils .area_integration
519541 )
520542
@@ -590,10 +612,9 @@ def make_post_processed_outputs(
590612 runtime_params ,
591613 )
592614 # Calculate fusion gain with a zero division guard.
593- Q_fusion = (
594- integrated_sources ['P_fusion' ]
595- / (integrated_sources ['P_external_total' ]
596- + constants .CONSTANTS .eps ))
615+ Q_fusion = integrated_sources ['P_fusion' ] / (
616+ integrated_sources ['P_external_total' ] + constants .CONSTANTS .eps
617+ )
597618
598619 P_LH_hi_dens , P_LH_min , P_LH , n_e_min_P_LH = (
599620 scaling_laws .calculate_plh_scaling_factor (
@@ -756,11 +777,48 @@ def cumulative_values():
756777 sim_state .core_sources .bootstrap_current .j_bootstrap , sim_state .geometry
757778 )
758779
759- j_external = sum (sim_state .core_sources .psi .values ())
760- psi_current = (
761- j_external + sim_state .core_sources .bootstrap_current .j_bootstrap
780+ # Parallel current densities
781+ # j_total is toroidal by default (see psi_calculations.calc_j_total)
782+ j_parallel_total = psi_calculations .j_tor_to_j_parallel (
783+ sim_state .core_profiles .j_total , sim_state .geometry
784+ )
785+ # Core sources psi are all <j.B>/B0
786+ j_parallel_external = sum (sim_state .core_sources .psi .values ())
787+ j_parallel_ohmic = (
788+ j_parallel_total
789+ - j_parallel_external
790+ - sim_state .core_sources .bootstrap_current .j_bootstrap # parallel by default
791+ )
792+
793+ # Toroidal current densities
794+ # j_total is toroidal by default (see psi_calculations.calc_j_total)
795+ j_total = sim_state .core_profiles .j_total
796+ # Other sources are parallel, so convert to toroidal
797+ j_bootstrap = psi_calculations .j_parallel_to_j_tor (
798+ sim_state .core_sources .bootstrap_current .j_bootstrap , sim_state .geometry
799+ )
800+ j_ohmic = psi_calculations .j_parallel_to_j_tor (
801+ j_parallel_ohmic , sim_state .geometry
802+ )
803+ j_external = psi_calculations .j_parallel_to_j_tor (
804+ j_parallel_external , sim_state .geometry
762805 )
763- j_ohmic = sim_state .core_profiles .j_total - psi_current
806+ j_sources = {}
807+ for source_name in ['ecrh' , 'generic_current' ]:
808+ if source_name in sim_state .core_sources .psi .keys ():
809+ j_sources [f'j_{ source_name } ' ] = psi_calculations .j_parallel_to_j_tor (
810+ sim_state .core_sources .psi [source_name ], sim_state .geometry
811+ )
812+ j_sources [f'j_parallel_{ source_name } ' ] = sim_state .core_sources .psi [
813+ source_name
814+ ]
815+ else :
816+ j_sources [f'j_{ source_name } ' ] = jnp .array (
817+ 0.0 , dtype = jax_utils .get_dtype ()
818+ )
819+ j_sources [f'j_parallel_{ source_name } ' ] = jnp .array (
820+ 0.0 , dtype = jax_utils .get_dtype ()
821+ )
764822
765823 beta_tor , beta_pol , beta_N = formulas .calculate_betas (
766824 sim_state .core_profiles , sim_state .geometry
@@ -813,8 +871,15 @@ def cumulative_values():
813871 rho_q_2_1_second = safety_factor_fit_outputs .rho_q_2_1_second ,
814872 rho_q_3_1_second = safety_factor_fit_outputs .rho_q_3_1_second ,
815873 I_bootstrap = I_bootstrap ,
816- j_external = j_external ,
874+ j_parallel_total = j_parallel_total ,
875+ j_parallel_ohmic = j_parallel_ohmic ,
876+ j_parallel_bootstrap = j_parallel_bootstrap ,
877+ j_parallel_external = j_parallel_external ,
878+ j_total = j_total ,
817879 j_ohmic = j_ohmic ,
880+ j_bootstrap = j_bootstrap ,
881+ j_external = j_external ,
882+ ** j_sources ,
818883 beta_tor = beta_tor ,
819884 beta_pol = beta_pol ,
820885 beta_N = beta_N ,
0 commit comments