NAME
FieldsFE - collection of finite element scalar fields (ie. vector
field)
INCLUDE
include "FieldFE.h"
SYNTAX
class FieldsFE : public FieldsWithPtValues
{
protected:
VecSimplest(Handle(FieldFE)) fesfvec; // array of scalar field pointers
public:
FieldsFE ();
FieldsFE (int n, // allocates n empty FieldFE components
const char* fieldname);
FieldsFE (GridFE& grid, // makes nsd equal fields of size nno
const char* fieldname);
FieldsFE (GridFE& grid, // makes n equal fields of size nno
int n, const char* fieldname);
FieldsFE (BasisFuncGrid& grid,
int n, const char* fieldname);
~FieldsFE ();
virtual void redim (int nsf, const char* fieldname);
bool redim (GridFE& grid, // makes nsd equal fields of size nno
const char* fieldname);
bool redim (GridFE& grid, // makes n equal fields of size nno
int n, const char* fieldname);
bool redim (BasisFuncGrid& grid,
int n, const char* fieldname);
virtual bool ok () const;
bool empty () const;
bool compatible (const FieldsFE& f) const;
bool update ();
FieldFE& operator () (int i);
const FieldFE& operator () (int i) const;
virtual FieldWithPtValues& component (int i);
virtual const FieldWithPtValues& component (int i) const;
void operator = (const FieldsFE& fields);
void operator = (const FieldsLattice& fields);
void fill (const FieldsFunc& func, real time);
void fill (NUMT value);
void fill (const Ptv(NUMT)& vec);
void interpolate (const FieldsFE& f);
virtual void attach (Field& field, int i = 1);
void attach (FieldFE& field, int i = 1);
void attach (FieldsFE& fields);
virtual void valuePt (Ptv(NUMT)& vec, const Ptv(real)& x,
real t = DUMMY);
virtual void valueFEM (Ptv(NUMT)& vec, const FiniteElement& fe,
real t = DUMMY);
void valueNode (Ptv(NUMT)& vec, int node) const;
void magnitude (FieldFE& m);
bool isoparametric() const;
virtual void print (Os os,
const char* heading =
"0rief printing of FieldsFE object") const;
virtual int getNoFields () const;
virtual int getNoValues () const;
virtual Field* getFieldBase (int i = 1) const;
CLASS_INFO
VIRTUAL_CAST(FieldsFE)
// temporary:
COPY_CONSTRUCTOR(FieldsFE);
};
KEYWORDS
finite elements, vector field, FieldFE
DESCRIPTION
The class implements a vector field suited for finite element
methods. The vector field is simply a collection of pointers
(handles) to scalar finite element field objects. The most com
mon way of creation is to use the constructor that takes a GridFE
object as input. The vector field will be allocated according to
the number of space dimensions and nodes in the grid. Having the
vector field, the operator() function gives access to the various
scalar field FieldFE components. Assigning values to a specific
vector component can then be accomplished by a combination of
operator() and the FieldFE functions, e.g., valueNode or values.
Some of the functions in FieldFE are reimplemented in FieldsFE
for efficiency reasons, for example, valuePt is inefficient if it
is called for each vector component since the search for the ele
ment where the global point is located must be performed for each
component. Therefore, check first if the function on the vector
field is implemented in FieldsFE. If not, call the approperiate
FieldFE function for each vector component. If FieldFE does not
offer the desired functionality, it may be necessary to extract
the nodal values vector or the GridFE object and call functions
in the vector/grid. Usually, tasks can be performed in a variety
of ways, and this offers flexibility. As a rule of thumb, try to
use functions in the class that has the highest abstraction level
(an example of decreasing abstraction level: FieldsFE, FieldFE,
GridFE, Vec(NUMT)).
Our FieldsFE class is simply an array of pointers to FieldFE
objects. Another possibility would be to have a grid and an
array of Vec(NUMT) vectors. The former design has several advan
tages. The most important is that all the functionality imple
mented in class FieldFE is automatically available for each com
ponent in class FieldsFE. With a grid and a vector of vectors in
FieldsFE we must implement every FieldFE functionality separately
in the vector class. Another advantage is that you can build a
vector field from existing scalar fields without increasing the
memory usage.
The source code of class FieldsFE is quite short and the program
mer is encouraged to study it to get a complete description of
the class.
CONSTRUCTORS AND INITIALIZATION
There is a constructor without arguments. This constructor needs
to be supplemented by redim first and then attach for each scalar
field member in the collection.
The most popular constructor takes a GridFE reference as argu
ment. Based on the number of space dimensions and the number of
nodes, both parameters provided by the GridFE object, this con
structor creates field components (of a vector field), each of a
length equal to the number of nodes in the mesh. The use of this
constructor is mainly for physical vector fields. A correspond
ing constructor that takes a BasisFuncGrid as argument is suit
able for mixed methods.
Another constructor takes the number of components as parameters.
Each component must then be attached using the attach function.
This constructor is used when, e.g., physically different fields
are attached to a FieldsFE for use in implicit methods, e.g.,
converting the field degrees of freedom to the numbering of
unknowns in a linear system (class DegFreeFE has functions for
this - vec2field and field2vec). Since the data in a FieldsFE
object contain an array of FieldFE pointers only, there is no
increase in the memory usage if one attaches existing scalar
fields to a FieldsFE object.
MEMBER FUNCTIONS
Much of the functionality of class FieldsFE is obtained by
accessing the "FieldFE functions of each component. However, sev
eral of the FieldFE functions are rewritten in class FieldsFE to
increase efficiency. Inefficient code may be caused by using
straightforward loops over the components with calls to the
scalar field functions. The valuePt is an example on this situa
tion: Some of the computations in valuePt (f.ex. finding the ele
ment containing the global point) are needed only for the first
component in the field.
valuePt - computes the value of the vector field at a global
point in space. This function is much more efficient than calling
FieldFE::valuePt for each component field in the vector.
redim - redimensions the internal data structure. The function
taking an int argument just redimensions the number of fields,
but each field is empty (NULL pointer). The redim function taking
a GridFE argument creates as many components in the field as
there are number of space dimensions in the grid. Each component
is then created as a scalar field over the grid.
ok - checks whether the object is in an ok state. This implies
that each component points to the same grid object, and that the
ok function of each scalar field returns a true value. Several of
the FieldsFE functions assume that each component uses the same
grid, but this is strictly not necessary. Consult the code (and
avoid the ok function) if you plan to use different grids for the
different components.
empty - returns true if the object has not allocated the internal
data structures. In contrast to ok, no error messages are issued.
Hence the function is convenient in test where one wants to call
a redim function if the field is empty.
update - calls FieldFE::update for each of the field components.
Necessary in problems where the grid changes during the
simulation. The primary purpose of update is to redimension the
field data structures according to a change in the underlying
grid.
operator() - allows indexing a vector field. operator()(i)
returns access to component no i in the field (the return value
is a FieldFE object).
attach - attaches existing field(s) to a FieldsFE object. Fields
in the FieldsFE object are then deattached (using the standard
rebind function of the handles). You can attach a single FieldFE
field or an existing FieldsFE vector field. The attach function
taking a FieldFE object is often used for creating a vector field
of two independent scalar fields for use in linear systems when
solving a system of PDEs. The overloaded function that is vir
tual is mainly used by the SimResFile og FieldReader classes.
isoparametric - returns true if all the components in the field
has meshes consisting of isoparametric elements only. This func
tion needs a loop with tests so move its value outside long
loops. Note that some of the FieldsFE function do not work prop
erly if not isoparametric is true. A similar test for FieldFE is
enabled by
FieldFE::grid4basisFunc().isoparametric()
fill - sets all the nodal values of each vector component equal
to the argument value.
fill(FieldsFunc,real) - works as the corresponding fill function
in the FieldFE class, except that the functor now returns a vec
tor.
getNoFields - computes the number of fields.
getNoValues - total number of degrees of freedom in the vector
field. The function performs some computations, therefore one
should always store the result of the function in an int if the
number is to be used in loops.
getFieldBase - a virtual function that is called by the SimRes
File or FileReader classes (for reading fields from files).
magnitude - computes the magnitude of the vector field as a
FieldFE object. The magnitude is simply the Eucledian norm of the
vector (at each node). The argument (result) field m will be
automatically initialized in magnitude (by a relevant redim call)
if the field is empty at input.
print - prints brief info about the vector field. The names of
the components, their number of nodes etc are printed. Note that
this print function is not identical to a loop over the vector
components where the print function of each scalar field is
called (the FieldFE::print prints both the grid and field values
in detail). The second argument is used to customize the heading
of the printing. The character is string will in print be fol
lowed by the name of the FieldsFE object, a colon and a newline
(this should be taken into account when constructing a proper
header string in the call).
SEE ALSO
class FieldFE, class GridFE
DEVELOPED BY
SINTEF Applied Mathematics, Oslo, Norway, and University of Oslo,
Dept. of Mathematics, Norway
AUTHOR
Hans Petter Langtangen, SINTEF/UiO