As with all such things, PANACEA was not created in a vacuum and owes a debt of thanks to many people who contributed in many different ways to its evolution. There are many more than can be mentioned in this short space, and the ones who are singled out are not mentioned in any particular order.
1.0
Introduction
A numerical simulation code is fundamentally a device to solve an initial value problem. Very often these programs are written starting with the routines that solve some system of equations. Unless care is taken to formulate these routines with regard to a host of issues (e.g., data flow), it can be very awkward to set up a problem or to look at the answers that the code returns. Furthermore, it can be nearly impossible to take advantage of some of the excellent work that various groups have done (e.g., equation solver packages) because the data flow and structuring issues have not been given sufficient attention in the program design stages.
2.0 The PANACEA Model
This section discusses the motivation for and offers an explanation of the PANACEA model. It summarizes the services that PANACEA provides and examines some related code issues.
2.1 Sequence of States
An initial value problem can be viewed as a machine (some system of equations) and an initial state. The initial state is evolved to a final state by the machine. When the system of equations is solved numerically, the evolution of states by the machine is represented as a discrete sequence of states.
In this view, there are three broad phases to a numerical simulation. First, the initial state must be generated. Second, the numerical machine must evolve each state into its successor state until this cycle is terminated according to some criterion. Last, some or all of the information that represents the states of the system must be organized for visualization. The last two phases often occur simultaneously. For example, in a time plot of some physical variable in the simulation, the information for the plot must be gathered up in the course of the entire simulation and viewed at the end.
2.2 Simulation Packages
Many of the most complex simulation programs are broken down into parts that solve some subset of the system of equations in the simulation. For example, some codes have a thermal conduction package that is a separately callable module. The reasons are fourfold: ease of control (packages can be switched on and off); simplified design and maintenance; multiple packages solving the same subset of equations (algorithmic testing or problem domain differences); or code recycling. def_system()
{PA_run_time_package(global, NULL, NULL, def_global,
cont_global, init_vars, global_entry,
B_build_pseudo_mapping, NULL, NULL);
PA_run_time_package(hydrodynamics, NULL, NULL,
def_hydro, cont_hydro, init_hydro,
hydro, B_build_pseudo_mapping,
NULL, NULL);
PA_run_time_package(materials, NULL, NULL,
def_mat, cont_mat, mat_init,
mat, B_build_pseudo_mapping,
NULL, NULL);
return;}
/* B.C - the main simulation code of the ABC system */
#include b.h
/* MAIN - read the restart dump and run the physics loop */
main(c, v)
int c;
char **v;
{char *fname;
/* define the code system by setting up the packages */
def_system();
PA_build_domain_hook = B_build_domain;
PA_build_mapping_hook = B_build_mapping;
/* read the restart file */
if (fname != NULL)
{PA_rd_restart(fname, NONE);
name[2] = SC_strsave(fname);};
/* perform initialization */
PA_init_system(param[1], (param[3] - param[2])*param[4],
swtch[3], name[3], name[4], name[5]);
/* run the simulation */
PA_simulate(param[1], swtch[3], N_zones, param[2], param[3],
param[4], param[5], param[6], param[7],
name[2], name[3], name[4], name[5]);
/* write a restart dump before ending */
PA_wr_restart(name[2]);
exit(0);}
2.3 Simulation Variables
The complement to the simulation package is the simulation variable. Each package has three categories of variables: input variables, which are provided to the package by other packages; internal variables, which are neither imported into the package nor exported from it; and output variables, which are provided by the package for use by other packages.2.4 Physical Units
PANACEA maintains three systems of units: external, internal, and cgs. The end user specifies input quantities in external units and output quantities are given in external units. Internal units are those in which the simulation routines deal. This was done to give code developers the opportunity to debug in units that make sense to them while letting the end users deal in a system of units that is natural to the problems being run. A complete set of fundamental constants and many derived physical constants are maintained by PANACEA in cgs units originally. PANACEA handles all data conversions in an efficient and transparent way, though each variable must have its units defined so that conversions can be done. The conversions cannot work if there are any numerical constants that have physical units in a PANACEA code. For example, writing 2.99e10 for the speed of light in an expression is illegal (although PANACEA does nothing to enforce it). The PANACEA provided constant, c, must be used instead. /* DEF_HYDRO - define the hydrodynamics package data base */
def_hydro(pck)
PA_package *pck;
{int *P_zones;
P_zones = &swtch[4];
/* RESTART VARIABLES */
PA_def_var(n, SC_DOUBLE_S, NULL, NULL,
SCOPE, RESTART, CLASS, REQU, CENTER, Z_CENT, ATTRIBUTE
P_zones, DIMENSION, PER, CC, UNITS);
PA_def_var(P, SC_DOUBLE_S, NULL, NULL,
SCOPE, RESTART, CLASS, REQU, CENTER, Z_CENT, ATTRIBUTE
P_zones, DIMENSION, ERG, PER, CC, UNITS);
PA_def_var(rho, SC_DOUBLE_S, NULL, NULL,
SCOPE, RESTART, CLASS, REQU, CENTER, Z_CENT, ATTRIBUTE
P_zones, DIMENSION, G, PER, CC, UNITS);
/* RUNTIME VARIABLES */
PA_def_var(Rpdv, SC_DOUBLE_S, NULL, NULL,
CENTER, Z_CENT, ATTRIBUTE,
P_zones, DIMENSION, EV, PER, SEC, UNITS);
PA_def_var(Rqdv, SC_DOUBLE_S, NULL, NULL,
CENTER, Z_CENT, ATTRIBUTE,
P_zones, DIMENSION, EV, PER, SEC, UNITS);
PA_def_var(vol, SC_DOUBLE_S, NULL, NULL,
CENTER, Z_CENT, ATTRIBUTE,
P_zones, DIMENSION, CC, UNITS);
PA_def_var(mass-z, SC_DOUBLE_S, NULL, NULL,
CENTER, Z_CENT, ATTRIBUTE,
P_zones, DIMENSION, G, UNITS);
/* EDIT VARIABLES */
PA_def_var(Q, SC_DOUBLE_S, NULL, NULL,
SCOPE, EDIT, CLASS, REQU, CENTER, Z_CENT, ATTRIBUTE,
P_zones, DIMENSION, ERG, PER, CC, UNITS);
return;}
This efficiency offers three benefits. First, by requiring constants to be expressed in terms of physical constants and dimensionless numbers, a code system avoids certain arithmetic errors and is more self-documenting. Second, an extra level of consistency is built into simulation codes. I have found bugs in simulation packages by running a problem in two different systems of internal units. Such simulations should produce the same result, but various inconsistencies between packages can easily result in different answers. The third benefit is that without such a mechanism simulation packages in general would not be sharable! By carrying their system of units around in physical terms, packages can be moved around among simulations codes without regard to the way the original developer thought about units.2.5 Data Flow
With the three phase model in mind, the PANACEA model manages the data flow throughout a simulation as follows: the generator reads in ASCII and binary information to define the initial state, which is written as a binary file; the simulation phase code reads state files and source files, communicates with itself by writing state files, and communicates with the post-processor by writing dumps targeted for it; and the post-processor reads only the post-processor dumps and writes out files for target visualization systems.2.6 Generation of Initial State
The procedure for using PANACEA to build a program to generate initial states for a simulation is described in this section. For sake of example, the generator program will be referred to as A. As with all PANACEA codes the simulation packages are the focus of attention.
The class of a variable refers to whether it is required to be in the state file, whether it is optional in the state file, or whether it should be read from the state file only when specifically requested. The first two classes are read in whenever a state file is read. The last one only brings in the data when specifically accessed with PA_CONNECT.
Pointers to the size (number of elements and shape) information are necessary because, at the time the variables are defined, there is no problem definition to give values to these numbers. Therefore, PANACEA is given pointers to the locations where that information will be stored when a problem is generated or read in from a state file.
PANACEA provides a routine to install the code developers generator routines in the command hash table. Thus, in addition to the routines to process the input, a function to install these routines in the command table must be provided. This routine is one of the defining routines for a PANACEA package (see Figure 4).
Install commands for the global package. These form part of the initial value problem generator, A.
/* GLOBAL_CMMNDS - install the commands for the global package */
global_cmmnds()
{N_parts = 0;
PA_inst_c(make, NULL, FALSE, 0, make_mesh, PA_zargs, commands);
PA_inst_c(clear, NULL, FALSE, 0, clearh, PA_zargs, commands);
PA_inst_c(part, NULL, FALSE, 0, parth, PA_zargs, commands);
PA_inst_c(side, NULL, FALSE, 0, sideh, PA_zargs, commands);
/* named switches, parameters, and names */
PA_inst_c(start-time, param, SC_DOUBLE_I, 2, PA_pshand,
PA_sargs, commands);
PA_inst_c(stop-time, param, SC_DOUBLE_I, 3, PA_pshand,
PA_sargs, commands);
return;}
A PANACEA package provides for three arrays: one array of integers called switches; one array of doubles called parameters; and one array of strings called names, which the developer may wish to use to control a packages operation. For example, a number of sub-iterations or a multiplier on some process might be managed by PANACEA on behalf of the code developer (i.e., the database manager overhead can be reduced by managing arrays rather than large numbers of scalars). The code developer can use this facility by providing a routine that specifies how many switches, parameters, and names are required for a given package and specifies their default values. PANACEA itself provides routines to handle input commands to set values for these quantities (collectively referred to as controls). In fact, PANACEA even provides the developer with the option of referring to the controls by names (at least from the generator input see Figure 4). The routine that defines the controls is one of the package defining routines (see Figure 5).
The normal execution sequence for a PANACEA generator follows:
/* CONT_HYDRO - set the hydrodynamics package controls */
cont_hydro(pck)
PA_package *pck;
{static int n_names = 2, n_params = 15, n_swtches = 10;
PA_mk_control(pck, hydrodynamics, n_names, n_params, n_swtches);
swtch[1] = TRUE; /* hydro switch */
swtch[2] = 0;
swtch[3] = 0;
swtch[4] = global_swtch[12];
swtch[5] = 0;
swtch[6] = 1;
swtch[7] = 0;
param[1] = 0.2;
param[2] = 2.0;
param[3] = 1.0;
param[4] = 1.5;
param[5] = 0.2;
param[6] = 0.2;
param[7] = 0.2;
param[8] = 1.0;
param[9] = 0.0;
param[10] = 1.0;
param[11] = 3.0/2.0;
param[12] = 1.0e-6;
param[13] = 0.1;
param[14] = 2.0;
param[15] = 1.0;
return;}
The last step is carried out by PANACEA alone. The step in which the variables are interned in the database requires a routine supplied by the developer to make PANACEA calls that associate local or global variables with entries in the database. This is the final defining routine for a package in the generation phase (see Figure 6).
Intern the variables for the hydrodynamics package. This is a function defined for the initial value problem generator, A, by the hydrodynamics package.
/* INTERN_HYDRO - INTERN the variables of the hydrodynamics package
* - prior to writing the initial restart dump
*/
intern_hydro()
{swtch[2] = global_swtch[1];
swtch[3] = global_swtch[2];
swtch[4] = global_swtch[12];
param[12] *= (global_param[3] - global_param[2]);
param[13] *= (global_param[3] - global_param[2]);
PA_INTERN(n, n, double);
PA_INTERN(p, P, double);
PA_INTERN(rho, rho, double);
return;}
Finally, to build a PANACEA generator, the code developer writes a driver module that issues calls to PANACEA to define the packages given the functions discussed above, to process command line arguments, and to hand control of the input reading process to PANACEA. All further action is controlled by PANACEA and the information in the input stream, i.e., reviewing information, writing the initial state file, and exiting. This driver is compiled and loaded with the package libraries, the PANACEA library, and some other lower level libraries such as PDBLib.
In practice, the first place to start is the global package. If the simulation code has a computational mesh, the routines to translate a collection of user specifications into a representation appropriate for the simulation routines should reside here. Controls that specify how many cycles to run, that keep the names of file families, etc. go in the global package. In addition, routines for direct visualization of the initial state before writing a state file might be most logically included in the global package.
This process would be repeated for each package of the simulation until a complete generator code was specified. It is important to remember that PANACEA attempts to make limited assumptions about what the code developer wants to do - a necessity to have some structure specifying a framework on which to hang simulation packages. It is best to keep in mind a picture of fundamental processes of data flow and management and computational flow control, i.e., to think about what has to be happening to get a generation code to work properly.
Once the database has been read in from the state file, PANACEA alone has access to the variables in the database. In order to gain access to the data, the code developer must issue calls to connect local or global code variables to the information in the database. Even though the database is hash driven and is therefore quite efficient, PANACEA overhead can be reduced by connecting to package variables once and leaving those connections intact for the entire simulation run. This is not required, but it is very convenient and efficient. The code developer can supply a routine in which all of these connections are made on a package-by-package basis, i.e., one routine per package. These routines are defining routines for the packages. PANACEA will execute each of these packages once per simulation run before the main simulation routines are called (see Figure 7).
Most PANACEA packages have a main entry point which is where the real simulation work occurs. The main entry point is probably the routine which is most often the starting point when a code developer sets out to write a new simulation package. Typically, the main entry point it designed to be executed once per major computational cycle. From PANACEAs point of view it is both an easy point to control and a natural point to monitor the performance and resource usage of a package. Figure 8 illustrates a main entry point routine.
PANACEA packages also include slots for routines to handle special purpose I/O and routines to run after the main simulations routines have been called for the last time in a run. The code developer can provide them if necessary and supply them to the call which defines the package to the simulation code.
PANACEA provides a service to sequentially execute the main simulation routines until a certain time has elapsed. Many variations on such a service are possible and the code developer does not have to use the ones PANACEA provides. Given the list of packages, the code developer can manipulate them in whatever fashion is appropriate to the problem at hand (see Figure 2).
Initialize the hydrodynamics package. Note that this is one of the functions installed as part of the definition of the hydrodynamics package in Figure 1.
/* INIT_HYDRO - initialize and allocate hydro variables once */
init_hydro(pck)
PA_package *pck;
{int i, j;
/* PA_CONNECT global zonal variables */
PA_CONNECT(rho, rho, double *, TRUE);
PA_CONNECT(n, n, double *, TRUE);
PA_CONNECT(p, P, double *, TRUE);
PA_CONNECT(massz, mass-z, double *, TRUE);
PA_CONNECT(t, T, double *, TRUE);
PA_CONNECT(ab, A-bar, double *, TRUE);
PA_CONNECT(zb, Z-bar, double *, TRUE);};
/* allocate local zonal variables */
cs = MAKE_N(double, N_zones);
dtvg = MAKE_N(double, N_zones);
pdv = MAKE_N(double, N_zones);
qdv = MAKE_N(double, N_zones);
voln = MAKE_N(double, N_zones);
volo = MAKE_N(double, N_zones);
/* set some scalars */
csmin = param[9];
hgamma = 1.0 + 1.0/(param[11] + SMALL);
/* initialize some zonal arrays */
for (j = frz; j <= lrz; j++)
{volo[j] = vol[j];
massz[j] = rho[j]*vol[j];};
return;}The main entry point for a PANACEA package. Note that this is one of the functions installed as part of the definition of the hydrodynamics package in Figure 1.
/* HYDRO - the main hydro entry point */
hydro(pck)
PA_package *pck;
{int hyd_z;
double hyd_dt;
static int first = TRUE;
/* check that this package was requested */
if (swtch[1] == FALSE)
return;
if (first)
pck->space = (double) Ssp_alloc;
PA_MARK_TIME;
init_cycle();
/* do the real hydro work */
hydro_wrk(&hyd_dt, &hyd_z);
/* record the hydro timestep vote */
pck->dt = hyd_dt;
pck->dt_zone = hyd_z;
PA_ACCM_TIME(pck->time);
if (first)
{pck->space = (double) Ssp_alloc - pck->space;
first = FALSE;};
return;}
To help with the monitoring of performance, each package has slots to record the CPU time spent in the package and the total memory required by the package. The latter is most useful when memory is being managed dynamically. PANACEA will print out statistics for each of the packages at the end of a run. In practice, this tends to be very useful information when algorithmic optimization is being pursued or when obscure behavior is suggesting memory bugs. See Figure 8.
There are two basic kinds of data flow out of the simulation code. First, at each cycle, the data that is completed in a cycle must be written out according to user requests. Second, information that is accumulated across more than one cycle must be addressed.
The snapshot requests (complete in one cycle) can be put out either directly for the visualization system or into some intermediate form for subsequent processing. In the PANACEA model, output data are not kept in the state of the running code. In fact, PANACEA services are aimed at transferring the data from the code to data files as efficiently as possible. The main advantage of this scheme is that the task of visualization can be done on a different machine while the simulation progresses if data is put out every cycle. A second advantage is that the running code does not grow as a result of the stored output data.
The output whose meaning comes from the results of several computational cycles (generically referred to as time plots) is handled differently. PANACEA dumps the information computed in each cycle out into an intermediate file family at the end of the cycle. After the simulation is complete a separate post-processing code transposes the information and writes it in the desired format. This process naturally involves the code developer to a greater extent than the generation process, given that input parsing is ASCII based whereas visualization systems have a variety of input mechanisms.
The PACT tool, PDBView, has facilities to display the snapshot files generated by PANACEA. PANACEA has support for post processor codes to emit files for ULTRA II, the PACT utility for presentation, analysis, and manipulation of 1D data sets. Typically these are time plots since the snapshot mechanism covers most other cases.
Sample PANACEA plot request specifications. All of the range and domain variables are in the database.
graph {vx,vy}(t=step(0.0;1.0e2;20.0),rx,ry) A vector plot with components rho and n every 20.0 time units from 0 to 100.0 over the entire mesh.
graph {rho,n}(t=step(0.0;1.0e2;20.0),rx,ry) The radiation field at time 50.0 and frequency 1000.0 over the entire mesh. This could be rendered as a contour plot, a surface plot, a wire-frame plot, or an image plot.
graph jnu(t=50.0,rx,ry,nu=1000.0) The variable, p, at every time over the entire mesh.
graph p(t,rx,ry) PANACEA has very powerful and general mechanisms for plotting data from the database. These mechanisms translate output requests into data for a visualization system (see Figure 9).
PANACEA provides a set of services to manage source or boundary value data. The characterization of the data is specified in the input phase. The characterization may include information as to where or when the source is to be applied, a file from which to read the data, etc. During the simulation phase, the source data is interpolated by PANACEA and handed to simulation routines upon request.
To make this process as efficient as possible, when source data is so voluminous as to require data files to contain it reasonably, it is prepared in advance in the form of PDB files. The self-describing nature of these files and variable database of PANACEA make it easy to code and efficient at run time. PANACEA provides routines to facilitate the writing of a code to gather source information from whatever sources the code developer has and to produce the required PDB source files. The further advantage of this approach is that many simulation runs can be done (and typically are) with one set of source information that does not change. Having the PDB files separate makes this fast and convenient.
The source variable notion is very natural from the data generation and specification point of view. However, from the point of view of the algorithms, additional issues concern initial or boundary value data. Often this data is not directly part of the variable database (perhaps because it is applied to the boundaries of one of the database variables). PANACEA distinguishes between initial or boundary value data and source data. It treats source data as a separate sub-class of initial value data. In particular, source data usually involves information coming in over many computational cycles, and it may require interpolation with respect to time. It also may involve large quantities of data that are most conveniently kept in files (PDB files actually). PANACEA services make as much of this transparent to the developer as possible.
PANACEA services gather up specifications, doing some processing when appropriate, and hold that information for the simulation on demand. These services also interpolate temporal data to the correct time in a simulation. Even though PANACEA makes a distinction between sources and initial value data, it gathers them in the same fashion (see Figure 10).
Some examples of source and initial value specifications in PANACEA.
specify bc boundary-pressure from press.dat Set a boundary condition tagged as constant-vx. The hydrodynamics package will look for constant-vx specifications and take the given values as the place to apply it.
specify bc constant-vx 1 1 1 5 Impose a profile on the source variable tagged as temperature-floor. The relevant package looks for a source variable tagged this way. It will interpret (with PANACEAs help) and interpolate the time, value pairs.
specify src temperature-floor s 0.0 50.0 s 0.3 100.0 s 0.5 300.0 s 0.8 400.0 s 1.0 500.0 Variables defined in the PANACEA database can be directly controlled by source variables. In this case, the variable rho would be interpolated from the source file rho.dat instead of being computed by a hydrodynamics package.
specify rho from rho.dat Typically, a PANACEA simulation code system will have a program to build source files for simulation runs. PANACEA has the routines to do the generic work here. It helps to map ASCII (or other) data files that are derived from experiments or other simulations into the database of the simulation code system. The developer provides the routines with specific information about the input data; the PANACEA services package it in a form that is most efficient for the simulation code to use.
One additional set of structures (provided by an associated math library called PML, Portable Mathematics Library) is important for its ability to tie some key aspects of data flow together. In attempting to deal with data that are generated from a specification that is natural for the end user, computed within a form natural to numerical algorithms, stored in intermediate data files or transmitted over networks, and finally visualized in yet a different form, it was important to formulate a description of data that is self-consistent and mathematically precise. In this way, data sets could be assembled, passed among computational routines, stored, and visualized all in a relatively efficient and general way. This description had to be general enough to deal with multidimensional data with a variety of properties.
The key concepts are those of sets and mappings. Mathematically, for the purposes of both computation and visualization, one is interested in working with mappings of domain sets to range sets. A set consists of a collection of data items along with information describing the type of elements, the dimensionality of the set, the dimensionality of the elements, the topology of the set, the metric information, etc. Ideally, the set structure contains sufficient information to allow routines to process them without additional specifications. For example, a set might be a collection of 3-vectors on a 2-sphere or a simple 1-D array.
Sets can be related by mappings that describe how elements of two sets are related. The mapping structure contains a domain set, a range set, some information about extremes of both sets, and other descriptive information (e.g., relative centering). Ideally, a differentiation routine could be handed a mapping whose properties it understands and return a new mapping representing the gradient of the argument mapping. The goal is to objectify a complete collection of information for the purposes of storage and computation.
A third layer of structure combines a mapping with rendering specifications that make it possible to visualize the data set embodied in the mapping. This structure is referred to as a graph, and it provides a means of associating mathematically complete data sets (i.e. mappings) with information describing how they are to be displayed. For example, a mapping with a two-dimensional domain and a one-dimensional range could be rendered as a contour plot, a wire frame mesh plot, a surface plot, or an image plot. These rendering techniques all take the same fundamental data, embodied in the mapping structure (see Figure 9).
Although coded in C, PANACEA is coded in an object-oriented style. The most important ramification of this is that abstract objects (e.g., packages, variables, and mappings) have a relatively faithful concrete representation. This puts PANACEA on a sound conceptual basis and helps to delineate the generic from the specific in simulation code systems.
As an additional benefit, the modularization that follows from this style lends itself to natural coarse-grained parallelization of code systems. In practice, packages can also be organized so as to make fine grained parallelization possible because the controlling structures and the data objects of PANACEA do not really intrude into the detailed workings of the simulation algorithms. Therefore, while PANACEA helps modularize a code system so that packages or large parts of packages might be run in parallel, it does not interfere with parallelizing individual routines which permit it.
The encapsulation of abstract objects in concrete representations facilitates the process of manipulating these objects symbolically. I have used PANACEA with the PACT SCHEME interpreter to give users of one PANACEA code the ability to manipulate the code in very broad and general ways.
This technique allows the manipulation of the packages execution sequences, the examination of the state of the running code, and the changes in the state of the code. When carried to its logical conclusion, this method will also permit the prototyping of algorithms at the LISP level before investing the effort in writing more efficient code at a lower level.
Finally, PANACEA can bind simulation packages generated by a tool, such as ALPAL, into entire code systems. PANACEA complements ALPAL very neatly by attending to large control and data flow issues, while ALPAL uses the PANACEA services rather than getting loaded down with these issues.
The functions that an application supplies are:
gencmd() define the generator commands
dfstrc(pdrs) define data structures used in package variables
intrn() intern variables into the database at generation
defun(pck) define new units
defvar(pck) define the package variables
defcnt(pck) define the package controls
inizer(pck) initialize the package
main(pck) the main entry into the package
ppsor(pr, t) handle package specific output
finzer(pck) close out the package
All of these functions except ppsor must return 1 if they complete successfully and 0 otherwise.
3.2 Variables
A PANACEA variable consists of a collection of descriptive information and the actual data associated with a computational quantity used in a numerical simulation. PANACEA variables can be scalars or arrays. They correspond to what code developers traditionally think of as variables in systems of equations. In addition they include information which governs their use. This information is collectively referred to as the attributes of the variable.3.2.1
Variable Scopes
DEFN
RESTART
DMND
RUNTIME
EDIT
3.2.1.1
DEFN
3.2.1.2
RESTART
3.2.1.3
DMND
3.2.1.4
RUNTIME
3.2.1.5
EDIT
3.2.2
Variable Classes
REQU
OPTL
PSEUDO
3.2.2.1
REQU
3.2.2.2
OPTL
PANACEA variables with the OPTL class can be thought of as optional. In contrast to REQU variables, PANACEA returns a NULL pointer if the data cannot be found for the variable (by the same procedure as for the REQU variables) instead of terminating with a fatal error.3.2.2.3 PSEUDO
In some simulations auxiliary variables which can be thought of logically as arrays are implemented as scalars or subsets of other arrays. Ordinarily this is no concern of PANACEA. However, when it is desired to put such data out into post processor files, PANACEA attempts to assist. The generic descriptive information that PANACEA requires of all variables is insufficient to specify how to construct the logical array structure desired in the output files from the actual information as implemented in the simulation coding. The application package will have to supply routines to accomplish this mapping. The PSEUDO class tells PANACEA to handle such a variable in a special way which requires more coordination with the particular package. The PSEUDO class is currently only meaningful in connection with variables of EDIT scope.3.2.3
Variable Persistence
Another attribute is that of variable persistence. This specifies the actions PANACEA is to take in the PA_DISCONNECT process. The defined persistence categories are:
KEEP
CACHE_F
CACHE_R
REL
3.2.3.1
KEEP
In many situations the application developer wants to relinquish the applications access to a PANACEA variables data yet insure that PANACEA retains the data in memory. This allows for rapid re-connections later via PA_CONNECT.
3.2.3.2
CACHE_F
For larger data arrays, the application may not wish to have access to the data for part of the simulation, not wish PANACEA to retain it in memory either, and still require the data at a later point in the simulation. The CACHE_F persistence tells PANACEA to write the data out to a temporary scratch file and release its own copy from memory. It also tells PANACEA that the variable will never have its size changed via PA_change_dim or PA_change_length.
3.2.3.3
CACHE_R
For larger data arrays, the application may not wish to have access to the data for part of the simulation, not wish PANACEA to retain it in memory either, and still require the data at a later point in the simulation. The CACHE_R persistence tells PANACEA to write the data out to a temporary scratch file and release its own copy from memory. Unlike CACHE_F, CACHE_R variables can be resized. The distinction is enforced for the sake of execution and disk space efficiency.3.2.3.4
REL
Perhaps the most common situation for RUNTIME variables when the data is not going to be used and the application invokes PA_DISCONNECT is for PANACEA to release the memory associated with the PANACEA variable data altogether. It is not retained in any way and would have to be recreated if a PA_CONNECT call were to be made at a later point in the simulation.
The following table summarizes the interaction between scope, class, and persistence:
SCOPE CLASS PERSISTENCE
REQU OPTL PSEUDO KEEP CACHE _X REL
DEFN + - - - - -
RESTART + + - + + +
DMND + + - + + +
RUNTIME + + - + + +
EDIT - - + NA NA NA
3.2.4
Variable Centering
PANACEA variables which are not scalar variables as defined by PA_inst_scalar also have an attribute specifying their centering relative to the spatial mesh. (NOTE: this concept will be properly generalized in future releases of PANACEA).
Z_CENT zone centered
N_CENT node centered
E_CENT edge centered
F_CENT face centered
U_CENT uncentered
3.2.5
Variable Allocation
PANACEA can handle either of two situations on a variable by variable basis. One, memory is to be dynamically allocated and managed by the PANACEA database services. Two, memory is statically allocated by a compiler and the PANACEA database services hand out pointers to such spaces.
STATIC static allocation (i.e. by compiler)
DYNAMIC dynamic allocation (i.e. by run time memory manager)
3.3 Source Variables
3.4 Initial Value Specifications
3.5 Plot Requests
3.6 Unit Specifications
4.0 The PANACEA C API
The following commands are broken down by service category. The PANACEA service categories are:4.1 Database Definition and Control Functionality
This group of functions governs the creation and management of the PANACEA database. They are relevant to both the generator and simulation codes.
Optional Functions PA_current_package
4.1.1
PA_CURRENT_PACKAGE
PA_current_package()
At any moment in a generator or simulation code, PANACEA has a notion of the current package. It is the one whose controls are connected to the global variables, swtch, param, and name. Applications may wish to query or access the current package.
This function returns a pointer to the PA_package structure which is PANACEAs current package.
4.1.2
PA_DEF_PACKAGE
PA_def_package(char *name,
PFInt gcmd,
PFInt dfs,
PFInt dfu,
PFInt dfr,
PFInt cnt,
PFInt izr,
PFInt inr,
PFInt mn,
PFPPM_mapping psr,
PFInt fzr,
PFInt pcmd,
char *fname),
To define a package in complete generality the following functions must be supplied:
gcmd installs the functions which handle generator commands
dfs defines data structures used by package variables
dfu defines the units of the package
dfr defines the variables of the package
cnt defines and sets initial or default values for the controls of the package
izr initializes the package one time before the main entry point is called
inr interns package variables into the database prior to writing the state file
mn the main entry point for the package
psr makes PM_mappings (for output purposes) of package specific quantities which PANACEAs generic capabilities cannot handle
fzr finalizes a package one time before exiting the simulation
pcmd installs the functions which handle post processor commands
fname names a dictionary file to be processed at runtime by the dfr function
With the exception of the psr function which returns a pointer to a PM_mapping structure if successful and NULL otherwise, these functions must return TRUE if successful and FALSE otherwise. If any of these functions is irrelevant to the package being defined, NULL should be passed in in its place.
4.1.3
PA_GEN_PACKAGE
PA_gen_package(char *name,
PFInt cmd,
PFInt dfs,
PFInt dfu,
PFInt dfr,
PFInt cnt,
PFInt inr,
char *fname)
To define a package to a generator code the application must supply functions:
cmd installs the functions which handle generator commands
dfs defines data structures used by package variables
dfu defines the units of the package
dfr defines the variables of the package
cnt defines and sets initial or default values for the controls of the package
inr interns package variables into the database prior to writing the state file
fname names a dictionary file to be processed at runtime by the dfr function
These functions must return TRUE if successful and FALSE otherwise. If any of these functions is irrelevant to the package being defined, NULL should be passed in in its place.
4.1.4
PA_GET_MAX_NAME_SPACE
PA_GET_MAX_NAME_SPACE(int flag)
Returns the value of the name space flag in the argument flag. See the PA_SET_NAME_SPACE function for further information.
4.1.5
PA_INSTALL_FUNCTION
PA_install_function(char *name, PFByte fnc)
This function provides a means for applications to make arbitrary procedures known to the PANACEA database. This is critical for interactive or interpreted applications which may need to invoke a function given only its name. It associates an address to which control can be passed with an ASCII name.
The arguments to this function are: name, an ASCII string naming the function; and fnc, a compiled function which may be invoked by PANACEA. Currently the function installed this way can take no arguments and returns no value.
4.1.6
PA_INSTALL_IDENTIFIER
PA_install_identifier(char *name, byte *vr)
This function provides a means for applications to make arbitrary compiled variables known to the PANACEA database. This is critical for interactive or interpreted applications which may need to refer to a variable given only its name. It associates an address with which a value can be accessed with an ASCII name.
The arguments to this function are: name, an ASCII string naming the function; and vr, a compiled variable which may be referenced by PANACEA.
4.1.7
PA_RUN_TIME_PACKAGE
PA_run_time_package(char *name,
PFInt dfs,
PFInt dfu,
PFInt dfr,
PFInt cnt,
PFInt izr,
PFInt mn,
PFPPM_mapping psr,
PFInt fzr,
char *fname)
To define a package to a simulation code the application must supply functions:
dfs defines data structures used by package variables
dfu defines the units of the package
dfr defines the variables of the package
cnt defines and sets initial or default values for the controls of the package
izr initializes the package (executed once before any main entry point)
mn the main entry point of the package (executed once each major cycle)
psr returns a PM_mapping pointer for PSEUDO EDIT variables (each cycle)
fzr shuts down the package (executed once after the last call to any main entry)
All of the functions except psr must return TRUE if successful and FALSE otherwise. psr returns a pointer to a PM_mapping associated with a plot request of a PSEUDO EDIT variable. If any of these functions is irrelevant to the package being defined, NULL should be passed in in its place.
4.1.8
PA_SET_MAX_NAME_SPACE
PA_SET_MAX_NAME_SPACE(int flag)
If flag is TRUE then the name space of PANACEA variables is maximized in that variables are defined to the database under a name made up from the package name, a hyphen, and the variable name. In this scheme, there is less potential for name conflicts. If flag is FALSE then variable are defined to the database simply by the variable name.
4.2 Variable Definers
Variables are one of the main objects in PANACEA and consequently their definition to the database is crucial. Both scalar and array variables can be defined in the database and variables may have any data type used in the simulation code system.
4.2.1
PA_DEF_VAR
PA_def_var(char *vname,
char *vtype,
byte *viv,
byte *vif,
...)
To define a variable to the PANACEA database certain descriptive information must be supplied.
vname defines the name of the variable
vtype defines the type of the variable (variables may be of any type including structures)
viv a pointer to a default initial value to be broadcast into the array
vif a pointer to a function which can be called to compute initial values for the
variable
... defines the attributes, dimensions,
The attributes of the variable are specified by attribute identifier, attribute value pairs. When all the attributes are specified the ATTRIBUTE keyword terminates the processing of attribute specifications. By default, variables will be defined as RUNTIME, OPTL, REL, U_CENT, DYNAMIC. To set the scope, the SCOPE keyword is used followed by one of the values: DEFN; RESTART; DMND; RUNTIME; or EDIT. To set the class, the CLASS keyword is used followed by one of the values: REQU; OPTL; or PSEUDO. To set the persistence, the PERSIST keyword is used followed by one of the values: KEEP; CACHE_F, CACHE_R; or REL. To set the centering of the variable with respect to its spatial mesh use the CENTER keyword followed by one of the values: Z_CENT; N_CENT; E_CENT; F_CENT; or U_CENT.
Another feature of dimension specification in PANACEA is that a dimension can be specified in three ways. First a single pointer indicates to PANACEA that the dimension scalar represents the number of elements in that dimension. Second, each time the PANACEA provided pointer, PA_DON, occurs in the dimension list, the next two integer pointers in the argument list are interpreted to be a pointer to the value of the minimum index value of the dimension and a pointer to the value of the number of elements in the dimension of the variable, respectively (i.e. DON means Dimension, Offset, and Number). Third, each time the PANACEA provided pointer, PA_DUL, occurs in the dimension list, the next two integer pointers in the argument list are interpreted to be a pointer to the value of the minimum index value of the dimension and a pointer to the value of the maximum index value of the dimension of the variable, respectively (i.e. DUL means Dimension, Upper, and Lower). The reason for this distinction between the second and third case is that although the arithmetic is simple, the meaning of the scalar variables describing the dimensions is different. Since PANACEA does not deal with the dimension range values but pointers to the values, it must respect the semantics of these dimensioning scalars. This in turn dictates the presence of at least the two cases here.
The physical units of a PANACEA variable are described in terms of a collection of conversion factors from CGS units. There are arrays of factors for both internal and external units. They are indexed the same way and so the effective specification of the physical units of a variable are in terms of the integer indices into these arrays. PA_def_var processes the arguments after the dimension specification terminator, DIMENSION, and before the unit specification terminator, UNITS. It takes the arguments from left to right and multiplies the values in the conversion factor arrays indexed by the values together. If it encounters the PANACEA provided argument, PER, it collects the factors remaining until, UNITS, and divides the two terms to compute the correct conversion factors (internal and external units conversion). The arguments are handled this way so that the call to PA_def_var reads very much like English and the units are clear at a glance. PANACEA goes further by providing the following constants as the index values:
Macro Variable Unit
RAD PA_radian angle
STER PA_steradian solid angle
MOLE PA_mole number
Q PA_electric_charge Coulomb
CM PA_cm length
SEC PA_sec time
G PA_gram mass
EV PA_eV energy
K PA_kelvin temperature
ERG PA_erg energy
CC PA_cc volume
Application developers are encouraged to use this practice to make the units they define easy to read in this context of variable definition.
The syntax for PA_def_var is:
PA_def_var(name, type, init_val_ptr, init_func_ptr,
attribute_spec, ..., ATTRIBUTE,
dimension_spec, ..., DIMENSION,
unit_spec, ..., UNITS
[, data_ptr])
attribute_spec := attribute_id, attribute_val
attribute_id := SCOPE | CLASS | PERSIST |
CENTER | ALLOCATION
attribute_val(SCOPE) := DEFN | RESTART | DMND |
RUNTIME | EDIT
attribute_val(CLASS) := REQU | OPTL | PSEUDO
attribute_val(PERSIST) := REL | KEEP | CACHE_F | CACHE_R
attribute_val(ALLOCATION):= STATIC | DYNAMIC
attribute_val(CENTER) := Z_CENT | N_CENT | F_CENT |
E_CENT | U_CENT
dimension_spec := n_elements_ptr |
PA_DUL, lower_bnd_ptr, upper_bnd_ptr |
PA_DON, offset_ptr, n_elements_ptr
unit_spec := unit_index | PER
unit_index := RAD | STER | MOLE | Q | CM | SEC |
G | EV | K | ERG | CC |
<user defined index>
RUNTIME, OPTL, REL, U_CENT, DYNAMIC
4.3 Control Accessors/Definers
Optional Functions
PA_control_set(char *s)
4.4 Unit Conversion/Definition Functionality
4.4.1 Unit/Conversion Definitions
4.4.2 Unit/Conversion Setup
4.5 Database Access Functionality
4.5.1 Variable Access for Simulation
PA_change_size
4.5.1.1
PA_INTERN
PA_INTERN(byte *var, char *name)
Intern a given array in the variable data base.4.5.1.2
PA_CONNECT
PA_CONNECT(byte *var, char *name, int flag)
In the PANACEA model the PANACEA database is viewed as the manager of dynamic memory. As such one of its key functions is to dispense pointers to the data associated with PANACEA variables. PA_CONNECT is the principal means of doing this.
The call to this macro takes the application pointer which is to be set, var; the name of the variable in the PANACEA database; and a flag that informs PANACEA that it must track this pointer so that its value may be reset it another database operation changes the space to which the pointer points (see PA_change_dim). If the value of flag is TRUE then PANACEA will reset the applications pointer if the space is reallocated or released by another PANACEA operation.
The following steps are performed when a PA_CONNECT request is made:
The variable specified by name is looked up in the database hash table.
If the variable is not found PA_ERR is called and the application exits with the error message: VARIABLE name NOT IN DATA BASE - PA_GET_ACCESS.
The class of the variable is checked. If the class is PSEUDO PA_ERR is called and the
application exits.
If the scope of the variable is DMND and it has not already been read in (presumably
by another PA_CONNECT operation) the variable is read in from the state dump file.
Each PANACEA variable has two sets of dimensions: 1) derived from the contents of
the addresses of integer scalars (necessary for correct dynamic behavior at run time);
and 2) derived from the dimensions as specified in the PDB file (necessary for correct
storage behavior). On PA_CONNECT, PANACEA reconciles these two sets of dimensions to obtain consistency and computes the actual current size in elements of the variable. The reconciliation of the two sets of dimensions is done via the following steps:
If the class of the variable is REQU the following actions are taken:
If the class of the variable is OPTL the following actions are taken:
Set the PANACEA variable data pointer to the address of the space
Set the pointer var to the address of the space.
If track is TRUE, PANACEA is requested to keep track of this reference by adding it to the list of tracked pointers.
Return.
PA_DISCONNECT(char *name, byte *ptr)In the course of doing a numerical simulation, an application may wish to relinquish access to the data associated with a PANACEA variable. Most likely this access was obtained via PA_CONNECT. Since PANACEA is monitoring database access, it is not a good idea to simply set the application pointer to NULL because the database may be tracking that pointer and it could mysteriously be reappear later with a value.The correct procedure to invoke PA_DISCONNECT to inform PANACEA that this access is to be terminated.
The arguments to this macro are: name, the name of the PANACEA variable in the database; and ptr, the application pointer whose access to the data associated with the named PANACEA variable is to be relinquished.
The following steps are carried out when a call to inform the PANACEA database that the application no longer requires a specified reference to the data associated with a PANACEA variable:
The variable specified by name is looked up in the database hash table. If the variable is
not found PA_ERR is called and the application exits with the error message: VARIABLE name NOT IN DATA BASE - PA_REL_ACCESS
If the scope of the variable is EDIT the following actions are taken:
Remove the reference ptr from the list of pointers pointing to this data
Set the reference ptr to NULL if the PANACEA variable is not a scalar variable as defined by PA_inst_scalar.
If there are no more references to the data associated with the PANACEA variable the following actions are taken:
Return
PA_ACCESS(char * name, type, long offs, long ne)Return a connection to a sub-space of an array.
PA_RELEASE(char * name, byte * ptr, long offs, long ne)Release the access to an array sub-space.
void PA_change_dim(int *pdm, int val)Change the value of an integer quantity, pointed to by pdm, to which the PANACEA variable dimensions of one or more PANACEA variables point to the given value, val, and reallocate all of the PANACEA variables which have this quantity as a dimension. This rather elaborate and expensive operation is the most consistent way of handling PANACEA database variables whose sizes are changing as a result of dynamically recomputing the computational domain (e.g. a spatial or frequency mesh). The alternate method provided by PA_change_size is not consistent and can produce extremely bizarre behavior which is difficult to debug.
The arguments to this function are: pdm, a pointer to the integer value to be changed (this should match at least one of the quantities used in a PA_def_var call used to define the database variables; and val, the new value to be assigned to the location pointed to by pdm.
NOTE: the use of val here is trivial but is intended to help enforce the discipline of using PA_change_dim correctly.
4.5.1.7
PA_CHANGE_SIZE
void PA_change_size(char *name, int flag)
Reallocate the PANACEA variable specified by name using the current values implied by set of dimensions specified by flag. With this call it is assumed that the application has changed the value of a dimensioning integer and now wants PANACEA to handle the resizing of the space associated with a particular PANACEA variable. In general, this is an extremely risky thing to do. However, some code systems which have automatically generated code can enforce consistency via the code generator. In such a case, the performance overhead of PA_change_dim is diminished to some extent.
The arguments to this function are: name, a string containing the name of the PANACEA database variable to be reallocated; and flag, an integer having either of the two values PA_FILE or PA_DATABASE signifying which set of dimensions (file or database respectively) to use in enforcing consistency on this one variable.
NOTE: use this function at your own risk!
4.5.2
Structured Data Support
To provide an additional dimension in data handling for FORTRAN packages and to support interactive runtime data structuring, PANACEA supplies services to define, create and release instances, and get or set members of data structure independent of any compiled in data structure such as a C struct or FORTRAN common block. This facility is completely dynamic and interpreted at runtime.
4.5.2.1
PA_MK_INSTANCE
void *PA_mk_instance(char *name,
char *type,
long n)
Allocate and return a pointer to an array of instances of a type (defined in the virtual internal file) which is n items long.The type must have been defined from a dictionary file or from an explicit function call.
The return value of this function is a pointer to the space allocated to hold n elements each of which is of sufficient byte size to hold one item of type type. The instance is also installed in an internal table under the name name so that PANACEA can track the variable.
4.5.2.2
PA_RL_INSTANCE
void PA_rl_instance(char *name)
Release the named instance of an entry allocated with PA_mk_instance.
This function has no return value.
4.5.2.3
PA_GET_MEMBER
void *PA_get_member(char *name,
char *member)
Get the named member of the instance of a structured variable allocated by PA_mk_instance under the name name.
A pointer to the member is returned if successful and NULL is returned otherwise.
4.5.2.4
PA_SET_MEMBER
void PA_set_member(char *name,
void *data,
char *member)
Set the named member of an instance of a data structure return by PA_mk_instance to point to the given data. The instance is identified by name.
This function returns nothing.
4.5.3 Variable Access for Output
4.6
Simulation Control
The functions in the section describe the services PANACEA offers the simulation phase code. These are fairly high level functions which encapsulate much of the detailed inner workings of the PANACEA database and the PANACEA packages.
4.6.1
PA_RD_RESTART
void PA_rd_restart(char *rsname,
int convs)
This function reads a state file as a prelude to performing simulations starting from the state specified in the file. Statistics about the amount of data in the state file which is actually loaded into memory are printed
The arguments are: rsname, the name of the state file; and convs, the type of conversions to do. The conversion options are:
NONE perform no conversions
INT_CGS convert from internal units to CGS units
INT_EXT convert from internal units to external units
EXT_CGS convert from external units to CGS units
EXT_INT convert from external units to internal units
CGS_INT convert from CGS units to internal units
CGS_EXT convert from CGS units to external units
The internal system of units is defined by the unit array. The external system of units is defined by the convrsn array.
The system of units of the data in the state file is under the control of the code developer, but it must be consistent.
4.6.2
PA_SIMULATE
void PA_simulate(double tc,
int nc,
int nz,
double ti,
double tf,
double dtf_init,
double dtf_min,
double dtf_max,
double dtf_inc,
char *rsname,
char *edname,
char *ppname,
char *pvname)
This function is provided as a template for controlling and coordinating the execution of the packages and other PANACEA services. It is clear that no one routine can satisfy all of the requirements of all simulation systems, and this routine does not really attempt to do so. It is provided as an example to be used in constructing the simulation control for any given application code and to be used by those applications for which it is sufficient.
The arguments are: tc, the current problem time; nc, the current problem cycle; nz, the number of zones/cells/particles in the problem; ti, the starting time; tf, the stopping time; dtf_init, the initial fractional time step; dtf_min, the minimum fractional time step; dtf_max, the maximum, fractional time step; dtf_inc, the fractional increase in the time step each cycle; rsname, the name of the most recently read state file; edname, the name of the ASCII edit file; ppname, the name of the time history file; and pvname, the name of the PVA file. Each file name is a base name ending with two digits. Each time a new file in each of the respective families is closed, the next member of the family is given a name with the number indicated by the final digits advanced by one.
PA_simulate performs the following actions in a loop over time from ti to tf:
calls PA_source_variable to update all source variables in the simulation for the current time and time step
calls PA_run_package to execute each installed package in the order of installation
calls PA_dump_pp to check all plot requests and write out any requested data in the
time history and PVA files for the current time and cycle
calls PA_file_mon to determine whether the current edit, time history, or PVA file need
to be closed and the next member of the family created
calls PA_advance_t to poll the packages for their time step votes and determine the
next time step
At the conclusion of the loop over time, PA_simulate, prints a message to the terminal announcing that the stop time has been reached, and then it calls PA_fin_system to call the package fzr routines and print the simulation statistics to the terminal.
This routine has no return value.
4.6.3
PA_RUN_PACKAGES
void PA_run_packages(double t,
double dt,
int cycle)
This routine executes the main entry point of each installed package and dumps any information corresponding to a plot request associated with the package.
The arguments are: t, the current problem time; dt, the current problem time step; and cycle, the current problem cycle number. This information is passed to the packages main entry point via the package structure.
This function has no return value.
4.6.4
PA_FIN_SYSTEM
void PA_fin_system(int nz,
int nc)
This function runs the finalizer routine for each installed package and prints performance statistics on the packages for the simulation (or partial simulation) just concluded. The performance statistics are based on the CPU time spent in the package as reported by the package and the storage space used by the package in kBytes. Whether this information is gathered is up to the package developer. If no information is stored in a package, PANACEA does not print any statistics for that package. The macros PA_MARK_TIME, PA_ACCM_TIME, PA_MARK_SPACE, and PA_ACCM_SPACE can be used by the package developer to save the timing and memory usage information in the package structure.
The arguments are: nz, the number of zones/cells/particles in the problem; and nc the number of cycles run.
4.6.5
PA_ADVANCE_T
double PA_advance_t(double dtmn,
double dtn,
double dtmx)
This function computes a time step for the next major computational cycle based on the time step votes returned in each package after the package main entry point is executed. The algorithm is that the smallest time step from the packages is computed, the smaller of this time step, dtn, and dtmx is taken; and the larger of dtmn and the result of the previous step is returned.
The arguments are: dtmn, the minimum allowed time step, dtn, the current time step; and dtmx, the maximum allowed time step.
4.6.6
PA_WR_RESTART
void PA_wr_restart(char *rsname)
This function causes a state file to be written out. The name of the file is specified by rsname and after the file is closed successfully, the name is incremented. By convention files which PANACEA writes have names ending with two digits. When PANACEA increments a file name it adds one to the number represented by the two digits and replaces them in the file name.
4.6.7
PA_INIT_SYSTEM
void PA_init_system(double t,
double dt,
int nc,
char *edname,
char *ppname,
char *pvname)
This function initializes a PANACEA simulation phase code. It is not for generation phase programs. It performs the following actions:
opens any specified source files and initializes the appropriate source variables
opens and initializes the specified ASCII edit file, time history file, and PVA file
runs the initializer function for each package
processes the plot requests for run time efficiency
calls PA_dump_pp to make an initial dump of the information specified by the plot
requests
The arguments to this function are: t, the initial problem time; dt, the initial problem time step; nc, the initial problem major cycle number; edname, the name of the ASCII edit file; ppname, the name of the time history file; and pvname, the name of the PVA file.
4.6.8
PA_TERMINATE
void PA_terminate(char *edname,
char *ppname,
char *pvname,
int cycle)
This function gracefully shuts down a simulation run. It closes any open ASCII edit files, time history files, PVA files, cache files, or state files. If this function is not called, these files may not be valid data files!
The arguments are: edname, the name of the ASCII edit file; ppname, the name of the time history file; pvname, the name of the PVA file; and cycle, the current problem cycle. These arguments are currently unused, however, that is subject to change.
4.7 Plot Request Handling
4.8 Generation Support
4.8.1 Generator Command Management
PA_inst_c(char *cname, byte *cvar, int ctype, int cnum, PFVoid cproc, PFVoid chand)
Optional Functions PA_get_commands
4.8.1.1
PA_INST_COM
HASHTAB *PA_inst_com(void)
Initialize and set up the table of commands needed to parse an ASCII input file and generate an initial state for a simulation. This function does the following thing:
Installs the generic commands
Installs the package generator commands (see the gencmd argument of the
PA_gen_package function)
Calls PA_definitions to define the unit and conv arrays for PANACEA.
Calls PA_variables to complete the definition of the database variables (the units are not
completed with this call since the input deck may redefine the unit system).
The generic PANACEA supplied generator commands are:
read read the named input file
specify specify an initial value condition
s continue an initial value condition specification
package set the current package
switch set the value of a switch in the current package
parameter set the value of a switch in the current package
name set the value of a name in the current package
unit set an internal conversion factor (sets the internal system of units)
conversion set an external conversion factor (sets the external system of units)
4.8.1.2
PA_GET_COMMANDS
PA_get_commands(FILE *fp, void (*errfnc)())
This function reads from the specified input stream, parses command lines, and dispatches to functions installed in the PANACEA command table via the PA_inst_c function.
It executes the following steps in a loop:
Get a line of text
If no more text is available close the stream (if it is not stdin) and return.
If the line is a blank or comment line loop
Lookup up the first token in the PANACEA command table
If there is an associated function dispatch to it
If there is no associated function call the errfnc from the argument list.
4.8.2 Generation Time Functions
4.9 Source Variable/Initial Value Data Handling
PANACEA provides functionality for handling data which is to be used as boundary condition or source information or to set values of database variables. One application of this capability is to use the results of one simulation to drive a second simulation whose intent is to simulate one phenomenon in an environment which itself is the result of a simulation. To emphasize the inherent unity of sources and to provide a simple mechanism for applications, PANACEA defines the concept of an initial value specification. Initial value specifications are made in the ASCII input defining a problem with the specify command. The data may be provided with the specify or s commands. It may also be provided from a source file which is produced by a utility which the simulation system designer must write. This utility uses PANACEA services to format data in such a way that PANACEA can access it quickly and efficiently at run time. This is also done because it is impossible for PANACEA to know about even the smallest fraction of potential sources for initial value data and their formats.
An initial value specification is the mathematical notion of initial value data which together with a set of differential equations defines an initial value problem. PANACEA defines a structure called a PA_iv_specification to represent an initial value specification. In particular, an initial value specification has:
a type: bc, for boundary condition which specifies information on the boundary of the
computational mesh; src, for source which specifies a set of values imposed in some
region of the interior of the computational mesh; or the name of a database variable
whose values throughout the simulation are interpolated from a set of predetermined
data
a name by which the initial value specification may be selected
a file name in which the actual initial value data may be found
a flag specifying whether the data is to be interpolated or treated as discrete sets that are
to be used as the exact specified times
the number of data points in one time slice of the data set
various representations of any data that exists in memory (PANACEA manages this
with the aim of handling this data as efficiently as possible with respect to both time
and space)
To help manage initial value specifications whose data is to be imported from a source file, PANACEA defines the concept of a source variable and a structure called a PA_src_variable. The source variable contains information about the data in a source file and the data structures necessary to manage the interpolations which may be done by PANACEA. Source variables must have counterparts in the database. They fundamentally are devices to help load the appropriate initial value data into a database variable.
The following functions are all optional in that an application can use PANACEA without using the initial value handling services of the library. If the application does use these services, the basic operations at the application level involve accessing initial value data and interpolating values from initial value data structures. There is also a more global operation which tells PANACEA to update all sourced variables.
4.9.1 PA_GET_IV_SOURCE
PA_iv_specification *PA_get_iv_source(char *name)
This routine searches the list of initial value specifications and returns the named PA_iv_specification. In order for this function to succeed, the given name must match the name used in at least one specify command in the problem definition.
Input to this function is: name, an ASCII string naming the initial value specification for which to search.
4.9.2
PA_GET_SOURCE
PA_src_variable *PA_get_source(char *s, int start_flag)
This function returns a pointer to a source variable specified by the name, s. It is permissible to have many instances of a source variable in a source file or to have many source files with the same source variable. In such a case each call to PA_get_source returns the next available instance of the source variable. If the start_flag is TRUE the first instance is found and returned.
Input to this function is: s, an ASCII string naming the source variable; and start_flag, an integer signalling whether to start from the beginning of the source variable list or from the last position searched.
4.9.3
PA_INTERP_SRC
void PA_interp_src(void *v,
PA_src_variable *svp,
int ni,
int nf,
double t,
double dt)
This function interpolates the data from the given PA_src_variable into the space pointed to by v from v[ni] to v[nf]. The data is interpolated in time at time t with timestep dt. The interpolation is quadratic.4.9.4
PA_INTR_SPEC
double PA_intr_spec(PA_iv_specification *sp,
double t,
double val,
long off)
This function finds the interpolated source value from the given initial value specification information. For efficiency sake when interpolating the initial value data, the index into the data set from each call is saved and used as the starting point for the next interpolation. This means that the initial value data is assumed to be stored in increasing time order.
The return value of this function is the interpolated value of the initial value data set.
4.9.5
PA_SOURCE_VARIABLES
void PA_source_variables(double t,
double dt)
This function sets the values (by interpolation) of the database variables which have been identified with source variables. This function is called once per major time cycle in PA_simulate. Those applications controlling their own time stepping must call this function if they wish to have PANACEA handle source data. In PA_simulate, this function is called before the packages are executed.
This function performs the following steps:
Loops over each source variable set up by PA_init_system.
If the database variable corresponding to the source variable does not exist or has a
NULL data pointer no further action is performed.
PA_interp_src is called to interpolate the source variable data in time and fill the data
associated with the database variable.
The input to this function is: t, a double containing the time at which the source variable are to be interpolated; and dt, a double containing the corresponding time step.4.10
Time History Data Management
The following functions define a service for the management of time history data.
The time history data is written out in families PDB of files. A family of time history PDB files is started with a call to PA_th_open. The function PA_th_family is used to close out one member of the family and start the next if the current files size is above a user set threshold. Each file in a family maintains a link to the previous file in the family. This is very useful when applications restart a simulation from an earlier state and, potentially, follow a different branch of execution. Knowing the last time history file in any branch allows the unambiguous reconstruction of the time history data for that branch.
In addition to the time history data, any sort of associated data may be defined via the attribute mechanism in PDBLib. Additionally attributes may be assigned to particular instances of time history data structures via the PA_th_wr_iattr call.
Since PANACEA is a part of PACT, it supplies functions to transpose the time history data files into ULTRA files (also a PACT tool). These functions are: PA_th_trans_name; PA_th_trans_link; and PA_th_trans_family. In this way, applications may directly transpose their time history files if desired. The stand alone program TOUL which transposes a family of time history files into a family of ULTRA files simply calls these functions appropriately. NOTE: all files in the family must be closed before any transpose operation. Functions to merge an arbitrary list of ULTRA files or a family of ULTRA files are also provided. These functions are: PA_merge_files and PA_merge_family.
This facility is substantially independent of the rest of PANACEA and can be used without any other parts of PANACEA.
Optional Functions PA_merge_family, PA_merge_files, PA_th_trans_name, PA_th_trans_link, PA_th_trans_family, PA_th_wr_iattr
intPA_merge_family(char *base,
char *family,
int nc)Merge a family of ULTRA files into a single file or family of files. The ULTRA source files are specified here by family base name.
ULTRA source files are assumed to follow the naming convention
family.uddwhere family is the base source file name supplied and dd are base 36 digits (0-9a-z).
ULTRA target files produced by this function similarly follow the naming convention
base.uddwhere base is the base target file name supplied.
Argument nc, determines how target files are familied by specifying the approximate number of curves per file. However, regardless of the value of nc, all curves from a given source file will reside in a single target file. If nc is zero, all curves will be merged into a single file.
For efficiency this function currently assumes that all curves in a given source file share the domain of the first curve in that file. This is true for ULTRA files produced by the PANACEA time history transpose routines. Curves from arbitrary ULTRA files can be merged, albeit less efficiently, using the save command in the ULTRA utility.
Input to this function is: base, an ASCII string containing the base target file name; family, an ASCII string containing the base source file name; and nc an integer approximate number of curves per ULTRA target file.
int
PA_merge_family(char *base,
char *family,
int nc)
#include panace.h
.
.
.
/* merge files in family foo */
if (!
PA_merge_family(bar, foo, 0))
printf(stderr, %s\n, PD_err);
.
.
.
4.10.2 PA_MERGE_FILES
int
PA_merge_files(char *base,
int n,
char **names,
int nc)
Merge a set of ULTRA files into a single file or family of files. The ULTRA source files are specified here explicitly by name.
ULTRA target files produced by this function follow the naming convention
base.udd
where base is the base target file name supplied and dd are base 36 digits (0-9a-z).
Input to this function is: base, an ASCII string containing the base file name; n, an integer number of file names supplied in names; names, an array of ASCII strings containing the full names of the ULTRA source files; and nc an integer approximate number of curves per ULTRA target file.
int
PA_merge_files(char *base,
int n,
char **names,
int nc)
#include panace.h
char **names;
.
.
.
/* only merge foo.u09 through foo.u0b */
names = MAKE_N(char *, 3);
names[0] = SC_strsave(foo.t09);
names[1] = SC_strsave(foo.t0a);
names[2] = SC_strsave(foo.t0b);
if (!
PA_merge_files(bar, 3, names, 0))
printf(stderr, %s\n, PD_err);
SFREE(names[0]);
SFREE(names[1]);
SFREE(names[2]);
SFREE(names);
.
.
.
4.10.3 PA_TH_DEF_REC
defstr *
PA_th_def_rec(PDBfile *file,
char *name,
char *type,
int nmemb,
char **members,
char **labels)
Define a special type to be used for the purpose of gathering time history data in such a fashion that a generic tool (e.g. TOUL) can be used to convert the data into arrays of time ordered data. This defines both a derived data type and an entry in the symbol table of the file to contain the data. PANACEA implicitly adds another entry which contains information that a transposer would use.
The members must follow the rules for member specifications as described in the PDBLib Users Manual with the exception that if no type is specified the type is taken to be double. Briefly, a member specification consists of a type, an identifier, and optional dimension specifications. Member identifiers must not contain white space characters or any of the following: *, [, ], (, ), or .. The first member is taken to be the domain data (x value) and the remaining members are taken to be ranges. Each data set of the specified type transposes into nmemb-1 curves, that is one x array and nmemb-1 y arrays.
A pointer to the types defstr is returned if the call is successful; otherwise, NULL is returned and the ASCII string PD_err contains any error message that was generated.
defstr *
PA_th_def_rec(PDBfile *file,
char *name,
char *type,
int nmemb,
char **members,
char **labels)
#include panace.h
PDBfile *file;
defstr *ptr;
char **members;
.
.
.
members = MAKE_N(char *, 3);
members[0] = SC_strsave(time);
members[1] = SC_strsave(d[20]);
members[2] = SC_strsave(p at x,y);
ptr =
PA_th_def_rec(file, t-data, t-struct, 3, members, NULL);
SFREE(members[0]);
SFREE(members[1]);
SFREE(members[2]);
SFREE(members);
.
.
.
4.10.4 PA_TH_FAMILY
PDBfile *
PA_th_family(PDBfile *file)
Check the current files size against the maximum size as specified in the PA_th_open call. If the file is larger than the maximum size, close the file, open the next member of the file family, and return a pointer to the new file.
Input to this function is: file, a pointer to a PDBfile.
PDBfile *
PA_th_family(PDBfile *file)
#include panace.h
PDBfile *oldfile, *newfile;
.
.
.
newfile =
PA_th_family(oldfile);
if (newfile != oldfile)
printf(Next member of family opened\n);
.
.
.
4.10.5 PA_TH_OPEN
PDBfile *
PA_th_open(char *name,
char *mode,
long size,
char *prev)
Open a new time history data file. This implicitly defines a family of files. The name should be of the form: base.tdd where d is a base 36 digit (i.e. 0-9a-z). This is only a convention, but there are certain consequences for not following it in as much as the familying mechanism assumes that the last two characters form a base 36 number and increments it accordingly. As an application writes data to a time history file, periodic calls to PA_th_family should be made to monitor the file size and when necessary close the current family member and open the next.
Since simulations may be restarted and each code may have a different strategy for continuing time history collection in the event of a restart, it is necessary to allow for name changes in the family. The consequence of this is that each member of a file family must contain the name of the previous file in the family. In that way, the transpose process may unambiguously and under the control of the user or simulation follow a chain of time history files from the end point back to the beginning. The prev argument is used to supply this information. The family of files that follows will be in sequence from the name supplied. Only across restarts, which implies calls to PA_th_open, may the sequence name be changed. A call to PA_th_open may have NULL for prev which indicates the absolute beginning of the sequence, i.e. the transpose will stop in its search for files at this point.
PDBfile *
PA_th_open(char *name,
char *mode,
long size,
char *prev)
#include panace.h
PDBfile *newfile;
.
.
.
newfile =
PA_th_open(foo.t00, w, 1000000L, NULL);
if (newfile == NULL)
printf(Cant open time history file\n);
.
.
.
4.10.6 PA_TH_TRANS_FAMILY
int
PA_th_trans_family(char *name,
int ord,
int nc)
Write an ULTRA file by transposing the time history data from a given set of time history files.
A family of time history files is conventionally named
name.tdd
where name is the base file name and dd are base 36 digits (0-9a-z).
name.udd
There is the possibility inherent in this model of handling file families that two or more files to be processed will have data for some regions in time. Because of the underlying PDB machinery, the data from the last file processed will predominate. Also, since the files are linked together from latest to earliest, it is sometimes necessary to require that the files be processed in the opposite order in which they are specified. The ord argument is used for this purpose. A value of 1 causes the files to be processed in the order in which they are specified while a value of -1 causes them to be processed in reverse order.
int
PA_th_trans_family(char *name,
int ord,
int nc)
#include panace.h
.
.
.
if (!
PA_th_trans_family(foo, 1, 1000))
printf(stderr, %s\n, PD_err);
.
.
.
4.10.7 PA_TH_TRANS_LINK
int
PA_th_trans_link(int n,
char **names,
int ord,
int nc)
Write an ULTRA file by transposing the time history data from a specified set of time history files. The time history files are specified here by giving the names of files at the end of file family chains.
On occasion, files in a family are lost. This breaks the chain of files as well as leaving gaps in the data. Since this function can take many file names, it can be used to take into account missing files by supplying the files at the top of the gap(s) of missing files. In the accompanying example it is assumed that the files foo.t09 through foo.t11 are missing.
name.tdd
where name is the base file name and dd are base 36 digits (0-9a-z).
name.udd
Input to this function is: n, an integer number of file names supplied in names; names, an array of ASCII strings containing the full names of the time history files; ord, an integer flag specifying the order of processing; and nc a maximum number of curves per file in the ULTRA file family.
int
PA_th_trans_link(int n,
char **names,
int ord,
int nc)
#include panace.h
char **names;
.
.
.
/* files foo.t09 through foo.t11 are missing */
names = MAKE_N(char *, 2);
names[0] = SC_strsave(foo.t1f);
names[1] = SC_strsave(foo.t08);
if (!
PA_th_trans_link(2, names, -1, 1000))
err_proc();
SFREE(names[0]);
SFREE(names[1]);
SFREE(names);
.
.
.
4.10.8 PA_TH_TRANS_NAME
int
PA_th_trans_name(int n,
char **names,
int ord,
int nc)
Write an ULTRA file by transposing the time history data from a specified set of time history files. The time history files are specified here explicitly by name.
On occasion, it is desirable to transpose only selected files from a family. For example, a user may know that only certain times are of interest and doesnt wish to see the entire data set. This function gives the finest level of control to the application about which files to transpose.
name.tdd
where name is the base file name and dd are base 36 digits (0-9a-z).
name.udd
Input to this function is: n, an integer number of file names supplied in names; names, an array of ASCII strings containing the full names of the time history files; ord, an integer flag specifying the order of processing; and nc a maximum number of curves per file in the ULTRA file family.
int
PA_th_trans_name(int n,
char **names,
int ord,
int nc)
#include panace.h
char **names;
.
.
.
/* only transpose foo.t09 through foo.t0b */
names = MAKE_N(char *, 3);
names[0] = SC_strsave(foo.t09);
names[1] = SC_strsave(foo.t0a);
names[2] = SC_strsave(foo.t0b);
if (!
PA_th_trans_name(3, names, 1, 1000))
err_proc();
SFREE(names[0]);
SFREE(names[1]);
SFREE(names[2]);
SFREE(names);
.
.
.
4.10.9 PA_TH_TRANSPOSE
int
PA_th_transpose(char *name,
int nc)
WARNING: This is a deprecated function. Use PA_th_trans_family instead.
Write an ULTRA file by transposing the time history data from a given set of time history files.
A family of time history files is conventionally named
name.tdd
where name is the base file name and dd are base 36 digits (0-9a-z).
name.udd
Input to this function is: name, an ASCII string containing the base name of the time history file family; and nc a maximum number of curves per file in the ULTRA file family.
int
PA_th_transpose(char *name,
int nc)
#include panace.h
.
.
.
if (!
PA_th_transpose(foo, 1000))
printf(stderr, %s\n, PD_err);
.
.
.
4.10.10 PA_TH_WR_IATTR
int
PA_th_wr_iattr(PDBfile *file,
char *var,
int inst,
char *attr,
void *avl)
Assign an attribute value to an instance of a time history data record.
Input to this function is: file, a pointer to a PDBfile; var, an ASCII string containing the name of the data entry in the symbol table; inst, an integer instance index; attr, an ASCII string containing the name of the attribute; and avl, a pointer to the attribute value.
int
PA_th_wr_iattr(PDBfile *file,
char *var,
int inst,
char *attr,
void *avl)
#include panace.h
PDBfile *file;
double *vr
.
.
.
vr = MAKE_N(double, 9);
.
.
.
if (!
PA_th_wr_iattr(file, t-data, 3, date, today))
printf(stderr, %s\n, PD_err);
.
.
.
4.10.11 PA_TH_WRITE
int
PA_th_write(PDBfile *file,
char *name,
char *type,
int inst,
int nr,
void *vr)
Write out nr instances of time history data whose structure has been defined by PA_th_def_rec. This function writes out nr complete instances of a time history record! Using this function an application can manage multiple sets of time history data which are written at different frequencies.
The name and type arguments should match those used in defining the structure with PA_th_def_rec.
Input to this function is: file, a pointer to a PDBfile; name, an ASCII string containing the name of the data entry in the symbol table; type, an ASCII string containing the name of the time history domain struct; inst, an integer specifying the instance index of the first record in this call; nr, an integer specifying the number of instances of the structure pointed to by vr; and vr, a pointer to the data.
int
PA_th_write(PDBfile *file,
char *name,
char *type,
int inst,
int nr,
void *vr)
#include panace.h
PDBfile *file;
double *vr
.
.
.
vr = MAKE_N(double, 9);
.
.
.
if (!
PA_th_write(file, t-data, t-struct, 0, 3, vr))
printf(stderr, %s\n, PD_err);
.
.
.
if (!
PA_th_write(file, t-data, t-struct, 3, 2, vr))
printf(stderr, %s\n, PD_err);
.
.
.
if (!
PA_th_write(file, t-data, t-struct, 5, 3, vr))
printf(stderr, %s\n, PD_err);
.
.
.
4.10.12 PA_TH_WR_MEMBER
int
PA_th_wr_member(PDBfile *file,
char *name,
char *member,
char *type,
int inst,
void *vr)
Write out one member of a time history data record whose structure has been defined by PA_th_def_rec. This function writes out one member of a time history record. Its utility is most apparent when the member is an array which could be large or is part of a very large record.
Input to this function is: file, a pointer to a PDBfile; name, an ASCII string containing the name of the data entry in the symbol table; member, an ASCII string containing the name of the time history record member; type, an ASCII string containing the name of the time history domain struct; inst, an integer specifying the instance index of the first record in this call; and vr, a pointer to the data.
int
PA_th_wr_member(PDBfile *file,
char *name,
char *member,
char *type,
int inst,
void *vr)
#include panace.h
PDBfile *file;
double *vr
.
.
.
vr = MAKE_N(double, 10000);
.
.
.
if (!PA_th_wr_member(file, t-data, v_1, t-struct, 1, vr))
printf(stderr, %s\n, PD_err);
.
.
.
4.11 Miscellaneous
4.11.1 Parsing Support
4.11.2 Array Operations
4.11.3 Error Handling
4.11.4 Timing Routines
4.11.5 Comparison Routines
5.0 The PANACEA FORTRAN API
The FORTRAN interface to PANACEA has some global conventions. First, the function names adhere strictly to the FORTRAN77 naming convention of six characters. The names all begin with PA to identify them with PANACEA.5.1 Database Definition and Control Functionality
These functions provide for overall control of the PANACEA database and packages.
Optional Functions
5.1.1
PAGNSP
PAGNSP(integer flag)
Returns the value of the name space flag in the argument flag. See the PASNSP function for further information.
5.1.2
PASNSP
PASNSP(integer flag)
If flag is TRUE then the name space of PANACEA variables is maximized in that variables are defined to the database under a name made up from the package name, a hyphen, and the variable name. In this scheme, there is less potential for name conflicts. If flag is FALSE then variable are defined to the database simply by the variable name.
5.1.3
PASPCK
PASPCK(pnc, pname)
This function sets the current package to be the named one. PANACEA uses the concept of current package to set a context for operations such as variable access and control use. That is to say that such operations are only meaningful when a particular package is in effect to provide information and procedures necessary to their function.5.2 Variable Definers
5.3 Control Accessors/Definers
5.4 Unit Conversion/Definition Functionality
5.5 Database Access Functionality
This group of functions gives application packages access to the database variables or to non-database managed memory.
Optional Functions PALLOC
5.5.1
PACONN
PACONN(pv, pnc, vname, pf)
Connect the given pointer to the data associated with the named variable. PANACEA will record the address of the pointer pv if the flag, pf, is 1. In that case, if another operation causes PANACEA to change the size of or move the block of memory associated with the database variable, PANACEA will update the pointer pv to point to the new space. 5.5.2
PADCON
PADCON(pv, pnc, vname)
Disconnect the pointer, pv, from the database variable named by name. The pointer is set to NULL (0x0) and future references to it will induce a crash or some other possibly undesirable behavior. PANACEA simply guarantees that the pointer will no longer be pointing to the memory block associated with the database variable.
The arguments to this function are: pv, the pointer to be disconnected from the database variable vname; pnc, the number of characters in vname; and vname, the name of the variable in the database.
5.5.3
PALLOC
PALLOC(pv, pnc, vname, pf, dim1, ...)
Define the dimensions for the named variable, allocate it, and set pv to point to the new space. Each dimension is ignored unless the corresponding dimension was NULL when the variable was defined.5.5.4
PALOCA
PALOCA(pv, pbpi, pn, dim1, ...)
Allocate some local space and set the pv to point to the new space.5.5.5
PAMCON
PAMCON(pnc, vn, pp, pn)
Connect the pointers in pp to the variables named by the entries in vn. There must be pn pointers in pp and pn strings in vn.
The arguments to this function are: pnc, an array containing the length of the variable names in vn; vn, an array of names of the variables in the database; pp, an array of pointers to be connected to the database variables named in vn; and pn, the number of variables to be connected. Each of the arrays pnc, vn, and pp must be pn long.
5.6 Simulation Control
5.7 Plot Request Handling
5.8 Generation Support
5.9 Source Variable/Initial Value Data Handling
5.10 Time History Data Management
The following functions define a service for the management of time history data.
The time history data is written out in families PDB of files. A family of time history PDB files is started with a call to PATHOP. The function PATHFM is used to close out one member of the family and start the next if the current files size is above a user set threshold. Each file in a family maintains a link to the previous file in the family. This is very useful when applications restart a simulation from an earlier state and, potentially, follow a different branch of execution. Knowing the last time history file in any branch allows the unambiguous reconstruction of the time history data for that branch.
In addition to the time history data, any sort of associated data may be defined via the attribute mechanism in PDBLib. Additionally attributes may be assigned to particular instances of time history data structures via the PAWRIA call.
Since PANACEA is a part of PACT, it supplies functions to transpose the time history data files into ULTRA files (also a PACT tool). These functions are: PATRNN; PATRNL; and PATRNF. In this way, applications may directly transpose their time history files if desired. The stand alone program TOUL which transposes a family of time history files into a family of ULTRA files simply calls these functions appropriately. NOTE: all files in the family must be closed before any transpose operation. Functions to merge an arbitrary list of ULTRA files or a family of ULTRA files are also provided. These functions are: PAMRGN and PAMRGF.
Optional Functions PAMRGF, PAMRGN, PATRNN, PATRNL, PATRNF, PAWRIA
integerPAAREC(integer fileid,
integer recid,
integer nm,
char *memb,
integer nl,
char *labl)Add a member to the definition of the time history data structure specified.
This function is a part of the process which defines a special derived type to be used for gathering time history data that a generic tool (e.g. TOUL) can convert into arrays of time ordered data.
See also PABREC, PAEREC, and PAWREC.
integer
PAAREC(integer fileid,
integer recid,
integer nm,
char *memb,
integer nl,
char *labl)
integer paarec
integer fileid, recid
.
.
.
if (paarec(fileid, recid, 5, d[20], 0, ) .eq. 0)
$ call errproc
.
.
.
5.10.2 PABREC
integer PABREC(integer fileid,
integer nf,
char *name,
integer nt,
char *type,
integer nd,
char *domain)
Begin the definition of a special type to be used for gathering time history data that a generic tool (e.g. TOUL) can convert into arrays of time ordered data. This begins a process which defines both a derived data type and an entry in the symbol table of the file to contain the data. PANACEA implicitly adds another entry which contains information that a transposer would use.
The name of the domain member is supplied here since each time history struct has only one domain variable (x data).
See also PAAREC, PAEREC, and PAWREC.
integer PABREC(integer fileid,
integer nf,
char *name,
integer nt,
char *type,
integer nd,
char *domain)
integer pabrec
integer fileid, recid
.
.
.
recid = pabrec(fileid, 6, t-data, 8, t-struct, 4, time)
.
.
.
5.10.3 PAEREC
integer
PAEREC(integer fileid,
integer recid)
Complete the definition of a time history data structure and enter the definition in the PDB file.
Input to PAEREC is: fileid, an integer identifying a PDB file; and recid, an integer identifying a derived type definition started by PABREC.
See also PAAREC, PABREC, and PAWREC.
integer
PAEREC(integer fileid,
integer recid)
integer paerec
integer fileid, recid
.
.
.
if (
paerec(fileid, recid) .eq. 0)
$ call errproc
.
.
.
5.10.4 PAMRGF
integer
PAMRGF(integer nb,
char *base,
integer nf,
char *family,
integer nc)
Merge a family of ULTRA files into a single file or family of files. The ULTRA source files are specified here by family base name. family.udd
where family is the base source file name supplied and dd are base 36 digits (0-9a-z). base.udd
where base is the base target file name supplied.
Input to this function is: nb, an integer number of characters in base; base, an ASCII string containing the base target file name; nf, an integer number of characters in famly; family, an ASCII string containing the base source file name; and nc an integer approximate number of curves per ULTRA target file.
See also PAMRGN.
integer
PAMRGF(integer nb,
char *base,
integer nf,
char *family,
integer nc)
integer pamrgf
.
.
.
if (
pamrgf(3, bar, 3, foo, 1000) .eq. 0)
$ call errproc
.
.
.
5.10.5 PAMRGN
integer
PAMRGN(integer nb,
char *base,
integer nn,
char *names,
integer nc)
Merge a set of ULTRA files into a single file or family of files. The ULTRA source files are specified here explicitly by name.
ULTRA target files produced by this function follow the naming convention
base.udd
where base is the base target file name supplied and dd are base 36 digits (0-9a-z).
Input to this function is: nb, an integer number of characters in base; base, an ASCII string containing the base file name; nn, an integer number of characters in names; names, an ASCII string containing the space delimited full names of the ULTRA source files; and nc an integer approximate number of curves per ULTRA target file.
See also PAMRGF.
integer
PAMRGN(integer nb,
char *base,
integer nn,
char *names,
integer nc)
integer pamrgn
character*8 names(3)
.
.
.
c merge files foo.u09 through foo.u0b
names(1) = foo.u09
names(2) = foo.u0a
names(3) = foo.u0b
if (
pamrgn(3, bar, 24, names, 1000) .eq. 0)
$ call errproc
.
.
.
5.10.6 PATHFM
integer
PATHFM(integer fileid)
Check the current files size against the maximum size as specified in the PATHOP call. If the file is larger than the maximum size, close the file, open the next member of the file family, and return an id for the new file.
Input to this function is: fileid, an integer file identifier.
See also PABREC, PAAREC, PAEREC, PAWREC, and PATHOP.
integer
PATHFM(integer fileid)
integer pathfm
integer nfid, fid
.
.
.
nfid =
pathfm(fid)
if (nfid .eq. -1)
$ call errproc
if (nfid .ne. fid)
$ fid = nfid
.
.
.
5.10.7 PATHOP
integer
PATHOP(integer nf,
char *name,
integer nm,
char *mode,
integer sz,
integer np,
char *prev)
Open a new time history data file. This implicitly defines a family of files. The name should be of the form: base.tdd where d is a base 36 digit (i.e. 0-9a-z). This is only a convention, but there are certain consequences for not following it in as much as the familying mechanism assumes that the last two characters form a base 36 number and increments it accordingly. As an application writes data to a time history file, periodic calls to PATHFM should be made to monitor the file size and when necessary close the current family member and open the next.
Since simulations may be restarted and each code may have a different strategy for continuing time history collection in the event of a restart, it is necessary to allow for name changes in the family. The consequence of this is that each member of a file family must contain the name of the previous file in the family. In that way, the transpose process may unambiguously and under the control of the user or simulation follow a chain of time history files from the end point back to the beginning. The prev argument is used to supply this information. The family of files that follows will be in sequence from the name supplied. Only across restarts, which implies calls to PATHOP, may the sequence name be changed. A call to PATHOP may have 0 for np which indicates the absolute beginning of the sequence, i.e. the transpose will stop in its search for files at this point.
See also PABREC, PAAREC, PAEREC, PAWREC, and PATHFM.
integer
PATHOP(integer nf,
char *name,
integer nm,
char *mode,
integer sz,
integer np,
char *prev)
integer pathop
.
.
.
fid =
pathop(3, foo, 1, w, 1000000, 4, blat)
if (fid .eq. -1)
$ call errproc
.
.
.
5.10.8 PATHTL
integer
PATHTL(char *names,
integer ord,
int nc)
WARNING: This is a deprecated function. Use PATRNL instead.
Write an ULTRA file by transposing the time history data from a specified set of time history files. The time history files are specified here by giving the names of files at the end of file family chains.
On occasion, files in a family are lost. This breaks the chain of files as well as leaving gaps in the data. Since this function can take many file names, it can be used to take into account missing files by supplying the files at the top of the gap(s) of missing files. In the accompanying example it is assumed that the files foo.t09 through foo.t11 are missing.
name.tdd
where name is the base file name and dd are base 36 digits (0-9a-z).
name.udd
Input to this function is: names, an ASCII string containing the space delimited full names of the time history files; ord, an integer flag specifying the order of processing; and nc a maximum number of curves per file in the ULTRA file family.
See also PATRNN and PATRNF.
integer
PATHTL(char *names,
integer ord,
int nc)
integer pathtl
character*8 names(2)
.
.
.
c files foo.t09 through foo.t11 are missing
names(1) = foo.t1f
names(2) = foo.t08
if (
pathtl(names, -1, 1000) .eq. 0)
$ call errproc
.
.
.
5.10.9 PATHTN
integer
PATHTN(char *names,
integer ord,
int nc)
WARNING: This is a deprecated function. Use PATRNN instead.
Write an ULTRA file by transposing the time history data from a specified set of time history files. The time history files are specified here explicitly by name.
On occasion, it is desirable to transpose only selected files from a family. For example, a user may know that only certain times are of interest and doesnt wish to see the entire data set. This function gives the finest level of control to the application about which files to transpose.
name.tdd
where name is the base file name and dd are base 36 digits (0-9a-z).
name.udd
Input to this function is: names, an ASCII string containing the space delimited full names of the time history files; ord, an integer flag specifying the order of processing; and nc a maximum number of curves per file in the ULTRA file family.
See also PATRNL and PATRNF.
integer
PATHTN(char *names,
integer ord,
int nc)
integer pathtn
character*16 names(4)
.
.
.
c only transpose foo.t09 through foo.t0b
names(1) = foo.t09
names(2) = foo.t0a
names(3) = foo.t0b
names(4) =
if (
pathtn(names, 1, 1000) .eq. 0)
$ call errproc
.
.
.
5.10.10 PATHTR
integer
PATHTR(integer nf,
char *name,
integer nc)
WARNING This is a deprecated function. Use PATRNF instead.
Write an ULTRA file by transposing the time history data from a given set of time history files.
A family of time history files is conventionally named
name.tdd
where name is the base file name and dd are base 36 digits (0-9a-z).
name.udd
Input to this function is: nf, an integer number of characters in name; name, an ASCII string containing the base name of the time history file family; and nc a maximum number of curves per file in the ULTRA file family.
See also PATRNL and PATRNN.
integer
PATHTR(integer nf,
char *name,
integer nc)
integer pathtr
.
.
.
if (
pathtr(3, foo, 1000) .eq. 0)
$ call errproc
.
.
.
5.10.11 PATRNF
integer
PATRNF(integer nf,
char *name,
integer ord,
integer nc)
Write an ULTRA file by transposing the time history data from a given set of time history files.
A family of time history files is conventionally named
name.tdd
where name is the base file name and dd are base 36 digits (0-9a-z).
name.udd
There is the possibility inherent in this model of handling file families that two or more files to be processed will have data for some regions in time. Because of the underlying PDB machinery, the data from the last file processed will predominate. Also, since the files are linked together from latest to earliest, it is sometimes necessary to require that the files be processed in the opposite order in which they are specified. The ord argument is used for this purpose. A value of 1 causes the files to be processed in the order in which they are specified while a value of -1 causes them to be processed in reverse order.
See also PATRNL and PATRNN.
integer
PATRNF(integer nf,
char *name,
integer ord,
integer nc)
integer patrnf
.
.
.
if (
patrnf(3, foo, 1, 1000) .eq. 0)
$ call errproc
.
.
.
5.10.12 PATRNL
integer
PATRNL(int nn,
char *names,
integer ord,
int nc)
Write an ULTRA file by transposing the time history data from a specified set of time history files. The time history files are specified here by giving the names of files at the end of file family chains.
On occasion, files in a family are lost. This breaks the chain of files as well as leaving gaps in the data. Since this function can take many file names, it can be used to take into account missing files by supplying the files at the top of the gap(s) of missing files. In the accompanying example it is assumed that the files foo.t09 through foo.t11 are missing.
name.tdd
where name is the base file name and dd are base 36 digits (0-9a-z).
name.udd
Input to this function is: nn, an integer number of characters in names; names, an ASCII string containing the space delimited full names of the time history files; ord, an integer flag specifying the order of processing; and nc a maximum number of curves per file in the ULTRA file family.
See also PATRNN and PATRNF.
integer
PATRNL(int nn,
char *names,
integer ord,
int nc)
integer patrnl
character*8 names(2)
.
.
.
c files foo.t09 through foo.t11 are missing
names(1) = foo.t1f
names(2) = foo.t08
if (
patrnl(16, names, -1, 1000) .eq. 0)
$ call errproc
.
.
.
5.10.13 PATRNN
integer
PATRNN(int nn,
char *names,
integer ord,
int nc)
Write an ULTRA file by transposing the time history data from a specified set of time history files. The time history files are specified here explicitly by name.
On occasion, it is desirable to transpose only selected files from a family. For example, a user may know that only certain times are of interest and doesnt wish to see the entire data set. This function gives the finest level of control to the application about which files to transpose.
name.tdd
where name is the base file name and dd are base 36 digits (0-9a-z).
name.udd
Input to this function is: nn, an integer number of characters in names; names, an ASCII string containing the space delimited full names of the time history files; ord, an integer flag specifying the order of processing; and nc a maximum number of curves per file in the ULTRA file family.
See also PATRNL and PATRNF.
integer
PATRNN(int nn,
char *names,
integer ord,
int nc)
integer patrnn
character*8 names(3)
.
.
.
c only transpose foo.t09 through foo.t0b
names(1) = foo.t09
names(2) = foo.t0a
names(3) = foo.t0b
if (
patrnn(24, names, 1, 1000) .eq. 0)
$ call errproc
.
.
.
5.10.14 PAWREC
integer
PAWREC(integer fileid,
integer recid,
integer inst,
integer nr,
vr)
Write out nr instances of time history data whose structure has been defined by PABREC, PAAREC, and PAEREC. This function writes out nr complete instances of a time history record! Using this function an application can manage multiple sets of time history data which are written at different frequencies.
Input to this function is: fileid, an integer identifying a PDB file; recid, an integer identifier specifying a time history record type; inst, an integer specifying the instance index of the records to be written; nr, an integer specifying the number of instances of the structure pointed to by vr; and vr, the data to be written.
See also PAAREC, PABREC, PAEREC, and PAWRIA.
integer
PAWREC(integer fileid,
integer recid,
integer inst,
integer nr,
vr)
integer pawrec
integer fileid, recid
real*8 vr(9)
.
.
.
if (
pawrec(fileid, recid, 14, 3, vr) .eq. 0)
$ call errproc
.
.
.
5.10.15 PAWMEM
integer
PAWMEM(integer fileid,
integer recid,
integer nc,
char *name,
integer inst,
vr)
Write out one member of a time history data record whose structure has been defined by PABREC, PAAREC, and PAEREC. This function writes out one member of a time history record. Its utility is most apparent when the member is an array which could be large or is part of a very large record.
Input to this function is: fileid, an integer identifying a PDB file; recid, an integer identifier specifying a time history record type; nc, an integer number of characters in the member string; member, an ASCII string naming the member desired; inst, an integer specifying the instance number; and vr, the data to be written.
See also PAAREC, PABREC, PAEREC, and PAWRIA.
integer
PAWMEM(integer fileid,
integer recid,
integer nc,
char *name,
integer inst,
vr)
integer pawmem
integer fileid, recid
real*8 vr(100,100)
.
.
.
if (
pawmem(fileid, recid, 3, v_1, 14, vr) .eq. 0)
$ call errproc
.
.
.
5.10.16 PAWRIA
integer
PAWRIA(integer fileid,
integer nv,
char *var
integer inst,
integer na,
char *attr,
value)
Assign an attribute value to the indicated time history data instance.
Input to this function is: fileid, an integer identifying a PDB file; nv, an integer number of characters in the string var; var, an ASCII string naming the time history data entry; inst, an integer specifying the instance index of the records to be written; na, an integer specifying the number of characters in the attribute name; attr, an ASCII string containing the name of an attribute; and; and value, the attribute value.
See also PAAREC, PABREC, PAEREC, and PAWREC.
integer
PAWRIA(integer fileid,
integer nv,
char *var
integer inst,
integer na,
char *attr,
value)
integer pawria
integer fileid
character*8 datestr
.
.
.
if (
pawria(fileid, 6, t-data, 3, 4, date, datestr)
$ .eq. 0) call errproc
.
.
.
5.10.17 FORTRAN API
Time History Example
Here is an example of using the time history functionality of PANACEA.
5.11 Miscellaneous
6.0 PANACEA Initial Value Problem Generators
6.1 Generic Commands Supplied by PANACEA
dump
Build the database and write a restart dump.
end
Shutdown the generator.
graph
Specify a plot request.
name
Set the value of a name for the current package.
package
Specify the package to which subsequent SWITCH, PARAMETER, and NAME commands apply.
parameter
Set the value of a parameter for the current package.
read
Read a file of generator commands.
s
Continuation of last specify command.
specify
Specify an initial value constraint (BC, SRC, or <variable>). The precise syntax for this command is:
spec-list := spec-list spec | spec
spec := from file |
value
The specifications at and along are simply put their associated value into the array of floating point numbers which the specify command constructs. In short, they are for the clarity of the input command. The in specification invokes the PA_reg_hook to map a name to a number which goes in the array which specify builds. The intention again is to provide an additional level of clarity by allowing users of a PANACEA code to be able to specify at least some information by name. Any value can be denoted by an alias which is defined by a call to
switch
Set the value of a switch for the current package.7.0 PANACEA Supplied Physical Constants
PANACEA provides a service for handling physical units in simulation packages. It is geared toward solving problems associated with importing and exporting packages between PANACEA codes and toward letting the code developer and code users have control over the systems of units in which problems are run and debugged.7.0.1 Pure Numbers
alpha
Fine structure constant = 7.297353080e-3
Coulomb
Coulomb in fundamental charges = 6.241506363e18
N0
Avogadros number = 6.02213665e237.0.2 Fundamental Physical Constants
c
Speed of light (cm/sec) = 2.99792458e10
Gn
Newtonian gravitational constant (cm3/g-sec2) = 6.673231e-8
Hbar
Plancks constant divided by 2Pi (erg-sec) = 1.05457267e-27
kBoltz
Boltzman constant (erg/K) = 1.380658e-16
M_e
electron mass (g) = 9.109389754e-287.0.3 Derived Physical Constants
e
Electron charge, sqrt(alpha*Hbar*c) (esu) = 4.80320680e-10
eV_erg
eV to erg, 1.0e7/Coulomb (erg/eV) = 1.60217733e-12
HbarC
Hbar*c (eV-cm) = 1.97327054e-5
M_a
Atomic mass unit, 1/N0 (g) = 1.660540210e-24
M_e_eV
Electron mass, Me*c*c/eV_erg (eV) = 5.10999065e5
Ryd
Rydberg, (M_e*c2*alpha2)/2 (eV) = 13.605698140
DEG_RAD
Conversion from degrees to radians = 0.017453292519943295
PI
= 3.1415926535897931
RAD_DEG
Conversion from radians to degrees = 57.2957795130823238.0
Physical Units in PANACEA
Type Macro Variable
angle RAD PA_radian
STER PA_steradian
charge Q PA_electric_charge
energy EV PA_eV
ERG PA_erg
length CM PA_cm
mass G PA_gram
number MOLE PA_mole
temperature K PA_kelvin
time SEC PA_sec
volume CC PA_cc
The code developer can define new units with a call to PA_def_unit. PA_def_unit takes a numerical value and a list of previously defined units and returns the index of a newly defined unit. For example, the units CM, SEC, ERG and CC are defined as:
PA_cm = PA_def_unit(1.0, UNITS);
PA_sec = PA_def_unit(1.0, UNITS);
PA_erg = PA_def_unit(1.0, G, CM, CM, PER, SEC, SEC, UNITS);
PA_cc = PA_def_unit(1.0, CM, CM, CM, UNITS);
In this way both primitive units, i.e. units which dont depend on any previously defined unit, and compound units may be defined and used by PANACEA code systems. #define CM PA_cm
#define SEC PA_sec
#define ERG PA_erg
#define CC PA_cc
would be the appropriate sort of association. length_internal = length_cgs*unit[CM]
length_external = length_cgs*convrsn[CM]
The two situations in which this is most useful is during initial value problem generation when the data which has been read in has not yet been used to create the data structures and arrays to be used in the simulation itself and during the simulation when data from source files is brought in. /* INIT_CONT - initialize the controls */
init_cont(def_unit_flag)
int def_unit_flag;
{PA_def_units(FALSE);
/* set up the physical constants in CGS units */
PA_physical_constants_cgs();
/* define the internal system of units
* if def_unit_flag it TRUE, natural units with Hbar = c = 1
* are defined
*/
if (def_unit_flag)
{unit[G] = g_icm;
unit[SEC] = c;
unit[K] = eV_icm*(kBoltz/eV_erg);
unit[EV] = eV_icm*unit[Q]*unit[Q]/unit[CM];}
/* the alternate internal system of units is the modified CGS system
* with temperatures in eV
*/
else
unit[K] = kBoltz/eV_erg;
/* define the external units to be modified CGS with
* temperatures in eV
*/
convrsn[K] = kBoltz/eV_erg;
/* make the conversion factors consistent with these changes */
PA_set_conversions(TRUE);
/* set up the physical constants in the external system of units */
PA_physical_constants_ext();
return;}
At this point the initial value problem generator has as consistent set of units and physical constants. If the user changes the systems of units in the input deck, the calls to PA_set_conversions and PA_physical_constants_ext should be repeated to keep every thing consistent.
9.0 Source Data Handling in PANACEA
10.0 The PANACEA Cookbook
The purpose of this section is to provide some concrete guidance to users who want to get started with PANACEA. The first two subsections describe how to analyze a simulation code with a view to building a new code from scratch or to converting an existing code to use PANACEA services. The last subsection gives extracts of the source code to the PANACEA code system, ABC. The extracts were taken to exemplify the PANACEA interface and to give complete (i.e. with full detail) functions which define PANACEA packages.10.1 Building a PANACEA Code System
The first place to start when building a PANACEA code is at the top. Since PANACEA is a model of a simulation code, the new code should be conceptualized in terms of the PANACEA model.
Replace dimensional numeric constants with variables whose values are constructed from the fundamental physical constants supplied by PANACEA (or plan on defining additional constants - see the section on Physical Units in PANACEA). x = 2.99e10*t;
with x = c*t;
When this process is complete, the only numeric constants in the code should be pure numbers, i.e. dimensionless.
With each package there will be a set of variables which the package owns. A helpful way to identify these is to ask what would be required to hand this package to another code system. Variables will fall into three main classes: RESTART, RUNTIME, and EDIT. The variable dimensions are typically stored in the swtch array for the package for efficiency in handling the state file. def_foo(pck)
PA_package *pck;
{P_dim_1 = &swtch[4];
P_dim_2 = &swtch[5];
P_dim_3 = &Two_I;
P_dim_4 = &Three_I;
/* RESTART VARIABLES */
PA_def_var(foo_var_1, SC_INTEGER_S, NULL, NULL,
SCOPE, RESTART, CLASS, OPTL, ATTRIBUTE,
P_dim_1, DIMENSION, UNITS);
/* RUNTIME VARIABLES */
PA_def_var(foo_var_2, SC_DOUBLE_S, NULL, NULL,
ATTRIBUTE,
P_dim_2, P_dim_3, DIMENSION, UNITS);
/* EDIT VARIABLES */
PA_def_var(foo_var_3, SC_INTEGER_S, NULL, NULL,
SCOPE, EDIT, CLASS, PSEUDO, ATTRIBUTE,
P_dim_4, DIMENSION, UNITS);
return(TRUE);}
With each package there will be a set of controlling parameters. PANACEA provides for an array of integer parameters, double precision parameters, and ASCII strings associated with each package. This permits efficient handling of these controls and does not hamper the code developer in associating them with named scalar variables.
cont_foo(pck)
PA_package *pck;
{static int n_names = 2, n_params = 2, n_swtches = 5;
PA_mk_control(pck, foo, n_names, n_params, n_swtches);
swtch[1] = TRUE; /* main switch - use this package if TRUE */
swtch[2] = 1; /* option #1 */
swtch[3] = 0; /* option #2 */
swtch[4] = 0; /* number of bar_1 values */
swtch[5] = 0; /* number of bar_2 values */
param[1] = 1.0; /* multiplier 1 */
param[2] = 1.0; /* multiplier 2 */
return(TRUE);}
Note: 1) the use of PA_mk_control; and 2) the static integers n_names, n_params and n_swtches which define the length of the swtch, name, and param arrays respectively.
This function will be executed once at start up and should connect database variables with local pointers as well as allocating local variables which will endure for the entire simulation run.
int *loc_var_1;
double *loc_var_2;
foo_init(pck)
PA_package *pck;
{N_foo_1 = swtch[2];
N_foo_2 = swtch[3];
/* PA_CONNECT for database variables */
PA_CONNECT(foo_var_1, variable_1, int *, TRUE);
/* MAKE_N for non-database local variables */
loc_var_1 = MAKE_N(int, N_foo_1);
loc_var_2 = MAKE_N(double, N_foo_1*N_foo_2);
return(TRUE);}
Note: 1) the use of PA_CONNECT and MAKE_N; and 2) the dimension constants extracted from the swtch array.
Since many packages will want to vote on the timestep for the next major computational cycle and since it will be useful for most packages to monitor their performance, it will be a good idea to build a wrapper function around the package main entry point. It is also a good place to invoke initializations which occur every time the main entry point is invoked as well as clean up after it has been executed.
main_foo(pck)
PA_package *pck;
{int foo_z;
double foo_dt;
static int first = TRUE;
/* check that this package was requested */
if (swtch[1] == FALSE)
return;
if (first)
pck->space = (double) Ssp_alloc;
PA_MARK_TIME;
init_cycle();
/* do the real work of foo*/
foo_work(&foo_dt, &foo_z);
/* record the hydro timestep vote */
pck->dt = foo_dt;
pck->dt_zone = foo_z;
PA_ACCM_TIME(pck->time);
if (first)
{pck->space = (double) Ssp_alloc - pck->space;
first = FALSE;};
return;}
Note: the use of PA_MARK_TIME and PA_ACCM_TIME.
Each input command that the initial value problem generator will have to parse requires a function which does the actual parsing and takes the appropriate actions. One function may handle many different commands, but it is best to keep the functions simple and that usually makes the correspondence between commands and functions one to one. For an existing code, the coding for these routines probably already exists but may have to be reorganized.
void command_1h()
{char *token_1, *token_2;
int i1, i2;
token_1 = PA_get_field(TOKEN_1, COMMAND_1, REQU);
token_2 = PA_get_field(TOKEN_2, COMMAND_1, REQU);
i1 = PA_stoi(PA_get_field(INTEGER_1, COMMAND_1, REQU));
i2 = PA_stoi(PA_get_field(INTEGER_2, COMMAND_1, REQU));
N_foo_1 = i1;
N_foo_2 = i1*i2;
return;}
Note: the use of PA_get_field and PA_stoi.
Not all packages require specific generator commands. The generic commands supplied by PANACEA may be sufficient. However, if commands have been defined in the previous step they must be made known to PANACEA. All commands are installed in a hash table which is used by PANACEA to process ASCII input files or interactive commands. foo_cmmnds()
{PA_inst_c(command_1, NULL, FALSE, 0, command_1h,
PA_zargs, commands);
/* optionally initialize some constants */
N_foo_1 = 0;
N_foo_2 = 0;
return;}
Note: the use of PA_inst_c and the reference to the function command_1h.
Before a state (restart) dump can be made two things must happen. First, the data read in from the input deck must be transformed into data structures usable by the simulation routines. Second, those data structures must be made available to the database, a process called interning. A function is supplied by the code developer whose responsibility is to ensure that the packages contribution to the database is complete and ready to be dumped. intern_foo()
{
swtch[4] = N_foo_1;
swtch[5] = N_foo_2;
PA_INTERN(foo_var_1, variable_1, int);
return;}
Note: 1) the use of PA_INTERN; and 2) the setting of the control array values (here swtch).
Make the foo package known to the PANACEA initial value problem generator code, A.
PA_gen_package(foo, foo_cmmnds, NULL, NULL, def_foo,
cont_foo, intern_foo);
Make the foo package known to the PANACEA main simulation code, B.
PA_run_time_package(foo, NULL, NULL, def_foo, cont_foo,
init_foo, main_foo, NULL, NULL);
This may seem like quite a lot of work. For an existing code, in some sense it is akin to starting over and building a new code, but the big advantage is that most of the coding already exists, has been tested, and has a base of test input problems. On the other hand, the payoff can be quite large rather quickly. The output data for the code will be completely portable. There is at least one existing system for visualizing the data produced which is very flexible and available on all sorts of computer platforms. Furthermore, for code systems which share the same computational meshes, there may be readily available routines that will provide interim or permanent capabilities (mesh generators, common packages, etc.).10.2 The Monolithic Approach
One way to approach converting an existing code system into a PANACEA code system is to start by viewing the entire simulation code as a single, global package. The advantage is that a few relatively simple pieces of interface coding will get the conversion going fairly quickly. Since there will be small amounts of interface coding, the connections to PANACEA services can be written one by one and tested before proceeding. The entire process becomes more of an evolutionary one than a major code rewrite exercise.10.3 ABC: A PANACEA Code
ABC is a simple 2d hydrodynamics code which shows how a PANACEA code system is structured. The A code is an initial value problem generator, the B code is the main simulation code, and the C code is a post processing code which transforms PANACEA output files for a particular visualization system.11.0 TOUL
TOUL is a stand alone utility to transpose time history files written by PANACEA into a family of ULTRA files.
name.tdd
where name is the base file name and dd are base 36 digits (0-9a-z).
-d Turn on debug mode for memory info
-f Use explicitly specified TH files
-h Print this help message and exit
-l Use internal links in TH files
+o Process TH files in the order specified (default)
-o Process TH files in reverse order
See the discussions of PA_th_trans_link,
This will result in a family of ULTRA files beginning with foo.u00.
The curves in the resulting ULTRA files will have a gap corresponding to the missing data from foo.t09 through foo.t12.
Because this is the most general level on which you can approach the transposition process, the resulting curves in the ULTRA files can look a little strange. You may have to get used to the gaps that might result from pieces of data widely spaced in time.
t ; system time
tstart ; system start time
tstop ; system stop time
dtf ; system time step fraction
dtfmin ; minimum time step fraction
dtfmax ; maximum time step fraction
dtfinc ; maximum time step fractional increase
cycle ; system time cycle number
nzones) ; number of computational units (zones)
sfname ; state file name
edname ; edit file name
ppname ; pp file name
pvname) ; PVA file name
simulation-init-problem
simulation-run-problem
simulation-fin-problem
combined-init-problem
combined-run-problem
combined-fin-problem
generator-termination
simulation-termination
interrupt-handler
generator-error-handler
region-name-to-index
pre-intern
domain-builder
mapping-builder
Only specified functions can be called. PANACEA doesnt attempt to call it if you dont define it. Any functions used here that are not PANACEA functions (PANACEA functions all begin with PA_ or _PA_) must be declared in a declare-function statement.
EXAMPLE: simulation-termination B_term
interrupt-handler PA_interrupt_handler
generator-error-handler A_gen_err
region-name-to-index part_reg
pre-intern load_reg
domain-builder LR_build_domain
mapping-builder LR_build_mapping)
spec := function handler |
type array index
type := integer | real | string
The second form of spec allows an application to name an element of an array as a command which sets the value of the element.
dimension integer swtch 1)
type := ascii | integer | real
EXAMPLE: ascii 8 NULL input deck name (ASCII)
integer 14 0 generation time mesh dumps if TRUE)
function-spec := type name arg-list
arg-list := (arg*)
arg := type [*]*name
type := any defined type (e.g. double)
EXAMPLE: char * foo (int s double t)
variable-spec := [class] type name dims initial-value
class := static | extern | const
type := any defined type (e.g. double)
dims := ()
initial-value := number
EXAMPLE: static int foo 3)
mesh-spec
[attribute-list
[unit-list
[init-val
[init-fnc
[data-pointer]]]]])
variable-spec := variable | ([variable]+)
type := any defined type (e.g. double)
mesh-spec := mesh | ([mesh]+)
attribute-list := [attribute]*
attribute := scope | class | persist |
allocation | center
scope := restart | runtime | demand | edit | defn
class := requ | optl | pseudo
persist := keep | cache-f | cache-r | rel
allocation := static | dynamic
center := zone | node | edge | face | un-centered
unit-list := (unit*)
unit := user-defined-unit | per |
rad | ster | mole | Q | cm | sec | g |
eV | K | erg | cc
init-val := a declare-variabled name
init-fnc := a declare-functiond name
data-pointer := a declare-variabled name
EXAMPLE: (def-var knob-a integer ()
(restart static)
()
kav () knoba)
(def-var cache-f-4 double spatial
(restart cache-r zone)
(K)
pi)
language := C | C++ | F77
type := + | -
The language argument allows the user to specify the target language of the generated code. At this time only C and C++ are support. Plans are for future versions to produce Fortran77 code. If type is + use SX extensions; and if - use PANACEA only. The argument name1 is the name of the generator code if name2 is also given; otherwise it is the name of the combined code. name2 is the name of the simulation code if given. Two names implies two codes and one name implies a combined code.
(generate C++ + a b)
(generate C++ - a b)
The files are the literal names of header files which the preprocessor must be able to find as specified.
mesh-spec := name variable
EXAMPLE:
EXAMPLE:
EXAMPLE: initialize global_init
main-entry global_main)
member := type [*]*member_name
type := any defined type (e.g. double)
EXAMPLE: double b)
name.udd
Its usage is:12.0 PANACHE
PANACHE is a tool to automate the process of building interface coding between numerical simulation code packages and PANACEA. PANACHE does this by processing a dictionary which contains compact and concise descriptions of variables, functions, commands, and actions. [...]* means zero or more of the items in the brackets
[...]+ means one or more of the items in the brackets
The following variables are pre-defined in PANACHE:
NULL - used to indicate a null pointer (ala NULL in C).
12.1
Commands
12.1.1
Global Definition Commands
generator-init-problem
simulation-init-problem
simulation-run-problem
simulation-fin-problem
or combined-init-problem
combined-run-problem
combined-fin-problem
system-scalars
Specify scalar variables which contain global information required by PANACEA.
system-files
Specify ASCII variables which contain the names of files used by PANACEA.
system-functions
Specify functions which PANACEA will call under certain conditions. Each function is paired with a name. All pairs are optional, but functions must be paired with the names. The current meaningful names for PANACEA are:
generator-termination global_end_graphics
12.1.2
Package Definition Commands
command
Defines generator commands.
side sideh PA_zargs
control
Defines PANACEA control items.
real 1 0.0 current problem time (internal units)
declare-function
Declare one or more functions pertaining to the package. These functions may be ones that are defined in hand coded routines but need to be referenced in generated code. They may also be given so that a complete package header can be generated. At this writing declarations involving pointers must be enclosed in quotes.
void load_reg ()
declare-variable
Declare one or more variables pertaining to the package. These variables may be ones that are referenced in hand coded routines but need to be referenced and or defined in generate code. They may also be given so that a complete package header can be generated. At this writing declarations involving pointers must be enclosed in quotes.
double bar ()
def-var
Define one or more database variables.
(def-var lindex long spatial (restart))
generate
Causes PANACHE to generate compilable code from the currently defined dictionary.
(generate C - fubar)
include
Specify one or more header files to be included by the header for the current package.
mesh
Define a mesh for the package. A mesh here corresponds to an array dimension.
package
Begins the definition of the named package. The definition continues until the next package command or until a generate command. The package name must be a legal C or Fortran identifier since it will be used to generate function and variable names.
package-functions
Defines the package functions that will be called by PANACEA. The following list shows all of the package functions available in PANACEA:
intern-variables global_intern
typedef
Define a structured data type. Database variables may be declared to be of any type (or any depth of
int *a
12.2 Example: ABC Dictionary
In this section we present a sample dictionary. This dictionary generates the interface coding for the ABC PANACEA test code. The actual listing is broken down into sections to allow for discussion.12.2.1 The ABC System Information
In many PANACEA codes there is some information about the entire code system which does not belong to any one package. Global time information is one example. The system of file families managed by PANACEA is another. At this point, this information is required to generate coding for the main routines where the A and B (or the combined AB code) start up.
12.2.2 The ABC Global Package
The global package in the PANACEA model has a special place in that it may provide for a computational mesh or some other central activity. This package provides a 2d mesh generator for the 2d hydrodynamics package in the next section.
12.2.3 The ABC Hydro Package
The ABC hydro package is a simple 2d hydro package which does actual hydrodynamics so that certain meaningful tests of PANACEA can be carried out (especially regarding post processing and package control functions).
12.2.4 The ABC Miscellaneous Package
This package is used to test various facets of PANACEA functionality. It has almost no significance as far as a simulation goes. It demonstrates more of the ways in which the dictionary defining function of PANACHE can be used.
12.2.5 Completing ABC
Once the system level information and the packages have been defined, PANACHE can be directed to generate the source code for a variety of configurations and in this case the compilation executed.
13.0 Other Documentation
PANACEA is a part of the PACT portable code development and visualization tool set. It depends on most of PACT. Readers may find useful material in the other PACT documents. PACT Users Guide, UCRL-MA-112087
SCORE Users Manual, UCRL-MA-108976 Rev.1
PPC Users Manual UCRL-MA-108964 Rev.1
PML Users Manual, UCRL-MA-108965 Rev.1
PDBLib Users Manual, M-270 Rev.2
PGS Users Manual, UCRL-MA-108966 Rev.1
PANACEA Users Manual, M-276 Rev.2 (this document)
ULTRA II Users Manual, UCRL-MA-108967 Rev.1
PDBDiff Users Manual, UCRL-MA-108975 Rev.1
PDBView Users Manual, UCRL-MA-108968 Rev.1
SX Users Manual, UCRL-MA-112315
Some additional references to work that readers may find interesting and useful are: