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_INTERN PetscBool  PCPatchcite;
     11: PETSC_INTERN 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_SINGLE_LIBRARY_INTERN PetscErrorCode PCPatchComputeFunction_Internal(PC, Vec, Vec, PetscInt);
    146: PETSC_SINGLE_LIBRARY_INTERN PetscErrorCode PCPatchComputeOperator_Internal(PC, Vec, Mat, PetscInt, PetscBool);
    147: typedef enum {
    148:   SCATTER_INTERIOR,
    149:   SCATTER_WITHARTIFICIAL,
    150:   SCATTER_WITHALL
    151: } PatchScatterType;
    152: PETSC_SINGLE_LIBRARY_INTERN PetscErrorCode PCPatch_ScatterLocal_Private(PC, PetscInt, Vec, Vec, InsertMode, ScatterMode, PatchScatterType);