anzhi2710gmailcom's picture
Upload folder using huggingface_hub
10f2621 verified
Raw
History Blame Contribute Delete
17.9 kB
/**
* @defgroup PDE PDE class
* @brief the differential equation object.
*/
/**
* @file pde.h
* @ingroup PDE
* @brief Class PDE: the differential equation object.
* @note
* @verbatim
* The differential operator information is provided by
* specifying the following:
*
* vec Product dim (unknowns per spatial point)
* sym[MAXV][MAXV]; Symmetry/nonsymmetry of bilinear form
*
* initAssemble Once-per-assembly initialization
* initElement Once-per-element initialization
* initFace Once-per-face initialization
* initPoint Once-per-point (e.g. quadrature pt) initialization
*
* Fu The nonlinear strong form defining the PDE
* Ju The nonlinear energy (PDE is the Euler condition)
* Fu_v The nonlinear weak form defining the PDE
* DFu_wv The bilinear linearization weak form
* delta The delta function source term (if present)
* u_D The dirichlet boundary condition function
* u_T Optional analytical solution function (for testing)
*
* bisectEdge The rule used to spit edges of simplices
* mapBoundary The rule used to recover boundary surfaces exactly
* markSimplex The rule used to mark simplices for refinement
* oneChart Coordinate transformations
*
* simplexBasisInit Trial and test space bases initialization
* simplexBasisForm Trial and test space bases formation
*
* The following two additional parameters are determined by the
* input manifold, and are then set appropriately to be available
* to the user's PDE definition routines above:
*
* dim Manifold intrinsic dim (determined by mesh input)
* dimII Manifold imbedding dim (determined by mesh input)
*
* Notes on the forms: Fu_v/DFu_wv
*
* At the single given point x, we must evaluate the functionals
*
* Fu_v = F(u)(v) = F (x, u(x),grad u(x), v(x),grad v(x))
*
* DFu_wv = DF(u)(w,v) = DF(x, u(x),grad u(x), v(x),grad v(x),
* w(x),grad w(x))
*
* The functional F(u)(v):HxH-->R is assumed to be linear in
* the argument v, but possibly nonlinear in the argument u.
*
* The functional DF(u)(w,v):HxHxH-->R is assumed to be linear in
* the arguments v and w, but possibly nonlinear in the argument u.
*
* Here, H is some Banach space of functions, such as the
* Sobolev space W^{1,p}(\Omega), 1<=p<\infty, or some product
* space based on these spaces.
*
* The forms Fu_v/DFu_wv and their use in Newton iterations:
*
* The functional F(u)(v) is a weak formulation of some nonlinear
* partial differential equation. This functional represents a
* nonlinear operator in an equation of the form:
*
* (P1) Find u in H such that F(u)(v)=0 for all v in H.
*
* As a function of its first argument only, the functional F(u)(v)
* can be viewed as a mapping from the space H into the space of
* linear functionals on H, or F(u)(v):H->L(H,R). Similarly, the
* Frechet derivative of F(u)(v) with respect to u represents a
* mapping DF(u)(w,v):H->L(HxH,R), which is a mapping from H into
* the space of bilinear forms on H. At a point z in H, such a
* bilinear form will be denoted:
*
* DF(z)(u,v).
*
* A Newton iteration for solving (P1) takes the form:
*
* (0) Given some initial guess of u in H.
* (For linear problems, we will always start with u=0.)
* (1) Find w in H such that DF(u)(w,v)=-F(u)(v), for all v in H.
* (2) Update u: u = u + w
* (3) If (F(u)(v)>TOL) for some v in H, goto (1)
* (4) Quit
*
* If this is a linear problem, in that F(u)(v) is only affine in the
* argument u rather than truly nonlinear, then the operator has
* the general form:
*
* F(u)(v) = A(u,v) - (f,v),
*
* where A(u,v) is bilinear. Therefore, problem (P1) has the form:
*
* (P2) Find u in H such that A(u,v)=(f,v) for all v in H.
*
* The Frechet derivative of F(u)(v) with respect to u at a point z
* is simply the bilinear form (independent of z)
*
* DF(z)(u,v) = A(u,v).
*
* Now, since we will require u=0 to start a Newton iteration for a
* linear problem, this will produce the linear source term as
* required to solve the linear problem:
*
* (Aw,v) = DF(0)(w,v) = -F(0)(v) = (f,v)
*
* So, Step (1) in our Newton iteration will be exactly the
* solution of the linear problem (P2), which is the proper
* linearization of a linear (affine) problem. Step (2) of the
* Newton iteration them forms u as u=0+w, and Step (3) then sees
* F(u)(v)=A(w,v)-(f,v)=0, which leads to completion in Step (4).
*
* Sub-form implementation of Fu_v/DFu_wv and computational details:
*
* For the sake of efficiency, these forms may be implemented in
* terms of sub-forms on orthogonal spaces. For systems of partial
* differential equations, the functions u,v,w above have the form:
*
* u=(u_1, u_2, ... , u_m),
*
* so that u then lies in the product space H=[H_1xH_2x...xH_m],
* with each component function u_i in the space H_i.
*
* While the argument appearing nonlinearly in each form (namely u)
* may have all components u_i nonzero, it is assumed that the other
* two arguments which appear linearly always have only ONE component
* (v_i != 0) for a given i; thus,
*
* v=(0, 0, ... , 0, v_i, 0, ... ,0), for some i,
* w=(0, 0, ... , 0, w_j, 0, ... ,0), for some j.
*
* There may be (quite) significant reduction in computational costs
* if this is known apriori. The arguments v and w will ALWAYS have
* this form. Due to their linear appearance in the forms and the
* orthogonality of spaces H_i and H_j for (i!=j) in the setting of
* a product of spaces, the above forms can be viewed as:
*
* F(u)(v) = F_1(u)(v_1) + ... + F_m(u)(v_m).
*
* DF(u)(w,v) = DF_11(u)(w_1,v_1) + ... + DF_1m(u)(w_1,v_m)
* + DF_21(u)(w_2,v_1) + ... + DF_2m(u)(w_2,v_m)
* .
* .
* .
* + DF_m1(u)(w_m,v_1) + ... + DF_mm(u)(w_m,v_m)
*
* Therefore, it may be more efficient to represent the forms
* F(u)(v) and DF(u)(w,v) as additive collections of the sub-forms:
*
* F_i(u)(v_i), i=1,...,m
*
* DF_ij(u)(w_j,v_i), i=1,...,m, j=1,...,m
*
* In fact, in a finite element discretization, somewhere we will
* have to split the forms into the above sub-forms. We can attempt
* to exploit this known structure and save on some computation by
* designing the F(u)(v) and DF(u)(w,v) routines to return ARRAYS
* of values, GAMMA[m][1] and THETA[m][m], containing the values of
* the above sub-forms at the given input point. If it is difficult
* to split the forms by hand, one can of course simply use the full
* forms F(u)(v) and DF(u)(w,v) to fill the arrays GAMMA and THETA;
* you just need to plug in the basis functions having the form:
*
* v=(0, 0, ... , 0, v_i, 0, ... ,0),
* w=(0, 0, ... , 0, w_j, 0, ... ,0),
*
* taking i=1,...,m, and also j=1,...,m.
*
* @endverbatim
* @version $Id: pde.h,v 1.23 2010/08/12 05:19:18 fetk Exp $
* @author Michael Holst
*
* @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 _PDE_H_
#define _PDE_H_
#include <mc/mc_base.h>
/*
* ***************************************************************************
* Class PDE: Parameters and datatypes
* ***************************************************************************
*/
/**
* @ingroup PDE
* @brief Class PDE: Definition
* @author Michael Holst
*/
struct sPDE {
/*
* ************************************************************************
* User-supplied problem information -- ALL must be supplied by the user.
* ************************************************************************
*/
/** @brief User-supplied - Manifold intrinsic dim (determined by mesh) */
int dim;
/** @brief User-supplied - Manifold imbedding dim (determined by mesh) */
int dimII;
/** @brief User-supplied - Product dim (unknowns per spatial point) */
int vec;
/**
* @brief User-supplied symmetry/nonsymmetry of bilinear form:\n
* sym[i][j]=0 ==> nonsym bilinear form\n
* sym[i][j]=1 ==> sym bilinear form\n
* sym[i][j]=2 ==> sym image of block in upper triangle
* (2 requires i>j)
*/
int sym[MAXV][MAXV];
/** @brief User-supplied - error estimator weights */
double est[MAXV];
/** @brief User-supplied - boundary type (re)mapping */
int bmap[MAXV][VMAX_BDTYPE];
/** @brief Once-per-assembly/element/face/point initialization */
void (*initAssemble)(struct sPDE *thee, int ip[], double rp[]);
/** @brief Once-per-assembly/element/face/point initialization */
void (*initElement)(struct sPDE *thee, int elementType,
int chart, double tvx[][3], void *data);
/** @brief Once-per-assembly/element/face/point initialization */
void (*initFace)(struct sPDE *thee, int faceType,
int chart, double tnvec[]);
/** @brief Once-per-assembly/element/face/point initialization */
void (*initPoint)(struct sPDE *thee, int pointType,
int chart, double txq[],
double U[], double dU[][3]);
/** @brief Nonlinear/bilinear strong/weak forms defining PDE and
*linearization */
void (*Fu)(struct sPDE *thee, int key, double F[]);
/** @brief Nonlinear/bilinear strong/weak forms defining PDE and
*linearization */
double (*Ju)(struct sPDE *thee, int key);
/** @brief Nonlinear/bilinear strong/weak forms defining PDE and
*linearization */
double (*Fu_v)(struct sPDE *thee, int key,
double V[], double dV[][3]);
/** @brief Nonlinear/bilinear strong/weak forms defining PDE and
*linearization */
double (*DFu_wv)(struct sPDE *thee, int key,
double W[], double dW[][3],
double V[], double dV[][3]);
/** @brief Nonlinear/bilinear strong/weak forms defining PDE and
*linearization */
double (*p_wv)(struct sPDE *thee,
int key, double W[], double V[]);
/** @brief Delta functions, Dirichlet boundary condition, analytical
* solution */
void (*delta)(struct sPDE *thee, int type,
int chart, double txq[], void *data, double F[]);
/** @brief Delta functions, Dirichlet boundary condition, analytical
* solution */
void (*u_D)(struct sPDE *thee, int type,
int chart, double txq[], double F[]);
/** @brief Delta functions, Dirichlet boundary condition, analytical
* solution */
void (*u_T)(struct sPDE *thee, int type,
int chart, double txq[], double F[], double dF[][3]);
/** @brief Bisect edge rule (for refinement) and the chart unification
* routine */
void (*bisectEdge)(int dim, int dimII,
int edgeType, int chart[], double vx[][3]);
/** @brief Bisect edge rule (for refinement) and the chart unification
* routine */
void (*mapBoundary)(int dim, int dimII, int vertexType,
int chart, double vx[3]);
/** @brief Bisect edge rule (for refinement) and the chart unification
* routine */
int (*markSimplex)(int dim, int dimII,
int simplexType, int faceType[4], int vertexType[4],
int chart[], double vx[][3], void *data);
/** @brief Bisect edge rule (for refinement) and the chart unification
* routine */
void (*oneChart)(int dim, int dimII,
int objType, int chart[], double vx[][3], int dimV);
/** @brief Trial and test space bases evaluation routine */
int (*simplexBasisInit)(int key, int dim, int comp,
int *ndof, int dof[]);
/** @brief Trial and test space bases evaluation routine */
void (*simplexBasisForm)(int key, int dim, int comp,
int pdkey, double xq[], double basis[]);
/** @brief To allow user to hang problem-specific variables off PDE
* structure */
void *user;
};
/**
* @ingroup PDE
* @brief Declaration of the PDE class as the PDE structure
* @author Michael Holst
*/
typedef struct sPDE PDE;
/*
* ***************************************************************************
* Class PDE: Inlineable methods (pde.c)
* ***************************************************************************
*/
#if !defined(VINLINE_PDE)
/**
* @ingroup PDE
* @brief Set the extrinsic spatial dimension.
* @author Michael Holst
* @note Class PDE: Inlineable methods (pde.c)
* @return None
* @param thee Pointer to the PDE object
* @param d the extrinsic spatial dimension
*/
VEXTERNC void PDE_setDim(PDE *thee, int d);
/**
* @ingroup PDE
* @brief Set the extrinsic spatial dimension.
* @author Michael Holst
* @note Class PDE: Inlineable methods (pde.c)
* @return None
* @param thee Pointer to the PDE object
* @param d the intrinsic spatial dimension
*/
VEXTERNC void PDE_setDimII(PDE *thee, int d);
/**
* @ingroup PDE
* @brief Return the extrinsic spatial dimension.
* @author Michael Holst
* @note Class PDE: Inlineable methods (pde.c)
* @return the extrinsic spatial dimension.
* @param thee Pointer to the PDE object
*/
VEXTERNC int PDE_dim(PDE *thee);
/**
* @ingroup PDE
* @brief Return the extrinsic spatial dimension.
* @author Michael Holst
* @note Class PDE: Inlineable methods (pde.c)
* @return the extrinsic spatial dimension.
* @param thee Pointer to the PDE object
*/
VEXTERNC int PDE_dimII(PDE *thee);
/**
* @ingroup PDE
* @brief Return the PDE product space dimension.
* @author Michael Holst
* @note Class PDE: Inlineable methods (pde.c)
* @return the PDE product space dimension.
* @param thee Pointer to the PDE object
*/
VEXTERNC int PDE_vec(PDE *thee);
#else /* if defined(VINLINE_PDE) */
# define PDE_setDim(thee,d) ( (thee)->dim = (d) )
/** @brief Class PDE: Inlineable methods (pde.c) if defined(VINLINE_PDE) */
# define PDE_setDimII(thee,d) ( (thee)->dimII = (d) )
/** @brief Class PDE: Inlineable methods (pde.c) if defined(VINLINE_PDE) */
# define PDE_dim(thee) ( (thee)->dim )
/** @brief Class PDE: Inlineable methods (pde.c) if defined(VINLINE_PDE) */
# define PDE_dimII(thee) ( (thee)->dimII )
/** @brief Class PDE: Inlineable methods (pde.c) if defined(VINLINE_PDE) */
# define PDE_vec(thee) ( (thee)->vec )
#endif /* if !defined(VINLINE_PDE) */
/*
* ***************************************************************************
* Class PDE: Non-inlineable methods (pde.c)
* ***************************************************************************
*/
/**
* @ingroup PDE
* @brief Construct a fake differential equation object in case there
* is not one provided.
* @author Michael Holst
* @note Class PDE: Non-Inlineable methods (pde.c)
* @return Pointer to a new allocated PDE object
*/
VEXTERNC PDE* PDE_ctor_default(void);
/**
* @ingroup PDE
* @brief Destroy a fake differential equation object.
* @author Michael Holst
* @note Class PDE: Non-Inlineable methods (pde.c)
* @return None
* @param thee Pointer to the PDE object
*/
VEXTERNC void PDE_dtor_default(PDE **thee);
/**
* @ingroup PDE
* @brief Return the bilinear form minor symmetry (i,j).
* @author Michael Holst
* @note Class PDE: Non-Inlineable methods (pde.c)
* @return the bilinear form minor symmetry (i,j).
* @param thee Pointer to the PDE object
* @param i index for the symmetry test
* @param j index for the symmetry test
*/
VEXTERNC int PDE_sym(PDE *thee, int i, int j);
#endif /* _PDE_H_ */