The macros are organized following a well defined-methodology.
The philosophical change is that rather than having
only macros that write out input file snippets directly, now
there are macros that instead write the snippets into
“accumulation variables”. Then, at the end of the file, a call
is made to finalize()
, which writes out the accumulated
information with the nesting needed for correct interpretation by
Vorpal. A requirement for use of these version 8 macros is that
the input (.pre) file must adhere to some structure, but the
result is a much less constrained structure compared with the
previous macros, which had to be placed in the pre-file in the
location where the substitution was desired.
Here we provide an overview of these depcrecated macros. We will define direct macros to be those that directly write snippets. They can be used just as macros were used before. We define accumulation macros to be those that add snippets to accumulation variables. The latter are often effected by the former, as we shall see. The old macros will be removed in a later version.
Direct Macros Overview: Namespacing and input file structure
All global variables, e.g., the accumulation variables (to be
discussed later), for the new macros start with VPM_
. The
standard macros are not namespaced, but may be namespaced in a
future release. Also, there are variables that are namespaced starting
with TXU_
; for instance, variables that describe units.
With the new macros, the input file has to have a particular structure:
Preamble: Setting of user-defined variables and variables that determine the type of simulation, e.g., electromagnetic versus electrostatic.
Macro file importing.
The user-defined regular and space-time functions.
The ordered macros, i.e., grid and timing.
The unordered macros (for all other dynamics).
Finalization.
The Preamble
The preamble consists of the setting of the variables that one might want to use in the input file. For pre files generated from visual setup, the input file preamble begins with
#######################################################
#
# This PRE file,
# emcartfull.pre,
# was generated from the simulation definition file,
# emcartfull.sdf,
# by the sdf2vpre translator.
# Any changes to this file will be lost if the
# translator is rerun.
#
#######################################################
#######################################################
#
# Ordered blocks
#
#######################################################
#######################################################
# User defined constants and parameters
#######################################################
$ import mathphys
$ WAVELENGTH = 1.00000000000000e-01
$ WIDTH = 3*WAVELENGTH
$ DX = WAVELENGTH/16
$ QWID = 0.5*HALFWIDTH
$ EXPFAC = 0.5/(QWID^2)
$ XeMass = 131.3*PROTMASS
Of course, the comments (anything after the #
) are not processed,
nor are the blank lines. The user has freedom to choose the variable
names provided they do not clash with the names in mathphys.mac, nor do
they begin with VPM_
or TXU_
, which are reserved for distinguishing
variables that are defined for system use. The macro system defines
various boolean variables, so the user should not define variables with
names like True
or FALSE
. Similarly, common math functions and
Python system functions are reserved and should not be used as variable
names. For this reason, users should not assign variable names like cos
,
sqrt
, open
, or float
.
Next follows the basic variables that define the simulation:
#######################################################
# Simulation definition from the basic settings
#######################################################
$ VPM_COORDINATE_SYSTEM = "cartesian"
# cylindrical not found.
$ VPM_NDIM = "3"
$ VPM_PRECISION = "double"
$ VPM_USE_GPU = "False"
$ VPM_SIMULATION_TYPE = "electromagnetic"
# electrostatic not found.
$ VPM_GRID_SPACING = "uniform"
$ VPM_INCLUDE_PARTICLES = "False"
# include particles.estimated max electron density not found.
# include particles.estimated max electron temperature (eV) not found.
$ VPM_TOP_LEVEL_VERBOSITY = VPM_INFO
$ VPM_GRID_TYPE = UniformCartesian
and if VPM_INCLUDE_PARTICLES
is True
, one must also define
$ VPM_MAX_ELECTRON_DENSITY = "1.e18"
$ VPM_MAX_ELECTRON_TEMP_EV = "1.0"
These variables are used later to calculate the time step, if one is not provided, by later macros.
Macro Importing
To obtain that standard macros, the user need import only a single file, VSim,
$ import VSim
This in turn imports all of the standard macro files needed for the simulation of type defined in the preamble. This also initializes all of the accumulation variables, which will be further discussed below. If a user creates custom macro files, they should be imported after the above statement. For example,
$ import mymacrofile
User-defined regular and space-time functions.
The user defines regular and space-time functions in this part of the file in the regular way. Examples are shown below.
#######################################################
# User defined functions
#######################################################
<function SomeFunc(x,y)>
cos(x)*sin(y)
</function>
#######################################################
# User defined space-time functions
#######################################################
$ Jz = exp(-EXPFAC*(y^2+z^2))*sin(OMEGA*t)
The Ordered Macro Calls
There are only two ordered macro calls. Each must be preceded by the definition of some global variables. The grid macro call comes first and has the form,
#######################################################
# Translation of grid
#######################################################
$ VPM_BGN0 = 0 * TXU_METERS
$ VPM_BGN1 = NEGHW * TXU_METERS
$ VPM_BGN2 = NEGHW * TXU_METERS
$ VPM_L0 = $LENGTH - 0$ * TXU_METERS
$ VPM_L1 = $HALFWIDTH - NEGHW$ * TXU_METERS
$ VPM_L2 = $HALFWIDTH - NEGHW$ * TXU_METERS
$ VPM_N0 = NX
$ VPM_N1 = NPERP
$ VPM_N2 = NPERP
$ VPM_PERIODIC_DIRS = []
setGridData(VPM_NDIM, VPM_GRID_TYPE)
with the following definitions
VPM_BGN0: The start of the grid in the first coordinate.
VPM_BGN1: The start of the grid in the second coordinate.
VPM_BGN2: The start of the grid in the third coordinate.
VPM_L0: The extent of the grid in the first coordinate.
VPM_L1: The extent of the grid in the second coordinate.
VPM_L2: The extent of the grid in the third coordinate.
VPM_N0: The number of cells in the first direction.
VPM_N1: The number of cells in the second direction.
VPM_N2: The number of cells in the third direction.
- VPM_PERIODIC_DIRS: An array listing the coordinate directions in
which one has periodic boundary conditions.
Following that is the timing setup, which has the form,
#######################################################
# Translation of the time group
#######################################################
$ VPM_DT = "0.0"
$ VPM_CFL_NUMBER = "0.95"
$ VPM_NSTEPS = 100
$ VPM_DUMP_PERIOD = 20
setTimingData()
- VPM_DT: The time step for the simulation. If it is set to zero,
the setTimingData macro will provide a best guess.
- VPM_CFL_NUMBER: This is used when VPM_DT is set to zero.
The time step is set to this factor times the maximum known stable time step.
VPM_NSTEPS: The number of time steps for the simulation.
VPM_DUMP_PERIOD: The number of time steps between each data dump.
The Unordered Macro Calls
With the new version-8 macros, one can now call the accumulation macros in any order. For example, one can add boundary conditions via
addBoundaryLauncher(boundaryLauncher0, ElectricField, 0.0, None, 0.0, upperY)
addMalBoundary(mal0, emField, lowerY, MALWID)
addOpenBoundary(open0, emField, upperX)
and one can add particle species, sinks and loaders with
addParticleSpecies(Xenon, 1.602176487e-19, XeMass, relBoris, variableWeights, 1.e18, 5.0, None)
addParticleSpeciesSink(absorbAndSave0, electrons0, absAndSav, lowerX)
addParticleSpeciesLoader(particleLoader0, xvLoaderEmitter, electrons0, 0.00000000000000e+00, 0.00000000000000e+00, relativeDensity, 1.0, grid, beamVelocityGen, [0.00000000000000e+00, 0.00000000000000e+00, 0.00000000000000e+00],[5.00000000000000e+06, 5.00000000000000e+06, 5.00000000000000e+06], [-0.5, -0.5, -0.5], [0.5, 0.5, 0.5])
addParticleSpecies(electrons0, ELECCHARGE, ELECMASS, relBoris, variableWeights, 1.e18, 5.0, None)
From the above one can see that the order is independent, as the species,
electrons0
, is added after its loaders and sinks. However, if a loader
or sink is added for a species that ultimately is not added, no such species
shows up in the simulation.
Finalization
Finalization consists of a single line,
$ finalize()
This macro takes all of the accumulated descriptions of the simulation, held in the accumulation variables, and writes it into the file with correct ordering and nesting.
Version 8 Macros Methodology
The basic units of the new macro system are the direct macros. An example of one from solvers.mac is
# Add the base solver block to an accumulation variable.
# @param name the accumulation variable
# @param krySize the Krylov subspace size (for gmres)
# @param orthogType the orthogonality type for the Krylov subspace (for gmres
<macro writeBaseSolverBlock(name, krySize, orthogType)>
<BaseSolver myBS>
kind = name
$ if isEqualString(name, generalized minimal residual solver)
kspace = krySize
orthog = orthogType
$ endif
</BaseSolver>
</macro>
Like all macros, this macro has basic documentation in the macros
file, giving the macro name along with any parameters. In
this case the macro directly writes an input file fragment, hence
its name. Direct macros can be used just like any of the
traditional macros, where the user controls the file structure, and
the user knows where to place this macro call for the desired
effect. Because all direct macros directly write, their names
begin with write
.
The above is actually an independent direct macro in that it can be used at any place in the file (though it may not make sense in any place). In particular, it need not be preceded with any other macros that set any accumulation variables, which we now turn to.
However, for deferred writing to allow the system to get the order of the macros correct, instead of writing directly, we accumulate these blocks in accumulation variables using accumulation macros, and then we write those out at finalization time. An example of an accumulation macro is
# Add the base solver block to the accumulation variable, VPM_MATRIX_SOLVER.
# Used for iterative solvers, such as gmres.
# @param name the name of the base solver block
# @param krySize the Krylov subspace size (for gmres)
# @param orthog the orthogonality type for the Krylov subspace (for gmres)
<macro addBaseSolver(name, krySize, orthog)>
$ requires VPM_MATRIX_SOLVER
$ VPM_MATRIX_SOLVER = appendToBlock(VPM_MATRIX_SOLVER, writeBaseSolverBlock(name, krySize, orthog) )
$ global VPM_MATRIX_SOLVER
</macro>
This macro counts on there being a global accumulation variable, VPM_MATRIX_SOLVER, which is defined in solvers.mac. It is important to initialize accumulation variables to an empty string prior to accumulating input file lines into them. Thus, the definition of an accumulation variable should be of the form,
$ VPM_MATRIX_SOLVER = ""
Accumulation into a variable appends to that variable the output
of the previous macro, e.g. writeBaseSolverBlock(...)
. With
this device, we now have the base solver stored in the variable
VPM_MATRIX_SOLVER, and we can write that variable out where
it is needed.
For example, to write out a linear solver, one calls the dependent direct macro,
# Write the interative poisson solver block. When used, it must come
# after addBaseSolver and addPreconditioner, as it writes the accumulation
# variables for the base solver and the preconditioner.
# @param maxIt the maximum number of iterations allowed.
# @param tol the tolerance for the solution
# @param met the metric for convergence, e.g., L1, L2
# Verbosity set to same as top level verbosity
<macro writePoissonSolverIterativeBlock(maxIt, tol, met)>
$ requires VPM_TOP_LEVEL_VERBOSITY
<LinearSolver linearSolver>
kind = iterativeSolver
verbosity = VPM_TOP_LEVEL_VERBOSITY
maxIterations = maxIt
tolerance = tol
metric = met
VPM_MATRIX_SOLVER
VPM_PRE_CONDITIONER
</LinearSolver>
</macro>
This is called dependent because it relies on previous macro calls to have defined VPM_MATRIX_SOLVER and VPM_PRE_CONDITIONER. This writes (and so is a direct macro) a linear solver block, which can be used inside a multifield block. A user may use this macro just like any of the pre-version-8 macros, provided that the variables, VPM_MATRIX_SOLVER and VPM_PRE_CONDITIONER have been appropriately initialized.
In the application to multifields, one has at least the updaters,
the update steps, and the update step order. The above macro
would be used to write an update step. It is accumulated in the
variable, VPM_ES_SOLVER_UPDATERS, which is finally
written into the multifield block during the call to
finalize()
.
Version 8 Macro Files Organization
There are three sections in a macro file for (1) public macros, (2) global (including accumulation) variables, and (3) private macros. When working in the visual setup, the problem description is written out in an xml-like format that the translator translates to macro calls that are then processed to produce input file lines. Because most users only ever see these macro calls, they come first in the macro file. After those macro calls, the file defines the accumulation variables and then the other macros.
Public Macros
These are the macros currently written by the translator plus a few more, so they are sometimes called translator macros. They can be order dependent. For example, the macros calls for defining an iterative solver must occur as
addBaseSolver(bicgstab)
addPreconditioner(multigrid, SA, 30, GaussSeidel, 3, before, Jacobi, 1.33300000000000e+00, 0.00000000000000e+00, increasing)
# This writes preconditioner, so it must be last.
addPoissonSolver(relPerm, 1000, 1.00000000000000e-08, r0)
Global (including accumulation) Variables
These are the variables into which one accumulates blocks for later printing in the correct order. All variables are namespaced with VPMT_, VPM_ or TXU_ so that the user can confidently use names that are not namespaced with VPMT_, VPM_, or TXU_ provided they also avoid the names in mathphys.mac.
There is no guarantee that these variables will not change with future versions.
Private Macros
The translator macros make use of many other macros to accumulate blocks. These other macros take many forms: direct macros, utility macros, string manipulation, and so forth. These macros are not guaranteed to be stable between versions unless they appear in the documentation.
Top Level Macro Files
The top-level macro files are VSim.mac, VSimEm.mac, and VSimEs.mac. These control which other macro files are included, provide some universally used macros, and define the basic accumulation variables. In particular, if VPM_SIMULATION_TYPE equals Electromagnetic, then VSimEm.mac is loaded and it loads the macro files needed for electromagnetic simulations. If VPM_SIMULATION_TYPE equals Electrostatic, then VSimEs.mac is loaded and it loads the macro files needed for electrostatic simulations. Subsequently, VSim.mac loads the macro files for particles, fluids, collisions, etc., depending on what the preamble requested.
Remaining Macro Files
The remaining macro files are organized by functionality. For example, electrostatic boundary condition macros are in esbcs.mac. The particle macros are in particles.mac. When following the standard organization decribed above, the accumulation variables for any macros in a macro file are defined and initialized in either that file or in a previously loaded file.