Actual source code: pcpatchimpl.h

  1: /*
  2:       Data structure used for Patch preconditioner.
  3: */
  4: #pragma once
  5: #include <petsc/private/pcimpl.h>
  6: #include <petsc/private/hashseti.h>
  7: #include <petsc/private/hashmapi.h>
  8: #include <petscksp.h>

 10: PETSC_EXTERN PetscBool  PCPatchcite;
 11: PETSC_EXTERN const char PCPatchCitation[];

 13: typedef struct {
 14:   /* Topology */
 15:   PCPatchConstructType ctype;                                           /* Algorithm for patch construction */
 16:   PetscErrorCode (*patchconstructop)(void *, DM, PetscInt, PetscHSetI); /* patch construction */
 17:   PetscErrorCode (*userpatchconstructionop)(PC, PetscInt *, IS **, IS *, void *ctx);
 18:   void        *userpatchconstructctx;
 19:   IS          *userIS;
 20:   PetscInt     npatch;       /* Number of patches */
 21:   PetscBool    user_patches; /* Flag for user construction of patches */
 22:   PetscInt     dim, codim;   /* Dimension or codimension of mesh points to loop over; only one of them can be set */
 23:   PetscSection cellCounts;   /* Maps patch -> # cells in patch */
 24:   IS           cells;        /* [patch][cell in patch]: Cell number */
 25:   IS           extFacets;
 26:   IS           intFacets;
 27:   IS           intFacetsToPatchCell; /* Support of interior facet in local patch point numbering: AKA which two cells touch the facet (in patch local numbering of cells) */
 28:   PetscSection intFacetCounts;
 29:   PetscSection extFacetCounts;
 30:   PetscSection cellNumbering; /* Plex: NULL Firedrake: Numbering of cells in DM */
 31:   PetscSection pointCounts;   /* Maps patch -> # points with dofs in patch */
 32:   IS           points;        /* [patch][point in patch]: Point number */
 33:   /* Dof layout */
 34:   PetscBool     combined;        /* Use a combined space with all fields */
 35:   PetscInt      nsubspaces;      /* Number of fields */
 36:   PetscSF       sectionSF;       /* Combined SF mapping process local to global */
 37:   PetscSection *dofSection;      /* ?? For each field, patch -> # dofs in patch */
 38:   PetscInt     *subspaceOffsets; /* Plex: NULL Firedrake: offset of each field in concatenated process local numbering for mixed spaces */
 39:   PetscInt    **cellNodeMap;     /* [field][cell][dof in cell]: global dofs in cell TODO Free this after its use in PCPatchCreateCellPatchDiscretisationInfo() */
 40:   IS            dofs;            /* [patch][cell in patch][dof in cell]: patch local dof */
 41:   IS            offs;            /* [patch][point in patch]: patch local offset (same layout as 'points', used for filling up patchSection) */
 42:   IS            dofsWithArtificial;
 43:   IS            offsWithArtificial;
 44:   IS            dofsWithAll;
 45:   IS            offsWithAll;
 46:   PetscSection  patchSection;             /* Maps points -> patch local dofs */
 47:   IS            globalBcNodes;            /* Global dofs constrained by global Dirichlet conditions TODO Replace these with process local constrained dofs */
 48:   IS            ghostBcNodes;             /* Global dofs constrained by global Dirichlet conditions on this process and possibly others (patch overlaps boundary) */
 49:   PetscSection  gtolCounts;               /* ?? Indices to extract from local to patch vectors */
 50:   PetscSection  gtolCountsWithArtificial; /* ?? Indices to extract from local to patch vectors including those with artificial bcs*/
 51:   PetscSection  gtolCountsWithAll;        /* ?? Indices to extract from local to patch vectors including those in artificial or global bcs*/
 52:   IS            gtol;
 53:   IS            gtolWithArtificial;
 54:   IS            gtolWithAll;
 55:   PetscInt     *bs;                   /* [field] block size per field (can come from global operators?) */
 56:   PetscInt     *nodesPerCell;         /* [field] Dofs per cell TODO Change "node" to "dof" everywhere */
 57:   PetscInt      totalDofsPerCell;     /* Dofs per cell counting all fields */
 58:   PetscHSetI    subspaces_to_exclude; /* If you don't want any other dofs from a particular subspace you can exclude them with this.
 59:                                                 Used for Vanka in Stokes, for example, to eliminate all pressure dofs not on the vertex
 60:                                                 you're building the patch around */
 61:   PetscInt      vankadim;             /* In Vanka construction, should we eliminate any entities of a certain dimension on the initial patch? */
 62:   PetscInt      ignoredim;            /* In Vanka construction, should we eliminate any entities of a certain dimension on the boundary? */
 63:   PetscInt      pardecomp_overlap;    /* In parallel decomposition construction, how much overlap? */
 64:   /* Patch system assembly */
 65:   PetscErrorCode (*usercomputeop)(PC, PetscInt, Vec, Mat, IS, PetscInt, const PetscInt *, const PetscInt *, void *);
 66:   void *usercomputeopctx;
 67:   PetscErrorCode (*usercomputef)(PC, PetscInt, Vec, Vec, IS, PetscInt, const PetscInt *, const PetscInt *, void *);
 68:   void *usercomputefctx;
 69:   /* Interior facet integrals: Jacobian */
 70:   PetscErrorCode (*usercomputeopintfacet)(PC, PetscInt, Vec, Mat, IS, PetscInt, const PetscInt *, const PetscInt *, void *);
 71:   void *usercomputeopintfacetctx;
 72:   /* Residual */
 73:   PetscErrorCode (*usercomputefintfacet)(PC, PetscInt, Vec, Vec, IS, PetscInt, const PetscInt *, const PetscInt *, void *);
 74:   void           *usercomputefintfacetctx;
 75:   IS              cellIS;                   /* Temporary IS for each cell patch */
 76:   PetscBool       save_operators;           /* Save all operators (or create/destroy one at a time?) */
 77:   PetscBool       precomputeElementTensors; /* Precompute all element tensors (each cell is assembled exactly once)? */
 78:   IS              allCells;                 /* Unique cells in union of all patches */
 79:   IS              allIntFacets;             /* Unique interior facets in union of all patches */
 80:   PetscBool       partition_of_unity;       /* Weight updates by dof multiplicity? */
 81:   PetscBool       multiplicative;           /* Gauss-Seidel instead of Jacobi?  */
 82:   PCCompositeType local_composition_type;   /* locally additive or multiplicative? */
 83:   /* Patch solves */
 84:   Vec          cellMats;                           /* Cell element tensors */
 85:   PetscInt    *precomputedTensorLocations;         /* Locations of the precomputed tensors for each cell. */
 86:   Vec          intFacetMats;                       /* interior facet element tensors */
 87:   PetscInt    *precomputedIntFacetTensorLocations; /* Locations of the precomputed tensors for each interior facet. */
 88:   Mat         *mat;                                /* System matrix for each patch */
 89:   Mat         *matWithArtificial;                  /* System matrix including dofs with artificial bcs for each patch */
 90:   MatType      sub_mat_type;                       /* Matrix type for patch systems */
 91:   Vec          patchRHS, patchUpdate;              /* Work vectors for RHS and solution on each patch */
 92:   IS          *dofMappingWithoutToWithArtificial;
 93:   IS          *dofMappingWithoutToWithAll;
 94:   Vec          patchRHSWithArtificial;         /* like patchRHS but extra entries to include dofs with artificial bcs*/
 95:   Vec         *patch_dof_weights;              /* Weighting for dof in each patch */
 96:   Vec          localRHS, localUpdate;          /* ??? */
 97:   Vec          dof_weights;                    /* In how many patches does each dof lie? */
 98:   PetscBool    symmetrise_sweep;               /* Should we sweep forwards->backwards, backwards->forwards? */
 99:   PetscBool    optionsSet;                     /* SetFromOptions was called on this PC */
100:   IS           iterationSet;                   /* Index set specifying how we iterate over patches */
101:   PetscInt     currentPatch;                   /* The current patch number when iterating */
102:   PetscObject *solver;                         /* Solvers for each patch TODO Do we need a new KSP for each patch? */
103:   PetscBool    denseinverse;                   /* Should the patch inverse by applied by computing the inverse and a matmult? (Skips KSP/PC etc...) */
104:   PetscErrorCode (*densesolve)(Mat, Vec, Vec); /* Matmult for dense solve (used with denseinverse) */
105:   PetscErrorCode (*setupsolver)(PC);
106:   PetscErrorCode (*applysolver)(PC, PetscInt, Vec, Vec);
107:   PetscErrorCode (*resetsolver)(PC);
108:   PetscErrorCode (*destroysolver)(PC);
109:   PetscErrorCode (*updatemultiplicative)(PC, PetscInt, PetscInt);
110:   /* Monitoring */
111:   PetscBool         viewPatches;     /* View information about patch construction */
112:   PetscBool         viewCells;       /* View cells for each patch */
113:   PetscViewer       viewerCells;     /*   Viewer for patch cells */
114:   PetscViewerFormat formatCells;     /*   Format for patch cells */
115:   PetscBool         viewIntFacets;   /* View intFacets for each patch */
116:   PetscViewer       viewerIntFacets; /*   Viewer for patch intFacets */
117:   PetscViewerFormat formatIntFacets; /*   Format for patch intFacets */
118:   PetscBool         viewExtFacets;   /* View extFacets for each patch */
119:   PetscViewer       viewerExtFacets; /*   Viewer for patch extFacets */
120:   PetscViewerFormat formatExtFacets; /*   Format for patch extFacets */
121:   PetscBool         viewPoints;      /* View points for each patch */
122:   PetscViewer       viewerPoints;    /*   Viewer for patch points */
123:   PetscViewerFormat formatPoints;    /*   Format for patch points */
124:   PetscBool         viewSection;     /* View global section for each patch */
125:   PetscViewer       viewerSection;   /*   Viewer for patch sections */
126:   PetscViewerFormat formatSection;   /*   Format for patch sections */
127:   PetscBool         viewMatrix;      /* View matrix for each patch */
128:   PetscViewer       viewerMatrix;    /*   Viewer for patch matrix */
129:   PetscViewerFormat formatMatrix;    /*   Format for patch matrix */
130:   /* Extra variables for SNESPATCH */
131:   Vec         patchState;        /* State vectors for patch solvers */
132:   Vec         patchStateWithAll; /* State vectors for patch solvers with all boundary data */
133:   Vec         localState;        /* Scatter vector for state */
134:   Vec         patchResidual;     /* Work vectors for patch residual evaluation*/
135:   const char *classname;         /* "snes" or "pc" for options */
136:   PetscBool   isNonlinear;       /* we need to do some things differently in nonlinear mode */
137: } PC_PATCH;

139: PETSC_EXTERN PetscLogEvent PC_Patch_CreatePatches;
140: PETSC_EXTERN PetscLogEvent PC_Patch_ComputeOp;
141: PETSC_EXTERN PetscLogEvent PC_Patch_Solve;
142: PETSC_EXTERN PetscLogEvent PC_Patch_Apply;
143: PETSC_EXTERN PetscLogEvent PC_Patch_Prealloc;

145: PETSC_EXTERN PetscErrorCode PCPatchComputeFunction_Internal(PC, Vec, Vec, PetscInt);
146: PETSC_EXTERN PetscErrorCode PCPatchComputeOperator_Internal(PC, Vec, Mat, PetscInt, PetscBool);
147: typedef enum {
148:   SCATTER_INTERIOR,
149:   SCATTER_WITHARTIFICIAL,
150:   SCATTER_WITHALL
151: } PatchScatterType;
152: PETSC_EXTERN PetscErrorCode PCPatch_ScatterLocal_Private(PC, PetscInt, Vec, Vec, InsertMode, ScatterMode, PatchScatterType);