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