Date: 2022-03-04T17:40:02+00:00

Actual source code: dmpleximpl.h

      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: #if defined(PETSC_HAVE_EXODUSII)
     11: #include <exodusII.h>
     12: #endif

     14: PETSC_EXTERN PetscLogEvent DMPLEX_Interpolate;
     15: PETSC_EXTERN PetscLogEvent DMPLEX_Partition;
     16: PETSC_EXTERN PetscLogEvent DMPLEX_PartSelf;
     17: PETSC_EXTERN PetscLogEvent DMPLEX_PartLabelInvert;
     18: PETSC_EXTERN PetscLogEvent DMPLEX_PartLabelCreateSF;
     19: PETSC_EXTERN PetscLogEvent DMPLEX_PartStratSF;
     20: PETSC_EXTERN PetscLogEvent DMPLEX_CreatePointSF;
     21: PETSC_EXTERN PetscLogEvent DMPLEX_Distribute;
     22: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeCones;
     23: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeLabels;
     24: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeSF;
     25: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeOverlap;
     26: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeField;
     27: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeData;
     28: PETSC_EXTERN PetscLogEvent DMPLEX_Migrate;
     29: PETSC_EXTERN PetscLogEvent DMPLEX_InterpolateSF;
     30: PETSC_EXTERN PetscLogEvent DMPLEX_GlobalToNaturalBegin;
     31: PETSC_EXTERN PetscLogEvent DMPLEX_GlobalToNaturalEnd;
     32: PETSC_EXTERN PetscLogEvent DMPLEX_NaturalToGlobalBegin;
     33: PETSC_EXTERN PetscLogEvent DMPLEX_NaturalToGlobalEnd;
     34: PETSC_EXTERN PetscLogEvent DMPLEX_Stratify;
     35: PETSC_EXTERN PetscLogEvent DMPLEX_Symmetrize;
     36: PETSC_EXTERN PetscLogEvent DMPLEX_Preallocate;
     37: PETSC_EXTERN PetscLogEvent DMPLEX_ResidualFEM;
     38: PETSC_EXTERN PetscLogEvent DMPLEX_JacobianFEM;
     39: PETSC_EXTERN PetscLogEvent DMPLEX_InterpolatorFEM;
     40: PETSC_EXTERN PetscLogEvent DMPLEX_InjectorFEM;
     41: PETSC_EXTERN PetscLogEvent DMPLEX_IntegralFEM;
     42: PETSC_EXTERN PetscLogEvent DMPLEX_CreateGmsh;
     43: PETSC_EXTERN PetscLogEvent DMPLEX_RebalanceSharedPoints;
     44: PETSC_EXTERN PetscLogEvent DMPLEX_CreateFromFile;
     45: PETSC_EXTERN PetscLogEvent DMPLEX_BuildFromCellList;
     46: PETSC_EXTERN PetscLogEvent DMPLEX_BuildCoordinatesFromCellList;
     47: PETSC_EXTERN PetscLogEvent DMPLEX_LocatePoints;

     49: typedef struct _n_PlexGeneratorFunctionList *PlexGeneratorFunctionList;
     50: struct _n_PlexGeneratorFunctionList {
     51:   PetscErrorCode    (*generate)(DM, PetscBool, DM*);
     52:   PetscErrorCode    (*refine)(DM, PetscReal*, DM*);
     53:   PetscErrorCode    (*adaptlabel)(DM, DMLabel, DM*);
     54:   char              *name;
     55:   PetscInt          dim;
     56:   PlexGeneratorFunctionList next;
     57: };

     59: /* Utility struct to store the contents of a Fluent file in memory */
     60: typedef struct {
     61:   int          index;    /* Type of section */
     62:   unsigned int zoneID;
     63:   unsigned int first;
     64:   unsigned int last;
     65:   int          type;
     66:   int          nd;       /* Either ND or element-type */
     67:   void        *data;
     68: } FluentSection;

     70: struct _PetscGridHash {
     71:   PetscInt     dim;
     72:   PetscReal    lower[3];    /* The lower-left corner */
     73:   PetscReal    upper[3];    /* The upper-right corner */
     74:   PetscReal    extent[3];   /* The box size */
     75:   PetscReal    h[3];        /* The subbox size */
     76:   PetscInt     n[3];        /* The number of subboxes */
     77:   PetscSection cellSection; /* Offsets for cells in each subbox*/
     78:   IS           cells;       /* List of cells in each subbox */
     79:   DMLabel      cellsSparse; /* Sparse storage for cell map */
     80: };

     82: /* Point Numbering in Plex:

     84:    Points are numbered contiguously by stratum. Strate are organized as follows:

     86:    First Stratum:  Cells [height 0]
     87:    Second Stratum: Vertices [depth 0]
     88:    Third Stratum:  Faces [height 1]
     89:    Fourth Stratum: Edges [depth 1]

     91:    We do this so that the numbering of a cell-vertex mesh does not change after interpolation. Within a given stratum,
     92:    we allow additional segregation of by cell type.
     93: */
     94: typedef struct {
     95:   PetscInt             refct;

     97:   PetscSection         coneSection;       /* Layout of cones (inedges for DAG) */
     98:   PetscInt             maxConeSize;       /* Cached for fast lookup */
     99:   PetscInt            *cones;             /* Cone for each point */
    100:   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 */
    101:   PetscSection         supportSection;    /* Layout of cones (inedges for DAG) */
    102:   PetscInt             maxSupportSize;    /* Cached for fast lookup */
    103:   PetscInt            *supports;          /* Cone for each point */
    104:   PetscBool            refinementUniform; /* Flag for uniform cell refinement */
    105:   char                *transformType;     /* Type of transform for uniform cell refinement */
    106:   PetscReal            refinementLimit;   /* Maximum volume for refined cell */
    107:   PetscErrorCode     (*refinementFunc)(const PetscReal [], PetscReal *); /* Function giving the maximum volume for refined cell */
    108:   PetscInt             overlap;           /* Overlap of the partitions as passed to DMPlexDistribute() or DMPlexDistributeOverlap() */
    109:   DMPlexInterpolatedFlag interpolated;
    110:   DMPlexInterpolatedFlag interpolatedCollective;

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

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

    117:   /* Generation */
    118:   char                *tetgenOpts;
    119:   char                *triangleOpts;
    120:   PetscPartitioner     partitioner;
    121:   PetscBool            partitionBalance;  /* Evenly divide partition overlap when distributing */
    122:   PetscBool            remeshBd;

    124:   /* Submesh */
    125:   DMLabel              subpointMap;       /* Label each original mesh point in the submesh with its depth, subpoint are the implicit numbering */
    126:   IS                   subpointIS;        /* IS holding point number in the enclosing mesh of every point in the submesh chart */
    127:   PetscObjectState     subpointState;     /* The state of subpointMap when the subpointIS was last created */

    129:   /* Labels and numbering */
    130:   PetscObjectState     depthState;        /* State of depth label, so that we can determine if a user changes it */
    131:   PetscObjectState     celltypeState;     /* State of celltype label, so that we can determine if a user changes it */
    132:   IS                   globalVertexNumbers;
    133:   IS                   globalCellNumbers;

    135:   /* Constraints */
    136:   PetscSection         anchorSection;      /* maps constrained points to anchor points */
    137:   IS                   anchorIS;           /* anchors indexed by the above section */
    138:   PetscErrorCode     (*createanchors)(DM); /* automatically compute anchors (probably from tree constraints) */
    139:   PetscErrorCode     (*computeanchormatrix)(DM,PetscSection,PetscSection,Mat);

    141:   /* Tree: automatically construct constraints for hierarchically non-conforming meshes */
    142:   PetscSection         parentSection;     /* dof == 1 if point has parent */
    143:   PetscInt            *parents;           /* point to parent */
    144:   PetscInt            *childIDs;          /* point to child ID */
    145:   PetscSection         childSection;      /* inverse of parent section */
    146:   PetscInt            *children;          /* point to children */
    147:   DM                   referenceTree;     /* reference tree to which child ID's refer */
    148:   PetscErrorCode      (*getchildsymmetry)(DM,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt*,PetscInt*);

    150:   /* MATIS support */
    151:   PetscSection         subdomainSection;

    153:   /* Adjacency */
    154:   PetscBool            useAnchors;        /* Replace constrained points with their anchors in adjacency lists */
    155:   PetscErrorCode      (*useradjacency)(DM,PetscInt,PetscInt*,PetscInt[],void*); /* User callback for adjacency */
    156:   void                *useradjacencyctx;  /* User context for callback */

    158:   /* Projection */
    159:   PetscInt             maxProjectionHeight; /* maximum height of cells used in DMPlexProject functions */
    160:   PetscInt             activePoint;         /* current active point in iteration */

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

    166:   /* Geometry */
    167:   PetscBool            ignoreModel;       /* Ignore the geometry model during refinement */
    168:   PetscReal            minradius;         /* Minimum distance from cell centroid to face */
    169:   PetscBool            useHashLocation;   /* Use grid hashing for point location */
    170:   PetscGridHash        lbox;              /* Local box for searching */
    171:   void               (*coordFunc)(PetscInt, PetscInt, PetscInt, /* Function used to remap newly introduced vertices */
    172:                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
    173:                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
    174:                                   PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]);

    176:   /* Neighbors */
    177:   PetscMPIInt*         neighbors;

    179:   /* Debugging */
    180:   PetscBool            printSetValues;
    181:   PetscInt             printFEM;
    182:   PetscInt             printL2;
    183:   PetscReal            printTol;
    184: } DM_Plex;

    186: PETSC_EXTERN PetscErrorCode DMPlexVTKWriteAll_VTU(DM,PetscViewer);
    187: PETSC_EXTERN PetscErrorCode VecView_Plex_Local(Vec,PetscViewer);
    188: PETSC_EXTERN PetscErrorCode VecView_Plex_Native(Vec,PetscViewer);
    189: PETSC_EXTERN PetscErrorCode VecView_Plex(Vec,PetscViewer);
    190: PETSC_EXTERN PetscErrorCode VecLoad_Plex_Local(Vec,PetscViewer);
    191: PETSC_EXTERN PetscErrorCode VecLoad_Plex_Native(Vec,PetscViewer);
    192: PETSC_EXTERN PetscErrorCode VecLoad_Plex(Vec,PetscViewer);
    193: PETSC_INTERN PetscErrorCode DMPlexGetFieldType_Internal(DM, PetscSection, PetscInt, PetscInt *, PetscInt *, PetscViewerVTKFieldType *);
    194: PETSC_INTERN PetscErrorCode DMPlexView_GLVis(DM,PetscViewer);
    195: PETSC_INTERN PetscErrorCode DMSetUpGLVisViewer_Plex(PetscObject,PetscViewer);
    196: #if defined(PETSC_HAVE_HDF5)
    197: PETSC_EXTERN PetscErrorCode VecView_Plex_Local_HDF5(Vec, PetscViewer);
    198: PETSC_EXTERN PetscErrorCode VecView_Plex_HDF5(Vec, PetscViewer);
    199: PETSC_EXTERN PetscErrorCode VecLoad_Plex_HDF5(Vec, PetscViewer);
    200: PETSC_EXTERN PetscErrorCode VecView_Plex_HDF5_Native(Vec, PetscViewer);
    201: PETSC_EXTERN PetscErrorCode VecLoad_Plex_HDF5_Native(Vec, PetscViewer);
    202: PETSC_EXTERN PetscErrorCode DMPlexView_HDF5(DM, PetscViewer);
    203: PETSC_EXTERN PetscErrorCode DMPlexLoad_HDF5(DM, PetscViewer);
    204: PETSC_INTERN PetscErrorCode DMPlexTopologyView_HDF5_Internal(DM, IS, PetscViewer);
    205: PETSC_INTERN PetscErrorCode DMPlexCoordinatesView_HDF5_Internal(DM, PetscViewer);
    206: PETSC_INTERN PetscErrorCode DMPlexLabelsView_HDF5_Internal(DM, IS, PetscViewer);
    207: PETSC_INTERN PetscErrorCode DMPlexSectionView_HDF5_Internal(DM, PetscViewer, DM);
    208: PETSC_INTERN PetscErrorCode DMPlexGlobalVectorView_HDF5_Internal(DM, PetscViewer, DM, Vec);
    209: PETSC_INTERN PetscErrorCode DMPlexLocalVectorView_HDF5_Internal(DM, PetscViewer, DM, Vec);
    210: PETSC_INTERN PetscErrorCode DMPlexTopologyLoad_HDF5_Internal(DM, PetscViewer, PetscSF*);
    211: PETSC_INTERN PetscErrorCode DMPlexCoordinatesLoad_HDF5_Internal(DM, PetscViewer);
    212: PETSC_INTERN PetscErrorCode DMPlexLabelsLoad_HDF5_Internal(DM, PetscViewer);
    213: PETSC_INTERN PetscErrorCode DMPlexSectionLoad_HDF5_Internal(DM, PetscViewer, DM, PetscSF, PetscSF*, PetscSF*);
    214: PETSC_INTERN PetscErrorCode DMPlexVecLoad_HDF5_Internal(DM, PetscViewer, DM, PetscSF, Vec);
    215: PETSC_INTERN PetscErrorCode DMPlexView_HDF5_Internal(DM, PetscViewer);
    216: PETSC_INTERN PetscErrorCode DMPlexLoad_HDF5_Internal(DM, PetscViewer);
    217: PETSC_INTERN PetscErrorCode DMPlexLoad_HDF5_Xdmf_Internal(DM, PetscViewer);
    218: PETSC_INTERN PetscErrorCode VecView_Plex_HDF5_Internal(Vec, PetscViewer);
    219: PETSC_INTERN PetscErrorCode VecView_Plex_HDF5_Native_Internal(Vec, PetscViewer);
    220: PETSC_INTERN PetscErrorCode VecView_Plex_Local_HDF5_Internal(Vec, PetscViewer);
    221: PETSC_INTERN PetscErrorCode VecLoad_Plex_HDF5_Internal(Vec, PetscViewer);
    222: PETSC_INTERN PetscErrorCode VecLoad_Plex_HDF5_Native_Internal(Vec, PetscViewer);
    223: #endif

    225: PETSC_INTERN PetscErrorCode DMPlexVecGetClosureAtDepth_Internal(DM, PetscSection, Vec, PetscInt, PetscInt, PetscInt *, PetscScalar *[]);
    226: PETSC_INTERN PetscErrorCode DMPlexClosurePoints_Private(DM,PetscInt,const PetscInt[],IS*);
    227: PETSC_INTERN PetscErrorCode DMSetFromOptions_NonRefinement_Plex(PetscOptionItems *, DM);
    228: PETSC_INTERN PetscErrorCode DMCoarsen_Plex(DM, MPI_Comm, DM *);
    229: PETSC_INTERN PetscErrorCode DMCoarsenHierarchy_Plex(DM, PetscInt, DM []);
    230: PETSC_INTERN PetscErrorCode DMRefine_Plex(DM, MPI_Comm, DM *);
    231: PETSC_INTERN PetscErrorCode DMRefineHierarchy_Plex(DM, PetscInt, DM []);
    232: PETSC_INTERN PetscErrorCode DMAdaptLabel_Plex(DM, DMLabel, DM *);
    233: PETSC_INTERN PetscErrorCode DMAdaptMetric_Plex(DM, Vec, DMLabel, DM *);
    234: PETSC_INTERN PetscErrorCode DMPlexInsertBoundaryValues_Plex(DM, PetscBool, Vec, PetscReal, Vec, Vec, Vec);
    235: PETSC_INTERN PetscErrorCode DMPlexInsertTimeDerivativeBoundaryValues_Plex(DM, PetscBool, Vec, PetscReal, Vec, Vec, Vec);
    236: PETSC_INTERN PetscErrorCode DMProjectFunctionLocal_Plex(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,InsertMode,Vec);
    237: 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);
    238: 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);
    239: 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);
    240: PETSC_INTERN PetscErrorCode DMProjectBdFieldLabelLocal_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[],const PetscReal[],PetscInt,const PetscScalar[],PetscScalar[]),InsertMode,Vec);
    241: PETSC_INTERN PetscErrorCode DMComputeL2Diff_Plex(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,Vec,PetscReal *);
    242: PETSC_INTERN PetscErrorCode DMComputeL2GradientDiff_Plex(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[], const PetscReal[],PetscInt,PetscScalar *,void *),void **,Vec,const PetscReal [],PetscReal *);
    243: PETSC_INTERN PetscErrorCode DMComputeL2FieldDiff_Plex(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,Vec,PetscReal *);
    244: PETSC_INTERN PetscErrorCode DMLocatePoints_Plex(DM, Vec, DMPointLocationType, PetscSF);

    246: #if defined(PETSC_HAVE_EXODUSII)
    247: PETSC_EXTERN PetscErrorCode DMView_PlexExodusII(DM, PetscViewer);
    248: PETSC_INTERN PetscErrorCode VecView_PlexExodusII_Internal(Vec, PetscViewer);
    249: PETSC_INTERN PetscErrorCode VecLoad_PlexExodusII_Internal(Vec, PetscViewer);
    250: PETSC_INTERN PetscErrorCode VecViewPlex_ExodusII_Nodal_Internal(Vec, int, int, int);
    251: PETSC_INTERN PetscErrorCode VecLoadPlex_ExodusII_Nodal_Internal(Vec, int, int, int);
    252: PETSC_INTERN PetscErrorCode VecViewPlex_ExodusII_Zonal_Internal(Vec, int, int, int);
    253: PETSC_INTERN PetscErrorCode VecLoadPlex_ExodusII_Zonal_Internal(Vec, int, int, int);
    254: PETSC_INTERN PetscErrorCode EXOGetVarIndex_Internal(int, ex_entity_type, const char[], int*);
    255: #endif
    256: PETSC_INTERN PetscErrorCode DMPlexVTKGetCellType_Internal(DM,PetscInt,PetscInt,PetscInt*);
    257: PETSC_INTERN PetscErrorCode DMPlexGetAdjacency_Internal(DM,PetscInt,PetscBool,PetscBool,PetscBool,PetscInt*,PetscInt*[]);
    258: PETSC_INTERN PetscErrorCode DMPlexGetRawFaces_Internal(DM,DMPolytopeType,const PetscInt[],PetscInt*,const DMPolytopeType*[],const PetscInt*[],const PetscInt*[]);
    259: PETSC_INTERN PetscErrorCode DMPlexRestoreRawFaces_Internal(DM,DMPolytopeType,const PetscInt[],PetscInt*,const DMPolytopeType*[],const PetscInt*[],const PetscInt*[]);
    260: PETSC_INTERN PetscErrorCode DMPlexComputeCellType_Internal(DM, PetscInt, PetscInt, DMPolytopeType *);
    261: PETSC_INTERN PetscErrorCode DMPlexCreateCellTypeOrder_Internal(DMPolytopeType, PetscInt *[], PetscInt *[]);
    262: PETSC_INTERN PetscErrorCode DMPlexVecSetFieldClosure_Internal(DM, PetscSection, Vec, PetscBool[], PetscInt, PetscInt, const PetscInt[], DMLabel, PetscInt, const PetscScalar[], InsertMode);
    263: PETSC_INTERN PetscErrorCode DMPlexProjectConstraints_Internal(DM, Vec, Vec);
    264: PETSC_EXTERN PetscErrorCode DMPlexCreateReferenceTree_SetTree(DM, PetscSection, PetscInt[], PetscInt[]);
    265: PETSC_EXTERN PetscErrorCode DMPlexCreateReferenceTree_Union(DM,DM,const char *,DM*);
    266: PETSC_EXTERN PetscErrorCode DMPlexComputeInterpolatorTree(DM,DM,PetscSF,PetscInt *,Mat);
    267: PETSC_EXTERN PetscErrorCode DMPlexComputeInjectorTree(DM,DM,PetscSF,PetscInt *,Mat);
    268: PETSC_EXTERN PetscErrorCode DMPlexAnchorsModifyMat(DM,PetscSection,PetscInt,PetscInt,const PetscInt[],const PetscInt ***,const PetscScalar[],PetscInt*,PetscInt*,PetscInt*[],PetscScalar*[],PetscInt[],PetscBool);
    269: PETSC_EXTERN PetscErrorCode indicesPoint_private(PetscSection,PetscInt,PetscInt,PetscInt *,PetscBool,PetscInt,PetscInt []);
    270: PETSC_EXTERN PetscErrorCode indicesPointFields_private(PetscSection,PetscInt,PetscInt,PetscInt [],PetscBool,PetscInt,PetscInt []);
    271: PETSC_INTERN PetscErrorCode DMPlexLocatePoint_Internal(DM,PetscInt,const PetscScalar [],PetscInt,PetscInt *);
    272: /* these two are PETSC_EXTERN just because of src/dm/impls/plex/tests/ex18.c */
    273: PETSC_EXTERN PetscErrorCode DMPlexOrientInterface_Internal(DM);

    275: /* Applications may use this function */
    276: PETSC_EXTERN PetscErrorCode DMPlexCreateNumbering_Plex(DM, PetscInt, PetscInt, PetscInt, PetscInt *, PetscSF, IS *);

    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 *);
    282: PETSC_INTERN PetscErrorCode DMCreateMatrix_Plex(DM, Mat*);

    284: PETSC_INTERN PetscErrorCode DMPlexGetOverlap_Plex(DM, PetscInt *);

    286: #if 1
    287: PETSC_STATIC_INLINE PetscInt DihedralInvert(PetscInt N, PetscInt a)
    288: {
    289:   return (a <= 0) ? a : (N - a);
    290: }

    292: PETSC_STATIC_INLINE PetscInt DihedralCompose(PetscInt N, PetscInt a, PetscInt b)
    293: {
    294:   if (!N) return 0;
    295:   return  (a >= 0) ?
    296:          ((b >= 0) ? ((a + b) % N) : -(((a - b - 1) % N) + 1)) :
    297:          ((b >= 0) ? -(((N - b - a - 1) % N) + 1) : ((N + b - a) % N));
    298: }

    300: PETSC_STATIC_INLINE PetscInt DihedralSwap(PetscInt N, PetscInt a, PetscInt b)
    301: {
    302:   return DihedralCompose(N,DihedralInvert(N,a),b);
    303: }
    304: #else
    305: /* TODO
    306:    This is a reimplementation of the tensor dihedral symmetries using the new orientations.
    307:    These should be turned on when we convert to new-style orientations in p4est.
    308: */
    309: /* invert dihedral symmetry: return a^-1,
    310:  * using the representation described in
    311:  * DMPlexGetConeOrientation() */
    312: PETSC_STATIC_INLINE PetscInt DihedralInvert(PetscInt N, PetscInt a)
    313: {
    314:   switch (N) {
    315:     case 0: return 0;
    316:     case 2: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_SEGMENT, 0, a);
    317:     case 4: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_QUADRILATERAL, 0, a);
    318:     case 8: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_HEXAHEDRON, 0, a);
    319:     default: SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid celltype for DihedralInvert()");
    320:   }
    321:   return 0;
    322: }

    324: /* compose dihedral symmetry: return b * a,
    325:  * using the representation described in
    326:  * DMPlexGetConeOrientation() */
    327: PETSC_STATIC_INLINE PetscInt DihedralCompose(PetscInt N, PetscInt a, PetscInt b)
    328: {
    329:   switch (N) {
    330:     case 0: return 0;
    331:     case 2: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_SEGMENT, b, a);
    332:     case 4: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_QUADRILATERAL, b, a);
    333:     case 8: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_HEXAHEDRON, b, a);
    334:     default: SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid celltype for DihedralCompose()");
    335:   }
    336:   return 0;
    337: }

    339: /* swap dihedral symmetries: return b * a^-1,
    340:  * using the representation described in
    341:  * DMPlexGetConeOrientation() */
    342: PETSC_STATIC_INLINE PetscInt DihedralSwap(PetscInt N, PetscInt a, PetscInt b)
    343: {
    344:   switch (N) {
    345:     case 0: return 0;
    346:     case 2: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_SEGMENT, b, a);
    347:     case 4: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_QUADRILATERAL, b, a);
    348:     case 8: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_HEXAHEDRON, b, a);
    349:     default: SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid celltype for DihedralCompose()");
    350:   }
    351:   return 0;
    352: }
    353: #endif
    354: PETSC_EXTERN PetscInt       DMPolytopeConvertNewOrientation_Internal(DMPolytopeType, PetscInt);
    355: PETSC_EXTERN PetscInt       DMPolytopeConvertOldOrientation_Internal(DMPolytopeType, PetscInt);
    356: PETSC_EXTERN PetscErrorCode DMPlexConvertOldOrientations_Internal(DM);

    358: PETSC_EXTERN PetscErrorCode DMPlexComputeResidual_Internal(DM, PetscFormKey, IS, PetscReal, Vec, Vec, PetscReal, Vec, void *);
    359: PETSC_EXTERN PetscErrorCode DMPlexComputeResidual_Hybrid_Internal(DM, PetscFormKey[], IS, PetscReal, Vec, Vec, PetscReal, Vec, void *);
    360: PETSC_EXTERN PetscErrorCode DMPlexComputeJacobian_Internal(DM, PetscFormKey, IS, PetscReal, PetscReal, Vec, Vec, Mat, Mat, void *);
    361: PETSC_EXTERN PetscErrorCode DMPlexComputeJacobian_Hybrid_Internal(DM, PetscFormKey[], IS, PetscReal, PetscReal, Vec, Vec, Mat, Mat, void *);
    362: PETSC_EXTERN PetscErrorCode DMPlexComputeJacobian_Action_Internal(DM, PetscFormKey, IS, PetscReal, PetscReal, Vec, Vec, Vec, Vec, void *);
    363: PETSC_EXTERN PetscErrorCode DMPlexReconstructGradients_Internal(DM, PetscFV, PetscInt, PetscInt, Vec, Vec, Vec, Vec);

    365: /* Matvec with A in row-major storage, x and y can be aliased */
    366: PETSC_STATIC_INLINE void DMPlex_Mult2D_Internal(const PetscScalar A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
    367: {
    368:   const PetscScalar z[2] = {x[0*ldx], x[1*ldx]};
    369:   y[0*ldx] = A[0]*z[0] + A[1]*z[1];
    370:   y[1*ldx] = A[2]*z[0] + A[3]*z[1];
    371:   (void)PetscLogFlops(6.0);
    372: }
    373: PETSC_STATIC_INLINE void DMPlex_Mult3D_Internal(const PetscScalar A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
    374: {
    375:   const PetscScalar z[3] = {x[0*ldx], x[1*ldx], x[2*ldx]};
    376:   y[0*ldx] = A[0]*z[0] + A[1]*z[1] + A[2]*z[2];
    377:   y[1*ldx] = A[3]*z[0] + A[4]*z[1] + A[5]*z[2];
    378:   y[2*ldx] = A[6]*z[0] + A[7]*z[1] + A[8]*z[2];
    379:   (void)PetscLogFlops(15.0);
    380: }
    381: PETSC_STATIC_INLINE void DMPlex_MultTranspose2D_Internal(const PetscScalar A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
    382: {
    383:   const PetscScalar z[2] = {x[0*ldx], x[1*ldx]};
    384:   y[0*ldx] = A[0]*z[0] + A[2]*z[1];
    385:   y[1*ldx] = A[1]*z[0] + A[3]*z[1];
    386:   (void)PetscLogFlops(6.0);
    387: }
    388: PETSC_STATIC_INLINE void DMPlex_MultTranspose3D_Internal(const PetscScalar A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
    389: {
    390:   const PetscScalar z[3] = {x[0*ldx], x[1*ldx], x[2*ldx]};
    391:   y[0*ldx] = A[0]*z[0] + A[3]*z[1] + A[6]*z[2];
    392:   y[1*ldx] = A[1]*z[0] + A[4]*z[1] + A[7]*z[2];
    393:   y[2*ldx] = A[2]*z[0] + A[5]*z[1] + A[8]*z[2];
    394:   (void)PetscLogFlops(15.0);
    395: }
    396: PETSC_STATIC_INLINE void DMPlex_Mult2DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
    397: {
    398:   const PetscScalar z[2] = {x[0*ldx], x[1*ldx]};
    399:   y[0*ldx] = A[0]*z[0] + A[1]*z[1];
    400:   y[1*ldx] = A[2]*z[0] + A[3]*z[1];
    401:   (void)PetscLogFlops(6.0);
    402: }
    403: PETSC_STATIC_INLINE void DMPlex_Mult3DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
    404: {
    405:   const PetscScalar z[3] = {x[0*ldx], x[1*ldx], x[2*ldx]};
    406:   y[0*ldx] = A[0]*z[0] + A[1]*z[1] + A[2]*z[2];
    407:   y[1*ldx] = A[3]*z[0] + A[4]*z[1] + A[5]*z[2];
    408:   y[2*ldx] = A[6]*z[0] + A[7]*z[1] + A[8]*z[2];
    409:   (void)PetscLogFlops(15.0);
    410: }
    411: PETSC_STATIC_INLINE void DMPlex_MultAdd2DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
    412: {
    413:   const PetscScalar z[2] = {x[0*ldx], x[1*ldx]};
    414:   y[0*ldx] += A[0]*z[0] + A[1]*z[1];
    415:   y[1*ldx] += A[2]*z[0] + A[3]*z[1];
    416:   (void)PetscLogFlops(6.0);
    417: }
    418: PETSC_STATIC_INLINE void DMPlex_MultAdd3DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
    419: {
    420:   const PetscScalar z[3] = {x[0*ldx], x[1*ldx], x[2*ldx]};
    421:   y[0*ldx] += A[0]*z[0] + A[1]*z[1] + A[2]*z[2];
    422:   y[1*ldx] += A[3]*z[0] + A[4]*z[1] + A[5]*z[2];
    423:   y[2*ldx] += A[6]*z[0] + A[7]*z[1] + A[8]*z[2];
    424:   (void)PetscLogFlops(15.0);
    425: }
    426: PETSC_STATIC_INLINE void DMPlex_MultTransposeReal_Internal(const PetscReal A[], PetscInt m, PetscInt n, PetscInt ldx, const PetscScalar x[], PetscScalar y[])
    427: {
    428:   PetscScalar z[3];
    429:   PetscInt    i, j;
    430:   for (i = 0; i < m; ++i) z[i] = x[i*ldx];
    431:   for (j = 0; j < n; ++j) {
    432:     const PetscInt l = j*ldx;
    433:     y[l] = 0;
    434:     for (i = 0; i < m; ++i) {
    435:       y[l] += A[j*n+i]*z[i];
    436:     }
    437:   }
    438:   (void)PetscLogFlops(2*m*n);
    439: }
    440: PETSC_STATIC_INLINE void DMPlex_MultTranspose2DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
    441: {
    442:   const PetscScalar z[2] = {x[0*ldx], x[1*ldx]};
    443:   y[0*ldx] = A[0]*z[0] + A[2]*z[1];
    444:   y[1*ldx] = A[1]*z[0] + A[3]*z[1];
    445:   (void)PetscLogFlops(6.0);
    446: }
    447: PETSC_STATIC_INLINE void DMPlex_MultTranspose3DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
    448: {
    449:   const PetscScalar z[3] = {x[0*ldx], x[1*ldx], x[2*ldx]};
    450:   y[0*ldx] = A[0]*z[0] + A[3]*z[1] + A[6]*z[2];
    451:   y[1*ldx] = A[1]*z[0] + A[4]*z[1] + A[7]*z[2];
    452:   y[2*ldx] = A[2]*z[0] + A[5]*z[1] + A[8]*z[2];
    453:   (void)PetscLogFlops(15.0);
    454: }

    456: PETSC_STATIC_INLINE void DMPlex_MatMult2D_Internal(const PetscScalar A[], PetscInt n, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
    457: {
    458: #define PLEX_DIM__ 2
    459:   PetscScalar z[PLEX_DIM__];
    460:   for (PetscInt j = 0; j < n; ++j) {
    461:     for (int d = 0; d < PLEX_DIM__; ++d) z[d] = B[d*ldb+j];
    462:     DMPlex_Mult2D_Internal(A, 1, z, z);
    463:     for (int d = 0; d < PLEX_DIM__; ++d) C[d*ldb+j] = z[d];
    464:   }
    465:   (void)PetscLogFlops(8.0*n);
    466: #undef PLEX_DIM__
    467: }
    468: PETSC_STATIC_INLINE void DMPlex_MatMult3D_Internal(const PetscScalar A[], PetscInt n, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
    469: {
    470: #define PLEX_DIM__ 3
    471:   PetscScalar z[PLEX_DIM__];
    472:   for (PetscInt j = 0; j < n; ++j) {
    473:     for (int d = 0; d < PLEX_DIM__; ++d) z[d] = B[d*ldb+j];
    474:     DMPlex_Mult3D_Internal(A, 1, z, z);
    475:     for (int d = 0; d < PLEX_DIM__; ++d) C[d*ldb+j] = z[d];
    476:   }
    477:   (void)PetscLogFlops(8.0*n);
    478: #undef PLEX_DIM__
    479: }
    480: PETSC_STATIC_INLINE void DMPlex_MatMultTranspose2D_Internal(const PetscScalar A[], PetscInt n, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
    481: {
    482: #define PLEX_DIM__ 2
    483:   PetscScalar z[PLEX_DIM__];
    484:   for (PetscInt j = 0; j < n; ++j) {
    485:     for (int d = 0; d < PLEX_DIM__; ++d) z[d] = B[d*ldb+j];
    486:     DMPlex_MultTranspose2D_Internal(A, 1, z, z);
    487:     for (int d = 0; d < PLEX_DIM__; ++d) C[d*ldb+j] = z[d];
    488:   }
    489:   (void)PetscLogFlops(8.0*n);
    490: #undef PLEX_DIM__
    491: }
    492: PETSC_STATIC_INLINE void DMPlex_MatMultTranspose3D_Internal(const PetscScalar A[], PetscInt n, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
    493: {
    494: #define PLEX_DIM__ 3
    495:   PetscScalar z[PLEX_DIM__];
    496:   for (PetscInt j = 0; j < n; ++j) {
    497:     for (int d = 0; d < PLEX_DIM__; ++d) z[d] = B[d*ldb+j];
    498:     DMPlex_MultTranspose3D_Internal(A, 1, z, z);
    499:     for (int d = 0; d < PLEX_DIM__; ++d) C[d*ldb+j] = z[d];
    500:   }
    501:   (void)PetscLogFlops(8.0*n);
    502: #undef PLEX_DIM__
    503: }

    505: PETSC_STATIC_INLINE void DMPlex_MatMultLeft2D_Internal(const PetscScalar A[], PetscInt m, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
    506: {
    507:   for (PetscInt j = 0; j < m; ++j) DMPlex_MultTranspose2D_Internal(A, 1, &B[j*ldb], &C[j*ldb]);
    508:   (void)PetscLogFlops(8.0*m);
    509: }
    510: PETSC_STATIC_INLINE void DMPlex_MatMultLeft3D_Internal(const PetscScalar A[], PetscInt m, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
    511: {
    512:   for (PetscInt j = 0; j < m; ++j) DMPlex_MultTranspose3D_Internal(A, 1, &B[j*ldb], &C[j*ldb]);
    513:   (void)PetscLogFlops(8.0*m);
    514: }
    515: PETSC_STATIC_INLINE void DMPlex_MatMultTransposeLeft2D_Internal(const PetscScalar A[], PetscInt m, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
    516: {
    517:   for (PetscInt j = 0; j < m; ++j) DMPlex_Mult2D_Internal(A, 1, &B[j*ldb], &C[j*ldb]);
    518:   (void)PetscLogFlops(8.0*m);
    519: }
    520: PETSC_STATIC_INLINE void DMPlex_MatMultTransposeLeft3D_Internal(const PetscScalar A[], PetscInt m, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
    521: {
    522:   for (PetscInt j = 0; j < m; ++j) DMPlex_Mult3D_Internal(A, 1, &B[j*ldb], &C[j*ldb]);
    523:   (void)PetscLogFlops(8.0*m);
    524: }

    526: PETSC_STATIC_INLINE void DMPlex_PTAP2DReal_Internal(const PetscReal P[], const PetscScalar A[], PetscScalar C[])
    527: {
    528:   PetscScalar out[4];
    529:   PetscInt i, j, k, l;
    530:   for (i = 0; i < 2; ++i) {
    531:     for (j = 0; j < 2; ++j) {
    532:       out[i*2+j] = 0.;
    533:       for (k = 0; k < 2; ++k) {
    534:         for (l = 0; l < 2; ++l) {
    535:           out[i*2+j] += P[k*2+i]*A[k*2+l]*P[l*2+j];
    536:         }
    537:       }
    538:     }
    539:   }
    540:   for (i = 0; i < 2*2; ++i) C[i] = out[i];
    541:   (void)PetscLogFlops(48.0);
    542: }
    543: PETSC_STATIC_INLINE void DMPlex_PTAP3DReal_Internal(const PetscReal P[], const PetscScalar A[], PetscScalar C[])
    544: {
    545:   PetscScalar out[9];
    546:   PetscInt i, j, k, l;
    547:   for (i = 0; i < 3; ++i) {
    548:     for (j = 0; j < 3; ++j) {
    549:       out[i*3+j] = 0.;
    550:       for (k = 0; k < 3; ++k) {
    551:         for (l = 0; l < 3; ++l) {
    552:           out[i*3+j] += P[k*3+i]*A[k*3+l]*P[l*3+j];
    553:         }
    554:       }
    555:     }
    556:   }
    557:   for (i = 0; i < 2*2; ++i) C[i] = out[i];
    558:   (void)PetscLogFlops(243.0);
    559: }
    560: /* TODO Fix for aliasing of A and C */
    561: PETSC_STATIC_INLINE void DMPlex_PTAPReal_Internal(const PetscReal P[], PetscInt m, PetscInt n, const PetscScalar A[], PetscScalar C[])
    562: {
    563:   PetscInt i, j, k, l;
    564:   for (i = 0; i < n; ++i) {
    565:     for (j = 0; j < n; ++j) {
    566:       C[i*n+j] = 0.;
    567:       for (k = 0; k < m; ++k) {
    568:         for (l = 0; l < m; ++l) {
    569:           C[i*n+j] += P[k*n+i]*A[k*m+l]*P[l*n+j];
    570:         }
    571:       }
    572:     }
    573:   }
    574:   (void)PetscLogFlops(243.0);
    575: }

    577: PETSC_STATIC_INLINE void DMPlex_Transpose2D_Internal(PetscScalar A[])
    578: {
    579:   PetscScalar tmp;
    580:   tmp = A[1]; A[1] = A[2]; A[2] = tmp;
    581: }
    582: PETSC_STATIC_INLINE void DMPlex_Transpose3D_Internal(PetscScalar A[])
    583: {
    584:   PetscScalar tmp;
    585:   tmp = A[1]; A[1] = A[3]; A[3] = tmp;
    586:   tmp = A[2]; A[2] = A[6]; A[6] = tmp;
    587:   tmp = A[5]; A[5] = A[7]; A[7] = tmp;
    588: }

    590: PETSC_STATIC_INLINE void DMPlex_Invert2D_Internal(PetscReal invJ[], PetscReal J[], PetscReal detJ)
    591: {
    592:   const PetscReal invDet = 1.0/detJ;

    594:   invJ[0] =  invDet*J[3];
    595:   invJ[1] = -invDet*J[1];
    596:   invJ[2] = -invDet*J[2];
    597:   invJ[3] =  invDet*J[0];
    598:   (void)PetscLogFlops(5.0);
    599: }

    601: PETSC_STATIC_INLINE void DMPlex_Invert3D_Internal(PetscReal invJ[], PetscReal J[], PetscReal detJ)
    602: {
    603:   const PetscReal invDet = 1.0/detJ;

    605:   invJ[0*3+0] = invDet*(J[1*3+1]*J[2*3+2] - J[1*3+2]*J[2*3+1]);
    606:   invJ[0*3+1] = invDet*(J[0*3+2]*J[2*3+1] - J[0*3+1]*J[2*3+2]);
    607:   invJ[0*3+2] = invDet*(J[0*3+1]*J[1*3+2] - J[0*3+2]*J[1*3+1]);
    608:   invJ[1*3+0] = invDet*(J[1*3+2]*J[2*3+0] - J[1*3+0]*J[2*3+2]);
    609:   invJ[1*3+1] = invDet*(J[0*3+0]*J[2*3+2] - J[0*3+2]*J[2*3+0]);
    610:   invJ[1*3+2] = invDet*(J[0*3+2]*J[1*3+0] - J[0*3+0]*J[1*3+2]);
    611:   invJ[2*3+0] = invDet*(J[1*3+0]*J[2*3+1] - J[1*3+1]*J[2*3+0]);
    612:   invJ[2*3+1] = invDet*(J[0*3+1]*J[2*3+0] - J[0*3+0]*J[2*3+1]);
    613:   invJ[2*3+2] = invDet*(J[0*3+0]*J[1*3+1] - J[0*3+1]*J[1*3+0]);
    614:   (void)PetscLogFlops(37.0);
    615: }

    617: PETSC_STATIC_INLINE void DMPlex_Det2D_Internal(PetscReal *detJ, const PetscReal J[])
    618: {
    619:   *detJ = J[0]*J[3] - J[1]*J[2];
    620:   (void)PetscLogFlops(3.0);
    621: }

    623: PETSC_STATIC_INLINE void DMPlex_Det3D_Internal(PetscReal *detJ, const PetscReal J[])
    624: {
    625:   *detJ = (J[0*3+0]*(J[1*3+1]*J[2*3+2] - J[1*3+2]*J[2*3+1]) +
    626:            J[0*3+1]*(J[1*3+2]*J[2*3+0] - J[1*3+0]*J[2*3+2]) +
    627:            J[0*3+2]*(J[1*3+0]*J[2*3+1] - J[1*3+1]*J[2*3+0]));
    628:   (void)PetscLogFlops(12.0);
    629: }

    631: PETSC_STATIC_INLINE void DMPlex_Det2D_Scalar_Internal(PetscReal *detJ, const PetscScalar J[])
    632: {
    633:   *detJ = PetscRealPart(J[0])*PetscRealPart(J[3]) - PetscRealPart(J[1])*PetscRealPart(J[2]);
    634:   (void)PetscLogFlops(3.0);
    635: }

    637: PETSC_STATIC_INLINE void DMPlex_Det3D_Scalar_Internal(PetscReal *detJ, const PetscScalar J[])
    638: {
    639:   *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])) +
    640:            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])) +
    641:            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])));
    642:   (void)PetscLogFlops(12.0);
    643: }

    645: 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];}

    647: 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;}

    649: 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;}

    651: 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);}

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

    655: PETSC_INTERN PetscErrorCode DMPlexGetPointDualSpaceFEM(DM,PetscInt,PetscInt,PetscDualSpace *);
    656: PETSC_INTERN PetscErrorCode DMPlexGetIndicesPoint_Internal(PetscSection,PetscBool,PetscInt,PetscInt,PetscInt *,PetscBool,const PetscInt[],const PetscInt[],PetscInt[]);
    657: PETSC_INTERN PetscErrorCode DMPlexGetIndicesPointFields_Internal(PetscSection,PetscBool,PetscInt,PetscInt,PetscInt[],PetscBool,const PetscInt***,PetscInt,const PetscInt[],PetscInt[]);
    658: PETSC_INTERN PetscErrorCode DMPlexGetTransitiveClosure_Internal(DM, PetscInt, PetscInt, PetscBool, PetscInt *, PetscInt *[]);

    660: PETSC_EXTERN PetscErrorCode DMPlexGetAllCells_Internal(DM, IS *);
    661: PETSC_EXTERN PetscErrorCode DMSNESGetFEGeom(DMField, IS, PetscQuadrature, PetscBool, PetscFEGeom **);
    662: PETSC_EXTERN PetscErrorCode DMSNESRestoreFEGeom(DMField, IS, PetscQuadrature, PetscBool, PetscFEGeom **);
    663: PETSC_EXTERN PetscErrorCode DMPlexComputeResidual_Patch_Internal(DM, PetscSection, IS, PetscReal, Vec, Vec, Vec, void *);
    664: PETSC_EXTERN PetscErrorCode DMPlexComputeJacobian_Patch_Internal(DM, PetscSection, PetscSection, IS, PetscReal, PetscReal, Vec, Vec, Mat, Mat, void *);
    665: PETSC_INTERN PetscErrorCode DMCreateSubDomainDM_Plex(DM,DMLabel,PetscInt,IS*,DM*);
    666: PETSC_INTERN PetscErrorCode DMPlexBasisTransformPoint_Internal(DM, DM, Vec, PetscInt, PetscBool[], PetscBool, PetscScalar *);
    667: PETSC_EXTERN PetscErrorCode DMPlexBasisTransformPointTensor_Internal(DM, DM, Vec, PetscInt, PetscBool, PetscInt, PetscScalar *);
    668: PETSC_INTERN PetscErrorCode DMPlexBasisTransformApplyReal_Internal(DM, const PetscReal[], PetscBool, PetscInt, const PetscReal *, PetscReal *, void *);
    669: PETSC_INTERN PetscErrorCode DMPlexBasisTransformApply_Internal(DM, const PetscReal[], PetscBool, PetscInt, const PetscScalar *, PetscScalar *, void *);
    670: PETSC_INTERN PetscErrorCode DMCreateNeumannOverlap_Plex(DM, IS*, Mat*, PetscErrorCode (**)(Mat, PetscReal, Vec, Vec, PetscReal, IS, void*), void **);

    672: /* Functions in the vtable */
    673: PETSC_INTERN PetscErrorCode DMCreateInterpolation_Plex(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling);
    674: PETSC_INTERN PetscErrorCode DMCreateInjection_Plex(DM dmCoarse, DM dmFine, Mat *mat);
    675: PETSC_INTERN PetscErrorCode DMCreateMassMatrix_Plex(DM dmCoarse, DM dmFine, Mat *mat);
    676: PETSC_INTERN PetscErrorCode DMCreateLocalSection_Plex(DM dm);
    677: PETSC_INTERN PetscErrorCode DMCreateDefaultConstraints_Plex(DM dm);
    678: PETSC_INTERN PetscErrorCode DMCreateMatrix_Plex(DM dm,  Mat *J);
    679: PETSC_INTERN PetscErrorCode DMCreateCoordinateDM_Plex(DM dm, DM *cdm);
    680: PETSC_INTERN PetscErrorCode DMCreateCoordinateField_Plex(DM dm, DMField *field);
    681: PETSC_INTERN PetscErrorCode DMClone_Plex(DM dm, DM *newdm);
    682: PETSC_INTERN PetscErrorCode DMSetUp_Plex(DM dm);
    683: PETSC_INTERN PetscErrorCode DMDestroy_Plex(DM dm);
    684: PETSC_INTERN PetscErrorCode DMView_Plex(DM dm, PetscViewer viewer);
    685: PETSC_INTERN PetscErrorCode DMLoad_Plex(DM dm, PetscViewer viewer);
    686: PETSC_INTERN PetscErrorCode DMCreateSubDM_Plex(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm);
    687: PETSC_INTERN PetscErrorCode DMCreateSuperDM_Plex(DM dms[], PetscInt len, IS **is, DM *superdm);

    689: #endif /* _PLEXIMPL_H */