\section{ParFUM}
\label{sec:ParFUM}
ParFUM is the name for the latest version of FEM.
ParFUM includes additional features including parallel
mesh modification and adaptivity (geometrical). ParFUM also contains
functions which generate additional topological adjacency
information. ParFUM cannot be built separate from \charmpp{}
since it uses various messaging mechanisms that MPI does
not readily support. It is important to note that ParFUM adaptivity
at the moment has some limitations. It works only for meshes which
are two-dimensional. The other limitation is that the mesh on which
it works on must have one layer of node-deep ghosts. Most applications
reqire no or one layer ghosts, so it is really not a limitation,
but for applications that need multiple layers of ghost information,
the adaptivity operations cannot be used.
\subsection{Adaptivity Initialization}
If a FEM application wants to use parallel mesh adaptivity,
the first task is to call the initialization routine from the
{\it driver} function. This creates the node and element
adjacency information that is essential for the adaptivity
operations. It also initializes all the mesh adaptivity related
internal objects in the framework.
\function{void FEM\_ADAPT\_Init(int meshID)}
\index{femAdaptInit}
\desc{Initializes the mesh defined by {\it meshID} for the mesh
adaptivity operations.}
\subsection{Preparing the Mesh for Adaptivity}
For every element entity in the mesh, there is a desired size entry
for each element. This entry is called meshSizing. This meshSizing entry
contains a metric that decides the element quality. The default metric is
the average of the size of the three edges of an element. This section
provides various mechanisms to set this field. Some of the adaptive operations
actually use these metrics to maintain quality. Though there is another metric
which is computer for each element and maintained on the fly and that
is the ratio of the largest length to the smallest altitude and this value
during mesh adaptivity is not allowed to go beyond a certain limit. Because
the larger this value after a cecrtain limit, the worse the element quality.
\function{void FEM\_ADAPT\_SetElementSizeField(int meshID, int elem, double size);}
\index{femAdaptSetElementSizeField1}
\desc{For the mesh specified by {\it meshID}, for the element {\it elem},
we set the desired size for each element to be {\it size}.}
\function{void FEM\_ADAPT\_SetElementSizeField(int meshID, double *sizes);}
\index{femAdaptSetElementSizeField2}
\desc{For the mesh specified by {\it meshID}, for the element {\it elem},
we set the desired size for each element from the corresonponding entry in
the {\it sizes} array.}
\function{void FEM\_ADAPT\_SetReferenceMesh(int meshID);}
\index{femAdaptSetReferenceMesh}
\desc{For each element int this mesh defined by {\it meshID}
set its size to the average edge length of the corresponding element.}
\function{void FEM\_ADAPT\_GradateMesh(int meshID, double smoothness);}
\index{femAdaptGradateMesh}
\desc{Resize mesh elements to avoid jumps in element size.
i.e. avoid discontinuities in the desired sizes for elements of a mesh
by smoothing them out.
Algorithm based on h-shock correction, described in
Mesh Gradation Control, Borouchaki et al.}
\subsection{Modifying the Mesh}
Once the elements in the mesh has been prepared by specifying there desired
sizes, we are ready to use the actual adaptivity operations. Currently we
provide delauney flip operations, edge bisect operations and edge-coarsen
operations all of which are implemented in parallel, but the user has
access to these wrapper functions which interlligently decide when
and in which region of the mesh to use the adaptivity operations to
generate a mesh with higher quality elements while achieving the
desired size (which is usually average edge length per element), or it
could even be the area of each element.
\function{void FEM\_ADAPT\_Refine(int meshID, int qm, int method, double factor,double *sizes);}
\index{femAdaptRefine}
\desc{Perform refinements on the mesh specified by {\it meshId}.
Tries to maintain/improve element quality by refining the mesh
as specified by a quality measure {\it qm}.
If {\it method} = 0, refine areas with size larger than {\it factor} down to {\it factor}
If {\it method} = 1, refine elements down to sizes specified in the {\it sizes} array.
In this array each entry corresponds to the corresponding element.
Negative entries in sizes array indicate no refinement. }
\function{void FEM\_ADAPT\_Coarsen(int meshID, int qm, int method, double factor,double *sizes);}
\index{femAdaptCoarsen}
\desc{Perform refinements on the mesh specified by {\it meshId}.
Tries to maintain/improve element quality by coarsening the mesh
as specified by a quality measure {\it qm}.
If {\it method} = 0, coarsen areas with size smaller than {\it factor} down to {\it factor}
If {\it method} = 1, coarsen elements up to sizes specified in the {\it sizes} array.
In this array each entry corresponds to the corresponding element.
Negative entries in sizes array indicate no coarsening. }
\function{void FEM\_ADAPT\_AdaptMesh(int meshID, int qm, int method, double factor,double *sizes);}
\index{femAdaptAdaptMesh}
\desc{It has the same set of arguments as required by the previous two operations,
namely refine and coarsen. This function keeps using the above two functions till
we have all elements in the mesh with as close to the desired quality. Apart from
using the above two operations, it also performs a mesh repair operation where it
gets rid of some bad quality elements by delauney flip or coarsening as the
geometry in the area demands.}
\function{int FEM\_ADAPT\_SimpleRefineMesh(int meshID, double targetA, double xmin, double ymin, double xmax, double ymax);}
\index{femAdaptSimpleRefineMesh}
\desc{A region is defined by ({\it xmax, xmin, ymax, ymin})
and the target area to be achieved for all elements in this region
in the mesh specified by {\it meshID} is given by {\it targetA}.
This function only performs a series of refinements on the elements in this region.
If the area is larger, then no coarsening is done.}
\function{int FEM\_ADAPT\_SimpleCoarsenMesh(int meshID, double targetA, double xmin, double ymin, double xmax, double ymax);}
\index{femAdaptSimpleCoarsenMesh}
\desc{A region is defined by ({\it xmax, xmin, ymax, ymin})
and the target area to be achieved for all elements in this region
in the mesh specified by {\it meshID} is given by {\it targetA}.
This function only performs a series of coarsenings on the elements in this region.
If the area is smaller, then no refinement is done.}
\subsection{Verifiy correctness of the Mesh}
After adaptivity operations are performed and even before adaptivity operations,
it is important to first verify that we are working on a mesh that is consistent
geometrically with the types of mesh that the adaptivity algorithms are designed
to work on. There is a function that can be used to test various properties of
a mesh, like area, quality, geometric consistency, idxl list correctness, etc.
\function{void FEM\_ADAPT\_TestMesh(int meshID);}
\index{femAdaptTestMesh}
\desc{This provides a series of tests to determine the consistency of the
mesh specified by {\it meshID}.}
These four simple steps define what needs to be used by a program that wishes
to use the adaptivity features of ParFUM.
\subsection{ParFUM developers}
This manual is meant for ParFUM users, so developers should look at the source code
and the doxygen generated documentaion.