Skip to content

Commit 4eae751

Browse files
validation rule for sign of EM fields
1 parent 92aba5f commit 4eae751

File tree

2 files changed

+90
-532
lines changed

2 files changed

+90
-532
lines changed
Lines changed: 90 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,101 @@
11
"""Generic rules applying to the equilibrium IDS"""
22

3-
from imas_validator.common.cocos import compute_COCOS
3+
import numpy as np
44

5-
dd_cocos = {"3": 11, "4": 17}
65

7-
8-
@validator("equilibrium")
9-
def validate_cocos(ids):
6+
@validator("equilibrium", version="<4.0.0")
7+
def validate_sign_DD3(ids):
108
"""
11-
Validate that COCOS computed corresponds to the one in DD.
9+
Validate that the equilibrium IDS has consistent sign conventions.
1210
"""
1311

14-
ver = str(ids.ids_properties.version_put.data_dictionary.value)[0]
15-
ref = dd_cocos.get(ver)
16-
if ref is None:
17-
raise ValueError(f"Unsupported DD version_put: {ver}")
12+
# Loop through each time slice
13+
for itime, time_slice in enumerate(ids.time_slice):
14+
15+
# Get the time for this time slice
16+
if ids.ids_properties.homogeneous_time == 0:
17+
time = time_slice.time
18+
else:
19+
time = ids.time[itime]
20+
21+
# Set sign of Ip
22+
if time_slice.global_quantities.ip.has_value:
23+
ipsign = np.sign(time_slice.global_quantities.ip)
24+
else:
25+
ipsign = -9
26+
27+
# Set sign of B0
28+
if ids.vacuum_toroidal_field.b0.has_value:
29+
b0sign = np.sign(
30+
np.interp(time, ids.time, ids.vacuum_toroidal_field.b0)
31+
)
32+
else:
33+
b0sign = -9
34+
35+
#
36+
# Validate the sign conventions for EM fields
37+
#
38+
39+
if time_slice.profiles_1d.f.has_value:
40+
assert np.sign(time_slice.profiles_1d.f) == b0sign
41+
42+
if time_slice.profiles_1d.phi.has_value:
43+
# phi at center found as zero in DINA, CORSICA and etc.
44+
assert np.sign(time_slice.profiles_1d.phi[1:]) == b0sign
45+
46+
psi_axis = time_slice.global_quantities.psi_axis
47+
psi_boundary = time_slice.global_quantities.psi_boundary
48+
if psi_axis.has_value and psi_boundary.has_value:
49+
assert np.sign(psi_boundary - psi_axis) == ipsign
50+
51+
if time_slice.global_quantities.q_95.has_value:
52+
assert np.sign(time_slice.global_quantities.q_95) == ipsign * b0sign
1853

19-
# time_slice[:]
54+
55+
@validator("equilibrium", version=">=4.0.0")
56+
def validate_sign(ids):
57+
"""
58+
Validate that the equilibrium IDS has consistent sign conventions.
59+
"""
60+
61+
# Loop through each time slice
2062
for itime, time_slice in enumerate(ids.time_slice):
2163

22-
# time_slice[:].profiles_2d
23-
for i1, profiles_2d in enumerate(time_slice.profiles_2d):
24-
25-
if not (
26-
ids.vacuum_toroidal_field.b0.has_value
27-
and time_slice.global_quantities.ip.has_value
28-
and time_slice.global_quantities.magnetic_axis.z.has_value
29-
and time_slice.profiles_1d.psi.has_value
30-
and time_slice.profiles_1d.q.has_value
31-
and time_slice.profiles_1d.dpressure_dpsi.has_value
32-
and profiles_2d.b_field_z.has_value
33-
and profiles_2d.grid_type.index == 1
34-
and profiles_2d.psi.has_value
35-
and profiles_2d.r.has_value
36-
):
37-
continue
38-
39-
# Compute COCOS
40-
try:
41-
# ids._obj instead of ids since '&' operator not supported
42-
# yet in IMAS-Validator
43-
cocos = compute_COCOS(ids._obj, itime, i1)["COCOS"]
44-
except Exception:
45-
cocos = None
46-
47-
assert ref == cocos, (
48-
f"COCOS mismatch for time_slice {itime}, profiles_2d {i1}, "
49-
f"DD version_put/computed: {ref}/{cocos}"
64+
# Get the time for this time slice
65+
if ids.ids_properties.homogeneous_time == 0:
66+
time = time_slice.time
67+
else:
68+
time = ids.time[itime]
69+
70+
# Set sign of Ip
71+
if time_slice.global_quantities.ip.has_value:
72+
ipsign = np.sign(time_slice.global_quantities.ip)
73+
else:
74+
ipsign = -9
75+
76+
# Set sign of B0
77+
if ids.vacuum_toroidal_field.b0.has_value:
78+
b0sign = np.sign(
79+
np.interp(time, ids.time, ids.vacuum_toroidal_field.b0)
5080
)
81+
else:
82+
b0sign = -9
83+
84+
#
85+
# Validate the sign conventions for EM fields
86+
#
87+
88+
if time_slice.profiles_1d.f.has_value:
89+
assert np.sign(time_slice.profiles_1d.f) == b0sign
90+
91+
if time_slice.profiles_1d.phi.has_value:
92+
# phi at center found as zero in DINA, CORSICA and etc.
93+
assert np.sign(time_slice.profiles_1d.phi[1:]) == b0sign
94+
95+
psi_axis = time_slice.global_quantities.psi_axis
96+
psi_boundary = time_slice.global_quantities.psi_boundary
97+
if psi_axis.has_value and psi_boundary.has_value:
98+
assert np.sign(psi_boundary - psi_axis) == -ipsign
99+
100+
if time_slice.global_quantities.q_95.has_value:
101+
assert np.sign(time_slice.global_quantities.q_95) == ipsign * b0sign

0 commit comments

Comments
 (0)