Actual source code: plexhpddm.c
petsc-3.13.6 2020-09-29
Report Typos and Errors

      1:  #include <petsc/private/dmpleximpl.h>

      3: /*@C
      4:      DMCreateNeumannOverlap - Generates an IS, an unassembled (Neumann) Mat, a setup function, and the corresponding context to be used by PCHPDDM.

      6:    Input Parameter:
      7: .     dm - preconditioner context

      9:    Output Parameters:
     10: +     ovl - index set of overlapping subdomains
     11: .     J - unassembled (Neumann) local matrix
     12: .     setup - function for generating the matrix
     13: -     setup_ctx - context for setup

     15:    Options Database Keys:
     16: +   -dm_plex_view_neumann_original - view the DM without overlap
     17: -   -dm_plex_view_neumann_overlap - view the DM with overlap as needed by PCHPDDM

     19:    Level: advanced

     21: .seealso:  DMCreate(), DM, MATIS, PCHPDDM, PCHPDDMSetAuxiliaryMat()
     22: @*/
     23: PetscErrorCode DMCreateNeumannOverlap_Plex(DM dm, IS *ovl, Mat *J, PetscErrorCode (**setup)(Mat, PetscReal, Vec, Vec, PetscReal, IS, void*), void **setup_ctx)
     24: {
     25:   DM                     odm;
     26:   Mat                    pJ;
     27:   PetscSF                sf = NULL;
     28:   PetscSection           sec, osec;
     29:   ISLocalToGlobalMapping l2g;
     30:   const PetscInt         *idxs;
     31:   PetscInt               n, mh;
     32:   PetscErrorCode         ierr;

     35:   *setup     = NULL;
     36:   *setup_ctx = NULL;
     37:   *ovl       = NULL;
     38:   *J         = NULL;

     40:   /* Overlapped mesh
     41:      overlap is a little more generous, since it is not computed starting from the owned (Dirichlet) points, but from the locally owned cells */
     42:   DMPlexDistributeOverlap(dm, 1, &sf, &odm);
     43:   if (!odm) {
     44:     PetscSFDestroy(&sf);
     45:     return(0);
     46:   }

     48:   /* share discretization */
     49:   DMGetLocalSection(dm, &sec);
     50:   PetscSectionCreate(PetscObjectComm((PetscObject)sec), &osec);
     51:   PetscSFDistributeSection(sf, sec, NULL, osec);
     52:   /* what to do here? using both is fine? */
     53:   DMSetLocalSection(odm, osec);
     54:   DMCopyDisc(dm, odm);
     55:   DMPlexGetMaxProjectionHeight(dm, &mh);
     56:   DMPlexSetMaxProjectionHeight(odm, mh);
     57:   PetscSectionDestroy(&osec);

     59:   /* material parameters */
     60:   {
     61:     DM  dmAux;
     62:     Vec A;

     64:     PetscObjectQuery((PetscObject)dm, "dmAux", (PetscObject*)&dmAux);
     65:     PetscObjectQuery((PetscObject)dm, "A", (PetscObject*)&A);
     66:     if (dmAux) {
     67:       DM ocdm, odmAux;

     69:       DMClone(odm, &odmAux);
     70:       DMGetCoordinateDM(odm, &ocdm);
     71:       DMSetCoordinateDM(odmAux, ocdm);
     72:       DMCopyDisc(dmAux, odmAux);
     73:       if (A) {
     74:         Vec oA;

     76:         DMGetLocalSection(dmAux, &sec);
     77:         PetscSectionCreate(PetscObjectComm((PetscObject)sec), &osec);
     78:         VecCreate(PetscObjectComm((PetscObject)A), &oA);
     79:         /* TODO: what if these values changes? */
     80:         DMPlexDistributeField(dmAux, sf, sec, A, osec, oA);
     81:         DMSetLocalSection(odmAux, osec);
     82:         PetscSectionDestroy(&osec);
     83:         PetscObjectCompose((PetscObject)odm, "A", (PetscObject)oA);
     84:         VecDestroy(&oA);
     85:       }
     86:       PetscObjectCompose((PetscObject)odm, "dmAux", (PetscObject)odmAux);
     87:       DMDestroy(&odmAux);
     88:     }
     89:   }
     90:   PetscSFDestroy(&sf);

     92:   DMViewFromOptions(dm, NULL, "-dm_plex_view_neumann_original");
     93:   PetscObjectSetName((PetscObject)odm, "OVL");
     94:   DMViewFromOptions(odm, NULL, "-dm_plex_view_neumann_overlap");

     96:   /* MATIS for the overlap region
     97:      the HPDDM interface wants local matrices,
     98:      we attach the global MATIS to the overlap IS,
     99:      since we need it to do assembly */
    100:   DMSetMatType(odm, MATIS);
    101:   DMCreateMatrix(odm, &pJ);
    102:   MatISGetLocalMat(pJ, J);
    103:   PetscObjectReference((PetscObject)*J);

    105:   /* overlap IS */
    106:   MatGetLocalToGlobalMapping(pJ, &l2g, NULL);
    107:   ISLocalToGlobalMappingGetSize(l2g, &n);
    108:   ISLocalToGlobalMappingGetIndices(l2g, &idxs);
    109:   ISCreateGeneral(PetscObjectComm((PetscObject)odm), n, idxs, PETSC_COPY_VALUES, ovl);
    110:   ISLocalToGlobalMappingRestoreIndices(l2g, &idxs);
    111:   PetscObjectCompose((PetscObject)*ovl, "_DM_Overlap_HPDDM_MATIS", (PetscObject)pJ);
    112:   DMDestroy(&odm);
    113:   MatDestroy(&pJ);

    115:   /* special purpose setup function (composed in DMPlexSetSNESLocalFEM) */
    116:   PetscObjectQueryFunction((PetscObject)dm, "MatComputeNeumannOverlap_C", setup);
    117:   if (*setup) {
    118:     PetscObjectCompose((PetscObject)*ovl, "_DM_Original_HPDDM", (PetscObject)dm);
    119:   }
    120:   return(0);
    121: }