77import math
88from typing import List , Optional
99import numpy as np
10+ import pynucastro as pyna
1011import matplotlib .pyplot as plt
1112from mpl_toolkits .axes_grid1 import ImageGrid
1213from yt .frontends .boxlib .api import CastroDataset
1314from yt .units import km
1415
16+ def _ash (field , data ):
17+ '''
18+ Computes the rho X_ash.
19+ Here ash is anything heavier than Oxygen, but exclude Fe and Ni
20+ '''
21+
22+ ds = data .ds
23+ field_list = ds .field_list
24+
25+ # If X(ash) is directly stored, then just use that
26+ if ("boxlib" , "X(ash)" ) in field_list :
27+ return data ["boxlib" , "X(ash)" ] * data ["boxlib" , "density" ]
28+
29+ # If we cannot find X(ash) as a available field then compute manually
30+ rhoAsh = 0
31+ for f in field_list :
32+ # If the first two letters are "X(", then we're dealing with species massfractions
33+ if f [1 ][:2 ] == "X(" :
34+ # Then extract out what species we have, assuming the format is "X(...)"
35+ speciesName = f [1 ][2 :- 1 ]
36+ nuc = pyna .Nucleus (speciesName )
37+
38+ # Include elements beyond oxygen but don't include Ni56
39+ if nuc .Z > 8.0 and nuc .Z != 56 :
40+ rhoAsh += data ["boxlib" , "density" ] * data [f ]
41+
42+ return rhoAsh
43+
44+
1545def extract_info (ds ,
1646 loc : str = "top" , widthScale : float = 3.0 ,
1747 widthRatio : float = 1.0 ,
@@ -220,9 +250,8 @@ def slice(fnames:list[str], fields:list[str],
220250 loc : str = "top" , widthScale : float = 3.0 ,
221251 widthRatio : float = 1.0 ,
222252 theta : float | None = None ,
253+ position : float | None = None ,
223254 displace_theta : bool = False ,
224- annotate_vline : bool = False ,
225- annotate_lat_lines : bool = True ,
226255 show_full_star : bool = False ) -> None :
227256 """
228257 A slice plot of the datasets for different field parameters for Spherical2D geometry.
@@ -252,19 +281,15 @@ def slice(fnames:list[str], fields:list[str],
252281 For widthRatio > 1, the vertical width is larger than horizontal.
253282
254283 theta:
255- user defined theta center of the slice plot
284+ user defined theta (in radian) center of the slice plot
285+
286+ position:
287+ draw a vertical line on user defined front position in theta (in radian)
256288
257289 displace_theta:
258290 whether to displace theta so that the vertical lines that represents
259291 the flame front is offset by some amount
260292
261- annotate_vline:
262- whether to plot a vertical line to represent the flame front,
263- which is represented by what theta is.
264-
265- annotate_lat_lines:
266- whether to annotate latitude lines.
267-
268293 show_full_star:
269294 whether to plot the full star rather than a zoom-in
270295 """
@@ -278,7 +303,7 @@ def slice(fnames:list[str], fields:list[str],
278303 nx = math .ceil (num / ny )
279304
280305 grid = ImageGrid (fig , 111 , nrows_ncols = (nx , ny ),
281- axes_pad = 1 , label_mode = "L" , cbar_location = "right" ,
306+ axes_pad = 1.1 , label_mode = "L" , cbar_location = "right" ,
282307 cbar_mode = "each" , cbar_size = "2.5%" , cbar_pad = "0%" )
283308
284309 # Output plot file name
@@ -292,6 +317,12 @@ def slice(fnames:list[str], fields:list[str],
292317 theta = theta ,
293318 displace_theta = displace_theta ,
294319 show_full_star = show_full_star )
320+
321+ #add rhoX_ash as a derived field
322+ ds .add_field (("gas" , "ash" ), function = _ash ,
323+ display_name = r"\rho X\left(ash\right)" ,
324+ units = "auto" , sampling_type = "cell" )
325+
295326 for i , field in enumerate (fields ):
296327 # Plot each field parameter
297328 sp = yt .SlicePlot (ds , 'phi' , field , width = box_widths , fontsize = 20 )
@@ -310,6 +341,10 @@ def slice(fnames:list[str], fields:list[str],
310341 sp .set_zlim (field , 4 , 8 )
311342 sp .set_log (field , False )
312343 sp .set_cmap (field , "plasma_r" )
344+ elif field == "ash" :
345+ sp .set_zlim (field , 1.e-2 , 1e6 )
346+ sp .set_log (field , True )
347+ sp .set_cmap (field , "plasma_r" )
313348 elif field == "enuc" :
314349 sp .set_zlim (field , 1.e15 , 1.e20 )
315350 sp .set_log (field , linthresh = 1.e11 )
@@ -321,18 +356,17 @@ def slice(fnames:list[str], fields:list[str],
321356 # sp.annotate_text((0.05, 0.05), f"{currentTime.in_cgs():8.5f} s")
322357
323358 # Plot a vertical to indicate flame front
324- if theta is not None and annotate_vline :
325- sp .annotate_line ([r [0 ]* np .sin (theta ), r [0 ]* np .cos (theta )],
326- [r [2 ]* np .sin (theta ), r [2 ]* np .cos (theta )],
359+ if position is not None :
360+ sp .annotate_line ([r [0 ]* np .sin (position ), r [0 ]* np .cos (position )],
361+ [r [2 ]* np .sin (position ), r [2 ]* np .cos (position )],
327362 coord_system = "plot" ,
328363 color = "k" ,
329364 linewidth = 1.5 ,
330365 linestyle = "-." )
331366
332367 ### Annotate Latitude Lines
333- if annotate_lat_lines :
334- annotate_latitude_lines (sp , center , box_widths , r ,
335- show_full_star = show_full_star )
368+ annotate_latitude_lines (sp , center , box_widths , r ,
369+ show_full_star = show_full_star )
336370
337371 plot = sp .plots [field ]
338372 plot .figure = fig
@@ -391,6 +425,9 @@ def slice(fnames:list[str], fields:list[str],
391425 parser .add_argument ('-t' , '--theta' , type = float ,
392426 help = """user defined theta center location of the plot domain.
393427 Alternative way of defining plotting center""" )
428+ parser .add_argument ('-p' , '--position' , type = float ,
429+ help = """user defined front position in theta,
430+ this will draw a vertical line to annotate the front position""" )
394431 parser .add_argument ('-r' , '--ratio' , default = 1.0 , type = float ,
395432 help = """The ratio between the horizontal and vertical width of the slice plot.
396433 For ratio < 1, horizontal width is larger than vertical.
@@ -400,8 +437,6 @@ def slice(fnames:list[str], fields:list[str],
400437 parser .add_argument ('--displace_theta' , action = 'store_true' ,
401438 help = """whether to displace the theta that defines the center of the frame.
402439 This is useful when theta represents the flame front position.""" )
403- parser .add_argument ('--annotate_vline' , action = 'store_true' ,
404- help = "whether to annotate a vertical line along the given theta" )
405440 parser .add_argument ('--show_full_star' , action = 'store_true' ,
406441 help = "whether show the full star in the background" )
407442
@@ -417,6 +452,7 @@ def slice(fnames:list[str], fields:list[str],
417452 parser .error ("loc must be one of the three: {top, mid, bot}" )
418453
419454 slice (args .fnames , args .fields , loc = loc ,
420- widthScale = args .width , widthRatio = args .ratio , theta = args .theta ,
421- displace_theta = args .displace_theta , annotate_vline = args .annotate_vline ,
422- annotate_lat_lines = True , show_full_star = args .show_full_star )
455+ widthScale = args .width , widthRatio = args .ratio ,
456+ theta = args .theta , position = args .position ,
457+ displace_theta = args .displace_theta ,
458+ show_full_star = args .show_full_star )
0 commit comments