aboutsummaryrefslogtreecommitdiff
path: root/Examples/Tests/Larmor/plot_particle_path.py
diff options
context:
space:
mode:
Diffstat (limited to 'Examples/Tests/Larmor/plot_particle_path.py')
-rw-r--r--Examples/Tests/Larmor/plot_particle_path.py144
1 files changed, 144 insertions, 0 deletions
diff --git a/Examples/Tests/Larmor/plot_particle_path.py b/Examples/Tests/Larmor/plot_particle_path.py
new file mode 100644
index 000000000..0a9e965e7
--- /dev/null
+++ b/Examples/Tests/Larmor/plot_particle_path.py
@@ -0,0 +1,144 @@
+import numpy as np
+
+class AMReXParticleHeader(object):
+ '''
+
+ This class is designed to parse and store the information
+ contained in an AMReX particle header file.
+
+ Usage:
+
+ header = AMReXParticleHeader("plt00000/particle0/Header")
+ print(header.num_particles)
+ print(header.version_string)
+
+ etc...
+
+ '''
+
+ def __init__(self, header_filename):
+
+ self.real_component_names = []
+ self.int_component_names = []
+ with open(header_filename, "r") as f:
+ self.version_string = f.readline().strip()
+
+ particle_real_type = self.version_string.split('_')[-1]
+ particle_real_type = self.version_string.split('_')[-1]
+ if particle_real_type == 'double':
+ self.real_type = np.float64
+ elif particle_real_type == 'single':
+ self.real_type = np.float32
+ else:
+ raise RuntimeError("Did not recognize particle real type.")
+ self.int_type = np.int32
+
+ self.dim = int(f.readline().strip())
+ self.num_int_base = 2
+ self.num_real_base = self.dim
+ self.num_real_extra = int(f.readline().strip())
+ for i in range(self.num_real_extra):
+ self.real_component_names.append(f.readline().strip())
+ self.num_int_extra = int(f.readline().strip())
+ for i in range(self.num_int_extra):
+ self.int_component_names.append(f.readline().strip())
+ self.num_int = self.num_int_base + self.num_int_extra
+ self.num_real = self.num_real_base + self.num_real_extra
+ self.is_checkpoint = bool(int(f.readline().strip()))
+ self.num_particles = int(f.readline().strip())
+ self.max_next_id = int(f.readline().strip())
+ self.finest_level = int(f.readline().strip())
+ self.num_levels = self.finest_level + 1
+
+ if not self.is_checkpoint:
+ self.num_int_base = 0
+ self.num_int_extra = 0
+ self.num_int = 0
+
+ self.grids_per_level = np.zeros(self.num_levels, dtype='int64')
+ self.grids = []
+ for level_num in range(self.num_levels):
+ self.grids_per_level[level_num] = int(f.readline().strip())
+ self.grids.append([])
+
+ for level_num in range(self.num_levels):
+ for grid_num in range(self.grids_per_level[level_num]):
+ entry = [int(val) for val in f.readline().strip().split()]
+ self.grids[level_num].append(tuple(entry))
+
+
+def read_particle_data(fn, ptype="particle0"):
+ '''
+
+ This function returns the particle data stored in a particular
+ plot file and particle type. It returns two numpy arrays, the
+ first containing the particle integer data, and the second the
+ particle real data. For example, if a dataset has 3000 particles,
+ which have two integer and five real components, this function will
+ return two numpy arrays, one with the shape (3000, 2) and the other
+ with the shape (3000, 5).
+
+ Usage:
+
+ idata, rdata = read_particle_data("plt00000", "particle0")
+
+ '''
+ base_fn = fn + "/" + ptype
+ header = AMReXParticleHeader(base_fn + "/Header")
+
+ idtype = "(%d,)i4" % header.num_int
+ if header.real_type == np.float64:
+ fdtype = "(%d,)f8" % header.num_real
+ elif header.real_type == np.float32:
+ fdtype = "(%d,)f4" % header.num_real
+
+ idata = np.empty((header.num_particles, header.num_int ))
+ rdata = np.empty((header.num_particles, header.num_real))
+
+ ip = 0
+ for lvl, level_grids in enumerate(header.grids):
+ for (which, count, where) in level_grids:
+ if count == 0: continue
+ fn = base_fn + "/Level_%d/DATA_%04d" % (lvl, which)
+
+ with open(fn, 'rb') as f:
+ f.seek(where)
+ ints = np.fromfile(f, dtype = idtype, count=count)
+ floats = np.fromfile(f, dtype = fdtype, count=count)
+
+ idata[ip:ip+count] = ints
+ rdata[ip:ip+count] = floats
+ ip += count
+
+ return idata, rdata
+
+
+if __name__ == "__main__":
+ import pylab as plt
+ import glob
+
+ x0 = []
+ y0 = []
+ x1 = []
+ y1 = []
+
+ fn_list = glob.glob("plt?????")
+ fn_list.sort()
+
+ for fn in fn_list:
+ idata, rdata = read_particle_data(fn, ptype="particle0")
+ x0.append(rdata[0][0])
+ y0.append(rdata[0][1])
+ idata, rdata = read_particle_data(fn, ptype="particle1")
+ x1.append(rdata[0][0])
+ y1.append(rdata[0][1])
+
+ fig = plt.gcf()
+ fig.set_size_inches(8, 8)
+ plt.plot(x0, y0, 'r.')
+ plt.plot(x1, y1, 'b.')
+ plt.axis((-2., 2., -2., 2.))
+ ax = plt.gca()
+ ax.set_xlabel(r'$x$')
+ ax.set_ylabel(r'$y$')
+ plt.savefig('particles.png')