Skip to content

Commit

Permalink
RunInfo for WarpX (#49)
Browse files Browse the repository at this point in the history
* Added timeseries class

* Added flux_diagnostic file

* Nruof/runinfo minimal (#44)

* Update memaster with new upstream/development (#42)

* CI: Add Missing Python Analysis for EB Test (ECP-WarpX#2147)

* CI: Add Missing Python Analysis for EB Test

* Use 1 MPI Process for Azure

* a few _rt (ECP-WarpX#2146)

* PSATD: div Cleaning Implemented only with psatd.J_linear_in_time=1 (ECP-WarpX#2142)

* BTD: Don't Flush If Written (ECP-WarpX#2148)

Written BTD buffers for lab snapshot data are reset to zero size
(count). When we do the final write of all partly filled buffers
in `FilterComputePackFlushLastTimestep`, we should not write such
already completed backtransformed lab snapshots again.

* openPMD: `groupBased` Option Missing (ECP-WarpX#2149)

The `groupBased` iteration encoding (input: `g`) was not parsed.

* Remove predefined constants from example input files (ECP-WarpX#2153)

* BTD_ReducedSliceDiag: BTD Plotfiles (ECP-WarpX#2152)

By accident, the 2nd test did not use plotfile output.

* Allow extra particle attributes (besides ux, uy, uz and w) to be set at particle creation in AddNParticles() (ECP-WarpX#2115)

* exposes AddRealComp to Python to allow extra particle attributes to be added at runtime; also includes a new function to grab a particle data array from the name of the component rather than the index

* added functionality to AddNParticles() to allow extra particle attributes to also be set during particle creation

* added function to get index of a particle component given the PID name

* changed new get component index and get_particle_arrays_from_comp_name functions to take species name as argument rather than species id

* changed warpx_addRealComp to accept a species name as input and only add the new component for that species

* added a test of the pywarpx bridge to get particle data and add new particle attributes at runtime

* changed all particle interacting functions in libwarpx to use the species name rather than id, also changed the functions to get particle array data to use the component name rather than index

* updated test according to PR ECP-WarpX#2119 changes

* removed unneeded BL_ASSERT(nattr == 1) statement

* fixed bug in add_particles to correctly determine the number of extra attributes

* fixed bug in AddNParticles if fewer attribute values are passed than the number of extra arrays for the species

* use isinstance(attr, ndarray) rather than type(attr) is np.ndarray

* generalize_runtime_comps_io

* fix OpenPMD

* fix OpenPMD

* fix plot flags in WritePlotFile

* fix offset and comment

* changed extra pid test to not use an underscore in the pid name

* switched _libwarpx.py::add_particles to use kwargs to accept the weight and extra attribute arrays

* License update in test file

Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>

* fix typo

* added a test with unique_particles=False

* Apply suggestions from code review

Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>

* updated docstring and comments

Co-authored-by: atmyers <atmyers2@gmail.com>
Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>

* updated mewarpx with recent changes to _libwarpx.add_particles

* fix broken test - test_mepicmi.py

Co-authored-by: Edoardo Zoni <59625522+EZoni@users.noreply.github.com>
Co-authored-by: MaxThevenet <maxence.thevenet@desy.de>
Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
Co-authored-by: atmyers <atmyers2@gmail.com>

* Add runinfo from warp to warpx

* Doc string edit

Co-authored-by: Roelof Groenewald <40245517+roelof-groenewald@users.noreply.github.com>
Co-authored-by: Edoardo Zoni <59625522+EZoni@users.noreply.github.com>
Co-authored-by: MaxThevenet <maxence.thevenet@desy.de>
Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
Co-authored-by: atmyers <atmyers2@gmail.com>

* Ported more flux diags from warp

* Renamed FluxDiag to FluxDiagnostic

* Remove js, species conversion in runinfo

* Add TimeSeriesPlot

* Typo util -> mwxutil

* Added test for Timeseries

* Added test file for Timeseries

* Added appendable array

* Added parallel_util and added test for flux diag

* Renamed columns and added current checks to test

* Update runinfo.py and flux_diagnostic, up to FluxCalcDataFrame

* Updated flux_diagnostic.py

* Fixed indexing issues, flux diagnostics and plotting now works for injected particles

* Added test for flux diag pickle and plot, refactored code

* Change to use upper case variables to use with runinfo

* Update runinfo for warpx

* Add dill to requirements and remove mpi4py

* Remove unused lines from warp

* Removed functions that will not be used

* doc string format

Co-authored-by: Kevin Z. Zhu <86268612+KZhu-ME@users.noreply.github.com>

* Spacing

* Type in doc string

* Doc string update

* Update mewarpx/mewarpx/runinfo.py

Co-authored-by: Kevin Z. Zhu <86268612+KZhu-ME@users.noreply.github.com>

Co-authored-by: kzhu-ME <kevin.zhu@modernelectron.com>
Co-authored-by: Roelof Groenewald <40245517+roelof-groenewald@users.noreply.github.com>
Co-authored-by: Edoardo Zoni <59625522+EZoni@users.noreply.github.com>
Co-authored-by: MaxThevenet <maxence.thevenet@desy.de>
Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>
Co-authored-by: Neïl Zaim <49716072+NeilZaim@users.noreply.github.com>
Co-authored-by: atmyers <atmyers2@gmail.com>
Co-authored-by: Kevin Z. Zhu <86268612+KZhu-ME@users.noreply.github.com>
  • Loading branch information
9 people authored Aug 6, 2021
1 parent 2f4de79 commit 82baac8
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 126 deletions.
15 changes: 8 additions & 7 deletions mewarpx/examples/thermionic_ignition.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,18 +114,19 @@
######################################
# Add ME emission
#####################################
T_cathode = 1100.0 + 273.15 # K
WF_cathode = 2.0 # eV
CATHODE_TEMP = 1100.0 + 273.15 # K
CATHODE_PHI = 2.0 # eV
CATHODE_A = 6e5

cathode = assemblies.ZPlane(z=1e-10, zsign=-1, V=0, T=T_cathode,
WF=WF_cathode,
cathode = assemblies.ZPlane(z=1e-10, zsign=-1, V=0, T=CATHODE_TEMP,
WF=CATHODE_PHI,
name='cathode')
emitter = emission.ZPlaneEmitter(conductor=cathode, T=T_cathode,
emitter = emission.ZPlaneEmitter(conductor=cathode, T=CATHODE_TEMP,
use_Schottky=False)
injector = emission.ThermionicInjector(emitter=emitter, species=electrons,
npart_per_cellstep=50,
T=T_cathode, WF=WF_cathode,
A=6e5)
T=CATHODE_TEMP, WF=CATHODE_PHI,
A=CATHODE_A)

####################################
# Add ME diagnostic
Expand Down
1 change: 0 additions & 1 deletion mewarpx/mewarpx/appendablearray.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Array type which can be appended to in an efficient way.
"""

import numpy
import types
# Class which allows an appendable array.
Expand Down
156 changes: 38 additions & 118 deletions mewarpx/mewarpx/runinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
import os
import platform
import subprocess
import warnings

import dill
import mewarpx
import numpy as np

import mewarpx.util as mwxutil
Expand All @@ -22,71 +22,6 @@

logger = logging.getLogger(__name__)

def get_voltage_wf(shapelist, patchy_cathode=False):
"""Return voltage (and work fn) assigned to a list of shapes.
Raise ValueError if the voltages are not equal among the shapes,
unless patchy_cathode=True in which case voltage and WF comparisons
are not done.
Arguments:
shapelist (list): List of warp.Assembly shape objects
Returns:
voltage, wf (float, float): Voltage and work fn of the shapes. wf is
None if no work functions present. If patchy_cathode is True the
average wf and voltage is returned.
Notes:
This strategy is not fool-proof, because the voltage set on an
Assembly made from added (or subtracted?) Assemblies does not
necessarily equal the voltages of its components, which seem to be
what are used in the simulation. This just uses the main voltage
set for each entire warp.Assembly object.
Furthermore, in the patchy cathode case there is no check that the
average cathode voltage is equal to the specified cathode voltage in
user_var_dict. The patchess are also assumed to have equal weight i.e.
that the cathode has the same area of high and low patches.
"""
if patchy_cathode:
voltage = 0.
wf = 0.
else:
voltage = None
wf = None
for shape in shapelist:
if patchy_cathode:
wf += shape.WF
voltage += shape.V
else:
if wf is None:
wf = shape.WF
elif shape.WF != wf:
raise ValueError(
f'WF {shape.WF:.2f} on shape {shape.name} not equal to '
f'assigned WF {wf:.2f} used for its group'
)
if voltage is None:
voltage = shape.V
elif shape.V != voltage:
raise ValueError(
f'Voltage {shape.V:.2f} on shape {shape.name} '
f'not equal to assigned voltage {voltage:.2f} used '
f'for its group'
)
# Print a warning if WF is not set.
if wf == 0.0:
warnings.warn(
f'Note that WF is not set for shapes {[x.name for x in shapelist]}. '
f'This can cause errors in power calculations'
)

if patchy_cathode:
wf = wf/len(shapelist)
voltage = voltage/len(shapelist)

return voltage, wf

class SimInfo(object):

"""Store basic simulation parameters used throughout analysis.
Expand All @@ -98,6 +33,15 @@ class SimInfo(object):
SimInfo.dt (float)
SimInfo.periodic (bool)
Arguments:
nxyz (list): tuple of ints, holding the grid dimensions
pos_lims (list) : tuple of floats, holding the position limits along each
dimension (xmax, ymin, ymax, zmin, zmax)
geom (str): geometry string 'XZ', 'RZ', or 'XYZ' for 2D grid,
cylindrical, or 3D grid
dt (float): simulation timestep interval
periodic (bool): use periodic boundary conditions
Note:
This base class has been created to provide additional plotting
functionality, and allow post-run creation of this object if needed.
Expand All @@ -122,18 +66,12 @@ def get_vec(self, axis):
return np.linspace(xmin, xmax, npts + 1)

def get_rvec(self):
#TODO: Does this definition also apply to warpx as well
"""Return the r vector.
Note:
When fields are generated in warp, nx is kept, xmmin=0, and xmmax is
kept. This vector matches that convention.
"""
npts = self.nxyz[0]
xmin = 0.
xmax = self.pos_lims[1]
raise NotImplementedError
# npts = self.nxyz[0]
# xmin = 0.
# xmax = self.pos_lims[1]
# There is one more point on the grid than cell number
return np.linspace(xmin, xmax, npts + 1)
# return np.linspace(xmin, xmax, npts + 1)



Expand All @@ -148,13 +86,12 @@ def __init__(self):
mwxrun.zmin, mwxrun.zmax]
self.geom = mwxrun.geom_str
self.dt = mwxrun.get_dt()
self.periodic = (
#TODO: Should be implemented when needed
# warp.w3d.boundxy is warp.periodic
# self.periodic = (
# warp.w3d.boundxy is warp.periodic
# The rwall in RZ simulations can be set even if boundxy is
# periodic. It defaults to 1e36 so this should be fine.
# and warp.top.prwall > 1e10
)
# )


class RunInfo(SimInfo):
Expand All @@ -163,8 +100,8 @@ class RunInfo(SimInfo):
Attributes:
diagnames_dict (dict): Dictionary of paths to diagnostic outputs.
component_labels (dict): Ordered dictionary of (name, pretty_label) for
each device component.
component_labels (collections.OrderedDict): Ordered dictionary of
(name, pretty_label) for each device component.
"""

diagnames_dict = {'part_diag_dir': 'diags/xzsolver/hdf5',
Expand Down Expand Up @@ -255,8 +192,9 @@ def __init__(self, injector_dict, surface_dict,
# All kwargs should have been popped, so raise an error if that isn't
# the case.
if len(kwargs) > 0:
raise ValueError("Unrecognized kwarg(s) {}.".format(list(kwargs.keys())))

raise ValueError(
f'Unrecognized kwarg(s) {list(kwargs.keys())}'
)
# Shapes/injectors just adds all the lists of shapes together into one
# list
self.shapes = reduce(
Expand Down Expand Up @@ -368,20 +306,6 @@ def _check_voltages_wfs(self, check_names=False):
f'(at t = {mwxrun.get_t()*1e9:.2f} ns)'
)

V_cathode, WF_cathode = self._get_cathode_voltage_wf()

def _get_patchy_cathode(self):
# Check if a patchy cathode is used by checking if "CATHODE_DELTA_PHI"
# is greater than 0.0
return (self.user_var_dict.get("CATHODE_DELTA_PHI", 0.) > 0.)

def _get_cathode_voltage_wf(self):
# All cathode shapes must have same V and WF for accurate power
# calculation unless the cathode is patchy in which case the
# average voltage is used.
return get_voltage_wf(self.surface_dict['cathode'],
patchy_cathode=self._get_patchy_cathode())

def _save_sim_info(self):
"""Sets up the run_param_dict with helpful information.
Expand All @@ -407,26 +331,22 @@ def _save_sim_info(self):

def _save_version_info(self):
"""Save info about file versions."""
# self.run_param_dict['metools_version'] = metools.__version__
self.run_param_dict['mewarpx_version'] = mewarpx.__version__
# Version info is a tuple rather than a string
# self.run_param_dict['metools_version_info'] = metools.__version_info__
# self.run_param_dict['warp_info'] = warp.versionstext()
# self.run_param_dict['warp_commit'] = warp.commithash
# cwd = os.getcwd()
# try:
# os.chdir(util.con_dir)
# self.run_param_dict['metools_gitver'] = subprocess.check_output(
# ['git', 'describe'])
# self.run_param_dict['metools_commit'] = subprocess.check_output(
# ['git', 'log', '-n', '1', '--pretty=%h'])
# except subprocess.CalledProcessError as e:
# logger.warning(
# ("Failed to retrieve git information with error "
# "{}").format(e)
# )
# finally:
# os.chdir(cwd)
raise NotImplementedError
self.run_param_dict['mewarpx_version_info'] = mewarpx.__version_info__
cwd = os.getcwd()
try:
os.chdir(mwxutil.mewarpx_dir)
self.run_param_dict['mewarpx_gitver'] = subprocess.check_output(
['git', 'describe'])
self.run_param_dict['mewarpx_commit'] = subprocess.check_output(
['git', 'log', '-n', '1', '--pretty=%h'])
except subprocess.CalledProcessError as e:
logger.warning(
f'Failed to retrieve git information with error {e}'
)
finally:
os.chdir(cwd)

def _save_comp_info(self):
"""Save info about the computer."""
Expand Down

0 comments on commit 82baac8

Please sign in to comment.