Actual source code: dmpleximpl.h
petsc-3.10.5 2019-03-28
Report Typos and Errors

      1: #if !defined(_PLEXIMPL_H)
      2: #define _PLEXIMPL_H

      4:  #include <petscmat.h>
      5:  #include <petscdmplex.h>
      6:  #include <petscbt.h>
      7:  #include <petscsf.h>
      8:  #include <petsc/private/dmimpl.h>

     10: PETSC_EXTERN PetscLogEvent DMPLEX_Interpolate;
     11: PETSC_EXTERN PetscLogEvent DMPLEX_Partition;
     12: PETSC_EXTERN PetscLogEvent DMPLEX_Distribute;
     13: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeCones;
     14: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeLabels;
     15: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeSF;
     16: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeOverlap;
     17: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeField;
     18: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeData;
     19: PETSC_EXTERN PetscLogEvent DMPLEX_Migrate;
     20: PETSC_EXTERN PetscLogEvent DMPLEX_InterpolateSF;
     21: PETSC_EXTERN PetscLogEvent DMPLEX_GlobalToNaturalBegin;
     22: PETSC_EXTERN PetscLogEvent DMPLEX_GlobalToNaturalEnd;
     23: PETSC_EXTERN PetscLogEvent DMPLEX_NaturalToGlobalBegin;
     24: PETSC_EXTERN PetscLogEvent DMPLEX_NaturalToGlobalEnd;
     25: PETSC_EXTERN PetscLogEvent DMPLEX_Stratify;
     26: PETSC_EXTERN PetscLogEvent DMPLEX_Preallocate;
     27: PETSC_EXTERN PetscLogEvent DMPLEX_ResidualFEM;
     28: PETSC_EXTERN PetscLogEvent DMPLEX_JacobianFEM;
     29: PETSC_EXTERN PetscLogEvent DMPLEX_InterpolatorFEM;
     30: PETSC_EXTERN PetscLogEvent DMPLEX_InjectorFEM;
     31: PETSC_EXTERN PetscLogEvent DMPLEX_IntegralFEM;
     32: PETSC_EXTERN PetscLogEvent DMPLEX_CreateGmsh;

     34: PETSC_EXTERN PetscBool      PetscPartitionerRegisterAllCalled;
     35: PETSC_EXTERN PetscErrorCode PetscPartitionerRegisterAll(void);

     37: typedef enum {REFINER_NOOP = 0,
     38:               REFINER_SIMPLEX_1D,
     39:               REFINER_SIMPLEX_2D,
     40:               REFINER_HYBRID_SIMPLEX_2D,
     41:               REFINER_SIMPLEX_TO_HEX_2D,
     42:               REFINER_HYBRID_SIMPLEX_TO_HEX_2D,
     43:               REFINER_HEX_2D,
     44:               REFINER_HYBRID_HEX_2D,
     45:               REFINER_SIMPLEX_3D,
     46:               REFINER_HYBRID_SIMPLEX_3D,
     47:               REFINER_SIMPLEX_TO_HEX_3D,
     48:               REFINER_HYBRID_SIMPLEX_TO_HEX_3D,
     49:               REFINER_HEX_3D,
     50:               REFINER_HYBRID_HEX_3D} CellRefiner;

     52: typedef struct _PetscPartitionerOps *PetscPartitionerOps;
     53: struct _PetscPartitionerOps {
     54:   PetscErrorCode (*setfromoptions)(PetscOptionItems*,PetscPartitioner);
     55:   PetscErrorCode (*setup)(PetscPartitioner);
     56:   PetscErrorCode (*view)(PetscPartitioner,PetscViewer);
     57:   PetscErrorCode (*destroy)(PetscPartitioner);
     58:   PetscErrorCode (*partition)(PetscPartitioner, DM, PetscInt, PetscInt, PetscInt[], PetscInt[], PetscSection, IS *);
     59: };

     61: struct _p_PetscPartitioner {
     62:   PETSCHEADER(struct _PetscPartitionerOps);
     63:   void           *data;             /* Implementation object */
     64:   PetscInt        height;           /* Height of points to partition into non-overlapping subsets */
     65: };

     67: typedef struct {
     68:   PetscInt dummy;
     69: } PetscPartitioner_Chaco;

     71: typedef struct {
     72:   PetscInt ptype;
     73: } PetscPartitioner_ParMetis;

     75: typedef struct {
     76:   PetscSection section;   /* Sizes for each partition */
     77:   IS           partition; /* Points in each partition */
     78:   PetscBool    random;    /* Flag for a random partition */
     79: } PetscPartitioner_Shell;

     81: typedef struct {
     82:   PetscInt dummy;
     83: } PetscPartitioner_Simple;

     85: typedef struct {
     86:   PetscInt dummy;
     87: } PetscPartitioner_Gather;

     89: /* Utility struct to store the contents of a Gmsh file in memory */
     90: typedef struct {
     91:   PetscInt dim;      /* Entity dimension */
     92:   PetscInt id;       /* Element number */
     93:   PetscInt numNodes; /* Size of node array */
     94:   int nodes[8];      /* Node array */
     95:   PetscInt numTags;  /* Size of tag array */
     96:   int tags[4];       /* Tag array */
     97:   PetscInt cellType; /* Cell type */
     98: } GmshElement;

    100: /* Utility struct to store the contents of a Fluent file in memory */
    101: typedef struct {
    102:   int          index;    /* Type of section */
    103:   unsigned int zoneID;
    104:   unsigned int first;
    105:   unsigned int last;
    106:   int          type;
    107:   int          nd;       /* Either ND or element-type */
    108:   void        *data;
    109: } FluentSection;

    111: struct _PetscGridHash {
    112:   PetscInt     dim;
    113:   PetscReal    lower[3];    /* The lower-left corner */
    114:   PetscReal    upper[3];    /* The upper-right corner */
    115:   PetscReal    extent[3];   /* The box size */
    116:   PetscReal    h[3];        /* The subbox size */
    117:   PetscInt     n[3];        /* The number of subboxes */
    118:   PetscSection cellSection; /* Offsets for cells in each subbox*/
    119:   IS           cells;       /* List of cells in each subbox */
    120:   DMLabel      cellsSparse; /* Sparse storage for cell map */
    121: };

    123: typedef struct {
    124:   PetscInt             refct;

    126:   /* Sieve */
    127:   PetscSection         coneSection;       /* Layout of cones (inedges for DAG) */
    128:   PetscInt             maxConeSize;       /* Cached for fast lookup */
    129:   PetscInt            *cones;             /* Cone for each point */
    130:   PetscInt            *coneOrientations;  /* Orientation of each cone point, means cone traveral should start on point 'o', and if negative start on -(o+1) and go in reverse */
    131:   PetscSection         supportSection;    /* Layout of cones (inedges for DAG) */
    132:   PetscInt             maxSupportSize;    /* Cached for fast lookup */
    133:   PetscInt            *supports;          /* Cone for each point */
    134:   PetscBool            refinementUniform; /* Flag for uniform cell refinement */
    135:   PetscReal            refinementLimit;   /* Maximum volume for refined cell */
    136:   PetscErrorCode     (*refinementFunc)(const PetscReal [], PetscReal *); /* Function giving the maximum volume for refined cell */
    137:   PetscInt             hybridPointMax[8]; /* Allow segregation of some points, each dimension has a divider (used in VTK output and refinement) */

    139:   PetscInt            *facesTmp;          /* Work space for faces operation */

    141:   /* Hierarchy */
    142:   PetscBool            regularRefinement; /* This flag signals that we are a regular refinement of coarseMesh */

    144:   /* Generation */
    145:   char                *tetgenOpts;
    146:   char                *triangleOpts;
    147:   PetscPartitioner     partitioner;
    148:   PetscBool            partitionBalance;  /* Evenly divide partition overlap when distributing */
    149:   PetscBool            remeshBd;

    151:   /* Submesh */
    152:   DMLabel              subpointMap;       /* Label each original mesh point in the submesh with its depth, subpoint are the implicit numbering */

    154:   /* Labels and numbering */
    155:   PetscObjectState     depthState;        /* State of depth label, so that we can determine if a user changes it */
    156:   IS                   globalVertexNumbers;
    157:   IS                   globalCellNumbers;

    159:   /* Constraints */
    160:   PetscSection         anchorSection;      /* maps constrained points to anchor points */
    161:   IS                   anchorIS;           /* anchors indexed by the above section */
    162:   PetscErrorCode     (*createanchors)(DM); /* automatically compute anchors (probably from tree constraints) */
    163:   PetscErrorCode     (*computeanchormatrix)(DM,PetscSection,PetscSection,Mat);

    165:   /* Tree: automatically construct constraints for hierarchically non-conforming meshes */
    166:   PetscSection         parentSection;     /* dof == 1 if point has parent */
    167:   PetscInt            *parents;           /* point to parent */
    168:   PetscInt            *childIDs;          /* point to child ID */
    169:   PetscSection         childSection;      /* inverse of parent section */
    170:   PetscInt            *children;          /* point to children */
    171:   DM                   referenceTree;     /* reference tree to which child ID's refer */
    172:   PetscErrorCode      (*getchildsymmetry)(DM,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt*,PetscInt*);

    174:   /* MATIS support */
    175:   PetscSection         subdomainSection;

    177:   /* Adjacency */
    178:   PetscBool            useAnchors;        /* Replace constrained points with their anchors in adjacency lists */
    179:   PetscErrorCode      (*useradjacency)(DM,PetscInt,PetscInt*,PetscInt[],void*); /* User callback for adjacency */
    180:   void                *useradjacencyctx;  /* User context for callback */

    182:   /* Projection */
    183:   PetscInt             maxProjectionHeight; /* maximum height of cells used in DMPlexProject functions */

    185:   /* Output */
    186:   PetscInt             vtkCellHeight;            /* The height of cells for output, default is 0 */
    187:   PetscReal            scale[NUM_PETSC_UNITS];   /* The scale for each SI unit */

    189:   /* Geometry */
    190:   PetscReal            minradius;         /* Minimum distance from cell centroid to face */
    191:   PetscBool            useHashLocation;   /* Use grid hashing for point location */
    192:   PetscGridHash        lbox;              /* Local box for searching */

    194:   /* Debugging */
    195:   PetscBool            printSetValues;
    196:   PetscInt             printFEM;
    197:   PetscInt             printL2;
    198:   PetscReal            printTol;
    199: } DM_Plex;

    201: PETSC_EXTERN PetscErrorCode DMPlexVTKWriteAll_VTU(DM,PetscViewer);
    202: PETSC_EXTERN PetscErrorCode VecView_Plex_Local(Vec,PetscViewer);
    203: PETSC_EXTERN PetscErrorCode VecView_Plex_Native(Vec,PetscViewer);
    204: PETSC_EXTERN PetscErrorCode VecView_Plex(Vec,PetscViewer);
    205: PETSC_EXTERN PetscErrorCode VecLoad_Plex_Local(Vec,PetscViewer);
    206: PETSC_EXTERN PetscErrorCode VecLoad_Plex_Native(Vec,PetscViewer);
    207: PETSC_EXTERN PetscErrorCode VecLoad_Plex(Vec,PetscViewer);
    208: PETSC_INTERN PetscErrorCode DMPlexGetFieldType_Internal(DM, PetscSection, PetscInt, PetscInt *, PetscInt *, PetscViewerVTKFieldType *);
    209: PETSC_INTERN PetscErrorCode DMPlexView_GLVis(DM,PetscViewer);
    210: PETSC_INTERN PetscErrorCode DMSetUpGLVisViewer_Plex(PetscObject,PetscViewer);
    211: #if defined(PETSC_HAVE_HDF5)
    212: PETSC_EXTERN PetscErrorCode VecView_Plex_Local_HDF5(Vec, PetscViewer);
    213: PETSC_EXTERN PetscErrorCode VecView_Plex_HDF5(Vec, PetscViewer);
    214: PETSC_EXTERN PetscErrorCode VecLoad_Plex_HDF5(Vec, PetscViewer);
    215: PETSC_EXTERN PetscErrorCode VecView_Plex_HDF5_Native(Vec, PetscViewer);
    216: PETSC_EXTERN PetscErrorCode VecLoad_Plex_HDF5_Native(Vec, PetscViewer);
    217: PETSC_EXTERN PetscErrorCode DMPlexView_HDF5(DM, PetscViewer);
    218: PETSC_EXTERN PetscErrorCode DMPlexLoad_HDF5(DM, PetscViewer);
    219: #endif

    221: PETSC_INTERN PetscErrorCode DMSetFromOptions_NonRefinement_Plex(PetscOptionItems *, DM);
    222: PETSC_INTERN PetscErrorCode DMCoarsen_Plex(DM, MPI_Comm, DM *);
    223: PETSC_INTERN PetscErrorCode DMCoarsenHierarchy_Plex(DM, PetscInt, DM []);
    224: PETSC_INTERN PetscErrorCode DMRefine_Plex(DM, MPI_Comm, DM *);
    225: PETSC_INTERN PetscErrorCode DMRefineHierarchy_Plex(DM, PetscInt, DM []);
    226: PETSC_INTERN PetscErrorCode DMAdaptLabel_Plex(DM, DMLabel, DM *);
    227: PETSC_INTERN PetscErrorCode DMAdaptMetric_Plex(DM, Vec, DMLabel, DM *);
    228: PETSC_INTERN PetscErrorCode DMPlexInsertBoundaryValues_Plex(DM, PetscBool, Vec, PetscReal, Vec, Vec, Vec);
    229: PETSC_INTERN PetscErrorCode DMProjectFunctionLocal_Plex(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,InsertMode,Vec);
    230: PETSC_INTERN PetscErrorCode DMProjectFunctionLabelLocal_Plex(DM,PetscReal,DMLabel,PetscInt,const PetscInt[],PetscInt,const PetscInt[],PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,InsertMode,Vec);
    231: PETSC_INTERN PetscErrorCode DMProjectFieldLocal_Plex(DM,PetscReal,Vec,void (**)(PetscInt,PetscInt,PetscInt,const PetscInt[],const PetscInt[],const PetscScalar[],const PetscScalar[],const PetscScalar[],const PetscInt[],const PetscInt[],const PetscScalar[],const PetscScalar[],const PetscScalar[],PetscReal,const PetscReal[],PetscInt,const PetscScalar[],PetscScalar[]),InsertMode,Vec);
    232: PETSC_INTERN PetscErrorCode DMProjectFieldLabelLocal_Plex(DM,PetscReal,DMLabel,PetscInt,const PetscInt[],PetscInt,const PetscInt[],Vec,void (**)(PetscInt,PetscInt,PetscInt,const PetscInt[],const PetscInt[],const PetscScalar[],const PetscScalar[],const PetscScalar[],const PetscInt[],const PetscInt[],const PetscScalar[],const PetscScalar[],const PetscScalar[],PetscReal,const PetscReal[],PetscInt,const PetscScalar[],PetscScalar[]),InsertMode,Vec);
    233: PETSC_INTERN PetscErrorCode DMComputeL2Diff_Plex(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,Vec,PetscReal *);
    234: PETSC_INTERN PetscErrorCode DMComputeL2GradientDiff_Plex(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[], const PetscReal[],PetscInt,PetscScalar *,void *),void **,Vec,const PetscReal [],PetscReal *);
    235: PETSC_INTERN PetscErrorCode DMComputeL2FieldDiff_Plex(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,Vec,PetscReal *);
    236: PETSC_INTERN PetscErrorCode DMLocatePoints_Plex(DM, Vec, DMPointLocationType, PetscSF);

    238: PETSC_INTERN PetscErrorCode DMPlexBuildFromCellList_Internal(DM, PetscInt, PetscInt, PetscInt, PetscInt, const int[], PetscBool);
    239: PETSC_INTERN PetscErrorCode DMPlexBuildFromCellList_Parallel_Internal(DM, PetscInt, PetscInt, PetscInt, PetscInt, const int[], PetscBool, PetscSF *);
    240: PETSC_INTERN PetscErrorCode DMPlexBuildCoordinates_Internal(DM, PetscInt, PetscInt, PetscInt, const double[]);
    241: PETSC_INTERN PetscErrorCode DMPlexBuildCoordinates_Parallel_Internal(DM, PetscInt, PetscInt, PetscInt, PetscSF, const PetscReal[]);
    242: PETSC_INTERN PetscErrorCode DMPlexLoadLabels_HDF5_Internal(DM, PetscViewer);
    243: PETSC_INTERN PetscErrorCode DMPlexView_HDF5_Internal(DM, PetscViewer);
    244: PETSC_INTERN PetscErrorCode DMPlexLoad_HDF5_Internal(DM, PetscViewer);
    245: PETSC_INTERN PetscErrorCode DMPlexLoad_HDF5_Xdmf_Internal(DM, PetscViewer);
    246: PETSC_INTERN PetscErrorCode VecView_Plex_HDF5_Internal(Vec, PetscViewer);
    247: PETSC_INTERN PetscErrorCode VecView_Plex_HDF5_Native_Internal(Vec, PetscViewer);
    248: PETSC_INTERN PetscErrorCode VecView_Plex_Local_HDF5_Internal(Vec, PetscViewer);
    249: PETSC_INTERN PetscErrorCode VecLoad_Plex_HDF5_Internal(Vec, PetscViewer);
    250: PETSC_INTERN PetscErrorCode VecLoad_Plex_HDF5_Native_Internal(Vec, PetscViewer);
    251: /* TODO Make these INTERN */
    252: PETSC_EXTERN PetscErrorCode DMPlexView_ExodusII_Internal(DM, int, PetscInt);
    253: PETSC_EXTERN PetscErrorCode VecViewPlex_ExodusII_Nodal_Internal(Vec, int, int);
    254: PETSC_EXTERN PetscErrorCode VecLoadPlex_ExodusII_Nodal_Internal(Vec, int, int);
    255: PETSC_EXTERN PetscErrorCode VecViewPlex_ExodusII_Zonal_Internal(Vec, int, int);
    256: PETSC_EXTERN PetscErrorCode VecLoadPlex_ExodusII_Zonal_Internal(Vec, int, int);
    257: PETSC_INTERN PetscErrorCode DMPlexVTKGetCellType_Internal(DM,PetscInt,PetscInt,PetscInt*);
    258: PETSC_INTERN PetscErrorCode DMPlexGetAdjacency_Internal(DM,PetscInt,PetscBool,PetscBool,PetscBool,PetscInt*,PetscInt*[]);
    259: PETSC_INTERN PetscErrorCode DMPlexGetFaces_Internal(DM,PetscInt,PetscInt,PetscInt*,PetscInt*,const PetscInt*[]);
    260: PETSC_INTERN PetscErrorCode DMPlexGetRawFaces_Internal(DM,PetscInt,PetscInt,const PetscInt[], PetscInt*,PetscInt*,const PetscInt*[]);
    261: PETSC_INTERN PetscErrorCode DMPlexRestoreFaces_Internal(DM,PetscInt,PetscInt,PetscInt*,PetscInt*,const PetscInt*[]);
    262: PETSC_INTERN PetscErrorCode DMPlexRefineUniform_Internal(DM,CellRefiner,DM*);
    263: PETSC_INTERN PetscErrorCode DMPlexGetCellRefiner_Internal(DM,CellRefiner*);
    264: PETSC_INTERN PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner, PetscInt *, PetscReal *[], PetscReal *[], PetscReal *[]);
    265: PETSC_INTERN PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner, PetscInt *, PetscReal *[], PetscReal *[], PetscReal *[]);
    266: PETSC_INTERN PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner, const PetscReal[], PetscBool *);
    267: PETSC_INTERN PetscErrorCode DMPlexInvertCell_Internal(PetscInt, PetscInt, PetscInt[]);
    268: PETSC_INTERN PetscErrorCode DMPlexVecSetFieldClosure_Internal(DM, PetscSection, Vec, PetscBool[], PetscInt, PetscInt, const PetscInt[], const PetscScalar[], InsertMode);
    269: PETSC_INTERN PetscErrorCode DMPlexProjectConstraints_Internal(DM, Vec, Vec);
    270: PETSC_EXTERN PetscErrorCode DMPlexCreateReferenceTree_Union(DM,DM,const char *,DM*);
    271: PETSC_EXTERN PetscErrorCode DMPlexComputeInterpolatorTree(DM,DM,PetscSF,PetscInt *,Mat);
    272: PETSC_EXTERN PetscErrorCode DMPlexComputeInjectorTree(DM,DM,PetscSF,PetscInt *,Mat);
    273: PETSC_EXTERN PetscErrorCode DMPlexAnchorsModifyMat(DM,PetscSection,PetscInt,PetscInt,const PetscInt[],const PetscInt ***,const PetscScalar[],PetscInt*,PetscInt*,PetscInt*[],PetscScalar*[],PetscInt[],PetscBool);
    274: PETSC_EXTERN PetscErrorCode indicesPoint_private(PetscSection,PetscInt,PetscInt,PetscInt *,PetscBool,PetscInt,PetscInt []);
    275: PETSC_EXTERN PetscErrorCode indicesPointFields_private(PetscSection,PetscInt,PetscInt,PetscInt [],PetscBool,PetscInt,PetscInt []);
    276: PETSC_INTERN PetscErrorCode DMPlexLocatePoint_Internal(DM,PetscInt,const PetscScalar [],PetscInt,PetscInt *);

    278: PETSC_INTERN PetscErrorCode DMPlexCreateCellNumbering_Internal(DM, PetscBool, IS *);
    279: PETSC_INTERN PetscErrorCode DMPlexCreateVertexNumbering_Internal(DM, PetscBool, IS *);
    280: PETSC_INTERN PetscErrorCode DMPlexRefine_Internal(DM, DMLabel, DM *);
    281: PETSC_INTERN PetscErrorCode DMPlexCoarsen_Internal(DM, DMLabel, DM *);

    283: /* invert dihedral symmetry: return a^-1,
    284:  * using the representation described in
    285:  * DMPlexGetConeOrientation() */
    286: PETSC_STATIC_INLINE PetscInt DihedralInvert(PetscInt N, PetscInt a)
    287: {
    288:   return (a <= 0) ? a : (N - a);
    289: }

    291: /* invert dihedral symmetry: return b * a,
    292:  * using the representation described in
    293:  * DMPlexGetConeOrientation() */
    294: PETSC_STATIC_INLINE PetscInt DihedralCompose(PetscInt N, PetscInt a, PetscInt b)
    295: {
    296:   if (!N) return 0;
    297:   return  (a >= 0) ?
    298:          ((b >= 0) ? ((a + b) % N) : -(((a - b - 1) % N) + 1)) :
    299:          ((b >= 0) ? -(((N - b - a - 1) % N) + 1) : ((N + b - a) % N));
    300: }

    302: /* swap dihedral symmetries: return b * a^-1,
    303:  * using the representation described in
    304:  * DMPlexGetConeOrientation() */
    305: PETSC_STATIC_INLINE PetscInt DihedralSwap(PetscInt N, PetscInt a, PetscInt b)
    306: {
    307:   return DihedralCompose(N,DihedralInvert(N,a),b);
    308: }

    310: PETSC_EXTERN PetscErrorCode DMPlexComputeResidual_Internal(DM, IS , PetscReal, Vec, Vec, PetscReal, Vec, void *);
    311: PETSC_EXTERN PetscErrorCode DMPlexComputeJacobian_Internal(DM, IS, PetscReal, PetscReal, Vec, Vec, Mat, Mat, void *);
    312: PETSC_EXTERN PetscErrorCode DMPlexReconstructGradients_Internal(DM, PetscFV, PetscInt, PetscInt, Vec, Vec, Vec, Vec);

    314: PETSC_STATIC_INLINE void DMPlex_Invert2D_Internal(PetscReal invJ[], PetscReal J[], PetscReal detJ)
    315: {
    316:   const PetscReal invDet = 1.0/detJ;

    318:   invJ[0] =  invDet*J[3];
    319:   invJ[1] = -invDet*J[1];
    320:   invJ[2] = -invDet*J[2];
    321:   invJ[3] =  invDet*J[0];
    322:   (void)PetscLogFlops(5.0);
    323: }

    325: PETSC_STATIC_INLINE void DMPlex_Invert3D_Internal(PetscReal invJ[], PetscReal J[], PetscReal detJ)
    326: {
    327:   const PetscReal invDet = 1.0/detJ;

    329:   invJ[0*3+0] = invDet*(J[1*3+1]*J[2*3+2] - J[1*3+2]*J[2*3+1]);
    330:   invJ[0*3+1] = invDet*(J[0*3+2]*J[2*3+1] - J[0*3+1]*J[2*3+2]);
    331:   invJ[0*3+2] = invDet*(J[0*3+1]*J[1*3+2] - J[0*3+2]*J[1*3+1]);
    332:   invJ[1*3+0] = invDet*(J[1*3+2]*J[2*3+0] - J[1*3+0]*J[2*3+2]);
    333:   invJ[1*3+1] = invDet*(J[0*3+0]*J[2*3+2] - J[0*3+2]*J[2*3+0]);
    334:   invJ[1*3+2] = invDet*(J[0*3+2]*J[1*3+0] - J[0*3+0]*J[1*3+2]);
    335:   invJ[2*3+0] = invDet*(J[1*3+0]*J[2*3+1] - J[1*3+1]*J[2*3+0]);
    336:   invJ[2*3+1] = invDet*(J[0*3+1]*J[2*3+0] - J[0*3+0]*J[2*3+1]);
    337:   invJ[2*3+2] = invDet*(J[0*3+0]*J[1*3+1] - J[0*3+1]*J[1*3+0]);
    338:   (void)PetscLogFlops(37.0);
    339: }

    341: PETSC_STATIC_INLINE void DMPlex_Det2D_Internal(PetscReal *detJ, const PetscReal J[])
    342: {
    343:   *detJ = J[0]*J[3] - J[1]*J[2];
    344:   (void)PetscLogFlops(3.0);
    345: }

    347: PETSC_STATIC_INLINE void DMPlex_Det3D_Internal(PetscReal *detJ, const PetscReal J[])
    348: {
    349:   *detJ = (J[0*3+0]*(J[1*3+1]*J[2*3+2] - J[1*3+2]*J[2*3+1]) +
    350:            J[0*3+1]*(J[1*3+2]*J[2*3+0] - J[1*3+0]*J[2*3+2]) +
    351:            J[0*3+2]*(J[1*3+0]*J[2*3+1] - J[1*3+1]*J[2*3+0]));
    352:   (void)PetscLogFlops(12.0);
    353: }

    355: PETSC_STATIC_INLINE void DMPlex_Det2D_Scalar_Internal(PetscReal *detJ, const PetscScalar J[])
    356: {
    357:   *detJ = PetscRealPart(J[0])*PetscRealPart(J[3]) - PetscRealPart(J[1])*PetscRealPart(J[2]);
    358:   (void)PetscLogFlops(3.0);
    359: }

    361: PETSC_STATIC_INLINE void DMPlex_Det3D_Scalar_Internal(PetscReal *detJ, const PetscScalar J[])
    362: {
    363:   *detJ = (PetscRealPart(J[0*3+0])*(PetscRealPart(J[1*3+1])*PetscRealPart(J[2*3+2]) - PetscRealPart(J[1*3+2])*PetscRealPart(J[2*3+1])) +
    364:            PetscRealPart(J[0*3+1])*(PetscRealPart(J[1*3+2])*PetscRealPart(J[2*3+0]) - PetscRealPart(J[1*3+0])*PetscRealPart(J[2*3+2])) +
    365:            PetscRealPart(J[0*3+2])*(PetscRealPart(J[1*3+0])*PetscRealPart(J[2*3+1]) - PetscRealPart(J[1*3+1])*PetscRealPart(J[2*3+0])));
    366:   (void)PetscLogFlops(12.0);
    367: }

    369: PETSC_STATIC_INLINE void DMPlex_WaxpyD_Internal(PetscInt dim, PetscReal a, const PetscReal *x, const PetscReal *y, PetscReal *w) {PetscInt d; for (d = 0; d < dim; ++d) w[d] = a*x[d] + y[d];}

    371: PETSC_STATIC_INLINE PetscReal DMPlex_DotD_Internal(PetscInt dim, const PetscScalar *x, const PetscReal *y) {PetscReal sum = 0.0; PetscInt d; for (d = 0; d < dim; ++d) sum += PetscRealPart(x[d])*y[d]; return sum;}

    373: PETSC_STATIC_INLINE PetscReal DMPlex_DotRealD_Internal(PetscInt dim, const PetscReal *x, const PetscReal *y) {PetscReal sum = 0.0; PetscInt d; for (d = 0; d < dim; ++d) sum += x[d]*y[d]; return sum;}

    375: PETSC_STATIC_INLINE PetscReal DMPlex_NormD_Internal(PetscInt dim, const PetscReal *x) {PetscReal sum = 0.0; PetscInt d; for (d = 0; d < dim; ++d) sum += x[d]*x[d]; return PetscSqrtReal(sum);}

    377: PETSC_INTERN PetscErrorCode DMPlexGetPointDualSpaceFEM(DM,PetscInt,PetscInt,PetscDualSpace *);
    378: PETSC_INTERN PetscErrorCode DMPlexGetIndicesPoint_Internal(PetscSection,PetscInt,PetscInt,PetscInt *,PetscBool,const PetscInt[],PetscInt[]);
    379: PETSC_INTERN PetscErrorCode DMPlexGetIndicesPointFields_Internal(PetscSection,PetscInt,PetscInt,PetscInt[],PetscBool,const PetscInt***,PetscInt,PetscInt[]);

    381: PETSC_EXTERN PetscErrorCode DMSNESGetFEGeom(DMField, IS, PetscQuadrature, PetscBool, PetscFEGeom **);
    382: PETSC_EXTERN PetscErrorCode DMSNESRestoreFEGeom(DMField, IS, PetscQuadrature, PetscBool, PetscFEGeom **);
    383: PETSC_EXTERN PetscErrorCode DMPlexComputeJacobian_Patch_Internal(DM, PetscSection, PetscSection, IS, PetscReal, PetscReal, Vec, Vec, Mat, Mat, void *);
    384: PETSC_INTERN PetscErrorCode DMCreateSubDomainDM_Plex(DM,DMLabel,PetscInt,IS*,DM*);

    386: #endif /* _PLEXIMPL_H */