Skip to content

Commit 12872c9

Browse files
tamaranormanTorax team
authored andcommitted
Flatten __call__ and simplify _combine in CombinedTransportModel.
- Merge call_implementation() body into __call__(), removing the separate method. __call__ now directly combines core and pedestal coefficients, applies clipping, and applies smoothing. - Simplify _combine loop: call model() directly instead of separate model.call_implementation() + model.zero_out_disabled_channels(), since ComponentTransportModel.__call__ now wraps both. - Update combined_test.py to call model() instead of model.call_implementation(). PiperOrigin-RevId: 964556808
1 parent 295fac6 commit 12872c9

24 files changed

Lines changed: 414 additions & 374 deletions

torax/_src/mhd/tests/mhd_pydantic_model_test.py

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@
2828
from torax._src.sources import source_models as source_models_lib
2929
from torax._src.test_utils import default_configs
3030
from torax._src.torax_pydantic import model_config
31-
from torax._src.transport_model import transport_model as transport_model_lib
31+
from torax._src.transport_model import component
3232

3333

3434
class MHDPydanticModelTest(parameterized.TestCase):
3535

3636
def setUp(self):
3737
super().setUp()
38-
self.transport_model = mock.Mock(spec=transport_model_lib.TransportModel)
38+
self.transport_model = mock.Mock(spec=component.ComponentTransportModel)
3939
self.source_models = mock.Mock(spec=source_models_lib.SourceModels)
4040
self.pedestal_model = mock.Mock(spec=pedestal_model_lib.PedestalModel)
4141
self.neoclassical_models = mock.Mock(
@@ -48,10 +48,8 @@ def test_no_mhd_config_makes_empty_runtime_params(self):
4848
)
4949

5050
self.assertIsInstance(torax_config.mhd, mhd_pydantic_model.MHD)
51-
provider = (
52-
build_runtime_params.RuntimeParamsProvider.from_config(
53-
torax_config
54-
)
51+
provider = build_runtime_params.RuntimeParamsProvider.from_config(
52+
torax_config
5553
)
5654
runtime_params = provider(t=0.0)
5755
self.assertIsInstance(runtime_params.mhd, mhd_runtime_params.RuntimeParams)
@@ -67,10 +65,8 @@ def test_empty_mhd_config(self):
6765
assert isinstance(torax_config.mhd, mhd_pydantic_model.MHD)
6866
mhd_models = torax_config.mhd.build_mhd_models()
6967
self.assertIs(mhd_models.sawtooth_models, None)
70-
provider = (
71-
build_runtime_params.RuntimeParamsProvider.from_config(
72-
torax_config
73-
)
68+
provider = build_runtime_params.RuntimeParamsProvider.from_config(
69+
torax_config
7470
)
7571
runtime_params = provider(t=0.0)
7672
self.assertIsInstance(runtime_params.mhd, mhd_runtime_params.RuntimeParams)
@@ -96,10 +92,8 @@ def test_mhd_config_with_sawtooth(self):
9692
torax_config.mhd.sawtooth, sawtooth_pydantic_model.SawtoothConfig
9793
)
9894

99-
provider = (
100-
build_runtime_params.RuntimeParamsProvider.from_config(
101-
torax_config
102-
)
95+
provider = build_runtime_params.RuntimeParamsProvider.from_config(
96+
torax_config
10397
)
10498
runtime_params = provider(t=0.0)
10599
sawtooth_params = runtime_params.mhd.sawtooth

torax/_src/transport_model/bohm_gyrobohm.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
from torax._src.config import runtime_params as runtime_params_lib
2525
from torax._src.geometry import geometry
2626
from torax._src.pedestal_model import pedestal_model_output as pedestal_model_output_lib
27+
from torax._src.transport_model import component
2728
from torax._src.transport_model import runtime_params as transport_runtime_params_lib
28-
from torax._src.transport_model import transport_model as transport_model_lib
2929

3030
# pylint: disable=invalid-name
3131

@@ -49,7 +49,7 @@ class RuntimeParams(transport_runtime_params_lib.RuntimeParams):
4949

5050

5151
@dataclasses.dataclass(kw_only=True, frozen=True, eq=False)
52-
class BohmGyroBohmTransportModel(transport_model_lib.TransportModel):
52+
class BohmGyroBohmTransportModel(component.ComponentTransportModel):
5353
"""Calculates various coefficients related to particle transport according to the Bohm + gyro-Bohm Model."""
5454

5555
def call_implementation(
@@ -59,7 +59,7 @@ def call_implementation(
5959
geo: geometry.Geometry,
6060
core_profiles: state.CoreProfiles,
6161
pedestal_model_output: pedestal_model_output_lib.PedestalModelOutput,
62-
) -> transport_model_lib.TurbulentTransport:
62+
) -> component.TurbulentTransport:
6363
r"""Calculates transport coefficients using the BohmGyroBohm model.
6464
6565
We use the implementation from Tholerus et al, Section 3.3.
@@ -171,7 +171,7 @@ def call_implementation(
171171
# Electron convectivity set proportional to the electron diffusivity
172172
v_face_el = transport_runtime_params.V_face_coeff * d_face_el
173173

174-
return transport_model_lib.TurbulentTransport(
174+
return component.TurbulentTransport(
175175
chi_face_ion=chi_i, # pyrefly: ignore[bad-argument-type]
176176
chi_face_el=chi_e, # pyrefly: ignore[bad-argument-type]
177177
d_face_el=d_face_el,

torax/_src/transport_model/combined.py

Lines changed: 28 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -50,47 +50,12 @@ def __call__(
5050
core_profiles: state.CoreProfiles,
5151
pedestal_model_output: pedestal_model_output_lib.PedestalModelOutput,
5252
) -> transport_model_lib.TurbulentTransport:
53-
54-
transport_runtime_params = runtime_params.transport
55-
56-
# Calculate the transport coefficients - includes contribution from pedestal
57-
# and core transport models.
58-
transport_coeffs = self.call_implementation(
59-
transport_runtime_params,
60-
runtime_params,
61-
geo,
62-
core_profiles,
63-
pedestal_model_output,
64-
)
65-
# Apply min/max clipping
66-
transport_coeffs = self._apply_clipping(
67-
transport_runtime_params,
68-
transport_coeffs,
69-
)
70-
71-
transport_coeffs = self._smooth_coeffs(
72-
runtime_params,
73-
geo,
74-
transport_coeffs,
75-
pedestal_model_output,
76-
)
77-
78-
return transport_coeffs
79-
80-
def call_implementation(
81-
self,
82-
transport_runtime_params: transport_runtime_params_lib.CombinedRuntimeParams,
83-
runtime_params: runtime_params_lib.RuntimeParams,
84-
geo: geometry.Geometry,
85-
core_profiles: state.CoreProfiles,
86-
pedestal_model_output: pedestal_model_output_lib.PedestalModelOutput,
87-
) -> transport_model_lib.TurbulentTransport:
8853
r"""Calculates transport coefficients using the Combined model.
8954
55+
Combines coefficients from core and pedestal transport models, applies
56+
min/max clipping, and smooths the result.
57+
9058
Args:
91-
transport_runtime_params: Input runtime parameters for this transport
92-
model (expected to be an instance of CombinedRuntimeParams at runtime).
93-
Can change without triggering a JAX recompilation.
9459
runtime_params: Runtime parameters for the simulation at the current time.
9560
geo: Geometry of the torus at the current time.
9661
core_profiles: Core plasma profiles.
@@ -99,16 +64,20 @@ def call_implementation(
9964
Returns:
10065
coeffs: The transport coefficients
10166
"""
67+
transport_runtime_params = runtime_params.transport
68+
69+
# Calculate transport coefficients from core models.
10270
core_coeffs = self._combine(
10371
self.transport_models,
104-
transport_runtime_params.transport_model_params,
72+
transport_runtime_params.core_transport_model_params,
10573
runtime_params,
10674
geo,
10775
core_profiles,
10876
pedestal_model_output,
10977
transport_model_lib.compute_core_domain_mask,
11078
)
11179

80+
# Calculate transport coefficients from pedestal models.
11281
pedestal_coeffs = self._combine(
11382
self.pedestal_transport_models,
11483
transport_runtime_params.pedestal_transport_model_params,
@@ -120,11 +89,25 @@ def call_implementation(
12089
)
12190

12291
# Combine the transport coefficients from core and pedestal models.
123-
combined_transport_coeffs = jax.tree.map(
92+
transport_coeffs = jax.tree.map(
12493
_add_optional, core_coeffs, pedestal_coeffs
12594
)
12695

127-
return combined_transport_coeffs
96+
# Apply min/max clipping.
97+
transport_coeffs = self._apply_clipping(
98+
transport_runtime_params,
99+
transport_coeffs,
100+
)
101+
102+
# Apply smoothing.
103+
transport_coeffs = self._smooth_coeffs(
104+
runtime_params,
105+
geo,
106+
transport_coeffs,
107+
pedestal_model_output,
108+
)
109+
110+
return transport_coeffs
128111

129112
def _combine(
130113
self,
@@ -162,15 +145,12 @@ def _combine(
162145

163146
# TODO(b/344023668) explore batching or fori_loop for performance.
164147
for model, params in zip(models, params_list, strict=True):
165-
# 1. Calculate raw coefficients
166-
coeffs = model.call_implementation(
148+
# 1. Calculate raw coefficients and zero out disabled channels.
149+
coeffs = model(
167150
params, runtime_params, geo, core_profiles, pedestal_model_output
168151
)
169152

170-
# 2. Zero out disabled channels. Unused subchannels returned as None.
171-
coeffs = model.zero_out_disabled_channels(params, coeffs)
172-
173-
# 3. Calculate active domain mask. Values outside this are set to 0.
153+
# 2. Calculate active domain mask. Values outside this are set to 0.
174154
domain_mask = domain_mask_fn(
175155
params, runtime_params, geo, pedestal_model_output
176156
)
@@ -357,8 +337,7 @@ def build_profile_fallback():
357337

358338
def apply_pedestal_mask(profile):
359339
return jnp.where(
360-
geo.rho_face_norm
361-
< pedestal_model_output.rho_norm_ped_top,
340+
geo.rho_face_norm < pedestal_model_output.rho_norm_ped_top,
362341
profile,
363342
0.0,
364343
)

0 commit comments

Comments
 (0)