Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
VelocityPlots.py
1import numpy as np
2
3import shamrock.sys
4
5from .StandardPlotHelper import StandardPlotHelper
6
7try:
8 from numba import njit
9
10 _HAS_NUMBA = True
11except ImportError:
12 _HAS_NUMBA = False
13
14
15def SliceVzPlot(
16 model,
17 ext_r,
18 nx,
19 ny,
20 ex,
21 ey,
22 center,
23 analysis_folder,
24 analysis_prefix,
25 do_normalization=True,
26 min_normalization=1e-9,
27):
28 def compute_v_z_slice(helper):
29 def keep_only_v_z(arr_v):
30 return arr_v[:, :, 2]
31
32 arr_v = helper.slice_render(
33 "vxyz", "f64_3", do_normalization, min_normalization, keep_only_v_z
34 )
35
36 return arr_v
37
38 return StandardPlotHelper(
39 model,
40 ext_r,
41 nx,
42 ny,
43 ex,
44 ey,
45 center,
46 analysis_folder,
47 analysis_prefix,
48 compute_function=compute_v_z_slice,
49 )
50
51
52def ColumnAverageVzPlot(
53 model,
54 ext_r,
55 nx,
56 ny,
57 ex,
58 ey,
59 center,
60 analysis_folder,
61 analysis_prefix,
62 min_normalization=1e-9,
63):
64 def compute_v_z_slice(helper):
65 def custom_getter(size: int, dic_out: dict) -> np.array:
66 return dic_out["vxyz"][:, 2]
67
68 arr_v = helper.column_average_render(
69 "custom", "f64", min_normalization, custom_getter=custom_getter
70 )
71
72 return arr_v
73
74 return StandardPlotHelper(
75 model,
76 ext_r,
77 nx,
78 ny,
79 ex,
80 ey,
81 center,
82 analysis_folder,
83 analysis_prefix,
84 compute_function=compute_v_z_slice,
85 )
86
87
88def SliceDiffVthetaProfile(
89 model,
90 ext_r,
91 nx,
92 ny,
93 ex,
94 ey,
95 center,
96 analysis_folder,
97 analysis_prefix,
98 velocity_profile,
99 do_normalization=True,
100 min_normalization=1e-9,
101):
102 def compute_diff_vtheta_profile(helper):
103 if _HAS_NUMBA and shamrock.sys.world_rank() == 0:
104 print("Using numba for velocity profile in SliceDiffVthetaProfile")
105
106 if _HAS_NUMBA:
107 vel_profile_jit = njit(velocity_profile)
108 else:
109 vel_profile_jit = np.vectorize(velocity_profile)
110
111 def internal(
112 size: int, x: np.array, y: np.array, vx: np.array, vy: np.array, vz: np.array
113 ) -> np.array:
114 r = np.sqrt(x**2 + y**2)
115 r_safe = r + 1e-9
116 v_theta = (-y * vx + x * vy) / r_safe
117 v_relative = v_theta - vel_profile_jit(r)
118 return v_relative
119
120 if _HAS_NUMBA:
121 internal = njit(internal)
122
123 def custom_getter(size: int, dic_out: dict) -> np.array:
124 return internal(
125 size,
126 dic_out["xyz"][:, 0],
127 dic_out["xyz"][:, 1],
128 dic_out["vxyz"][:, 0],
129 dic_out["vxyz"][:, 1],
130 dic_out["vxyz"][:, 2],
131 )
132
133 arr_v = helper.slice_render(
134 "custom",
135 "f64",
136 do_normalization,
137 min_normalization,
138 custom_getter=custom_getter,
139 )
140
141 return arr_v
142
143 return StandardPlotHelper(
144 model,
145 ext_r,
146 nx,
147 ny,
148 ex,
149 ey,
150 center,
151 analysis_folder,
152 analysis_prefix,
153 compute_function=compute_diff_vtheta_profile,
154 )
155
156
157def VerticalShearGradient(
158 model,
159 ext_r,
160 nx,
161 ny,
162 ex,
163 ey,
164 center,
165 analysis_folder,
166 analysis_prefix,
167 do_normalization=True,
168 min_normalization=1e-9,
169):
170 def compute_vertical_shear_gradient(helper):
171 if _HAS_NUMBA and shamrock.sys.world_rank() == 0:
172 print("Using numba for custom getter in VerticalShearGradient")
173
174 def internal(
175 size: int, x: np.array, y: np.array, vx: np.array, vy: np.array, vz: np.array
176 ) -> np.array:
177 r = np.sqrt(x**2 + y**2)
178 r_safe = r + 1e-9
179 v_theta = (-y * vx + x * vy) / r_safe
180 return v_theta
181
182 if _HAS_NUMBA:
183 internal = njit(internal)
184
185 def custom_getter(size: int, dic_out: dict) -> np.array:
186 return internal(
187 size,
188 dic_out["xyz"][:, 0],
189 dic_out["xyz"][:, 1],
190 dic_out["vxyz"][:, 0],
191 dic_out["vxyz"][:, 1],
192 dic_out["vxyz"][:, 2],
193 )
194
195 arr_v_theta = helper.slice_render(
196 "custom",
197 "f64",
198 do_normalization,
199 min_normalization,
200 custom_getter=custom_getter,
201 )
202
203 extent = helper.get_extent()
204 dy = (extent[3] - extent[2]) / helper.ny
205
206 vert_shear_gradient = np.gradient(arr_v_theta, dy, axis=0) # / dy
207
208 return vert_shear_gradient
209
210 return StandardPlotHelper(
211 model,
212 ext_r,
213 nx,
214 ny,
215 ex,
216 ey,
217 center,
218 analysis_folder,
219 analysis_prefix,
220 compute_function=compute_vertical_shear_gradient,
221 )
222
223
224def gen_angular_momt_custom_getter(model, velocity_profile):
225 pmass = model.get_particle_mass()
226 hfact = model.get_hfact()
227
228 if _HAS_NUMBA:
229 if shamrock.sys.world_rank() == 0:
230 print(
231 "Using numba for velocity profile in SliceAngularMomentumTransportCoefficientPlot"
232 )
233 vel_profile_jit = njit(velocity_profile)
234 else:
235 vel_profile_jit = np.vectorize(velocity_profile)
236
237 def internal(
238 x: np.array,
239 y: np.array,
240 z: np.array,
241 vx: np.array,
242 vy: np.array,
243 vz: np.array,
244 hpart: np.array,
245 cs: np.array,
246 ) -> np.array:
247 rho = pmass * (hfact / hpart) ** 3
248 P = cs**2 * rho # TODO: use true pressure
249
250 r = np.sqrt(x**2 + y**2)
251 r_safe = r + 1e-9
252 v_r = (x * vx + y * vy) / r_safe
253 v_theta = (-y * vx + x * vy) / r_safe
254
255 delta_vtheta = v_theta - vel_profile_jit(r)
256 alpha = rho * v_r * delta_vtheta / P
257
258 return alpha
259
260 if _HAS_NUMBA:
261 if shamrock.sys.world_rank() == 0:
262 print("Using numba for custom getter in SliceAngularMomentumTransportCoefficientPlot")
263 internal = njit(internal)
264
265 def custom_getter(size: int, dic_out: dict) -> np.array:
266 return internal(
267 dic_out["xyz"][:, 0],
268 dic_out["xyz"][:, 1],
269 dic_out["xyz"][:, 2],
270 dic_out["vxyz"][:, 0],
271 dic_out["vxyz"][:, 1],
272 dic_out["vxyz"][:, 2],
273 dic_out["hpart"],
274 dic_out["soundspeed"],
275 )
276
277 return custom_getter
278
279
280def SliceAngularMomentumTransportCoefficientPlot(
281 model,
282 ext_r,
283 nx,
284 ny,
285 ex,
286 ey,
287 center,
288 analysis_folder,
289 analysis_prefix,
290 do_normalization=True,
291 min_normalization=1e-9,
292 velocity_profile=None,
293):
294 def compute_angular_momentum_transport_coefficient(helper):
295 custom_getter = gen_angular_momt_custom_getter(model, velocity_profile)
296
297 arr_v = helper.slice_render(
298 "custom",
299 "f64",
300 do_normalization,
301 min_normalization,
302 custom_getter=custom_getter,
303 )
304
305 return arr_v
306
307 return StandardPlotHelper(
308 model,
309 ext_r,
310 nx,
311 ny,
312 ex,
313 ey,
314 center,
315 analysis_folder,
316 analysis_prefix,
317 compute_function=compute_angular_momentum_transport_coefficient,
318 )
319
320
321def ColumnAverageAngularMomentumTransportCoefficientPlot(
322 model,
323 ext_r,
324 nx,
325 ny,
326 ex,
327 ey,
328 center,
329 analysis_folder,
330 analysis_prefix,
331 min_normalization=1e-9,
332 velocity_profile=None,
333):
334 def compute_angular_momentum_transport_coefficient(helper):
335 custom_getter = gen_angular_momt_custom_getter(model, velocity_profile)
336
337 arr_v = helper.column_average_render(
338 "custom",
339 "f64",
340 min_normalization,
341 custom_getter=custom_getter,
342 )
343 return arr_v
344
345 return StandardPlotHelper(
346 model,
347 ext_r,
348 nx,
349 ny,
350 ex,
351 ey,
352 center,
353 analysis_folder,
354 analysis_prefix,
355 compute_function=compute_angular_momentum_transport_coefficient,
356 )