Index

NAME

FieldReader - reading of fields from simres files


INCLUDE

include "FieldReader.h"

SYNTAX

 class FieldReader
 {
 private:

   String name_of_dataset;

   // data input files
   Is fieldfile;
   Is gridfile;

   // index files
   Is field_ixfile;
   Is grid_ixfile;

   // files open/closed flag
   bool files_open;

   void ignoreString (Is& input, const String& string);
   void readGridHeader (int& gridnumber, int& checknumber, String& classname,
                        int& dimensions);
   long findGridAddress  (const int gridnum);

   void readFieldHeader
     (
      int&    fieldnum,
      String& header,
      real&   time,
      String& description,
      int&    gridrefnum,
      String& field_classname,
      int&    component,
      int&    maxcomponent
     );

   long findFieldAddress (const int fieldnum);

   void open();   // opens input files
   void close();  // closes input files

 public:
   FieldReader ();
   FieldReader (const String& dataset_name);
  ~FieldReader ();

   // it is possible to switch to another dataset:
   void setDatasetName (const String& dataset_name);

   int getNoFields ();
   int getNoGrids ();

   // returns information about the field identified by fieldnum
   void getFieldInfo
      (
       const int  fieldnum,
             String* header,
             real*   time = NULL,
             int*    dimensions = NULL,
             String* description = NULL,
             int*    component = NULL,
             int*    maxcomponent = NULL,
             String* fieldtype = NULL,
             String* gridtype = NULL
      );


   // This one takes header and time (optional) as input, and returns info
   // about the first matching field in the dataset. If the given time doesn't
   // match any field in the dataset, the closest match is returned and the value
   // of the time parameter will be replaced by the value found.
   // If no match is found, fieldnum will be set to 0.
   void getFieldInfo
      (
       const String header,
             int*    fieldnum,
             real*   time = NULL,
             int*    dimensions = NULL,
             String* description = NULL,
             int*    component = NULL,
             int*    maxcomponent = NULL,
             String* fieldtype = NULL,
             String* gridtype = NULL
      );


   void getGridInfo  // returns info about grid
      (
       const int  gridnum,
             int*    checknum = NULL,
             int*    dimensions = NULL,
             String* gridtype = NULL
       );


   void readField
      (
             Handle(Field)& field,
       const int            fieldnum = 1,
             String*        header = NULL,
             real*          time = NULL,
             String*        description = NULL,
             int*           component = NULL,
             int*           maxcomponent = NULL
      );
 };



DESCRIPTION

This  class  is a low-level tool mainly used from classes SimRes­
File or SaveSimRes.

The storage format is binary or ASCII. In binary mode we  try  to
use the hardware-independent xdr format if possible (on some sys­
tems, problems might arise with xdr and then the FieldReader  and
FieldWriter  classes  can be compiled using a straight (binary) C
file - see the .cpp file for how you can steer the compilation in
case  there  are  problems  with  the  xdr  format  in Is_xdr and
Os_xdr.)



MEMBER FUNCTIONS

setDatasetName - Sets the name of the dataset. When a dataset  is
already  open,  it will be closed and the FieldReader object will
connect to the new dataset instead.

getNoFields - Returns the number of fields in the  dataset.  This
is the number of scalar fields, counting each component of vector
fields.

getNoGrids - Returns the number of grids  in  the  dataset.  This
number  will be less than or equal to the number of fields in the
dataset, Because more than one field can use the same grid.

getFieldInfo - Returns information about the field with the spec­
ified  field  number.  The  information  includes the name of the
field, the registered time, the number of dimensions, the  number
of field components (if the field is part of a vector field), the
component number and the field type and grid type.

getFieldInfo - This overloaded version of the  function  takes  a
header  and  a  time  instead  of  a field number. It will try to
locate a matching field, and will set the  field  number  to  the
field  number of the field found. Note that an exact match of the
time is not necessary; the closest match  will  be  used.  If  no
match is found, the field number will be set to zero.

getGridInfo  -  Returns information about a grid specified by its
grid number.  The information includes the number  of  dimensions
and the grid type.

readField  -  This  function will read a field with the specified
field number.  All information for the field is returned. A  han­
dle  to a field which is to receive the information is given as a
parameter. If the existing field is based on the same grid as the
field  to be read, the existing grid will be used. Otherwise, the
grid will be read from the dataset and will replace the existing.



EXAMPLES

A simple code example of the usage is given below:

//  read and plot all field components in the dataset Simulation1
// also copy fields with the name Sim1 to a  new  dataset  Field­
Reader  reader(Simulation1);  FieldWriter  writer(SimCopy);  Han­
dle(Field) hField; GraphBasics plotter(Output.gb);  String  name;
int  numfields = reader.getNoFields(); for (int i=0; i<numfields;
i++) { reader.readField(field, i, &name);  // read a  field  from
the  dataset SimRes2gb::drawGrid(field, plotter);   // plot it if
(name==Sim1) writer.writeField(field, name); // write  the  field
to another dataset }

Some  background  information  about  the structure of the Field­
Reader/FieldWriter datasets are given here:

A dataset consists of 4 files. Grids are stored  sequentially  in
one  file, and fields (values for all the grid points) are stored
in another file.  To enable easy  and  fast  access  to  specific
fields  and  grids, each of the two data files has an index file.
The index files contain start positions for each field  or  grid.
Each field and grid is assigned a reference number. Each field in
a dataset will be stored with the reference number of its grid.

The classes and functions that  are  available  for  transferring
fields  and  grids  to  and from a dataset all use a general Han­
dle(Field). They do not know, and do not care about, what type of
field  or  grid  is being transferred.  All read/write operations
are performed by the Field/Grid objects themselves upon  request,
together       with       some       household       information.
FieldReader/FieldWriter will  therefore  support  new  field/grid
types with no changes.

Each  field  or  grid  can  be given a name, description and time
stamp when stored. These will be  returned  upon  retrieval.  The
name and time stamp can also be used for locating a field.

Vector  fields  are stored as a collection of scalar fields. Each
component (dimension) is  stored  separately,  and  can  also  be
retrieved  separately.   The  SimResFile  class is a higher level
interface that supports vector fields.

When writing a field to a dataset (using FieldWriter  or  SimRes­
File),  the grid will be stored to the dataset only if necessary.
The field values will always be stored. It is necessary to  store
a  grid to a dataset if it is not already present in the dataset.
It is, for example, not necessary to store a grid multiple  times
when  storing a field to a dataset several times during a simula­
tion. The logic used to determine whether a grid is already  pre­
sent in a dataset is as follows:

Each grid object keeps a list of the names of the datasets it has
been stored to. Before storing a grid to a dataset, the list will
be  checked to see if the grid is already stored in that dataset.
If not, the grid will be stored and the name of the dataset  will
be  added to the list.  Before reading a grid from a dataset, the
list will be checked to see if it has been read from or stored to
this  dataset  before.  If it has not, the grid will be read, the
list will be emptied and the name of the dataset will be added to
the  list.   Each  entry in the dataset list for a grid also con­
tains the grid number in the dataset, in addition to a  verifica­
tion  number created by a random generator when storing a grid to
a dataset.  The verification number is stored in the grid in  the
dataset  in addition to being remembered in the list. It makes it
possible to avoid an error if the contents of a dataset has  been
replaced so that the grid with the registered reference number in
the dataset is not equal to a grid object that has the dataset in
its  list. (This situation will normally not occur, unless multi­
ple users are accessing the same dataset. Nevertheless,  it  will
be detected if it occurs.)



SEE ALSO

Visualisering  av  skalar-  og  vektor-felt  by Fred Ivar Larsen,
1997.  (Thesis for the Cand.Scient. degree)

"Visualizing Scalar and Vector Fields  in  Diffpack  Hans  Petter
Langtangen / Fred Ivar Larsen


DEVELOPED BY

SINTEF Applied Mathematics, Oslo, Norway, and University of Oslo,
Dept. of Mathematics, Norway


AUTHOR

Fred Ivar Larsen, UiO