/** * @defgroup Aprx Aprx class * @brief The APpRoXimation library object. */ /** * @file aprx.h * @ingroup Aprx * @brief Class Aprx: the APpRoXimation library object. * @author Michael Holst * @note None * @version $Id: aprx.h,v 1.37 2010/08/12 05:18:21 fetk Exp $ * * @attention * @verbatim * * MC = < Manifold Code > * Copyright (C) 1994-- Michael Holst * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * @endverbatim */ #ifndef _APRX_H_ #define _APRX_H_ #include #include #include #include #include #include #include /** * @ingroup Aprx * @brief Class Aprx: Parameters and datatypes Class Aprx: Definition. * @author Michael Holst */ struct sAprx { /** @brief the memory manager */ Vmem *vmem; /** @brief did i make vmem or was it inherited */ int iMadeVmem; /** @brief geometry machine */ Gem *gm; /** @brief container for user-provided functions */ PDE *pde; /** @brief ptr to the Vset object for interactions */ Vset *lnkG; /** @brief ptr to the master elements */ Re *re[MAXV]; /** @brief ptr to the master bump elements */ Re *reB[MAXV]; /** @brief Global Number of 0-simplices (vertices) */ int numV; /** @brief Global Number of 1-simplices (edges) */ int numE; /** @brief Global Number of 2-simplices (faces) */ int numF; /** @brief Global Number of 3-simplices (simplices) */ int numS; /** @brief Global Vertex-to-Edge map */ int *I_V2E; /** @brief Global Vertex-to-Face map */ int *I_V2F; /** @brief Global Vertex-to-Simplex map */ int *I_V2S; /** @brief Global Edge-to-Face map */ int *I_E2F; /** @brief Global Edge-to-Simplex map */ int *I_E2S; /** @brief Global Face-to-Simplex map */ int *I_F2S; /** @brief complete node information */ Bnode *B; /** @brief number of dirichlet boundary nodes */ int numBV[MAXV]; /** @brief dirichlet boundary node numbers */ int *ibv[MAXV]; /** @brief dirichlet boundary node values */ double *bv[MAXV]; /** @brief ELEMENT work vectors */ Bvec *wev; /** @brief current a posteriori global error over mesh */ double gerror; /** @brief number of blocks */ int numB; /** @brief block prolongation operator TO this mesh */ Bmat *P; /** @brief order of approximation */ int order; }; /** * @ingroup Aprx * @brief Declaration of the Aprx class as the Aprx structure * @author Michael Holst * @return None */ typedef struct sAprx Aprx; /* * *************************************************************************** * Class Aprx: Inlineable methods (aprx.c) * *************************************************************************** */ #if !defined(VINLINE_APRX) #else /* if defined(VINLINE_APRX) */ #endif /* if !defined(VINLINE_APRX) */ /** * @ingroup Aprx * @brief Construct a linear Approximation object. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return Pointer to a newly allocated (empty) linear Approximation object * @param vmem Memory management object * @param tgm Geometry manager source * @param tpde PDE object */ VEXTERNC Aprx* Aprx_ctor(Vmem *vmem, Gem *tgm, PDE *tpde); /** * @ingroup Aprx * @brief Approximation object constructor. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return thee Pointer to an Aprx allocated memory location * @param vmem Memory management object * @param tgm Geometry manager source * @param tpde PDE object * @param order Order of approximation to be constructed */ VEXTERNC Aprx* Aprx_ctor2(Vmem *vmem, Gem *tgm, PDE *tpde,int order); /** * @ingroup Aprx * @brief Approximation object destructor. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @param thee Pointer to object to be destroyed */ VEXTERNC void Aprx_dtor(Aprx **thee); /** * @ingroup Aprx * @brief Return the number of blocks. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return the number of blocks * @param thee Pointer to an Aprx allocated memory location */ VEXTERNC int Aprx_numB(Aprx *thee); /** * @ingroup Aprx * @brief Return a pointer to the current prolongation matrix. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return a pointer to the current prolongation matrix. * @param thee Pointer to an Aprx allocated memory location */ VEXTERNC Bmat *Aprx_P(Aprx *thee); /** * @ingroup Aprx * @brief Read in the user-specified initial mesh given in the * "MCSF" or "MCEF" format, and transform into our internal * datastructures.\n * Do a little more than a "Gem_read", in that we also * initialize the extrinsic and intrinsic spatial dimensions * corresponding to the input mesh, and we also then build the * reference elements. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c)\n * See the documentation to Gem_read for a description of the * mesh input data file format. * @return Success enumeration * @param thee Pointer to an Aprx allocated memory location * @param key input format type * key=0 ==> simplex format * key=1 ==> edge format * key=2 ==> simplex-nabor format * @param sock socket for reading the external mesh data (NULL otherwise) */ VEXTERNC int Aprx_read(Aprx *thee, int key, Vio *sock); /** * @ingroup Aprx * @brief Reset all of the datastructures. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return None * @param thee Pointer to an Aprx allocated memory location */ VEXTERNC void Aprx_reset(Aprx *thee); /** * @ingroup Aprx * @brief Make node information. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return None * @param thee Pointer to an Aprx allocated memory location */ VEXTERNC void Aprx_initNodes(Aprx *thee); /** * @ingroup Aprx * @brief Determine the node types via a single fast traversal of * the elements by looking at the element faces. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return None * @param thee Pointer to an Aprx allocated memory location */ VEXTERNC void Aprx_buildNodes(Aprx *thee); /** * @ingroup Aprx * @brief Evaluate the trace information. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param Wud block NODAL dirichlet work vector * @param Wui block NODAL interior dirichlet work vector * @param Wut block NODAL analytical work vector */ VEXTERNC void Aprx_evalTrace(Aprx *thee, Bvec *Wud, Bvec *Wui, Bvec *Wut); /** * @ingroup Aprx * @brief Refine the mesh. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return Success enumeration * @param thee Pointer to an Aprx allocated memory location * @param rkey Boolean sets the rkey type for refining the mesh. * Input: If (rkey==0) Perform recursive simplex bisection until conformity * * If (rkey==1) Perform first quadra-[octa-]-section, followed by * recursive simplex bisection until conformity * * IMPORTANT NOTE: In 2D, (rkey==1) WILL generate * a conforming mesh. However, in 3D, this procedure * will in general produce nonconforming simplices. * To produce a conforming mesh in 3D would require an * implementation covering all possible face refinement * combinations (something like 169 cases). This has * been done e.g. by Jurgen Bey in AGM, but we are * not that patient; use (rkey==0) above if you want * a conforming mesh... * * If (rkey==2) As a test of the conformity procedure, perform * quadra-[octa-]-section until conformity, which * should produce a uniformly regularly refined mesh. * (In 2D, each triangle should be divided into four * children, and in 3D each tetrahedron should be * divided into eight children.) * @param bkey Boolean sets the bkey type for bisecting the mesh * If (bkey==0) Bisection type: Longest Edge * If (bkey==1) Bisection type: Newest Vertex * If (bkey==2) Bisection type: Newest Pair * @param pkey Boolean sets the pkey type to prolongate a vector */ VEXTERNC int Aprx_refine(Aprx *thee, int rkey, int bkey, int pkey); /** * @ingroup Aprx * @brief Unrefine the mesh. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return Success enumeration * @param thee Pointer to an Aprx allocated memory location * @param rkey Boolean sets the rkey type for un-refining the mesh. * @param pkey Boolean sets the pkey type to prolongate a vector */ VEXTERNC int Aprx_unRefine(Aprx *thee, int rkey, int pkey); /** * @ingroup Aprx * @brief Deform the mesh * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return Success enumeration for deforming the mesh. * @param thee Pointer to an Aprx allocated memory location * @param def The corresponding deforming block vector */ VEXTERNC int Aprx_deform(Aprx *thee, Bvec *def); /** * @ingroup Aprx * @brief Create storage for and build prolongation operator; the operator * prolongates a vector FROM a coarser level TO this level. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param numRc number of vertices before refinement * @param numR number of vertices after refinement * @param pkey Boolean sets the pkey type to prolongate a vector */ VEXTERNC void Aprx_buildProlong(Aprx *thee, int numRc, int numR, int pkey); /** * @ingroup Aprx * @brief Create block version of prolongation operator; also * updates the Bnode object. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param p Pointer to Bnode matrix */ VEXTERNC void Aprx_buildProlongBmat(Aprx *thee, Mat *p); /** * @ingroup Aprx * @brief Count up the total number of basis functions (nodes). * This is basically an a priori count of the number of rows in * the stiffness matrix. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) \n * This routine can handle COMPLETELY GENERAL ELEMENTS; see the * comments in Aprx_interact(). * @return the total number of basis functions (nodes). * @param thee Pointer to an Aprx allocated memory location * @param re a reference simplex element object. */ VEXTERNC int Aprx_nodeCount(Aprx *thee, Re *re); /** * @ingroup Aprx * @brief Count the number of basis (linear/quadratic/etc) functions which * interact with a given basis function. This is basically an * a priori count of the number of nonzeros per row in the * stiffness matrix, and the number of nozeros per row above the * diagonal (and thus the number of nonzeros per column below the * diagonal if we have symmetric nonzero structure). By doing this * count, we can one-time malloc storage for matrices before * assembly, and avoid extra copies as well as avoid the use * of linked list structures for representing matrices with * a priori unknown nonzero structure. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c)\n * This routine can handle COMPLETELY GENERAL ELEMENTS; all it needs * to do is simply compute all interactions of all nodes in the * element. The nodes may be any combination of vertex-based, * edge-based, face-based (3D only), or simplex-based (interior) * degrees of freedom.\n * This calculation is made possible because all of the node numbers * for all of the vertex/edge/face/simplex-nodes in each simplex are * available in O(1) time for each element, using the geometry * manager routine Gem_simplexInfo(). * @return None * @param thee Pointer to an Aprx allocated memory location * @param re a reference simplex element object. * @param reT a reference simplex element object. * @param numR num of rows in the matrix * @param numO num of nonzeros we are actually storing in the * strict upper-triangle of matrix. (DRC only) * @param numOYR YSMP-row(col) * @param IJA integer structure [ IA ; JA ] * @param IJAYR lower-triangle block from upper triangle block */ VEXTERNC void Aprx_interact(Aprx *thee, Re *re, Re *reT, int *numR, int *numO, int *numOYR, int **IJA, int **IJAYR); /** * @ingroup Aprx * @brief Determine all basis function interations. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param re array of reference simplex element objects * @param reT array of reference simplex element objects * @param sym symmetry keys for the matrix * @param mirror block mirror keys for the matrix * @param frmt Matrix format * @param numR num of rows in the matrix * @param numO num of nonzeros we are actually storing in the * strict upper-triangle of matrix. (DRC only) * @param IJA integer structure [ IA ; JA ] */ VEXTERNC void Aprx_interactBlock(Aprx *thee, Re *re[MAXV], Re *reT[MAXV], MATsym sym[MAXV][MAXV], MATmirror mirror[MAXV][MAXV], MATformat frmt[MAXV][MAXV], int numR[MAXV], int numO[MAXV][MAXV], int *IJA[MAXV][MAXV]); /** * @ingroup Aprx * @brief Compute global index of node of dimension dim in the matrix * @author Michael Holst, Oleg Korobkin * @note Class Aprx: Non-inlineable methods (aprx.c) * @return global index of node of dimension dim in the matrix * @param thee Pointer to an Aprx allocated memory location * @param re Pointer to the reference elemented to be used * @param i i-simplex global number * @param dim interactions index * @param q number of volume quadrature points */ VEXTERNC int Aprx_nodeIndex (Aprx *thee, Re *re, int i, int dim, int q); /** * @ingroup Aprx * @brief Given an index of node DF within the simplex and * its TT structure, compute global index for that node * @authors Michael Holst and Oleg Korobkin * @note Class Aprx: Non-inlineable methods (aprx.c) * @return global index for the node by given an index of node DF within * the simplex * @param thee Pointer to an Aprx allocated memory location * @param re Pointer to the reference elemented to be used * @param t Pointer to class T * @param idf index of node DF within the simplex */ VEXTERNC int Aprx_nodeIndexTT (Aprx *thee, Re *re, TT *t, int idf); /** * @ingroup Aprx * @brief Build boundary Bnode information into two Bmats. * @authors Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c)\n * Either/both Bmat objects can be VNULL without error; * the result for that VNULL Bmat is a No-Op. * @return None * @param thee Pointer to an Aprx allocated memory location * @param A Pointer to stiffness matrix * @param M Pointer to Mass matrix */ VEXTERNC void Aprx_buildBRC(Aprx *thee, Bmat *A, Bmat *M); /** * @ingroup Aprx * @brief Initialize vector test function "i" and its gradient, * generated by scalar test function "r" for this element. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (aprx.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param i vector test function index * @param r scalar test function index * @param phi values of local basis funcs at integ pt * @param phix first derivs of local basis funcs at integ pt * @param V vector test function * @param dV first derivs of vector test function */ VEXTERNC void Aprx_initSpace(Aprx *thee, int i, int r, double phi[], double phix[][3], double V[], double dV[][3]); #if 0 /** * @ingroup Aprx * @brief Build the scalar basis functions and their gradients * on this element. Also build an interpolant of the * solution and its gradient.\n * evalKey==0 ==> use U=[0+ud] as evaluation point \n * evalKey>=1 ==> use U=[u+ud] as evaluation point * @author Michael Holst * @note Class Aprx: Non-inlineable methods (assem.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param re a reference simplex element object. * @param evalKey evalKey==0 ==> use U=[0+ud] as evaluation point \n * evalKey>=1 ==> use U=[u+ud] as evaluation point * @param qp index of quad pts * @param face index of face types * @param t pointer to class T * @param xq coordinates of quad pts * @param phi values of local basis funcs at integ pt * @param phix first derivs of local basis funcs at integ pt * @param U block NODAL solution vector * @param dU first derivs of block NODAL solution vector * @param Wu block NODAL solution work vector * @param Wud block NODAL dirichlet work vector */ VEXTERNC void Aprx_buildBasis(Aprx *thee, Re *re, int evalKey, int qp, int face, TT *t, double xq[], double phi[], double phix[][3], double U[], double dU[][3], Bvec *Wu, Bvec *Wud); #endif /** * @ingroup Aprx * @brief Initialize an element matrix. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (assem.c) * @param thee Pointer to an Aprx allocated memory location * @param bumpKey == 0 ==> Do not assemble with bumps.\n * == 1 ==> Assemble bilinear form with bumps.\n * == 2 ==> Assemble residual form with bumps.\n * == ? ==> Same as 1.\n * @param t Pointer to class T * @param em Pointer to element matrix */ VEXTERNC void Aprx_initEmat(Aprx *thee, int bumpKey, TT *t, Emat *em); /** * @ingroup Aprx * @brief Build an element matrix and an element load vector for a * single given element, using quadrature. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (assem.c) \n * We handle both the volume and surface cases here, using * "face" and "t" as follows: \n * face < 0 ==> do volume quadrature; we take the node numbers * as just the identity mapping.\n * face >= 0 ==> do face quadrature for face "face", where the node * numbers for face are taken from t->loc[face][]. * @return None * @param thee Pointer to an Aprx allocated memory location * @param evalKey == 0 ==> Primal problem: evaluation at z=[0+ud].\n * == 1 ==> Primal problem: evaluation at z=[u+ud].\n * == 2 ==> Dual problem: evaluation at z=[0+ud].\n * == 3 ==> Dual problem: evaluation at z=[u+ud].\n * == ? ==> Same as 0. * @param energyKey == 0 ==> DON'T assemble an energy.\n * == 1 ==> Assemble the energy J(z).\n * == 2 ==> Assemble the energy 0.\n * == ? ==> Same as 0. * @param residKey == 0 ==> DON'T assemble a residual.\n * == 1 ==> Assemble the residual F(z)(v).\n * == 2 ==> Assemble the residual 0.\n * == ? ==> Same as 0. * @param tangKey == 0 ==> DON'T assemble a tangent matrix.\n * == 1 ==> Assemble the tangent matrix DF(z)(w,v).\n * == 2 ==> Assemble the tangent matrix 0.\n * == ? ==> Same as 0. * @param massKey == 0 ==> DON'T assemble a mass matrix.\n * == 1 ==> Assemble the mass matrix p(w,v).\n * == 2 ==> Assemble the mass matrix 0.\n * == ? ==> Same as 0. * @param bumpKey == 0 ==> Do not assemble with bumps.\n * == 1 ==> Assemble bilinear form with bumps.\n * == 2 ==> Assemble residual form with bumps.\n * == ? ==> Same as 1.\n * @param face face < 0 ==> do volume quadrature; we take the node * numbers as just the identity mapping.\n * face >= 0 ==> do face quadrature for face "face", where * the node numbers for face are taken from t->loc[face][]. * @param t Pointer to class T * @param em Pointer to element matrix * @param Wu block NODAL solution work vector * @param Wud block NODAL dirichlet work vector */ VEXTERNC void Aprx_quadEmat(Aprx *thee, int evalKey, int energyKey, int residKey, int tangKey, int massKey, int bumpKey, int face, TT *t, Emat *em, Bvec *Wu, Bvec *Wud); /** * @ingroup Aprx * @brief Fan out an element matrix to the global matrix, * and fan out an element vector to the global vector. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (assem.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param evalKey == 0 ==> Primal problem: evaluation at z=[0+ud].\n * == 1 ==> Primal problem: evaluation at z=[u+ud].\n * == 2 ==> Dual problem: evaluation at z=[0+ud].\n * == 3 ==> Dual problem: evaluation at z=[u+ud].\n * == ? ==> Same as 0. * @param energyKey == 0 ==> DON'T assemble an energy.\n * == 1 ==> Assemble the energy J(z).\n * == 2 ==> Assemble the energy 0.\n * == ? ==> Same as 0. * @param residKey == 0 ==> DON'T assemble a residual.\n * == 1 ==> Assemble the residual F(z)(v).\n * == 2 ==> Assemble the residual 0.\n * == ? ==> Same as 0. * @param tangKey == 0 ==> DON'T assemble a tangent matrix.\n * == 1 ==> Assemble the tangent matrix DF(z)(w,v).\n * == 2 ==> Assemble the tangent matrix 0.\n * == ? ==> Same as 0. * @param massKey == 0 ==> DON'T assemble a mass matrix.\n * == 1 ==> Assemble the mass matrix p(w,v).\n * == 2 ==> Assemble the mass matrix 0.\n * == ? ==> Same as 0. * @param bumpKey == 0 ==> Do not assemble with bumps.\n * == 1 ==> Assemble bilinear form with bumps.\n * == 2 ==> Assemble residual form with bumps.\n * == ? ==> Same as 1.\n * @param em Pointer to element matrix * @param A Pointer to stiffness matrix * @param M Pointer to Mass matrix * @param F Pointer to residual vector */ VEXTERNC void Aprx_fanEmat(Aprx *thee, int evalKey, int energyKey, int residKey, int tangKey, int massKey, int bumpKey, Emat *em, Bmat *A, Bmat *M, Bvec *F); /** * @ingroup Aprx * @brief Assemble one element matrix. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (assem.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param sm Pointer to a given simplex * @param evalKey == 0 ==> Primal problem: evaluation at z=[0+ud].\n * == 1 ==> Primal problem: evaluation at z=[u+ud].\n * == 2 ==> Dual problem: evaluation at z=[0+ud].\n * == 3 ==> Dual problem: evaluation at z=[u+ud].\n * == ? ==> Same as 0. * @param energyKey == 0 ==> DON'T assemble an energy.\n * == 1 ==> Assemble the energy J(z).\n * == 2 ==> Assemble the energy 0.\n * == ? ==> Same as 0. * @param residKey == 0 ==> DON'T assemble a residual.\n * == 1 ==> Assemble the residual F(z)(v).\n * == 2 ==> Assemble the residual 0.\n * == ? ==> Same as 0. * @param tangKey == 0 ==> DON'T assemble a tangent matrix.\n * == 1 ==> Assemble the tangent matrix DF(z)(w,v).\n * == 2 ==> Assemble the tangent matrix 0.\n * == ? ==> Same as 0. * @param massKey == 0 ==> DON'T assemble a mass matrix.\n * == 1 ==> Assemble the mass matrix p(w,v).\n * == 2 ==> Assemble the mass matrix 0.\n * == ? ==> Same as 0. * @param bumpKey == 0 ==> Do not assemble with bumps.\n * == 1 ==> Assemble bilinear form with bumps.\n * == 2 ==> Assemble residual form with bumps.\n * == ? ==> Same as 1.\n * @param em Pointer to element matrix * @param Wu block NODAL solution work vector * @param Wud block NODAL dirichlet work vector */ VEXTERNC void Aprx_assemEmat(Aprx *thee, SS *sm, int evalKey, int energyKey, int residKey, int tangKey, int massKey, int bumpKey, Emat *em, Bvec *Wu, Bvec *Wud); /** * @ingroup Aprx * @brief Assemble the tangent matrix and nonlinear residual * vector (which reduces to the normal stiffness matrix and load * vector in the case of a linear problem) for a general nonlinear * system of m components in spatial dimension d. * @note Class Aprx: Non-inlineable methods (assem.c) \n * The nonlinear residual should always be ZERO at dirichlet nodes! * @author Michael Holst * @return the assembled energy * @param thee Pointer to an Aprx allocated memory location * @param evalKey == 0 ==> Primal problem: evaluation at z=[0+ud].\n * == 1 ==> Primal problem: evaluation at z=[u+ud].\n * == 2 ==> Dual problem: evaluation at z=[0+ud].\n * == 3 ==> Dual problem: evaluation at z=[u+ud].\n * == ? ==> Same as 0. * @param energyKey == 0 ==> DON'T assemble an energy.\n * == 1 ==> Assemble the energy J(z).\n * == 2 ==> Assemble the energy 0.\n * == ? ==> Same as 0. * @param residKey == 0 ==> DON'T assemble a residual.\n * == 1 ==> Assemble the residual F(z)(v).\n * == 2 ==> Assemble the residual 0.\n * == ? ==> Same as 0. * @param tangKey == 0 ==> DON'T assemble a tangent matrix.\n * == 1 ==> Assemble the tangent matrix DF(z)(w,v).\n * == 2 ==> Assemble the tangent matrix 0.\n * == ? ==> Same as 0. * @param massKey == 0 ==> DON'T assemble a mass matrix.\n * == 1 ==> Assemble the mass matrix p(w,v).\n * == 2 ==> Assemble the mass matrix 0.\n * == ? ==> Same as 0. * @param bumpKey == 0 ==> Do not assemble with bumps.\n * == 1 ==> Assemble bilinear form with bumps.\n * == 2 ==> Assemble residual form with bumps.\n * == ? ==> Same as 1.\n * @param ip index for assembled energies * @param rp parameter for initially assembled PDE * @param A Pointer to stiffness matrix * @param M Pointer to Mass matrix * @param F block NODAL residual vector * @param Wu block NODAL solution work vector * @param Wud block NODAL dirichlet work vector */ VEXTERNC double Aprx_assem(Aprx *thee, int evalKey, int energyKey, int residKey, int tangKey, int massKey, int bumpKey, int ip[], double rp[], Bmat *A, Bmat *M, Bvec *F, Bvec *Wu, Bvec *Wud); /** * @ingroup Aprx * @brief Mark simplices to be refined * @author Michael Holst * @note Class Aprx: Non-inlineable methods (estim.c)\n * If ( (key == -1) || (key == 0) || (key == 1)) ==>\n * Let geometry manager deal with it.\n * If (key == 2) ==> Nonlinear residual indicator.\n * If (key == 3) ==> Dual-weighted residual indicator.\n * If (key == 4) ==> Local problem indicator. * @return number of marked simplices * @param thee Pointer to an Aprx allocated memory location * @param key If ( (key == -1) || (key == 0) || (key == 1)) ==>\n * Let geometry manager deal with it.\n * If (key == 2) ==> Nonlinear residual indicator.\n * If (key == 3) ==> Dual-weighted residual indicator.\n * If (key == 4) ==> Local problem indicator. * @param color chart type of marked simplices * @param bkey Bisection type * @param elevel level to determine the fraction of simplices * @param u block NODAL solution vector * @param ud block NODAL dirichlet vector * @param f block NODAL residual vector * @param r block NODAL temporary vector */ VEXTERNC int Aprx_markRefine(Aprx *thee, int key, int color, int bkey, double elevel, Bvec *u, Bvec *ud, Bvec *f, Bvec *r); /** * @ingroup Aprx * @brief A posteriori error estimation via several different approaches. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (estim.c) * @verbatim Apply one of several a posteriori error estimators: If (key == 2) ==> Nonlinear residual indicator. If (key == 3) ==> Dual-weighted residual indicator. If (key == 4) ==> Local problem indicator. If (key == 5) ==> Recovered gradient indicator. The error tolerance can be used in several ways: If (bkey == 0) ==> mark if: [error/S] > TOL If (bkey == 1) ==> mark if: [error/S] > (TOL^2/numS)^{1/2} If (bkey == 2) ==> mark fixed number/fraction (dep. on ETOL): if elevel < 1, mark fraction of simplices if elevel >=1, mark that many simplices (rounded to the smaller integer) @endverbatim * @return number of marked simplices * @param thee Pointer to an Aprx allocated memory location * @param key index of different types of a posteriori error estimators * @param color chart type of marked simplices * @param bkey Bisection type * @param elevel level to determine the fraction of simplices * @param u block NODAL solution vector * @param ud block NODAL dirichlet vector * @param f block NODAL residual vector * @param r block NODAL temporary vector */ VEXTERNC int Aprx_estRefine(Aprx *thee, int key, int color, int bkey, double elevel, Bvec *u, Bvec *ud, Bvec *f, Bvec *r); /** * @ingroup Aprx * @brief Selects a fixed number/fraction of simplicies to be refined. * @author Olen Korobkin, Michael Holst * @note Class Aprx: Non-inlineable methods (estim.c) * @verbatim This function is called by Aprx_markRefine if fixed number / fraction of simplices has to be refined. Returns number of marked elements. @endverbatim * @return Number of marked elements * @param thee Pointer to an Aprx allocated memory location * @param num2ref index for the refined simplex * @param color chart type of marked simplices */ VEXTERNC int Aprx_markRefineFixed (Aprx *thee, int num2ref, int color); /** * @ingroup Aprx * @brief Selects a fixed number/fraction of simplicies to be refined. * @author Olen Korobkin, Michael Holst * @note Class Aprx: Non-inlineable methods (estim.c) * @verbatim This function is called by Aprx_markRefine. Returns number of marked elements. @endverbatim * @return Number of marked elements * @param thee Pointer to an Aprx allocated memory location * @param percentToRefine Percentage to refine * @param color chart type of marked simplices */ VEXTERNC int Aprx_markRefineDorfler (Aprx *thee, double percentToRefine, int color); /** * @ingroup Aprx * @brief Evaluate a finite element solution at a set of arbitrary points. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (eval.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param u solution vector * @param block index for the block * @param numPts number of all interpolation pts for one simplex * @param pts coordinates of the pt * @param vals solution for the interpolated pts * @param marks index for marked or not */ VEXTERNC void Aprx_evalFunc(Aprx *thee, Bvec *u, int block, int numPts, double *pts, double *vals, int *marks); /** * @ingroup Aprx * @brief Interpolates data onto finite difference grid * @author Michael Holst, Doug Arnold and Karen Camarda * @note Class Aprx: Non-inlineable methods (eval.c)\n * Much is lifted from Aprx_evalFunc, * with some ideas from Doug Arnold. * Contributed by Karen Camarda. * @verbatim * Example: Below is a matlab example courtesy of Doug Arnold. * * %-- BEGIN MATLAB CODE -------------------------------------------------- * * function colormesh * * % This file demonstrates how to go from an unstructured grid to * % a structured one. Each point on the structured grid is colored * % according to which triangle in the unstructured grid it belongs to. * * % Douglas N. Arnold, 3/4/98 * * % set up a mesh * npts=10; * x=[ 1.13 1.66 0.50 0.46 0.26 0.20 0.70 1.93 1.01 0.65 ]; * y=[ 1.81 1.23 0.99 1.30 1.29 1.50 1.10 0.68 0.60 0.07 ]; * tri = delaunay(x,y); * ntri=size(tri,1); * * % grid spacing * h=.03; * k=.04; * * clf * [z,i]=sort(rand(64,1)); * colormap hsv; * cmap = colormap; * cmap=cmap(i,:,:); * * % loop over triangles * for m = 1:ntri * % get vertices of triangle i * v1=[x(tri(m,1)),y(tri(m,1))]; * v2=[x(tri(m,2)),y(tri(m,2))]; * v3=[x(tri(m,3)),y(tri(m,3))]; * * % plot the triangle * ttt=[v1;v2;v3;v1]; * line(ttt(:,1),ttt(:,2),'color','green') * * % find bounding box of triangle * xmin = min([v1(1),v2(1),v3(1)]); * xmax = max([v1(1),v2(1),v3(1)]); * ymin = min([v1(2),v2(2),v3(2)]); * ymax = max([v1(2),v2(2),v3(2)]); * * % loop through grid points in bounding box, plotting those in triangle * for i = ceil(xmin/h):floor(xmax/h) * for j = ceil(ymin/k):floor(ymax/k) * if intriangle(v1,v2,v3,[i*h,j*k]) * % set color according to triangle number * color = cmap(m,:); * line(i*h,j*k,'marker','.','markersize',10,'color',color) * end * end * end * * end * * function i = intriangle(v1,v2,v3,x) * % INTRIANGLE -- check if a point belongs to a triangle * % * % f = intriangle(v1,v2,v3,x) * % * % input: * % v1,v2,v3 2-vectors giving the vertices of the triangle * % x 2-vector giving the point * % * % output: * % i 1 if x belongs to the close triangle, 0 else * * % map point under affine mapping from given triangle to ref triangle * xhat = (x-v1)/[v2-v1;v3-v1]; * % check if mapped point belongs to reference triangle * i = xhat(1) >= 0 & xhat(2) >= 0 & 1-xhat(1)-xhat(2) >= 0; * %-- END MATLAB CODE -------------------------------------------------- * * *************************************************************************** @endverbatim * @return None * @param thee Pointer to an Aprx allocated memory location * @param u solution vector * @param block index of block * @param nx number of grids in X coordinates * @param ny number of grids in y coordinates * @param nz number of grids in z coordinates * @param x0 x coordinate of lower grid corner * @param y0 y coordinate of lower grid corner * @param z0 z coordinate of lower grid corner * @param dx Grid spacing in x direction * @param dy Grid spacing in y direction * @param dz Grid spacing in z direction * @param derivs index for different nfunc types * @param outTypeKey ASCII output or Binary output */ VEXTERNC void Aprx_fe2fd(Aprx *thee, Bvec *u, int block, int nx, int ny, int nz, double x0, double y0, double z0, double dx, double dy, double dz, int derivs, int outTypeKey); /** * @ingroup Aprx * @brief Evaluate a given boundary integral. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (eval.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param u block NODAL solution vector * @param ud block NODAL dirichlet vector * @param ut block NODAL analytical vector */ VEXTERNC void Aprx_bndIntegral(Aprx *thee, Bvec *u, Bvec *ud, Bvec *ut); /** * @ingroup Aprx * @brief Evaluate ADM mass from conformal factor. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (eval.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param u block NODAL solution vector * @param ud block NODAL dirichlet vector * @param ut block NODAL analytical vector * @param block index of a block */ VEXTERNC void Aprx_admMass(Aprx *thee, Bvec *u, Bvec *ud, Bvec *ut, int block); /** * @ingroup Aprx * @brief Evaluate error in solution in one of several norms. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (eval.c) \n * We evaluate the error in the solution (in the case that * an exact analytical solution is available) in one of several * norms:\n * If (key == 0) ==> L^2 norm of the error.\n * If (key == 1) ==> L^{\\infty} norm of the error.\n * If (key == 2) ==> H^1 norm of the error. * @return error in solution in one of several norms. * @param thee Pointer to an Aprx allocated memory location * @param pcolor simplex chart type * @param key If (key == 0) ==> L^2 norm of the error.\n * If (key == 1) ==> L^{\\infty} norm of the error.\n * If (key == 2) ==> H^1 norm of the error. * @param u block NODAL solution vector * @param ud block NODAL dirichlet vector * @param ut block NODAL analytical vector */ VEXTERNC double Aprx_evalError(Aprx *thee, int pcolor, int key, Bvec *u, Bvec *ud, Bvec *ut); /** * @ingroup Aprx * @brief Evaluate difference of two functions in H1 norm in one element. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (eval.c) \n * We evaluate difference of two functions in H1 norm in one element. * @return Difference of two functions in H1 norm in one element. * @param thee Pointer to an Aprx allocated memory location * @param sm simplex * @param u block NODAL solution vector * @param ud block NODAL dirichlet vector * @param ut block NODAL analytical vector */ VEXTERNC double Aprx_evalH1(Aprx *thee, SS *sm, Bvec *u, Bvec *ud, Bvec *ut); /** * @ingroup Aprx * @brief Write a finite element mesh or mesh function in some format. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (io.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param sock socket for reading the external mesh data (NULL otherwise) * @param defKey defKey == 0 ==> draw mesh as it is * defKey == 1 ==> use "def??" as new vertex coords (deformation) * defKey == 2 ==> add "def??" to old vertex coords (displacement) * * @param colKey colKey == 0 ==> color simplices all same default color * colKey == 1 ==> color simplices based on their chart * colKey == 2 ==> color boundary simplices based on type * * @param chartKey chartKey < 0 ==> draw all simplices * chartKey >= 0 ==> draw only simplices with chart chartKey * * @param gluVal gluVal == 1. ==> draw all simplices glued together * 0. < gluVal < 1. ==> draw simplices with some separation * * @param fkey fkey == 0 ==> draw simplices * fkey == 1 ==> draw only simplex boundary faces * fkey == 2 ==> draw only simplices with a boundary face * @param u block NODAL solution vector * @param format GV/MATH format */ VEXTERNC void Aprx_writeGEOM(Aprx *thee, Vio *sock, int defKey, int colKey, int chartKey, double gluVal, int fkey, Bvec *u, char *format); /** * @ingroup Aprx * @brief Write a finite element mesh or mesh function in some format. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (io.c) * @return None * @param thee Pointer to an Aprx allocated memory location * @param sock socket for reading the external mesh data (NULL otherwise) * @param u block NODAL solution vector * @param format GV/MATH format */ VEXTERNC void Aprx_writeSOL(Aprx *thee, Vio *sock, Bvec *u, char *format); /** * @ingroup Aprx * @brief Clear the partitioning (set all colors to pcolor). * @author Michael Holst * @note Class Aprx: Non-inlineable methods (parti.c) * @return Success enumeration * @param thee Pointer to an Aprx allocated memory location * @param pcolor simplex chart type */ VEXTERNC int Aprx_partSet(Aprx *thee, int pcolor); /** * @ingroup Aprx * @brief Smooth the partitioning. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (parti.c) * @return counted number of partitions * @param thee Pointer to an Aprx allocated memory location */ VEXTERNC int Aprx_partSmooth(Aprx *thee); /** * @ingroup Aprx * @brief Partition the domain using inertial bisection. * Partition sets of points in R^d (d=2 or d=3) by viewing them * as point masses of a rigid body, and by then employing the * classical mechanics ideas of inertia and Euler axes. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (parti.c)\n * We first locate the center of mass, then change the coordinate * system so that the center of mass is located at the origin. * We then form the (symmetric) dxd inertia tensor, and then find * the set of (real) eigenvalues and (orthogonal) eigenvectors. * The eigenvectors represent the principle inertial rotation axes, * and the eigenvalues represent the inertial strength in those * principle directions. The smallest inerial component along an * axis represents a direction along which the rigid body is most * "line-like" (assuming all the points have the same mass). \n * For our purposes, it makes sense to using the axis (eigenvector) * corresponding to the smallest inertia (eigenvalue) as the line to * bisect with a line (d=2) or a plane (d=3). We know the center of * mass, and once we also have this particular eigenvector, we can * effectively bisect the point set into the two regions separated * by the line/plane simply by taking an inner-product of the * eigenvector with each point (or rather the 2- or 3-vector * representing the point). A positive inner-product represents one * side of the cutting line/plane, and a negative inner-product * represents the other side (a zero inner-product is right on the * cutting line/plane, so we arbitrarily assign it to one region or * the other). * @return Success enumeration * @param thee Pointer to an Aprx allocated memory location * @param pcolor simplex chart type * @param numC number of columns in the matrix * @param evec eigenvector * @param simH simHelper class */ VEXTERNC int Aprx_partInert(Aprx *thee, int pcolor, int numC, double *evec, simHelper *simH); /** * @ingroup Aprx * @brief Partition the domain using spectral bisection. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (parti.c)\n * @verbatim * We solve the following generalized eigenvalue problem: * * Ax = lambda Bx * * for second smallest eigenpair. We then return the eigenvector * from the pair. We make this happen by turning it into a * regular eigenvalue problem: * * B^{-1/2} A B^{-1/2} ( B^{1/2} x ) = lambda ( B^{1/2} x ) * * or rather * * C y = lambda y, where C=B^{-1/2}AB^{-1/2}, y=B^{1/2}x. * * The matrix "B" is simply a diagonal matrix with a (positive) * error estimate for the element on the diagonal. Therefore, the * matrix B^{-1/2} is a well-defined positive diagonal matrix. * * We explicitly form the matrix C and then send it to the inverse * Rayleigh-quotient iteration to recover the second smallest * eigenpair. On return, we scale the eigenvector y by B^{-1/2} to * recover the actual eigenvector x = B^{-1/2} y. * * To handle the possibility that an element has zero error, in * which case the B matrix had a zero on the diagonal, we set the * corresponding entry in B^{-1/2} to be 1. * @endverbatim * @return Success enumeration * @param thee Pointer to an Aprx allocated memory location * @param pcolor simplex chart type * @param numC number of columns in the matrix * @param evec eigenvector * @param simH simHelper class * @param ford temporary storage ford array * @param rord temporary storage rord array * @param general index for creating different scaling matrix */ VEXTERNC int Aprx_partSpect(Aprx *thee, int pcolor, int numC, double *evec, simHelper *simH, int *ford, int *rord, int general); /** * @ingroup Aprx * @brief Do recursive bisection. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (parti.c) * @return Success enumeration * @param thee Pointer to an Aprx allocated memory location * @param pkey index for different partition option * @param pwht index for weighted partitioning * @param ppow partitioning steps */ VEXTERNC int Aprx_part(Aprx *thee, int pkey, int pwht, int ppow); /** * @ingroup Aprx * @brief Do a single bisection step. * @author Michael Holst * @note Class Aprx: Non-inlineable methods (parti.c) * @param thee Pointer to an Aprx allocated memory location * @param pkey partition method * @param pwht partitioning weighting * @param pcolor simplex chart type * @param poff an index */ VEXTERNC int Aprx_partOne(Aprx *thee, int pkey, int pwht, int pcolor, int poff); #endif /* _APRX_H_ */