Index

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