Index

NAME

BasisFuncGrid  -  basis  function modification of a GridFE object
(mixed FEM)


INCLUDE

include "BasisFuncGrid.h"

SYNTAX

 class BasisFuncGrid : public GridWithPts
 {
   friend class FieldFE;          // for efficient interpolation


   Handle(GridFE)     geomt_grid;
   bool               isop;       // true: isoparm. elm. => all info from grid
   int                nsd;
   int                nsd_phys;

   // note that the present implementation of BasisFuncGrid is restricted
   // to meshes where all the elements are of the same type!

   // these variables replace those in GridFE when isop==false, in case
   // of isoparametric elements, none of the variables below are used
   int                nno;        // no of basis function nodes
   int                nbf;        // total no of basis functions
   int                nbe;        // total no of basis functions in an element
   int                nne;        // no of basis function nodes in an element
   int                nbind;
   Handle(Indicators) essbind;
   MatSimple(real)    coor;
   String             elm_tp;
   HandleElmDefs      elmdef;
   MatSimple(int)     nodel;
   // loc2glob_arr(e,j): global dof corresponding to the local dof j in elm e
   MatSimple(int)     loc2glob_arr;
   VecSimple(int)     node2dof_arr;
   int                current_node; // used in the grid iterator functions
   bool               incorrect_coor;  // true if coor is not moved in move()

   void generateMesh ();  // compute new basis function nodes and dofs

 public:
   BasisFuncGrid ();
   BasisFuncGrid (const GridFE& grid);
  ~BasisFuncGrid ();

   void redim (const GridFE& grid);

   const GridFE& grid () const      { return geomt_grid(); }
         GridFE& grid ()            { return geomt_grid(); }

   void setElmType (const String& old_tp, const String& new_tp);
   void setElmType (const String& new_tp);

   bool update ();

   bool     ok () const;

   bool isoparametric () const     { return isop; }
   int  loc2glob (int e, int dof) const;
   void loc2glob (VecSimple(int)& l2g, int e) const;
   int  getNoNodesInElm (int e =1) const;      // basis func. nodes in elm e
   int  getNoBasisFuncInElm (int e =1) const;  // equals no of dof in elm e
   int  getNoBasisFuncAtBasisNodeInElm (int elm_node, int e = 1) const;
   int  getBasisFuncNoInElm (int elm_node, int basis_func_no_at_this_node,
                                int e = 1) const;
   int  getBasisFuncNode  (int global_basis_func_no) const;
   int  node2dof (int node) const;  // global node -> global basis func no

   int  getNoNodes () const;
   int  getTotalNoDof () const;
   int  getNoSpaceDim () const { return nsd; }
   int  getNoPhysicalSpaceDim () const { return nsd_phys; }
   real getCoor (int node, int dir) const;
   Ptv(real) getCoor (int node) const;
   void getCoor (Ptv(real)& point, int node) const;
   void getMinMaxCoord (Ptv(real)& mincoord, Ptv(real)& maxcoord) const;

   String getElmType (int e =1) const;  // this version: independent of e!
   bool allElmsOfSameType () const;

   const Indicators& getEssBoInds () const { return essbind.getRef(); }
         Indicators& getEssBoInds ()       { return essbind.getRef(); }
   void  setBoInd   (int node, int indno);
   void  clearBoInd (int node, int indno);
   void  attach (Indicators& essboinds, bool automatic_fill = true);
   void  fillIndicators (Indicators& bfind);

   bool notEqual (const BasisFuncGrid& bfnodes);

   // only essential conditions are handled here (natural conditions are
   // related to sides, i.e., the geometry and are handled by GridFE::BoNode)
   bool essBoNode (int node, int indno) const;
   bool essBoNode (int node) const;
   bool essBoNodesInElm (int elm_no, int indno) const;

   void print (Os os) const;
   void scan  (Is is);

   // iterate through all the grid points:
   virtual void startIterator ();
   virtual bool nextPt (Ptv(real)& x);
           bool nextPt (Ptv(real)& x, int& node);
   // other virtual functions defined in base classes:
   virtual int  getNoPoints () const;
           int  isNode (const Ptv(real)& point);
   virtual int  nearestPoint
     (const Ptv(real)& point, real& distance, bool& exact);
   virtual void   scale ();  //   scale the nodal coordinates
   virtual void unscale ();  // unscale the nodal coordinates
           void attachScale (const SpaceTimeScale& scale);

   virtual void isToBeChanged ();  // redefined here (inherited from Grid)

   void move (const FieldsFE& displacement, real scale_factor = 1.0);
   // re-generate basis function grid:
   void move (bool do_not_move_basis_function_nodes);

   CLASS_INFO

   VIRTUAL_CAST(BasisFuncGrid)
 };

 // a class VecSimplest(BasisFuncGrid) is defined



KEYWORDS

trial function nodes, mixed  finite  elements,  finite  elements,
grid



DESCRIPTION

Finite  element basis functions are usually defined in terms of a
standard  finite  element  grid  where  the  expansion   of   the
unknown(s) and the geometric transformation of a standard element
utilize the same basis functions. We refer to  such  elements  as
"isoparametric".   In  the  isoparametric case, GridFE represents
the complete information about the grid.

In mixed finite element methods one often  utilizes  non-isopara­
metric  elements,  that  is, elements where the geometric mapping
and the expansion of the unknown(s) are based on different  basis
functions.   One will then often have a set of nodes defining the
geometry and an additional set of  nodes  related  to  the  basis
functions  for  the  unknown. We will refer to the functions used
for approximating the unknown(s) as "basis functions". The corre­
sponding  functions used to map an element from the local element
coordinate system to the physical  domain  are  called  "geometry
functions".

The  description of various elements is represented as subclasses
in the ElmDef hierarchy. Every element has a  definition  of  its
geometry  functions  (geomtFunc  in  ElmDef)  and basis functions
(basisFunc in ElmDef).  The nodes that are related to the  geome­
try  functions are represented in a GridFE object. Our idea is to
introduce an additional class, BasisFuncGrid for representing the
nodes  related  to the basis functions.  In case of isoparametric
elements, class BasisFuncGrid gets all its  information  from  an
underlying  GridFE  object.  However,  for non-isoparametric ele­
ments, BasisFuncGrid will have its own set of nodes.

Technically, class BasisFuncGrid has an indicator  isop  that  is
true  if all elements in the grid are isoparametric. Typical Bas­
isFuncGrid member functions test if isop is true,  in  that  case
the corresponding function in the associated GridFE is called, if
it is false, the function has  to  look  up  information  in  the
internal data structure of class BasisFuncGrid.


CONSTRUCTORS AND INITIALIZATION

There are two constructors. First one without arguments that does
nothing.  Then there is a constructor taking an GridFE object  as
argument.   This second is identical to the empty constructor and
a redim call (this is standard in Diffpack).  Hence, to  initial­
ize  the  BasisFuncGrid  object, one must feed a GridFE object to
BasisFuncGrid, either using the constructor or  the  redim  func­
tion.  If the elements are isoparametric, this is sufficient ini­
tialization of the BasisFuncGrid  object.  For  non-isoparametric
elements,  one  must  assign the element type by call setElmType.
This version of class BasisFuncGrid can only work with  one  ele­
ment  type  if non-isoparametric elements are wanted. The setElm­
Type function will automatically initiate computations for manag­
ing the degrees of freedom for a scalar field over the given non-
isoparametric element.  Handling degrees of freedom for composite
fields is performed by class DegFreeFE.



MEMBER FUNCTIONS

grid - gives access to the underlying GridFE object.

update - updates the size of internal data structures if the grid
has been changed. For example, in adaptive  methods,  one  should
call  update  every  time the GridFE object has been manipulated.
Similar update functions  are  present  in  various  fields,  for
example, in FieldFE.

isoparametric  -  returns true if all elements in the grid are of
isoparametric type (that is, the  same  functions  are  used  for
determining  the  shape  of  the element and the expansion of the
unknown over the element).

log2glob - returns the global  node  number  corresponding  to  a
local  node  in  an  element. The term node here refers to a node
used for defining basis functions. Therefore this loc2glob  func­
tion  is  central for relating local degrees of freedom to global
degrees of freedom in the linear  system  that  arises  from  the
finite element discretization.

log2glob(VecSimplest(int),int)  -  redims and fills a vector with
global node numbers for all local nodes in the element.

getNoNodesInElm - returns the number of basis function  nodes  in
an  element.  For example, if we have the four node quadrilateral
element with a constant shape function,
// we have a BasisFuncGrid bg
int m = bg.grid().getNoNodesInElm(e);
int n = bg.getNoNodesInElm(e);
Here m will be 4 while n will be 1.

getNoNodes - returns the number of basis function nodes.  In  the
example  given  under getNoNodesInElm, bg.getNoNodes() equals the
number of elements in the grid, that is, bg.grid().getNoElms().

getNoSpaceDim - gets the number of space dimensions.

getNoBasisFuncAtBasisNodeInElm -  returns  the  number  of  basis
functions  (degrees  of  freedom)  at a basis function node in an
element. Normally this will be 1, but in p-FEM the basis function
nodes  on  the  sides  of  the elements will have many associated
basis functions.

getBasisFuncNoInElm - the inverse function of  "getNoBasisFuncAt­
BasisNodeInElm.

getBasisFuncNode  -  given a global basis function number (degree
of freedom for a scalar field) global_basis_func_no, the function
returns  the  basis function node number that corresponds to this
degree of freedom.  (At present, the function can only handle the
trivial  case where the number of basis functions equals the num­
ber of basis  function  nodes,  otherwise  an  error  message  is
issued.)

node2dof  -  returns  the  basis  function number (i.e. degree of
freedom number for the associated  scalar  field)  of  the  first
basis  function  at  a  particular  node.  Convenient  in,  e.g.,
FieldFE::valueNode for a quick look-up of function value  degrees
of freedom. If this application of the function is to be success­
ful, one must follow a convention that  when  there  are  several
degrees  of  freedom (associated with a single scalar field) at a
basis function node, the first degree of freedom  represents  the
function  value.  If  there is only one basis function (degree of
freedom) at each basis function node, the node2dof is an identity
mapping.

setElmType  -  sets the element type for an element. For example,
if you have generated a grid consisting of ElmB4n2D elements in a
preprocessor, you must apply the bilinear element for mapping the
element geometries, but the basis functions in each  element  can
be  changed - for example to piecewise constants. One then simply
calls setElmType with the proper argument. If you do not know  at
compile  them  the elements in the grid (old_tp), you can look up
the element type in the computed grid:

basis_func_grid->setElmType (new_tp);

or (the older)

basis_func_grid->setElmType (grid->getElmType(1),new_tp);

Note that getElmType(1) (i.e. look up type of element no.  1)  is
okay  since  any  use of BasisFuncGrid requires that all the ele­
ments in the geometry grid are of the same type.

getEssBoInds - returns access to  the  Indicators  object  inside
this  BasisFuncGrid  object.  Note that these indicators are used
for essential boundary conditions only (this is reflected in  the
name,  here  getEssBoInds,  while  the  corresponding function in
GridFE is boundaryData). Natural conditions are  associated  with
sides  in  elements  and reflect hence geometry properties, i.e.,
GridFE must be responsible for this information.  The  indicators
in GridFE (accessed by boundaryData and clear/setBoInd functions)
cover natural condititions, and in the case of isoparametric ele­
ments, also essential conditions.

attach  -  enables  attachment  of  a new boundary indicator (for
essential conditions, see documentation of getEssBoInds).  If one
attaches  a  new  set  of indicators in a GridFE object, one must
attach the corresponding Indicators objects in all  BasisFuncGrid
classes that are connected to this GridFE object, if the elements
are non-isoparametric. That is,  for  non-isoparametric  elements
the  an  indicator  consists of a GridFE indicator and one corre­
sponding indicator for  all  BasisFuncGrid  objects.  The  GridFE
indicator  will then determine the natural conditions along sides
(a geometric property), whereas the BasisFuncGrid indicators deal
with  the  essential conditions related to basis function degrees
of freedom.  If a GridFE indicator is set  and  attached  to  the
GridFE  object,  one  simply  calls fillIndicators to compute the
corresponding BasisFuncGrid indicator  and  attaches  the  result
using attach.  When the extra boolean argument to attach is true,
attach will first call fillIndicators to ensure that the  indica­
tor  is  updated  according  to  the indicator information in the
underlying grid.

fillIndicators - computes a boundary indicator  for  the  current
BasisFuncGrid object, using information about the current indica­
tor in the underlying GridFE object. This  function  is  normally
called from attach (see above).

setBoInd,  clearBoInd  -  these  functions  are  as  described in
GridFE, but now the "nodes" are the nodes that are  used  in  the
definition of the basis functions.

move  - moves the basis function nodes if the basis function grid
consists of non-isoparametric elements. One function takes a dis­
placement  field and moves the nodes according to this field (see
also the similar move function in class GridFE). The other  func­
tion  takes  a  do_not_move_basis_function_nodes argument, and if
this argument is false, it  recomputes  the  coordinates  of  the
basis function nodes by executing the generateMesh function. This
latter version is slower than the former, but the basis  function
coordinates  will be consistent with their location in the refer­
ence coordinate system (note that  interpolating  a  displacement
field generally gives a small mismatch between the moved node and
its location computed by first moving the geometry and then  map­
ping a local node).  If do_not_move_basis_function_nodes is true,
move does actually nothing  except  marking  that  the  grid  has
changed  and  must be restored the next time a field is dumped in
simres format. This is very efficient.  The internal bool  incor­
rect_coor  is  then turned on to indicate that the values in coor
are incorrect. However, it is seldom that these values are  actu­
ally  needed  in a simulation (plotting velocity vectors at basis
function nodes is one example). Also, if the mesh is  isoparamet­
ric,  move  has no effect on coor anyway.  Note that GridFE::move
must be called prior to any BasisFuncGrid::move!!


DEVELOPED BY

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


AUTHOR

Hans Petter Langtangen, SINTEF/UiO