Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
BfieldPlots.py
1import numpy as np
2
3from .StandardPlotHelper import StandardPlotHelper
4
5try:
6 from numba import njit
7
8 _HAS_NUMBA = True
9except ImportError:
10 _HAS_NUMBA = False
11
12
13def SliceByPlot(
14 model,
15 ext_r,
16 nx,
17 ny,
18 ex,
19 ey,
20 center,
21 analysis_folder,
22 analysis_prefix,
23 do_normalization=True,
24 min_normalization=1e-9,
25):
26 """Render a slice of the By magnetic field component.
27
28 The MHD solver stores ``B/rho`` (a 3-vector) so By is recovered as ``(B/rho)_y * rho``.
29 """
30
31 def compute_By_slice(helper):
32 def custom_getter(size: int, dic_out: dict) -> np.array:
33 B_over_rho_y = dic_out["B/rho"][:, 1]
34 pmass = model.get_particle_mass()
35 hfact = model.get_hfact()
36 rho = pmass * (hfact / dic_out["hpart"]) ** 3
37 return B_over_rho_y * rho
38
39 arr_By = helper.slice_render(
40 "custom",
41 "f64",
42 do_normalization,
43 min_normalization,
44 custom_getter=custom_getter,
45 )
46
47 return arr_By
48
49 return StandardPlotHelper(
50 model,
51 ext_r,
52 nx,
53 ny,
54 ex,
55 ey,
56 center,
57 analysis_folder,
58 analysis_prefix,
59 compute_function=compute_By_slice,
60 )
61
62
63def SliceBthetaPlot(
64 model,
65 ext_r,
66 nx,
67 ny,
68 ex,
69 ey,
70 center,
71 analysis_folder,
72 analysis_prefix,
73 do_normalization=True,
74 min_normalization=1e-9,
75):
76 """Render a slice of the azimuthal magnetic field component B_theta.
77
78 the azimuthal projection is ``(-y * Bx + x * By) / r``.
79 """
80
81 def compute_Btheta_slice(helper):
82 def internal(
83 size: int, x: np.array, y: np.array, Bx: np.array, By: np.array, rho: np.array
84 ) -> np.array:
85 r_safe = np.sqrt(x**2 + y**2) + 1e-9
86 B_over_rho_theta = (-y * Bx + x * By) / r_safe
87 return B_over_rho_theta * rho # recover B_theta = (B/rho)_theta * rho
88
89 if _HAS_NUMBA:
90 internal = njit(internal)
91
92 def custom_getter(size: int, dic_out: dict) -> np.array:
93 return internal(
94 size,
95 dic_out["xyz"][:, 0],
96 dic_out["xyz"][:, 1],
97 dic_out["B/rho"][:, 0],
98 dic_out["B/rho"][:, 1],
99 dic_out["hfact"],
100 )
101
102 arr_Btheta = helper.slice_render(
103 "custom",
104 "f64",
105 do_normalization,
106 min_normalization,
107 custom_getter=custom_getter,
108 )
109
110 return arr_Btheta
111
112 return StandardPlotHelper(
113 model,
114 ext_r,
115 nx,
116 ny,
117 ex,
118 ey,
119 center,
120 analysis_folder,
121 analysis_prefix,
122 compute_function=compute_Btheta_slice,
123 )
124
125
126def SliceBVerticalShearGradient(
127 model,
128 ext_r,
129 nx,
130 ny,
131 ex,
132 ey,
133 center,
134 analysis_folder,
135 analysis_prefix,
136 do_normalization=True,
137 min_normalization=1e-9,
138):
139 """Render a slice of the vertical shear gradient of the azimuthal magnetic field,
140 ``d(B_theta)/dz``
141
142 ``B_theta`` is recovered from the stored ``B/rho`` field as
143 ``(B/rho)_theta * rho``.
144 """
145
146 def compute_B_vertical_shear_gradient(helper):
147 def internal(
148 size: int, x: np.array, y: np.array, Bx: np.array, By: np.array, rho: np.array
149 ) -> np.array:
150 r_safe = np.sqrt(x**2 + y**2) + 1e-9
151 B_over_rho_theta = (-y * Bx + x * By) / r_safe
152 return B_over_rho_theta * rho # recover B_theta = (B/rho)_theta * rho
153
154 if _HAS_NUMBA:
155 internal = njit(internal)
156
157 def custom_getter(size: int, dic_out: dict) -> np.array:
158 return internal(
159 size,
160 dic_out["xyz"][:, 0],
161 dic_out["xyz"][:, 1],
162 dic_out["B/rho"][:, 0],
163 dic_out["B/rho"][:, 1],
164 dic_out["hfact"],
165 )
166
167 arr_Btheta = helper.slice_render(
168 "custom",
169 "f64",
170 do_normalization,
171 min_normalization,
172 custom_getter=custom_getter,
173 )
174
175 extent = helper.get_extent()
176 dy = (extent[3] - extent[2]) / helper.ny
177
178 B_vertical_shear_gradient = np.gradient(arr_Btheta, dy, axis=0)
179
180 return B_vertical_shear_gradient
181
182 return StandardPlotHelper(
183 model,
184 ext_r,
185 nx,
186 ny,
187 ex,
188 ey,
189 center,
190 analysis_folder,
191 analysis_prefix,
192 compute_function=compute_B_vertical_shear_gradient,
193 )