Skip to content

Commit 82f64a1

Browse files
authored
improvements to xrb plotting script (#3154)
this is for xrb_spherical
1 parent e7fdfa0 commit 82f64a1

File tree

10 files changed

+121
-59
lines changed

10 files changed

+121
-59
lines changed

Exec/science/xrb_spherical/GNUmakefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ NUM_MODELS := 2
2626
EOS_DIR := helmholtz
2727

2828
# This sets the network directory in $(MICROPHYSICS_HOME)/networks
29-
NETWORK_DIR := he-burn/he-burn-18a
29+
NETWORK_DIR := he-burn/he-burn-19am
3030

3131
INTEGRATOR_DIR := RKC
3232

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../flame_wave/Problem_Derive.H
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../flame_wave/Problem_Derive.cpp
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../flame_wave/Problem_Derives.H

Exec/science/xrb_spherical/analysis/flame_speed.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from front_tracker.py to plot the time evolution of flame front θ.
2929
''')
3030

31-
parser.add_argument('tracking_fname', type=str,
31+
parser.add_argument('tracking_fnames', nargs='+', type=str,
3232
help='cvs file generated from front_tracker.py to track flame front position')
3333
parser.add_argument('--tmin', default=0.0, type=float,
3434
help='minimum time for curve fitting. Note that this will not affect plotting')
@@ -37,20 +37,29 @@
3737

3838
args = parser.parse_args()
3939

40-
# Read in data
41-
# data has columns: fname, time, front_theta, theta_max_avg, max_avg, theta_max, max_val.
42-
tracking_data = pd.read_csv(args.tracking_fname)
40+
all_data = []
41+
42+
# Loop over all tracking files and append them
43+
for fname in args.tracking_fnames:
44+
df = pd.read_csv(fname)
45+
all_data.append(df)
46+
47+
# concatenate all files together
48+
tracking_data = pd.concat(all_data, ignore_index=True)
4349

50+
# sort by the time
51+
tracking_data = tracking_data.sort_values(by='time[ms]')
52+
53+
# data has columns: fname, time, front_theta, theta_max_avg, max_avg, theta_max, max_val.
4454
# Get time and theta, these should already be time-sorted
4555
times = tracking_data['time[ms]']
4656
front_thetas = tracking_data['front_theta']
4757

4858
# Only plot up to tmax
4959
if args.tmax is not None:
5060
cond = times < args.tmax
51-
52-
times = times[cond]
53-
front_thetas = front_thetas[cond]
61+
times = times[cond]
62+
front_thetas = front_thetas[cond]
5463

5564
# Now do a curve fit to the data.
5665
# Now apply tmin so that we ignore the transient phase during fitting

Exec/science/xrb_spherical/analysis/inset_slice.py

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@
1919
def single_slice(ds, field:str,
2020
loc: str = "top", widthScale: float = 3.0,
2121
theta: Optional[float] = None,
22+
position: float | None = None,
2223
displace_theta: bool = True,
23-
annotate_vline: bool = True,
24-
annotate_lat_lines: bool = True,
2524
show_full_star: bool = True) -> None:
2625
"""
2726
A slice plot a single dataset for a single field parameters for Spherical2D geometry.
@@ -45,14 +44,13 @@ def single_slice(ds, field:str,
4544
theta:
4645
user defined theta center of the slice plot
4746
47+
position:
48+
draw a vertical line on user defined front position in theta (in radian)
49+
4850
displace_theta:
4951
When theta is explicitly defined, do we want to displace the center
5052
of the slice plot by ~0.7. This is helpful when tracking the flame front.
5153
52-
annotate_vline:
53-
do we want to annotate a vertical line at where theta is.
54-
This is used to indicate flame front.
55-
5654
show_full_star:
5755
do we want to plot the full star instead of a zoom-in slice plot.
5856
"""
@@ -96,18 +94,17 @@ def single_slice(ds, field:str,
9694
# sp.annotate_text((0.05, 0.05), f"{currentTime.in_cgs():8.5f} s")
9795

9896
# Plot a vertical to indicate flame front
99-
if theta is not None and annotate_vline:
100-
sp.annotate_line([r[0]*np.sin(theta), r[0]*np.cos(theta)],
101-
[r[2]*np.sin(theta), r[2]*np.cos(theta)],
97+
if position is not None:
98+
sp.annotate_line([r[0]*np.sin(position), r[0]*np.cos(position)],
99+
[r[2]*np.sin(position), r[2]*np.cos(position)],
102100
coord_system="plot",
103101
color="k",
104102
linewidth=1.5,
105103
linestyle="-.")
106104

107105
### Annotate Latitude Lines
108-
if annotate_lat_lines:
109-
annotate_latitude_lines(sp, center, box_widths, r,
110-
show_full_star=show_full_star)
106+
annotate_latitude_lines(sp, center, box_widths, r,
107+
show_full_star=show_full_star)
111108

112109
sp._setup_plots()
113110
return sp
@@ -131,13 +128,14 @@ def single_slice(ds, field:str,
131128
parser.add_argument('-t', '--theta', type=float,
132129
help="""user defined theta center location of the plot domain.
133130
Alternative way of defining plotting center""")
131+
parser.add_argument('-p', '--position', type=float,
132+
help="""user defined front position in theta,
133+
this will draw a vertical line to annotate the front position""")
134134
parser.add_argument('-w', '--width', default=2.0, type=float,
135135
help="scaling for the domain width of the slice plot")
136136
parser.add_argument('--displace_theta', action='store_true',
137137
help="""whether to displace the theta that defines the center of the frame.
138138
This is useful when theta represents the flame front position.""")
139-
parser.add_argument('--annotate_vline', action='store_true',
140-
help="whether to annotate a vertical line along the given theta")
141139

142140
args = parser.parse_args()
143141

@@ -152,9 +150,9 @@ def single_slice(ds, field:str,
152150

153151
# First get the slice plot of the full-star.
154152
full_star_slice = single_slice(ds, args.field, loc=loc,
155-
widthScale=args.width, theta=args.theta,
156-
displace_theta=args.displace_theta, annotate_vline=args.annotate_vline,
157-
annotate_lat_lines=True, show_full_star=True)
153+
widthScale=args.width, theta=args.theta, position=args.position,
154+
displace_theta=args.displace_theta,
155+
show_full_star=True)
158156
# full_star_slice.render()
159157

160158
# Extract the figure of the full-star slice and use that as the main figure for plotting.
@@ -166,9 +164,9 @@ def single_slice(ds, field:str,
166164

167165
# Get the slice of the zoom-in plot
168166
zoom_in_slice = single_slice(ds, args.field, loc=loc,
169-
widthScale=args.width, theta=args.theta,
170-
displace_theta=args.displace_theta, annotate_vline=args.annotate_vline,
171-
annotate_lat_lines=True, show_full_star=False)
167+
widthScale=args.width, theta=args.theta, position=args.position,
168+
displace_theta=args.displace_theta,
169+
show_full_star=False)
172170
zoom_in_slice.hide_colorbar()
173171
# zoom_in_slice.render()
174172

@@ -226,10 +224,21 @@ def single_slice(ds, field:str,
226224

227225
### Now annotate inset box lines ###
228226
# loc1 and loc2: corners to connect (1: upper right, 2: upper left, 3: lower left, 4: lower right)
229-
if args.theta < np.pi/3.0 or (args.theta is None and loc=="top"):
227+
if args.theta is None:
228+
if loc == "top":
229+
loc1 = 1
230+
loc2 = 2
231+
elif loc == "bot":
232+
loc1 = 3
233+
loc2 = 4
234+
else:
235+
# mid
236+
loc1 = 1
237+
loc2 = 4
238+
elif args.theta < np.pi/3.0:
230239
loc1 = 1
231240
loc2 = 2
232-
elif args.theta > 2.0*np.pi/3.0 or (args.theta is None and loc=="bot"):
241+
elif args.theta > 2.0*np.pi/3.0:
233242
loc1 = 3
234243
loc2 = 4
235244
else:

Exec/science/xrb_spherical/analysis/slice.py

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,41 @@
77
import math
88
from typing import List, Optional
99
import numpy as np
10+
import pynucastro as pyna
1011
import matplotlib.pyplot as plt
1112
from mpl_toolkits.axes_grid1 import ImageGrid
1213
from yt.frontends.boxlib.api import CastroDataset
1314
from 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+
1545
def 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)

Exec/science/xrb_spherical/analysis/slice_sequence.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
parser.add_argument('--displace_theta', action='store_true',
2626
help="""whether to displace the theta that defines the center of the frame.
2727
This is useful when theta represents the flame front position.""")
28-
parser.add_argument('--annotate_vline', action='store_true',
29-
help="whether to annotate a vertical line along the given theta")
3028
parser.add_argument('--jobs', '-j', default=1, type=int,
3129
help="""Number of workers to plot in parallel""")
3230

@@ -40,13 +38,16 @@
4038
fnames = tracking_data["fname"]
4139
front_thetas = tracking_data["front_theta"]
4240

41+
# Process front_thetas with moving average so that frame doesn't jitter
42+
window = 10
43+
smooth_thetas = tracking_data['front_theta'].rolling(window, center=True).mean()
44+
4345
# Parallelize the plotting
4446
with ProcessPoolExecutor(max_workers=args.jobs) as executor:
4547
future_to_index = {
4648
executor.submit(slice, [fname], args.fields, widthScale=args.width,
47-
widthRatio=args.ratio, theta=front_thetas[i],
48-
displace_theta=args.displace_theta, annotate_vline=args.annotate_vline,
49-
annotate_lat_lines=True): i
49+
widthRatio=args.ratio, theta=smooth_thetas[i], position=front_thetas[i],
50+
displace_theta=args.displace_theta): i
5051
for i, fname in enumerate(fnames)
5152
}
5253
try:

Exec/science/xrb_spherical/inputs.He.10deg.1000Hz renamed to Exec/science/xrb_spherical/inputs/inputs.He.10deg.1000Hz

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ amr.derive_plot_vars = ALL
107107
amr.small_plot_file = xrb_spherical_1000Hz_smallplt # root name of plotfile
108108
amr.small_plot_per = 1.e-4 # number of seconds between plotfiles
109109
amr.small_plot_vars = density Temp
110-
amr.derive_small_plot_vars = abar x_velocity y_velocity z_velocity enuc
110+
amr.derive_small_plot_vars = abar x_velocity y_velocity z_velocity enuc X(ash)
111+
112+
amr.file_name_digits = 7
111113

112114
# problem initialization
113115

Exec/science/xrb_spherical/inputs.He.180deg.1000Hz renamed to Exec/science/xrb_spherical/inputs/inputs.He.180deg.1000Hz

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ amr.derive_plot_vars = ALL
107107
amr.small_plot_file = xrb_spherical_1000Hz_smallplt # root name of plotfile
108108
amr.small_plot_per = 1.e-4 # number of seconds between plotfiles
109109
amr.small_plot_vars = density Temp
110-
amr.derive_small_plot_vars = abar x_velocity y_velocity z_velocity enuc
110+
amr.derive_small_plot_vars = abar x_velocity y_velocity z_velocity enuc X(ash)
111+
112+
amr.file_name_digits = 7
111113

112114
# problem initialization
113115

0 commit comments

Comments
 (0)