WARPXM v1.10.0
|
The WARPXM input file (.inp
file) is an XML-like formatted file that provides setup information for a WARPXM simulation. For the Python language input files using the WARPXM interface library, warpy, see the warpy documenation.
The WARPXM input file (.inp
file) is an XML-like file format. Blocks are opened using an opening tag <tag_name>
, then closed with the matching </tag_name>
. Blocks can be nested as deep as desired. The only requirement is that all the direct children blocks and attributes of a given block must be unique, and must be(?) valid C identifiers (i.e. [A-Za-z_][A-za-z0-9_]*
). Like XML the input file is case-sensitive.
Note that you cannot add XML attributes to the opening tag; instead, all attributes of a given block are contained inside the body as key = value
pairs. There is one attribute per line. Valid value types are strings, numbers (both integer and floating point), and lists. The input file is unable to express boolean values directly; instead, boolean values are expressed as integers where non-zero values are true and zero as false. List value types are expressed using a square brackets and a comma separated list of values. An example input file section:
The actual types of the values is not fixed; for example, the value "1" can be interpreted as a string, integer, boolean, or floating pointing point number. Note that this is different from WARPX, where a particular value had a specific type, so "1" was always an int
, while "1.0" was always a double
. WARPXM is able to lexically cast between types as desired, so both of these values could be interpreted as any one of a multitude of different types. However, there are limitations. For example, an attribute with the value "[a,b]" cannot be cast to a number type, but can be cast to a string or a list of strings.
As a general rule of thumb, each block represents some sort of WARPXM class. So the above input file section might be used to construct a class top
something like this:
The order of blocks/attributes is not important(?), i.e. the following blocks are equivalent:
The general process by which objects are created and setup in WARPXM is:
void Setup(const WxCryptSet& wxc)
member function of the class is called to initialize the class parameters with what's read from the input file.The WxCryptSet class represents a single block of the input file, along with any nested attributes and sub-blocks. Note that you cannot access any input file parameters of your parent block, or any sybling blocks. These can be accessed indirectly by establishing a parent-child relation at creation time from WxCreator
.
To read an attribute, there are a set of templated get
functions defined in WxCryptSet
which will attempt to retrieve the value of a given attribute name. If no expected return type is specified, you will get a WxAny
object which represents a value of any type.
Allowed types (typedefs equivalent to any of these are allowed, too. These should be the raw types, i.e. int
instead of const int&
):
bool
char
unsigned char
short
unsigned short
int
unsigned int
long
unsigned long
long long
unsigned long long
float
double
std::string
WxAny
std::vector<T>
, where T
is any of the listed allowed typesYou can get sub blocks by calling getSet
with the name of the subblock. If you don't know the name of the subblock, it is possible to discover it using the getNamesOfTypes
. In order to use this function, the block must have an attribute named Type
(i.e. the base type). A de-facto standard in the code is that for polymorphic types, there is an attribute Kind
which can be used to look up the appropriate subclass in WxCreator. However, if you know that there will only be one such type you can always manually call new
without using WxCreator.
Example usage to iterate through all variables and create them:
In order to easily and extendably handle different class types, WARPXM uses an abstract factory pattern. This allows the arbitrary construction of polymorphic types (ex.: WmPatchProcess
is the base class of patch-based operations such as spatial solvers, variable adjusters, etc.). There is no requirement that all objects created from WxCreator must inherit from a single base class. However, a common base class type must be passed to the WxCreator in order to look up an appropriate subclass to construct.
In order for WxCreator to know what classes are available for construction, classes must be registered with WxCreator. To do this, at the bottom of the associated .cc
/.cpp
file add:
To get WxCreator to construct a subclass,
The general layout of a WARPXM input file is:
WmSimulation
class named warpxm
. This essentially the entry point into WARPXM. It has an attribute sim
which is the name of the subblock containing some sort of solver. At this time there can only be a single solver per simulation.WmSolver
block contains the actual contents for what is to be simulated. It defines the start/stop time, stores the mesh, distributed variables, contains any number of host actions, and defines appropriate sequences for how the host actions should be executed. Host actions are the top level wrappers for any executable task. This could be performing a variable sync operation, writing out data files, taking a timestep, etc. Note that there is a special host action for the time stepping controller which is not sequenced in the usual fashion as other host actions. It has a Kind
of time_stepper.<stepper_kind>
, where stepper_kind
is the actual kind of time stepper to use (fixed timesteps, error-based metric, stability criterion, etc.).WmSequencedGroup
is used to collect any number of host actions which are run in the order specified.WmSequencedGroup
s can be specified to execute at different phases of the simulation using the SolverSequence
. Lists of sequence groups are run serially in the order specified. Note that any sequence group can appear in any of the specified time periods, and can even appear multiple times within a single specified time period. You may only have one solver sequence per solver. Periods at which a sequence group can be run:StartOnly
- only run once at the beginning of the simulation. Note that on restarts these sequence groups are not run. Generally this is used for setting up initial conditions.PerStep
- These sequence groups are run every timestep.PreRedPerStep
- These sequence groups are run when the timestepper deems that the previous timestep must be re-ran (usually to take a smaller timestep).EndOnly
- These sequence groups are run when the simulation reaches the end normally, i.e. no error termination conditions arise.Restart
- These sequence groups are run when a simulation is being started from the middle of a previously terminated simulation, whether the termination was erroneous or not. One example use case of "non-erroneous" termination would be to continue a previous simulation where the end time was specified too early and you would like to extend the end time without having to re-run from the start.