NAME
FieldFormat - flexible formats for a variable coefficient in PDEs
INCLUDE
include "FieldFormat.h"
SYNTAX
class FieldFormat
{
protected:
public:
enum FieldFormat_type
{
CONSTANT,
CONSTANT_VECTOR,
FIELD_ON_FILE,
FUNCTOR,
MATERIAL_CONSTANTS
};
FieldFormat_type format;
String specification; // the format string read by scan
// name of associated field - must be set!
String fieldname;
// constant:
real constant;
Ptv(NUMT) vec_constant;
// a C++ function or functor name:
String function_name;
VecSimple(real) function_prm;
// field on a file (simres format):
String filename;
String fieldname_on_file;
real time;
// values of a FieldPiWisConst object
Vec(NUMT) material_values;
FieldFormat ();
virtual ~FieldFormat () {}
void scan (String input);
// setFieldname must be called prior to define/scan:
FieldFormat& setFieldname (const String& some_name)
{ fieldname = some_name; return *this; }
static void defineStatic
(MenuSystem& menu, const String& default_answer, const String& fieldname,
int level = MAIN);
void define (MenuSystem& menu, const String& default_answer, int level);
FieldFormat& scan (MenuSystem& menu);
bool allocateAndInit (Handle(Field)& field, GridFE* grid);
bool allocateAndInit (Handle(Fields)& field, GridFE* grid);
bool allocateAndInit (Handle(FieldFE)& field);
bool allocateAndInit (Handle(FieldsFE)& field);
void writeHeadings (StringList& headings, const char* fieldname);
void writeResults (StringList& results);
void writeExtendedResults (MultipleReporter& report,
const char* fieldname = NULL,
Field* field = NULL);
};
extern bool splitSimResFileName
(String& filename, String& fieldname, real& t);
KEYWORDS
variable coefficient, function/constant/file, PDE
DESCRIPTION
The class enables flexible handling of various formats of a vari
able coefficient in a PDE. The variable coefficient is repre
sented as a scalar field, or more precisely, as a Diffpack Field
class. Different formats are supported, corresponding to differ
ent Diffpack scalar field subclasses: A field given as an
explicit function, usually a functor, a finite element field
given from a datafile, a field as a piecewise constant function
over subdomains (where "subdomain" refers to the material concept
in class GridFE and the material values are read interactively),
and a constant field. Using this class it is easy to write a
short answer on a menu and the program can easily treat the field
in question as a constant, a function or read it from file. The
class contains information on the field format, and to some
extent the field values (constants and piecewise constant fields
have their values stored in data members of this class, other
fields have their filenames or function names stored in the
class). By checking the contents of the class, it is easy in an
application program to perform the necessary actions to compute
the field values. See the reports Efficient Finite Element Solu
tion of the Linear Wave Equation in Diffpack and A Solver for
the Linear Thermo-elastic Equations.
CONSTRUCTORS AND INITIALIZATION
There are no constructors. The initialization is performed in
scan which usually reads string answers from a menu. In order to
make use of the define, scan and allocateAndInit functions, the
programmer must assign a proper value to name. This variable is
used to generate and read menu items as well as when allocating a
new field object (i.e. the new field objects gets the name name).
MEMBER FUNCTIONS
Most of the data structures are public and can hence be accessed
directly.
scan(String) - reads a string in a special format (see below) and
fills the internal data structures. To print the contents of a
FieldFormat object one can either simply print the specification
string (which has the same syntax as the input string to scan) or
one can use the internal data structures and format the output
string as desired.
writeHeadings - writes headings for a summary report (see class
MultipleReporter).
writeResults - writes results for a summary report (see class
MultipleReporter). The amount of output is similar to writeEx
tendedResults, except for the FIELD_ON_FILE field format which is
reported more compactly by writeResults. For the MATERIAL_CON
STANTS format, both writeHeadings and writeResults generates an
item for each material. For example, if the fieldname is a and
there are two materials, there will be two summary items: a_1 and
a_2.
writeExtendedResults - writes a more detailed text containing the
characteristics of the field. If the field is constant, the con
stant value is reported, if the field is stored in simres format
on a file, the filename and the fieldname is written. The user
can supply an optional argument field that points to the field in
question. This argument is used for extracting min and max values
for characterizing the field. Of course, this will only affect
the FIELD_ON_FILE format. For the MATERIAL_CONSTANTS format, the
output consists of one line of text for every material. More
details about the output format can be gained by reading the body
of the function.
defineStatic - adds an item about a field format on a menu. This
function requires the fieldname. The define function applies the
internal fieldname (name). Note that the internal fieldname name
must be initialized in order to use define, scan(MenuSystem) and
allocateAndInit. The advantage of using this function is that
the menu command details are hidden in the application program.
scan(MenuSystem) - initializes the FieldFormat object on basis of
a string supplied by the menu. This scan function simply extracts
a string from the menu and calls scan(String). The advantage of
using this function is that the menu command details are hidden
in the application program.
allocateAndInit - given a handle to a field, the functions check
the field format, allocates the proper field object and initial
izes the field values. Two of the functions take a GridFE*
pointer as a second, optional argument. This grid pointer is
used (that is, the grid must exist and be properly initialized)
for the MATERIAL_CONSTANTS format only. If the field format is
FUNCTOR, the programmer must explicitly allocate the field in the
calling program. This is also the case for some of the other for
mats (error messages are issued if one calls an unimplemented
feature).
When the allocateAndInit functions load the field from a simres
file, information about the time point is available as the data
member time of the FieldFormat object.
At present, only FieldFE or FieldsFE objects can be read from
file. If another field type is actually stored on file, SimRes
File::readFile will issue an error message. The allocateAndInit
functions could easily be extended to handle any type of field on
file (look at the comments in the FieldFormat.cpp file).
Two other allocateAndInit functions have only Handle(FieldFE) and
Handle(FieldsFE) arguments. These can only be used for the for
mats FIELD_ON_FILE and CONSTANT. The final allocateAndInit func
tions take Handle(FieldFE) and Handle(FieldsFE) arguments. These
functions also support only constant values and fields on file
and require the fields to be in an ok state if the format is CON
STANT or CONSTANT_VECTOR.
The return value of allocateAndInit is true if the allocation and
initialization were successful, otherwise (e.g. in case of a for
mat that is not supported by the function), a false value is
returned.
// given FieldFormat u_format, Handle(GridFE) grid and Han
dle(FieldFE) u
if (!u_format.allocateAndInit (u)) {
// make grid, e.g., by calling readOrMakeGrid
u.rebind (new FieldFE(grid(),"u"));
} else
// u_format allocated the field and the associated grid
grid.rebind (u->grid());
// proceed with initialization of ALL other fields that depend on
grid
Here is another useful variant:
void MySimulator:: init ()
{
// u0_format is a FieldFormat with the user-format for an ini
tial
// condition, u_prev is the corresponding handle (Han
dle(FieldFE))
if (!u0_format.initAndAllocate (u_prev))
{
if (u0_format.format == FieldFormat::FUNCTOR)
{
u_prev.rebind (new FieldFE (grid(), "u_prev"));
if (u0_format.function_name == "plane")
func.rebind( new PlaneFromLeftU(*this));
else if (u0_format.function_name == "spherical")
func.rebind( new SphericalU (*this));
// etc
}
// else: error, the format cannot be used
}
else
// initAndAllocate either read a field from file or initial
ized
// the u_prev field by a constant, according to the user's
menu
// choice (read by u0_format.scan)
u_prev.setFieldname ("u_prev");
In simulator classes one will usually use "allocateAndInit(Han
dle(Field)&,GridFE*) for reading and initializing coefficients in
the equations, whereas allocateAndInit(Handle(FieldFE)&) is bet
ter suited for reading a primary unknown from file and continue a
previously aborted simulation.
In order to see how the FieldFormat class can be used in a code,
we encourage the reader to study the functions define, scan and
allocateAndInit. Especially the latter may be of importance. If
you find the allocateAndInit function(s) inappropriate, it is
easy to copy the body of these member functions, make the neces
sary modifications and insert the statements in the calling pro
gram.
We should remark that the MATERIAL_CONSTANTS format is not suit
ble for FieldPiWisConst fields where the elements are the subdo
mains (then there are too many parameters to assign, at least
when the syntax of FieldFormat:.scan is used).
EXAMPLES
Here are some examples of input strings to scan:
CONSTANT = 5.7
results in format=CONSTANT and constant=5.7.
CONSTANT_VECTOR = (3,5.2)
results in format=CONSTANT_VECTOR and vec_constant=(3,5.2).
FIELD_ON_FILE = myfile("v",t=92.3)
results in format=FIELD_ON_FILE, filename=myfile (which is actu
ally the filename stem only, the field data are then in
.myfile.field), fieldname=v and time=92.3. The data given here
are in accordance with the class SimResFile standard. If the
field is stationary, the time has no meaning and one can write
FIELD_ON_FILE = myfile2("v")
Here time=DUMMY while the other variables have the same content
as in the previous example.
MATERIAL_CONSTANTS = 2.5 7.1 9 ;
reads the material values using the SetOfNo::scan syntax and
results in format=MATERIAL_CONSTANTS and material_values=(2.5 7.1
9). The present version of FieldFormat can only handle scalar
material values. The other formats (constants, file fields and
functions) can be used for both scalar and vector fields. al
Here we show how a function name can be given:
FUNCTOR = MyClass
Here we assume that the function is actually a functor and that
the name is the name of the class. The content of the FieldFormat
object is now format=FUNCTOR and function_name=MyClass. If one
uses the Diffpack convention and have create-functions, it is
easy to create a class object of type MyClass by passing func
tion_name to the create-function for the hierarchy of which
MyClass is a subclass. Most functions need a set of additional
parameters besides the function argument. For example, a Gaussian
bell function needs parameters for the shape. Such parameters can
be given as a part of the command like this:
FUNCTOR = MyClass(3.2,5.6,-1)
Finally, we demonstrate the convenient usage of the name vari
able, the define, scan and allocateAndInit functions. Suppose you
have (e.g. in a PDE solver class)
Handle(Field) v; // e.g. a coefficient in a PDE
FieldFormat v_format; // format information
Here is how you can create v applying the user's information
given through the menu system.
// given MenuSystem menu, Handle(Field) v and Handle(GridFE)
grid
v_format.name = "v"; // set the name of the field
v_format.define (menu, "CONSTANT=1.0", level);
v_format.scan (menu); // read e.g. FIELD_ON_FILE=myfile("v")
and init v_format
v_format.allocateAndInit (v, grid->getPtr()); // make v
This small code sequence puts the format info of v on a menu,
extracts the user's answers and creates a field v according to
the specification in v_format. The code works regardless of
whether v is a constant or a finite element field store somewhere
in a result file from some Diffpack simulatation. If v is a to be
read from file (FIELD_ON_FILE format), the allocateAndInit rou
tine will also allocate the proper grid for this field (the
GridFE* argument is then ignored). In other cases, e.g. with the
MATERIAL_CONSTANTS format, the supplied grid (grid->getPtr()) is
used as basis for the field and the values in v_format is loaded
into the field.
DEVELOPED BY
SINTEF Applied Mathematics, Oslo, Norway, and University of Oslo,
Dept. of Mathematics, Norway
AUTHOR
Hans Petter Langtangen, SINTEF/UiO