147c6ae99SBarry Smith 2ccd284c7SBarry Smith #include <../src/dm/impls/composite/packimpl.h> /*I "petscdmcomposite.h" I*/ 3af0996ceSBarry Smith #include <petsc/private/isimpl.h> 4e10fd815SStefano Zampini #include <petsc/private/glvisviewerimpl.h> 52764a2aaSMatthew G. Knepley #include <petscds.h> 647c6ae99SBarry Smith 747c6ae99SBarry Smith /*@C 847c6ae99SBarry Smith DMCompositeSetCoupling - Sets user provided routines that compute the coupling between the 9*dce8aebaSBarry Smith separate components `DM` in a `DMCOMPOSITE` to build the correct matrix nonzero structure. 1047c6ae99SBarry Smith 11d083f849SBarry Smith Logically Collective 1247c6ae99SBarry Smith 13d8d19677SJose E. Roman Input Parameters: 1447c6ae99SBarry Smith + dm - the composite object 1547c6ae99SBarry Smith - formcouplelocations - routine to set the nonzero locations in the matrix 1647c6ae99SBarry Smith 1747c6ae99SBarry Smith Level: advanced 1847c6ae99SBarry Smith 19*dce8aebaSBarry Smith Note: 20*dce8aebaSBarry Smith See `DMSetApplicationContext()` and `DMGetApplicationContext()` for how to get user information into 2147c6ae99SBarry Smith this routine 2247c6ae99SBarry Smith 23*dce8aebaSBarry Smith Fortran Note: 24*dce8aebaSBarry Smith Not available from Fortran 25*dce8aebaSBarry Smith 26*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM` 2747c6ae99SBarry Smith @*/ 28d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeSetCoupling(DM dm, PetscErrorCode (*FormCoupleLocations)(DM, Mat, PetscInt *, PetscInt *, PetscInt, PetscInt, PetscInt, PetscInt)) 29d71ae5a4SJacob Faibussowitsch { 3047c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 3171b14b3eSStefano Zampini PetscBool flg; 3247c6ae99SBarry Smith 3347c6ae99SBarry Smith PetscFunctionBegin; 349566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 357a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 3647c6ae99SBarry Smith com->FormCoupleLocations = FormCoupleLocations; 3747c6ae99SBarry Smith PetscFunctionReturn(0); 3847c6ae99SBarry Smith } 3947c6ae99SBarry Smith 40d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDestroy_Composite(DM dm) 41d71ae5a4SJacob Faibussowitsch { 4247c6ae99SBarry Smith struct DMCompositeLink *next, *prev; 4347c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 4447c6ae99SBarry Smith 4547c6ae99SBarry Smith PetscFunctionBegin; 4647c6ae99SBarry Smith next = com->next; 4747c6ae99SBarry Smith while (next) { 4847c6ae99SBarry Smith prev = next; 4947c6ae99SBarry Smith next = next->next; 509566063dSJacob Faibussowitsch PetscCall(DMDestroy(&prev->dm)); 519566063dSJacob Faibussowitsch PetscCall(PetscFree(prev->grstarts)); 529566063dSJacob Faibussowitsch PetscCall(PetscFree(prev)); 5347c6ae99SBarry Smith } 549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)dm, "DMSetUpGLVisViewer_C", NULL)); 55435a35e8SMatthew G Knepley /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 569566063dSJacob Faibussowitsch PetscCall(PetscFree(com)); 5747c6ae99SBarry Smith PetscFunctionReturn(0); 5847c6ae99SBarry Smith } 5947c6ae99SBarry Smith 60d71ae5a4SJacob Faibussowitsch PetscErrorCode DMView_Composite(DM dm, PetscViewer v) 61d71ae5a4SJacob Faibussowitsch { 6247c6ae99SBarry Smith PetscBool iascii; 6347c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 6447c6ae99SBarry Smith 6547c6ae99SBarry Smith PetscFunctionBegin; 669566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii)); 6747c6ae99SBarry Smith if (iascii) { 6847c6ae99SBarry Smith struct DMCompositeLink *lnk = com->next; 6947c6ae99SBarry Smith PetscInt i; 7047c6ae99SBarry Smith 719566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(v, "DM (%s)\n", ((PetscObject)dm)->prefix ? ((PetscObject)dm)->prefix : "no prefix")); 7263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(v, " contains %" PetscInt_FMT " DMs\n", com->nDM)); 739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(v)); 7447c6ae99SBarry Smith for (i = 0; lnk; lnk = lnk->next, i++) { 7563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(v, "Link %" PetscInt_FMT ": DM of type %s\n", i, ((PetscObject)lnk->dm)->type_name)); 769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(v)); 779566063dSJacob Faibussowitsch PetscCall(DMView(lnk->dm, v)); 789566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(v)); 7947c6ae99SBarry Smith } 809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(v)); 8147c6ae99SBarry Smith } 8247c6ae99SBarry Smith PetscFunctionReturn(0); 8347c6ae99SBarry Smith } 8447c6ae99SBarry Smith 8547c6ae99SBarry Smith /* --------------------------------------------------------------------------------------*/ 86d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSetUp_Composite(DM dm) 87d71ae5a4SJacob Faibussowitsch { 8847c6ae99SBarry Smith PetscInt nprev = 0; 8947c6ae99SBarry Smith PetscMPIInt rank, size; 9047c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 9147c6ae99SBarry Smith struct DMCompositeLink *next = com->next; 9247c6ae99SBarry Smith PetscLayout map; 9347c6ae99SBarry Smith 9447c6ae99SBarry Smith PetscFunctionBegin; 9528b400f6SJacob Faibussowitsch PetscCheck(!com->setup, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Packer has already been setup"); 969566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(PetscObjectComm((PetscObject)dm), &map)); 979566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(map, com->n)); 989566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetSize(map, PETSC_DETERMINE)); 999566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(map, 1)); 1009566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(map)); 1019566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetSize(map, &com->N)); 1029566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRange(map, &com->rstart, NULL)); 1039566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&map)); 10447c6ae99SBarry Smith 1059ae5db72SJed Brown /* now set the rstart for each linked vector */ 1069566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank)); 1079566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 10847c6ae99SBarry Smith while (next) { 10947c6ae99SBarry Smith next->rstart = nprev; 11006ebdd98SJed Brown nprev += next->n; 11147c6ae99SBarry Smith next->grstart = com->rstart + next->rstart; 1129566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &next->grstarts)); 1139566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allgather(&next->grstart, 1, MPIU_INT, next->grstarts, 1, MPIU_INT, PetscObjectComm((PetscObject)dm))); 11447c6ae99SBarry Smith next = next->next; 11547c6ae99SBarry Smith } 11647c6ae99SBarry Smith com->setup = PETSC_TRUE; 11747c6ae99SBarry Smith PetscFunctionReturn(0); 11847c6ae99SBarry Smith } 11947c6ae99SBarry Smith 12047c6ae99SBarry Smith /* ----------------------------------------------------------------------------------*/ 12147c6ae99SBarry Smith 12273e31fe2SJed Brown /*@ 123*dce8aebaSBarry Smith DMCompositeGetNumberDM - Get's the number of `DM` objects in the `DMCOMPOSITE` 12447c6ae99SBarry Smith representation. 12547c6ae99SBarry Smith 12647c6ae99SBarry Smith Not Collective 12747c6ae99SBarry Smith 12847c6ae99SBarry Smith Input Parameter: 129*dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` object 13047c6ae99SBarry Smith 13147c6ae99SBarry Smith Output Parameter: 132*dce8aebaSBarry Smith . nDM - the number of `DM` 13347c6ae99SBarry Smith 13447c6ae99SBarry Smith Level: beginner 13547c6ae99SBarry Smith 136*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM` 13747c6ae99SBarry Smith @*/ 138d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeGetNumberDM(DM dm, PetscInt *nDM) 139d71ae5a4SJacob Faibussowitsch { 14047c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 14171b14b3eSStefano Zampini PetscBool flg; 1425fd66863SKarl Rupp 14347c6ae99SBarry Smith PetscFunctionBegin; 14447c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1459566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 1467a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 14747c6ae99SBarry Smith *nDM = com->nDM; 14847c6ae99SBarry Smith PetscFunctionReturn(0); 14947c6ae99SBarry Smith } 15047c6ae99SBarry Smith 15147c6ae99SBarry Smith /*@C 15247c6ae99SBarry Smith DMCompositeGetAccess - Allows one to access the individual packed vectors in their global 15347c6ae99SBarry Smith representation. 15447c6ae99SBarry Smith 155d083f849SBarry Smith Collective on dm 15647c6ae99SBarry Smith 1579ae5db72SJed Brown Input Parameters: 158*dce8aebaSBarry Smith + dm - the `DMCOMPOSITE` object 1599ae5db72SJed Brown - gvec - the global vector 1609ae5db72SJed Brown 1619ae5db72SJed Brown Output Parameters: 1620298fd71SBarry Smith . Vec* ... - the packed parallel vectors, NULL for those that are not needed 16347c6ae99SBarry Smith 16447c6ae99SBarry Smith Level: advanced 16547c6ae99SBarry Smith 166*dce8aebaSBarry Smith Note: 167*dce8aebaSBarry Smith Use `DMCompositeRestoreAccess()` to return the vectors when you no longer need them 168*dce8aebaSBarry Smith 169*dce8aebaSBarry Smith Fortran Note: 170*dce8aebaSBarry Smith Fortran callers must use numbered versions of this routine, e.g., DMCompositeGetAccess4(dm,gvec,vec1,vec2,vec3,vec4) 171*dce8aebaSBarry Smith or use the alternative interface `DMCompositeGetAccessArray()`. 172*dce8aebaSBarry Smith 173*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMCompositeGetEntries()`, `DMCompositeScatter()` 17447c6ae99SBarry Smith @*/ 175d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeGetAccess(DM dm, Vec gvec, ...) 176d71ae5a4SJacob Faibussowitsch { 17747c6ae99SBarry Smith va_list Argp; 17847c6ae99SBarry Smith struct DMCompositeLink *next; 17947c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 1805edff71fSBarry Smith PetscInt readonly; 18171b14b3eSStefano Zampini PetscBool flg; 18247c6ae99SBarry Smith 18347c6ae99SBarry Smith PetscFunctionBegin; 18447c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18547c6ae99SBarry Smith PetscValidHeaderSpecific(gvec, VEC_CLASSID, 2); 1869566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 1877a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 18847c6ae99SBarry Smith next = com->next; 18948a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 19047c6ae99SBarry Smith 1919566063dSJacob Faibussowitsch PetscCall(VecLockGet(gvec, &readonly)); 19247c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 19347c6ae99SBarry Smith va_start(Argp, gvec); 19447c6ae99SBarry Smith while (next) { 19547c6ae99SBarry Smith Vec *vec; 19647c6ae99SBarry Smith vec = va_arg(Argp, Vec *); 1979ae5db72SJed Brown if (vec) { 1989566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(next->dm, vec)); 1995edff71fSBarry Smith if (readonly) { 2005edff71fSBarry Smith const PetscScalar *array; 2019566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(gvec, &array)); 2029566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(*vec, array + next->rstart)); 2039566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(*vec)); 2049566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(gvec, &array)); 2055edff71fSBarry Smith } else { 2065edff71fSBarry Smith PetscScalar *array; 2079566063dSJacob Faibussowitsch PetscCall(VecGetArray(gvec, &array)); 2089566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(*vec, array + next->rstart)); 2099566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(gvec, &array)); 21047c6ae99SBarry Smith } 2115edff71fSBarry Smith } 21247c6ae99SBarry Smith next = next->next; 21347c6ae99SBarry Smith } 21447c6ae99SBarry Smith va_end(Argp); 21547c6ae99SBarry Smith PetscFunctionReturn(0); 21647c6ae99SBarry Smith } 21747c6ae99SBarry Smith 218f73e5cebSJed Brown /*@C 219f73e5cebSJed Brown DMCompositeGetAccessArray - Allows one to access the individual packed vectors in their global 220f73e5cebSJed Brown representation. 221f73e5cebSJed Brown 222d083f849SBarry Smith Collective on dm 223f73e5cebSJed Brown 224f73e5cebSJed Brown Input Parameters: 225*dce8aebaSBarry Smith + dm - the `DMCOMPOSITE` 226f73e5cebSJed Brown . pvec - packed vector 227f73e5cebSJed Brown . nwanted - number of vectors wanted 2280298fd71SBarry Smith - wanted - sorted array of vectors wanted, or NULL to get all vectors 229f73e5cebSJed Brown 230f73e5cebSJed Brown Output Parameters: 231f73e5cebSJed Brown . vecs - array of requested global vectors (must be allocated) 232f73e5cebSJed Brown 233f73e5cebSJed Brown Level: advanced 234f73e5cebSJed Brown 235*dce8aebaSBarry Smith Note: 236*dce8aebaSBarry Smith Use `DMCompositeRestoreAccessArray()` to return the vectors when you no longer need them 237*dce8aebaSBarry Smith 238*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMCompositeGetAccess()`, `DMCompositeGetEntries()`, `DMCompositeScatter()`, `DMCompositeGather()` 239f73e5cebSJed Brown @*/ 240d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeGetAccessArray(DM dm, Vec pvec, PetscInt nwanted, const PetscInt *wanted, Vec *vecs) 241d71ae5a4SJacob Faibussowitsch { 242f73e5cebSJed Brown struct DMCompositeLink *link; 243f73e5cebSJed Brown PetscInt i, wnum; 244f73e5cebSJed Brown DM_Composite *com = (DM_Composite *)dm->data; 245bee642f7SBarry Smith PetscInt readonly; 24671b14b3eSStefano Zampini PetscBool flg; 247f73e5cebSJed Brown 248f73e5cebSJed Brown PetscFunctionBegin; 249f73e5cebSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 250f73e5cebSJed Brown PetscValidHeaderSpecific(pvec, VEC_CLASSID, 2); 2519566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 2527a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 25348a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 254f73e5cebSJed Brown 2559566063dSJacob Faibussowitsch PetscCall(VecLockGet(pvec, &readonly)); 256f73e5cebSJed Brown for (i = 0, wnum = 0, link = com->next; link && wnum < nwanted; i++, link = link->next) { 257f73e5cebSJed Brown if (!wanted || i == wanted[wnum]) { 258f73e5cebSJed Brown Vec v; 2599566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(link->dm, &v)); 260bee642f7SBarry Smith if (readonly) { 261bee642f7SBarry Smith const PetscScalar *array; 2629566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(pvec, &array)); 2639566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(v, array + link->rstart)); 2649566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(v)); 2659566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(pvec, &array)); 266bee642f7SBarry Smith } else { 267bee642f7SBarry Smith PetscScalar *array; 2689566063dSJacob Faibussowitsch PetscCall(VecGetArray(pvec, &array)); 2699566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(v, array + link->rstart)); 2709566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(pvec, &array)); 271bee642f7SBarry Smith } 272f73e5cebSJed Brown vecs[wnum++] = v; 273f73e5cebSJed Brown } 274f73e5cebSJed Brown } 275f73e5cebSJed Brown PetscFunctionReturn(0); 276f73e5cebSJed Brown } 277f73e5cebSJed Brown 2787ac2b803SAlex Fikl /*@C 2797ac2b803SAlex Fikl DMCompositeGetLocalAccessArray - Allows one to access the individual 2807ac2b803SAlex Fikl packed vectors in their local representation. 2817ac2b803SAlex Fikl 282d083f849SBarry Smith Collective on dm. 2837ac2b803SAlex Fikl 2847ac2b803SAlex Fikl Input Parameters: 285*dce8aebaSBarry Smith + dm - the `DMCOMPOSITE` 2867ac2b803SAlex Fikl . pvec - packed vector 2877ac2b803SAlex Fikl . nwanted - number of vectors wanted 2887ac2b803SAlex Fikl - wanted - sorted array of vectors wanted, or NULL to get all vectors 2897ac2b803SAlex Fikl 2907ac2b803SAlex Fikl Output Parameters: 2917ac2b803SAlex Fikl . vecs - array of requested local vectors (must be allocated) 2927ac2b803SAlex Fikl 2937ac2b803SAlex Fikl Level: advanced 2947ac2b803SAlex Fikl 295*dce8aebaSBarry Smith Note: 296*dce8aebaSBarry Smith Use `DMCompositeRestoreLocalAccessArray()` to return the vectors 297*dce8aebaSBarry Smith when you no longer need them. 298*dce8aebaSBarry Smith 299*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMCompositeRestoreLocalAccessArray()`, `DMCompositeGetAccess()`, 300db781477SPatrick Sanan `DMCompositeGetEntries()`, `DMCompositeScatter()`, `DMCompositeGather()` 3017ac2b803SAlex Fikl @*/ 302d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeGetLocalAccessArray(DM dm, Vec pvec, PetscInt nwanted, const PetscInt *wanted, Vec *vecs) 303d71ae5a4SJacob Faibussowitsch { 3047ac2b803SAlex Fikl struct DMCompositeLink *link; 3057ac2b803SAlex Fikl PetscInt i, wnum; 3067ac2b803SAlex Fikl DM_Composite *com = (DM_Composite *)dm->data; 3077ac2b803SAlex Fikl PetscInt readonly; 3087ac2b803SAlex Fikl PetscInt nlocal = 0; 30971b14b3eSStefano Zampini PetscBool flg; 3107ac2b803SAlex Fikl 3117ac2b803SAlex Fikl PetscFunctionBegin; 3127ac2b803SAlex Fikl PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3137ac2b803SAlex Fikl PetscValidHeaderSpecific(pvec, VEC_CLASSID, 2); 3149566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 3157a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 31648a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 3177ac2b803SAlex Fikl 3189566063dSJacob Faibussowitsch PetscCall(VecLockGet(pvec, &readonly)); 3197ac2b803SAlex Fikl for (i = 0, wnum = 0, link = com->next; link && wnum < nwanted; i++, link = link->next) { 3207ac2b803SAlex Fikl if (!wanted || i == wanted[wnum]) { 3217ac2b803SAlex Fikl Vec v; 3229566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(link->dm, &v)); 3237ac2b803SAlex Fikl if (readonly) { 3247ac2b803SAlex Fikl const PetscScalar *array; 3259566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(pvec, &array)); 3269566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(v, array + nlocal)); 327b1c3483dSMark Adams // this method does not make sense. The local vectors are not updated with a global-to-local and the user can not do it because it is locked 3289566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(v)); 3299566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(pvec, &array)); 3307ac2b803SAlex Fikl } else { 3317ac2b803SAlex Fikl PetscScalar *array; 3329566063dSJacob Faibussowitsch PetscCall(VecGetArray(pvec, &array)); 3339566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(v, array + nlocal)); 3349566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(pvec, &array)); 3357ac2b803SAlex Fikl } 3367ac2b803SAlex Fikl vecs[wnum++] = v; 3377ac2b803SAlex Fikl } 3387ac2b803SAlex Fikl 3397ac2b803SAlex Fikl nlocal += link->nlocal; 3407ac2b803SAlex Fikl } 3417ac2b803SAlex Fikl 3427ac2b803SAlex Fikl PetscFunctionReturn(0); 3437ac2b803SAlex Fikl } 3447ac2b803SAlex Fikl 34547c6ae99SBarry Smith /*@C 346*dce8aebaSBarry Smith DMCompositeRestoreAccess - Returns the vectors obtained with `DMCompositeGetAccess()` 34747c6ae99SBarry Smith representation. 34847c6ae99SBarry Smith 349d083f849SBarry Smith Collective on dm 35047c6ae99SBarry Smith 3519ae5db72SJed Brown Input Parameters: 352*dce8aebaSBarry Smith + dm - the `DMCOMPOSITE` object 35347c6ae99SBarry Smith . gvec - the global vector 3540298fd71SBarry Smith - Vec* ... - the individual parallel vectors, NULL for those that are not needed 35547c6ae99SBarry Smith 35647c6ae99SBarry Smith Level: advanced 35747c6ae99SBarry Smith 358*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMCompositeAddDM()`, `DMCreateGlobalVector()`, 359db781477SPatrick Sanan `DMCompositeGather()`, `DMCompositeCreate()`, `DMCompositeGetISLocalToGlobalMappings()`, `DMCompositeScatter()`, 360db781477SPatrick Sanan `DMCompositeRestoreAccess()`, `DMCompositeGetAccess()` 36147c6ae99SBarry Smith @*/ 362d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeRestoreAccess(DM dm, Vec gvec, ...) 363d71ae5a4SJacob Faibussowitsch { 36447c6ae99SBarry Smith va_list Argp; 36547c6ae99SBarry Smith struct DMCompositeLink *next; 36647c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 3675edff71fSBarry Smith PetscInt readonly; 36871b14b3eSStefano Zampini PetscBool flg; 36947c6ae99SBarry Smith 37047c6ae99SBarry Smith PetscFunctionBegin; 37147c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37247c6ae99SBarry Smith PetscValidHeaderSpecific(gvec, VEC_CLASSID, 2); 3739566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 3747a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 37547c6ae99SBarry Smith next = com->next; 37648a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 37747c6ae99SBarry Smith 3789566063dSJacob Faibussowitsch PetscCall(VecLockGet(gvec, &readonly)); 37947c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 38047c6ae99SBarry Smith va_start(Argp, gvec); 38147c6ae99SBarry Smith while (next) { 38247c6ae99SBarry Smith Vec *vec; 38347c6ae99SBarry Smith vec = va_arg(Argp, Vec *); 3849ae5db72SJed Brown if (vec) { 3859566063dSJacob Faibussowitsch PetscCall(VecResetArray(*vec)); 3861baa6e33SBarry Smith if (readonly) PetscCall(VecLockReadPop(*vec)); 3879566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(next->dm, vec)); 38847c6ae99SBarry Smith } 38947c6ae99SBarry Smith next = next->next; 39047c6ae99SBarry Smith } 39147c6ae99SBarry Smith va_end(Argp); 39247c6ae99SBarry Smith PetscFunctionReturn(0); 39347c6ae99SBarry Smith } 39447c6ae99SBarry Smith 395f73e5cebSJed Brown /*@C 396*dce8aebaSBarry Smith DMCompositeRestoreAccessArray - Returns the vectors obtained with `DMCompositeGetAccessArray()` 397f73e5cebSJed Brown 398d083f849SBarry Smith Collective on dm 399f73e5cebSJed Brown 400f73e5cebSJed Brown Input Parameters: 401*dce8aebaSBarry Smith + dm - the `DMCOMPOSITE` object 402f73e5cebSJed Brown . pvec - packed vector 403f73e5cebSJed Brown . nwanted - number of vectors wanted 4040298fd71SBarry Smith . wanted - sorted array of vectors wanted, or NULL to get all vectors 405f73e5cebSJed Brown - vecs - array of global vectors to return 406f73e5cebSJed Brown 407f73e5cebSJed Brown Level: advanced 408f73e5cebSJed Brown 409*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMCompositeRestoreAccess()`, `DMCompositeRestoreEntries()`, `DMCompositeScatter()`, `DMCompositeGather()` 410f73e5cebSJed Brown @*/ 411d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeRestoreAccessArray(DM dm, Vec pvec, PetscInt nwanted, const PetscInt *wanted, Vec *vecs) 412d71ae5a4SJacob Faibussowitsch { 413f73e5cebSJed Brown struct DMCompositeLink *link; 414f73e5cebSJed Brown PetscInt i, wnum; 415f73e5cebSJed Brown DM_Composite *com = (DM_Composite *)dm->data; 416bee642f7SBarry Smith PetscInt readonly; 41771b14b3eSStefano Zampini PetscBool flg; 418f73e5cebSJed Brown 419f73e5cebSJed Brown PetscFunctionBegin; 420f73e5cebSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 421f73e5cebSJed Brown PetscValidHeaderSpecific(pvec, VEC_CLASSID, 2); 4229566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 4237a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 42448a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 425f73e5cebSJed Brown 4269566063dSJacob Faibussowitsch PetscCall(VecLockGet(pvec, &readonly)); 427f73e5cebSJed Brown for (i = 0, wnum = 0, link = com->next; link && wnum < nwanted; i++, link = link->next) { 428f73e5cebSJed Brown if (!wanted || i == wanted[wnum]) { 4299566063dSJacob Faibussowitsch PetscCall(VecResetArray(vecs[wnum])); 43048a46eb9SPierre Jolivet if (readonly) PetscCall(VecLockReadPop(vecs[wnum])); 4319566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(link->dm, &vecs[wnum])); 432f73e5cebSJed Brown wnum++; 433f73e5cebSJed Brown } 434f73e5cebSJed Brown } 435f73e5cebSJed Brown PetscFunctionReturn(0); 436f73e5cebSJed Brown } 437f73e5cebSJed Brown 4387ac2b803SAlex Fikl /*@C 439*dce8aebaSBarry Smith DMCompositeRestoreLocalAccessArray - Returns the vectors obtained with `DMCompositeGetLocalAccessArray()`. 4407ac2b803SAlex Fikl 441d083f849SBarry Smith Collective on dm. 4427ac2b803SAlex Fikl 4437ac2b803SAlex Fikl Input Parameters: 444*dce8aebaSBarry Smith + dm - the `DMCOMPOSITE` object 4457ac2b803SAlex Fikl . pvec - packed vector 4467ac2b803SAlex Fikl . nwanted - number of vectors wanted 4477ac2b803SAlex Fikl . wanted - sorted array of vectors wanted, or NULL to restore all vectors 4487ac2b803SAlex Fikl - vecs - array of local vectors to return 4497ac2b803SAlex Fikl 4507ac2b803SAlex Fikl Level: advanced 4517ac2b803SAlex Fikl 452*dce8aebaSBarry Smith Note: 453*dce8aebaSBarry Smith nwanted and wanted must match the values given to `DMCompositeGetLocalAccessArray()` 4547ac2b803SAlex Fikl otherwise the call will fail. 4557ac2b803SAlex Fikl 456*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMCompositeGetLocalAccessArray()`, `DMCompositeRestoreAccessArray()`, 457db781477SPatrick Sanan `DMCompositeRestoreAccess()`, `DMCompositeRestoreEntries()`, 458db781477SPatrick Sanan `DMCompositeScatter()`, `DMCompositeGather()` 4597ac2b803SAlex Fikl @*/ 460d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeRestoreLocalAccessArray(DM dm, Vec pvec, PetscInt nwanted, const PetscInt *wanted, Vec *vecs) 461d71ae5a4SJacob Faibussowitsch { 4627ac2b803SAlex Fikl struct DMCompositeLink *link; 4637ac2b803SAlex Fikl PetscInt i, wnum; 4647ac2b803SAlex Fikl DM_Composite *com = (DM_Composite *)dm->data; 4657ac2b803SAlex Fikl PetscInt readonly; 46671b14b3eSStefano Zampini PetscBool flg; 4677ac2b803SAlex Fikl 4687ac2b803SAlex Fikl PetscFunctionBegin; 4697ac2b803SAlex Fikl PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4707ac2b803SAlex Fikl PetscValidHeaderSpecific(pvec, VEC_CLASSID, 2); 4719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 4727a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 47348a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 4747ac2b803SAlex Fikl 4759566063dSJacob Faibussowitsch PetscCall(VecLockGet(pvec, &readonly)); 4767ac2b803SAlex Fikl for (i = 0, wnum = 0, link = com->next; link && wnum < nwanted; i++, link = link->next) { 4777ac2b803SAlex Fikl if (!wanted || i == wanted[wnum]) { 4789566063dSJacob Faibussowitsch PetscCall(VecResetArray(vecs[wnum])); 47948a46eb9SPierre Jolivet if (readonly) PetscCall(VecLockReadPop(vecs[wnum])); 4809566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(link->dm, &vecs[wnum])); 4817ac2b803SAlex Fikl wnum++; 4827ac2b803SAlex Fikl } 4837ac2b803SAlex Fikl } 4847ac2b803SAlex Fikl PetscFunctionReturn(0); 4857ac2b803SAlex Fikl } 4867ac2b803SAlex Fikl 48747c6ae99SBarry Smith /*@C 48847c6ae99SBarry Smith DMCompositeScatter - Scatters from a global packed vector into its individual local vectors 48947c6ae99SBarry Smith 490d083f849SBarry Smith Collective on dm 49147c6ae99SBarry Smith 4929ae5db72SJed Brown Input Parameters: 493*dce8aebaSBarry Smith + dm - the `DMCOMPOSITE` object 49447c6ae99SBarry Smith . gvec - the global vector 4950298fd71SBarry Smith - Vec ... - the individual sequential vectors, NULL for those that are not needed 49647c6ae99SBarry Smith 49747c6ae99SBarry Smith Level: advanced 49847c6ae99SBarry Smith 499*dce8aebaSBarry Smith Note: 500*dce8aebaSBarry Smith `DMCompositeScatterArray()` is a non-variadic alternative that is often more convenient for library callers and is 5016f3c3dcfSJed Brown accessible from Fortran. 5026f3c3dcfSJed Brown 503*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMDestroy()`, `DMCompositeAddDM()`, `DMCreateGlobalVector()`, 504db781477SPatrick Sanan `DMCompositeGather()`, `DMCompositeCreate()`, `DMCompositeGetISLocalToGlobalMappings()`, `DMCompositeGetAccess()`, 505db781477SPatrick Sanan `DMCompositeGetLocalVectors()`, `DMCompositeRestoreLocalVectors()`, `DMCompositeGetEntries()` 506db781477SPatrick Sanan `DMCompositeScatterArray()` 50747c6ae99SBarry Smith @*/ 508d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeScatter(DM dm, Vec gvec, ...) 509d71ae5a4SJacob Faibussowitsch { 51047c6ae99SBarry Smith va_list Argp; 51147c6ae99SBarry Smith struct DMCompositeLink *next; 512c599c493SJunchao Zhang PETSC_UNUSED PetscInt cnt; 51347c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 51471b14b3eSStefano Zampini PetscBool flg; 51547c6ae99SBarry Smith 51647c6ae99SBarry Smith PetscFunctionBegin; 51747c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 51847c6ae99SBarry Smith PetscValidHeaderSpecific(gvec, VEC_CLASSID, 2); 5199566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 5207a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 52148a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 52247c6ae99SBarry Smith 52347c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 52447c6ae99SBarry Smith va_start(Argp, gvec); 5258fd8f222SJed Brown for (cnt = 3, next = com->next; next; cnt++, next = next->next) { 5269ae5db72SJed Brown Vec local; 5279ae5db72SJed Brown local = va_arg(Argp, Vec); 5289ae5db72SJed Brown if (local) { 5299ae5db72SJed Brown Vec global; 5305edff71fSBarry Smith const PetscScalar *array; 53163a3b9bcSJacob Faibussowitsch PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscValidHeaderSpecific(local, VEC_CLASSID, (int)cnt)); 5329566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(next->dm, &global)); 5339566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(gvec, &array)); 5349566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(global, array + next->rstart)); 5359566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(next->dm, global, INSERT_VALUES, local)); 5369566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(next->dm, global, INSERT_VALUES, local)); 5379566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(gvec, &array)); 5389566063dSJacob Faibussowitsch PetscCall(VecResetArray(global)); 5399566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(next->dm, &global)); 54047c6ae99SBarry Smith } 54147c6ae99SBarry Smith } 54247c6ae99SBarry Smith va_end(Argp); 54347c6ae99SBarry Smith PetscFunctionReturn(0); 54447c6ae99SBarry Smith } 54547c6ae99SBarry Smith 5466f3c3dcfSJed Brown /*@ 5476f3c3dcfSJed Brown DMCompositeScatterArray - Scatters from a global packed vector into its individual local vectors 5486f3c3dcfSJed Brown 549d083f849SBarry Smith Collective on dm 5506f3c3dcfSJed Brown 5516f3c3dcfSJed Brown Input Parameters: 552*dce8aebaSBarry Smith + dm - the `DMCOMPOSITE` object 5536f3c3dcfSJed Brown . gvec - the global vector 554a2b725a8SWilliam Gropp - lvecs - array of local vectors, NULL for any that are not needed 5556f3c3dcfSJed Brown 5566f3c3dcfSJed Brown Level: advanced 5576f3c3dcfSJed Brown 5586f3c3dcfSJed Brown Note: 559*dce8aebaSBarry Smith This is a non-variadic alternative to `DMCompositeScatter()` 5606f3c3dcfSJed Brown 561*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMDestroy()`, `DMCompositeAddDM()`, `DMCreateGlobalVector()` 562db781477SPatrick Sanan `DMCompositeGather()`, `DMCompositeCreate()`, `DMCompositeGetISLocalToGlobalMappings()`, `DMCompositeGetAccess()`, 563db781477SPatrick Sanan `DMCompositeGetLocalVectors()`, `DMCompositeRestoreLocalVectors()`, `DMCompositeGetEntries()` 5646f3c3dcfSJed Brown @*/ 565d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeScatterArray(DM dm, Vec gvec, Vec *lvecs) 566d71ae5a4SJacob Faibussowitsch { 5676f3c3dcfSJed Brown struct DMCompositeLink *next; 5686f3c3dcfSJed Brown PetscInt i; 5696f3c3dcfSJed Brown DM_Composite *com = (DM_Composite *)dm->data; 57071b14b3eSStefano Zampini PetscBool flg; 5716f3c3dcfSJed Brown 5726f3c3dcfSJed Brown PetscFunctionBegin; 5736f3c3dcfSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5746f3c3dcfSJed Brown PetscValidHeaderSpecific(gvec, VEC_CLASSID, 2); 5759566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 5767a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 57748a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 5786f3c3dcfSJed Brown 5796f3c3dcfSJed Brown /* loop over packed objects, handling one at at time */ 5806f3c3dcfSJed Brown for (i = 0, next = com->next; next; next = next->next, i++) { 5816f3c3dcfSJed Brown if (lvecs[i]) { 5826f3c3dcfSJed Brown Vec global; 583c5d31e75SLisandro Dalcin const PetscScalar *array; 5846f3c3dcfSJed Brown PetscValidHeaderSpecific(lvecs[i], VEC_CLASSID, 3); 5859566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(next->dm, &global)); 5869566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(gvec, &array)); 5879566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(global, (PetscScalar *)array + next->rstart)); 5889566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(next->dm, global, INSERT_VALUES, lvecs[i])); 5899566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(next->dm, global, INSERT_VALUES, lvecs[i])); 5909566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(gvec, &array)); 5919566063dSJacob Faibussowitsch PetscCall(VecResetArray(global)); 5929566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(next->dm, &global)); 5936f3c3dcfSJed Brown } 5946f3c3dcfSJed Brown } 5956f3c3dcfSJed Brown PetscFunctionReturn(0); 5966f3c3dcfSJed Brown } 5976f3c3dcfSJed Brown 59847c6ae99SBarry Smith /*@C 59947c6ae99SBarry Smith DMCompositeGather - Gathers into a global packed vector from its individual local vectors 60047c6ae99SBarry Smith 601d083f849SBarry Smith Collective on dm 60247c6ae99SBarry Smith 603d8d19677SJose E. Roman Input Parameters: 604*dce8aebaSBarry Smith + dm - the `DMCOMPOSITE` object 60547c6ae99SBarry Smith . gvec - the global vector 606*dce8aebaSBarry Smith . imode - `INSERT_VALUES` or `ADD_VALUES` 6070298fd71SBarry Smith - Vec ... - the individual sequential vectors, NULL for any that are not needed 60847c6ae99SBarry Smith 60947c6ae99SBarry Smith Level: advanced 61047c6ae99SBarry Smith 611*dce8aebaSBarry Smith Fortran Note: 612*dce8aebaSBarry Smith Fortran users should use `DMCompositeGatherArray()` 613f5f57ec0SBarry Smith 614*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMDestroy()`, `DMCompositeAddDM()`, `DMCreateGlobalVector()`, 615db781477SPatrick Sanan `DMCompositeScatter()`, `DMCompositeCreate()`, `DMCompositeGetISLocalToGlobalMappings()`, `DMCompositeGetAccess()`, 616db781477SPatrick Sanan `DMCompositeGetLocalVectors()`, `DMCompositeRestoreLocalVectors()`, `DMCompositeGetEntries()` 61747c6ae99SBarry Smith @*/ 618d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeGather(DM dm, InsertMode imode, Vec gvec, ...) 619d71ae5a4SJacob Faibussowitsch { 62047c6ae99SBarry Smith va_list Argp; 62147c6ae99SBarry Smith struct DMCompositeLink *next; 62247c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 623c599c493SJunchao Zhang PETSC_UNUSED PetscInt cnt; 62471b14b3eSStefano Zampini PetscBool flg; 62547c6ae99SBarry Smith 62647c6ae99SBarry Smith PetscFunctionBegin; 62747c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 628064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(gvec, VEC_CLASSID, 3); 6299566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 6307a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 63148a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 63247c6ae99SBarry Smith 63347c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 6341dac896bSSatish Balay va_start(Argp, gvec); 6358fd8f222SJed Brown for (cnt = 3, next = com->next; next; cnt++, next = next->next) { 6369ae5db72SJed Brown Vec local; 6379ae5db72SJed Brown local = va_arg(Argp, Vec); 6389ae5db72SJed Brown if (local) { 63947c6ae99SBarry Smith PetscScalar *array; 6409ae5db72SJed Brown Vec global; 64163a3b9bcSJacob Faibussowitsch PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(PetscValidHeaderSpecific(local, VEC_CLASSID, (int)cnt)); 6429566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(next->dm, &global)); 6439566063dSJacob Faibussowitsch PetscCall(VecGetArray(gvec, &array)); 6449566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(global, array + next->rstart)); 6459566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(next->dm, local, imode, global)); 6469566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(next->dm, local, imode, global)); 6479566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(gvec, &array)); 6489566063dSJacob Faibussowitsch PetscCall(VecResetArray(global)); 6499566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(next->dm, &global)); 65047c6ae99SBarry Smith } 65147c6ae99SBarry Smith } 65247c6ae99SBarry Smith va_end(Argp); 65347c6ae99SBarry Smith PetscFunctionReturn(0); 65447c6ae99SBarry Smith } 65547c6ae99SBarry Smith 6566f3c3dcfSJed Brown /*@ 6576f3c3dcfSJed Brown DMCompositeGatherArray - Gathers into a global packed vector from its individual local vectors 6586f3c3dcfSJed Brown 659d083f849SBarry Smith Collective on dm 6606f3c3dcfSJed Brown 661d8d19677SJose E. Roman Input Parameters: 662*dce8aebaSBarry Smith + dm - the `DMCOMPOSITE` object 6636f3c3dcfSJed Brown . gvec - the global vector 664*dce8aebaSBarry Smith . imode - `INSERT_VALUES` or `ADD_VALUES` 6656f3c3dcfSJed Brown - lvecs - the individual sequential vectors, NULL for any that are not needed 6666f3c3dcfSJed Brown 6676f3c3dcfSJed Brown Level: advanced 6686f3c3dcfSJed Brown 669*dce8aebaSBarry Smith Note: 670*dce8aebaSBarry Smith This is a non-variadic alternative to `DMCompositeGather()`. 6716f3c3dcfSJed Brown 672*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMDestroy()`, `DMCompositeAddDM()`, `DMCreateGlobalVector()`, 673db781477SPatrick Sanan `DMCompositeScatter()`, `DMCompositeCreate()`, `DMCompositeGetISLocalToGlobalMappings()`, `DMCompositeGetAccess()`, 674db781477SPatrick Sanan `DMCompositeGetLocalVectors()`, `DMCompositeRestoreLocalVectors()`, `DMCompositeGetEntries()`, 6756f3c3dcfSJed Brown @*/ 676d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeGatherArray(DM dm, InsertMode imode, Vec gvec, Vec *lvecs) 677d71ae5a4SJacob Faibussowitsch { 6786f3c3dcfSJed Brown struct DMCompositeLink *next; 6796f3c3dcfSJed Brown DM_Composite *com = (DM_Composite *)dm->data; 6806f3c3dcfSJed Brown PetscInt i; 68171b14b3eSStefano Zampini PetscBool flg; 6826f3c3dcfSJed Brown 6836f3c3dcfSJed Brown PetscFunctionBegin; 6846f3c3dcfSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 685064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(gvec, VEC_CLASSID, 3); 6869566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 6877a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 68848a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 6896f3c3dcfSJed Brown 6906f3c3dcfSJed Brown /* loop over packed objects, handling one at at time */ 6916f3c3dcfSJed Brown for (next = com->next, i = 0; next; next = next->next, i++) { 6926f3c3dcfSJed Brown if (lvecs[i]) { 6936f3c3dcfSJed Brown PetscScalar *array; 6946f3c3dcfSJed Brown Vec global; 695064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(lvecs[i], VEC_CLASSID, 4); 6969566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(next->dm, &global)); 6979566063dSJacob Faibussowitsch PetscCall(VecGetArray(gvec, &array)); 6989566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(global, array + next->rstart)); 6999566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(next->dm, lvecs[i], imode, global)); 7009566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(next->dm, lvecs[i], imode, global)); 7019566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(gvec, &array)); 7029566063dSJacob Faibussowitsch PetscCall(VecResetArray(global)); 7039566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(next->dm, &global)); 7046f3c3dcfSJed Brown } 7056f3c3dcfSJed Brown } 7066f3c3dcfSJed Brown PetscFunctionReturn(0); 7076f3c3dcfSJed Brown } 7086f3c3dcfSJed Brown 709f5f57ec0SBarry Smith /*@ 710*dce8aebaSBarry Smith DMCompositeAddDM - adds a `DM` vector to a `DMCOMPOSITE` 71147c6ae99SBarry Smith 712d083f849SBarry Smith Collective on dm 71347c6ae99SBarry Smith 714d8d19677SJose E. Roman Input Parameters: 715*dce8aebaSBarry Smith + dmc - the `DMCOMPOSITE` object 716*dce8aebaSBarry Smith - dm - the `DM` object 71747c6ae99SBarry Smith 71847c6ae99SBarry Smith Level: advanced 71947c6ae99SBarry Smith 720*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMDestroy()`, `DMCompositeGather()`, `DMCompositeAddDM()`, `DMCreateGlobalVector()`, 721db781477SPatrick Sanan `DMCompositeScatter()`, `DMCompositeCreate()`, `DMCompositeGetISLocalToGlobalMappings()`, `DMCompositeGetAccess()`, 722db781477SPatrick Sanan `DMCompositeGetLocalVectors()`, `DMCompositeRestoreLocalVectors()`, `DMCompositeGetEntries()` 72347c6ae99SBarry Smith @*/ 724d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeAddDM(DM dmc, DM dm) 725d71ae5a4SJacob Faibussowitsch { 72606ebdd98SJed Brown PetscInt n, nlocal; 72747c6ae99SBarry Smith struct DMCompositeLink *mine, *next; 72806ebdd98SJed Brown Vec global, local; 72947c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dmc->data; 73071b14b3eSStefano Zampini PetscBool flg; 73147c6ae99SBarry Smith 73247c6ae99SBarry Smith PetscFunctionBegin; 73347c6ae99SBarry Smith PetscValidHeaderSpecific(dmc, DM_CLASSID, 1); 73447c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 7359566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dmc, DMCOMPOSITE, &flg)); 7367a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 73747c6ae99SBarry Smith next = com->next; 73828b400f6SJacob Faibussowitsch PetscCheck(!com->setup, PetscObjectComm((PetscObject)dmc), PETSC_ERR_ARG_WRONGSTATE, "Cannot add a DM once you have used the DMComposite"); 73947c6ae99SBarry Smith 74047c6ae99SBarry Smith /* create new link */ 7419566063dSJacob Faibussowitsch PetscCall(PetscNew(&mine)); 7429566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 7439566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dm, &global)); 7449566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(global, &n)); 7459566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dm, &global)); 7469566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &local)); 7479566063dSJacob Faibussowitsch PetscCall(VecGetSize(local, &nlocal)); 7489566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &local)); 7498865f1eaSKarl Rupp 75047c6ae99SBarry Smith mine->n = n; 75106ebdd98SJed Brown mine->nlocal = nlocal; 75247c6ae99SBarry Smith mine->dm = dm; 7530298fd71SBarry Smith mine->next = NULL; 75447c6ae99SBarry Smith com->n += n; 7557ac2b803SAlex Fikl com->nghost += nlocal; 75647c6ae99SBarry Smith 75747c6ae99SBarry Smith /* add to end of list */ 7588865f1eaSKarl Rupp if (!next) com->next = mine; 7598865f1eaSKarl Rupp else { 76047c6ae99SBarry Smith while (next->next) next = next->next; 76147c6ae99SBarry Smith next->next = mine; 76247c6ae99SBarry Smith } 76347c6ae99SBarry Smith com->nDM++; 76447c6ae99SBarry Smith com->nmine++; 76547c6ae99SBarry Smith PetscFunctionReturn(0); 76647c6ae99SBarry Smith } 76747c6ae99SBarry Smith 7689804daf3SBarry Smith #include <petscdraw.h> 76926887b52SJed Brown PETSC_EXTERN PetscErrorCode VecView_MPI(Vec, PetscViewer); 770d71ae5a4SJacob Faibussowitsch PetscErrorCode VecView_DMComposite(Vec gvec, PetscViewer viewer) 771d71ae5a4SJacob Faibussowitsch { 77247c6ae99SBarry Smith DM dm; 77347c6ae99SBarry Smith struct DMCompositeLink *next; 77447c6ae99SBarry Smith PetscBool isdraw; 775cef07954SSatish Balay DM_Composite *com; 77647c6ae99SBarry Smith 77747c6ae99SBarry Smith PetscFunctionBegin; 7789566063dSJacob Faibussowitsch PetscCall(VecGetDM(gvec, &dm)); 7797a8be351SBarry Smith PetscCheck(dm, PetscObjectComm((PetscObject)gvec), PETSC_ERR_ARG_WRONG, "Vector not generated from a DMComposite"); 78047c6ae99SBarry Smith com = (DM_Composite *)dm->data; 78147c6ae99SBarry Smith next = com->next; 78247c6ae99SBarry Smith 7839566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 78447c6ae99SBarry Smith if (!isdraw) { 78547c6ae99SBarry Smith /* do I really want to call this? */ 7869566063dSJacob Faibussowitsch PetscCall(VecView_MPI(gvec, viewer)); 78747c6ae99SBarry Smith } else { 78847c6ae99SBarry Smith PetscInt cnt = 0; 78947c6ae99SBarry Smith 79047c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 79147c6ae99SBarry Smith while (next) { 79247c6ae99SBarry Smith Vec vec; 793ca4278abSLisandro Dalcin const PetscScalar *array; 79447c6ae99SBarry Smith PetscInt bs; 79547c6ae99SBarry Smith 7969ae5db72SJed Brown /* Should use VecGetSubVector() eventually, but would need to forward the DM for that to work */ 7979566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(next->dm, &vec)); 7989566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(gvec, &array)); 7999566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(vec, (PetscScalar *)array + next->rstart)); 8009566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(gvec, &array)); 8019566063dSJacob Faibussowitsch PetscCall(VecView(vec, viewer)); 8029566063dSJacob Faibussowitsch PetscCall(VecResetArray(vec)); 8039566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(vec, &bs)); 8049566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(next->dm, &vec)); 8059566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawBaseAdd(viewer, bs)); 80647c6ae99SBarry Smith cnt += bs; 80747c6ae99SBarry Smith next = next->next; 80847c6ae99SBarry Smith } 8099566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawBaseAdd(viewer, -cnt)); 81047c6ae99SBarry Smith } 81147c6ae99SBarry Smith PetscFunctionReturn(0); 81247c6ae99SBarry Smith } 81347c6ae99SBarry Smith 814d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateGlobalVector_Composite(DM dm, Vec *gvec) 815d71ae5a4SJacob Faibussowitsch { 81647c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 81747c6ae99SBarry Smith 81847c6ae99SBarry Smith PetscFunctionBegin; 81947c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8209566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(dm)); 8219566063dSJacob Faibussowitsch PetscCall(DMSetUp(dm)); 8229566063dSJacob Faibussowitsch PetscCall(VecCreate(PetscObjectComm((PetscObject)dm), gvec)); 8239566063dSJacob Faibussowitsch PetscCall(VecSetType(*gvec, dm->vectype)); 8249566063dSJacob Faibussowitsch PetscCall(VecSetSizes(*gvec, com->n, com->N)); 8259566063dSJacob Faibussowitsch PetscCall(VecSetDM(*gvec, dm)); 8269566063dSJacob Faibussowitsch PetscCall(VecSetOperation(*gvec, VECOP_VIEW, (void (*)(void))VecView_DMComposite)); 82747c6ae99SBarry Smith PetscFunctionReturn(0); 82847c6ae99SBarry Smith } 82947c6ae99SBarry Smith 830d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateLocalVector_Composite(DM dm, Vec *lvec) 831d71ae5a4SJacob Faibussowitsch { 83247c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 83347c6ae99SBarry Smith 83447c6ae99SBarry Smith PetscFunctionBegin; 83547c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 83647c6ae99SBarry Smith if (!com->setup) { 8379566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(dm)); 8389566063dSJacob Faibussowitsch PetscCall(DMSetUp(dm)); 83947c6ae99SBarry Smith } 8409566063dSJacob Faibussowitsch PetscCall(VecCreate(PETSC_COMM_SELF, lvec)); 8419566063dSJacob Faibussowitsch PetscCall(VecSetType(*lvec, dm->vectype)); 8429566063dSJacob Faibussowitsch PetscCall(VecSetSizes(*lvec, com->nghost, PETSC_DECIDE)); 8439566063dSJacob Faibussowitsch PetscCall(VecSetDM(*lvec, dm)); 84447c6ae99SBarry Smith PetscFunctionReturn(0); 84547c6ae99SBarry Smith } 84647c6ae99SBarry Smith 84747c6ae99SBarry Smith /*@C 848*dce8aebaSBarry Smith DMCompositeGetISLocalToGlobalMappings - gets an `ISLocalToGlobalMapping` for each `DM` in the `DMCOMPOSITE`, maps to the composite global space 84947c6ae99SBarry Smith 850*dce8aebaSBarry Smith Collective on dm 85147c6ae99SBarry Smith 85247c6ae99SBarry Smith Input Parameter: 853*dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` object 85447c6ae99SBarry Smith 85547c6ae99SBarry Smith Output Parameters: 8569ae5db72SJed Brown . ltogs - the individual mappings for each packed vector. Note that this includes 857*dce8aebaSBarry Smith all the ghost points that individual ghosted `DMDA` may have. 85847c6ae99SBarry Smith 85947c6ae99SBarry Smith Level: advanced 86047c6ae99SBarry Smith 861*dce8aebaSBarry Smith Note: 862*dce8aebaSBarry Smith Each entry of ltogs should be destroyed with `ISLocalToGlobalMappingDestroy()`, the ltogs array should be freed with `PetscFree()`. 86347c6ae99SBarry Smith 864*dce8aebaSBarry Smith Fortran Note: 865f5f57ec0SBarry Smith Not available from Fortran 866f5f57ec0SBarry Smith 867*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMDestroy()`, `DMCompositeAddDM()`, `DMCreateGlobalVector()`, 868db781477SPatrick Sanan `DMCompositeGather()`, `DMCompositeCreate()`, `DMCompositeGetAccess()`, `DMCompositeScatter()`, 869c2e3fba1SPatrick Sanan `DMCompositeGetLocalVectors()`, `DMCompositeRestoreLocalVectors()`, `DMCompositeGetEntries()` 87047c6ae99SBarry Smith @*/ 871d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeGetISLocalToGlobalMappings(DM dm, ISLocalToGlobalMapping **ltogs) 872d71ae5a4SJacob Faibussowitsch { 87347c6ae99SBarry Smith PetscInt i, *idx, n, cnt; 87447c6ae99SBarry Smith struct DMCompositeLink *next; 87547c6ae99SBarry Smith PetscMPIInt rank; 87647c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 87771b14b3eSStefano Zampini PetscBool flg; 87847c6ae99SBarry Smith 87947c6ae99SBarry Smith PetscFunctionBegin; 88047c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8819566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 8827a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 8839566063dSJacob Faibussowitsch PetscCall(DMSetUp(dm)); 8849566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(com->nDM, ltogs)); 88547c6ae99SBarry Smith next = com->next; 8869566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank)); 88747c6ae99SBarry Smith 88847c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 88947c6ae99SBarry Smith cnt = 0; 89047c6ae99SBarry Smith while (next) { 8916eb61c8cSJed Brown ISLocalToGlobalMapping ltog; 8926eb61c8cSJed Brown PetscMPIInt size; 89386994e45SJed Brown const PetscInt *suboff, *indices; 8946eb61c8cSJed Brown Vec global; 89547c6ae99SBarry Smith 8966eb61c8cSJed Brown /* Get sub-DM global indices for each local dof */ 8979566063dSJacob Faibussowitsch PetscCall(DMGetLocalToGlobalMapping(next->dm, <og)); 8989566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetSize(ltog, &n)); 8999566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetIndices(ltog, &indices)); 9009566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &idx)); 90147c6ae99SBarry Smith 9026eb61c8cSJed Brown /* Get the offsets for the sub-DM global vector */ 9039566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(next->dm, &global)); 9049566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRanges(global, &suboff)); 9059566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)global), &size)); 9066eb61c8cSJed Brown 9076eb61c8cSJed Brown /* Shift the sub-DM definition of the global space to the composite global space */ 9086eb61c8cSJed Brown for (i = 0; i < n; i++) { 90986994e45SJed Brown PetscInt subi = indices[i], lo = 0, hi = size, t; 910e333b035SStefano Zampini /* There's no consensus on what a negative index means, 911e333b035SStefano Zampini except for skipping when setting the values in vectors and matrices */ 9129371c9d4SSatish Balay if (subi < 0) { 9139371c9d4SSatish Balay idx[i] = subi - next->grstarts[rank]; 9149371c9d4SSatish Balay continue; 9159371c9d4SSatish Balay } 9166eb61c8cSJed Brown /* Binary search to find which rank owns subi */ 9176eb61c8cSJed Brown while (hi - lo > 1) { 9186eb61c8cSJed Brown t = lo + (hi - lo) / 2; 9196eb61c8cSJed Brown if (suboff[t] > subi) hi = t; 9206eb61c8cSJed Brown else lo = t; 9216eb61c8cSJed Brown } 9226eb61c8cSJed Brown idx[i] = subi - suboff[lo] + next->grstarts[lo]; 9236eb61c8cSJed Brown } 9249566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingRestoreIndices(ltog, &indices)); 9259566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), 1, n, idx, PETSC_OWN_POINTER, &(*ltogs)[cnt])); 9269566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(next->dm, &global)); 92747c6ae99SBarry Smith next = next->next; 92847c6ae99SBarry Smith cnt++; 92947c6ae99SBarry Smith } 93047c6ae99SBarry Smith PetscFunctionReturn(0); 93147c6ae99SBarry Smith } 93247c6ae99SBarry Smith 93387c85e80SJed Brown /*@C 9349ae5db72SJed Brown DMCompositeGetLocalISs - Gets index sets for each component of a composite local vector 93587c85e80SJed Brown 93687c85e80SJed Brown Not Collective 93787c85e80SJed Brown 9384165533cSJose E. Roman Input Parameter: 939*dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` 94087c85e80SJed Brown 9414165533cSJose E. Roman Output Parameter: 942*dce8aebaSBarry Smith . is - array of serial index sets for each each component of the `DMCOMPOSITE` 94387c85e80SJed Brown 94487c85e80SJed Brown Level: intermediate 94587c85e80SJed Brown 94687c85e80SJed Brown Notes: 94787c85e80SJed Brown At present, a composite local vector does not normally exist. This function is used to provide index sets for 948*dce8aebaSBarry Smith `MatGetLocalSubMatrix()`. In the future, the scatters for each entry in the `DMCOMPOSITE` may be be merged into a single 9499ae5db72SJed Brown scatter to a composite local vector. The user should not typically need to know which is being done. 95087c85e80SJed Brown 951*dce8aebaSBarry Smith To get the composite global indices at all local points (including ghosts), use `DMCompositeGetISLocalToGlobalMappings()`. 95287c85e80SJed Brown 953*dce8aebaSBarry Smith To get index sets for pieces of the composite global vector, use `DMCompositeGetGlobalISs()`. 95487c85e80SJed Brown 955*dce8aebaSBarry Smith Each returned `IS` should be destroyed with `ISDestroy()`, the array should be freed with `PetscFree()`. 95687c85e80SJed Brown 957*dce8aebaSBarry Smith Fortran Note: 958f5f57ec0SBarry Smith Not available from Fortran 959f5f57ec0SBarry Smith 960*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMCompositeGetGlobalISs()`, `DMCompositeGetISLocalToGlobalMappings()`, `MatGetLocalSubMatrix()`, `MatCreateLocalRef()` 96187c85e80SJed Brown @*/ 962d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeGetLocalISs(DM dm, IS **is) 963d71ae5a4SJacob Faibussowitsch { 96487c85e80SJed Brown DM_Composite *com = (DM_Composite *)dm->data; 96587c85e80SJed Brown struct DMCompositeLink *link; 96687c85e80SJed Brown PetscInt cnt, start; 96771b14b3eSStefano Zampini PetscBool flg; 96887c85e80SJed Brown 96987c85e80SJed Brown PetscFunctionBegin; 97087c85e80SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 97187c85e80SJed Brown PetscValidPointer(is, 2); 9729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 9737a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 9749566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(com->nmine, is)); 97506ebdd98SJed Brown for (cnt = 0, start = 0, link = com->next; link; start += link->nlocal, cnt++, link = link->next) { 976520db06cSJed Brown PetscInt bs; 9779566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, link->nlocal, start, 1, &(*is)[cnt])); 9789566063dSJacob Faibussowitsch PetscCall(DMGetBlockSize(link->dm, &bs)); 9799566063dSJacob Faibussowitsch PetscCall(ISSetBlockSize((*is)[cnt], bs)); 980520db06cSJed Brown } 98187c85e80SJed Brown PetscFunctionReturn(0); 98287c85e80SJed Brown } 98387c85e80SJed Brown 98447c6ae99SBarry Smith /*@C 985*dce8aebaSBarry Smith DMCompositeGetGlobalISs - Gets the index sets for each composed object in a `DMCOMPOSITE` 98647c6ae99SBarry Smith 987d083f849SBarry Smith Collective on dm 98847c6ae99SBarry Smith 98947c6ae99SBarry Smith Input Parameter: 990*dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` object 99147c6ae99SBarry Smith 99247c6ae99SBarry Smith Output Parameters: 99347c6ae99SBarry Smith . is - the array of index sets 99447c6ae99SBarry Smith 99547c6ae99SBarry Smith Level: advanced 99647c6ae99SBarry Smith 99747c6ae99SBarry Smith Notes: 998*dce8aebaSBarry Smith The is entries should be destroyed with `ISDestroy()`, the is array should be freed with `PetscFree()` 99947c6ae99SBarry Smith 100047c6ae99SBarry Smith These could be used to extract a subset of vector entries for a "multi-physics" preconditioner 100147c6ae99SBarry Smith 1002*dce8aebaSBarry Smith Use `DMCompositeGetLocalISs()` for index sets in the packed local numbering, and 1003*dce8aebaSBarry Smith `DMCompositeGetISLocalToGlobalMappings()` for to map local sub-`DM` (including ghost) indices to packed global 10046eb61c8cSJed Brown indices. 100547c6ae99SBarry Smith 1006*dce8aebaSBarry Smith Fortran Note: 1007*dce8aebaSBarry Smith The output argument 'is' must be an allocated array of sufficient length, which can be learned using `DMCompositeGetNumberDM()`. 1008f3cb0f7eSJed Brown 1009*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMDestroy()`, `DMCompositeAddDM()`, `DMCreateGlobalVector()`, 1010db781477SPatrick Sanan `DMCompositeGather()`, `DMCompositeCreate()`, `DMCompositeGetAccess()`, `DMCompositeScatter()`, 1011c2e3fba1SPatrick Sanan `DMCompositeGetLocalVectors()`, `DMCompositeRestoreLocalVectors()`, `DMCompositeGetEntries()` 101247c6ae99SBarry Smith @*/ 1013d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeGetGlobalISs(DM dm, IS *is[]) 1014d71ae5a4SJacob Faibussowitsch { 101566bb578eSMark Adams PetscInt cnt = 0; 101647c6ae99SBarry Smith struct DMCompositeLink *next; 101747c6ae99SBarry Smith PetscMPIInt rank; 101847c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 101971b14b3eSStefano Zampini PetscBool flg; 102047c6ae99SBarry Smith 102147c6ae99SBarry Smith PetscFunctionBegin; 102247c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10239566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 10247a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 10257a8be351SBarry Smith PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Must call DMSetUp() before"); 10269566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(com->nDM, is)); 102747c6ae99SBarry Smith next = com->next; 10289566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank)); 102947c6ae99SBarry Smith 103047c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 103147c6ae99SBarry Smith while (next) { 1032e5e52638SMatthew G. Knepley PetscDS prob; 1033e5e52638SMatthew G. Knepley 10349566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PetscObjectComm((PetscObject)dm), next->n, next->grstart, 1, &(*is)[cnt])); 10359566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 1036e5e52638SMatthew G. Knepley if (prob) { 103765c226d8SMatthew G. Knepley MatNullSpace space; 103865c226d8SMatthew G. Knepley Mat pmat; 10390f21e855SMatthew G. Knepley PetscObject disc; 10400f21e855SMatthew G. Knepley PetscInt Nf; 104165c226d8SMatthew G. Knepley 10429566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 1043f24dd8d2SMatthew G. Knepley if (cnt < Nf) { 10449566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, cnt, &disc)); 10459566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery(disc, "nullspace", (PetscObject *)&space)); 10469566063dSJacob Faibussowitsch if (space) PetscCall(PetscObjectCompose((PetscObject)(*is)[cnt], "nullspace", (PetscObject)space)); 10479566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery(disc, "nearnullspace", (PetscObject *)&space)); 10489566063dSJacob Faibussowitsch if (space) PetscCall(PetscObjectCompose((PetscObject)(*is)[cnt], "nearnullspace", (PetscObject)space)); 10499566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery(disc, "pmat", (PetscObject *)&pmat)); 10509566063dSJacob Faibussowitsch if (pmat) PetscCall(PetscObjectCompose((PetscObject)(*is)[cnt], "pmat", (PetscObject)pmat)); 105165c226d8SMatthew G. Knepley } 1052f24dd8d2SMatthew G. Knepley } 105347c6ae99SBarry Smith cnt++; 105447c6ae99SBarry Smith next = next->next; 105547c6ae99SBarry Smith } 105647c6ae99SBarry Smith PetscFunctionReturn(0); 105747c6ae99SBarry Smith } 105847c6ae99SBarry Smith 1059d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFieldIS_Composite(DM dm, PetscInt *numFields, char ***fieldNames, IS **fields) 1060d71ae5a4SJacob Faibussowitsch { 10614d343eeaSMatthew G Knepley PetscInt nDM; 10624d343eeaSMatthew G Knepley DM *dms; 10634d343eeaSMatthew G Knepley PetscInt i; 10644d343eeaSMatthew G Knepley 10654d343eeaSMatthew G Knepley PetscFunctionBegin; 10669566063dSJacob Faibussowitsch PetscCall(DMCompositeGetNumberDM(dm, &nDM)); 10678865f1eaSKarl Rupp if (numFields) *numFields = nDM; 10689566063dSJacob Faibussowitsch PetscCall(DMCompositeGetGlobalISs(dm, fields)); 10694d343eeaSMatthew G Knepley if (fieldNames) { 10709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nDM, &dms)); 10719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nDM, fieldNames)); 10729566063dSJacob Faibussowitsch PetscCall(DMCompositeGetEntriesArray(dm, dms)); 10734d343eeaSMatthew G Knepley for (i = 0; i < nDM; i++) { 10744d343eeaSMatthew G Knepley char buf[256]; 10754d343eeaSMatthew G Knepley const char *splitname; 10764d343eeaSMatthew G Knepley 10774d343eeaSMatthew G Knepley /* Split naming precedence: object name, prefix, number */ 10784d343eeaSMatthew G Knepley splitname = ((PetscObject)dm)->name; 10794d343eeaSMatthew G Knepley if (!splitname) { 10809566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dms[i], &splitname)); 10814d343eeaSMatthew G Knepley if (splitname) { 10824d343eeaSMatthew G Knepley size_t len; 10839566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(buf, splitname, sizeof(buf))); 10848caf3d72SBarry Smith buf[sizeof(buf) - 1] = 0; 10859566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &len)); 10864d343eeaSMatthew G Knepley if (buf[len - 1] == '_') buf[len - 1] = 0; /* Remove trailing underscore if it was used */ 10874d343eeaSMatthew G Knepley splitname = buf; 10884d343eeaSMatthew G Knepley } 10894d343eeaSMatthew G Knepley } 10904d343eeaSMatthew G Knepley if (!splitname) { 109163a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(buf, sizeof(buf), "%" PetscInt_FMT, i)); 10924d343eeaSMatthew G Knepley splitname = buf; 10934d343eeaSMatthew G Knepley } 10949566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(splitname, &(*fieldNames)[i])); 10954d343eeaSMatthew G Knepley } 10969566063dSJacob Faibussowitsch PetscCall(PetscFree(dms)); 10974d343eeaSMatthew G Knepley } 10984d343eeaSMatthew G Knepley PetscFunctionReturn(0); 10994d343eeaSMatthew G Knepley } 11004d343eeaSMatthew G Knepley 1101e7c4fc90SDmitry Karpeev /* 1102e7c4fc90SDmitry Karpeev This could take over from DMCreateFieldIS(), as it is more general, 11030298fd71SBarry Smith making DMCreateFieldIS() a special case -- calling with dmlist == NULL; 1104e7c4fc90SDmitry Karpeev At this point it's probably best to be less intrusive, however. 1105e7c4fc90SDmitry Karpeev */ 1106d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateFieldDecomposition_Composite(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist) 1107d71ae5a4SJacob Faibussowitsch { 1108e7c4fc90SDmitry Karpeev PetscInt nDM; 1109e7c4fc90SDmitry Karpeev PetscInt i; 1110e7c4fc90SDmitry Karpeev 1111e7c4fc90SDmitry Karpeev PetscFunctionBegin; 11129566063dSJacob Faibussowitsch PetscCall(DMCreateFieldIS_Composite(dm, len, namelist, islist)); 1113e7c4fc90SDmitry Karpeev if (dmlist) { 11149566063dSJacob Faibussowitsch PetscCall(DMCompositeGetNumberDM(dm, &nDM)); 11159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nDM, dmlist)); 11169566063dSJacob Faibussowitsch PetscCall(DMCompositeGetEntriesArray(dm, *dmlist)); 111748a46eb9SPierre Jolivet for (i = 0; i < nDM; i++) PetscCall(PetscObjectReference((PetscObject)((*dmlist)[i]))); 1118e7c4fc90SDmitry Karpeev } 1119e7c4fc90SDmitry Karpeev PetscFunctionReturn(0); 1120e7c4fc90SDmitry Karpeev } 1121e7c4fc90SDmitry Karpeev 112247c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 112347c6ae99SBarry Smith /*@C 1124*dce8aebaSBarry Smith DMCompositeGetLocalVectors - Gets local vectors for each part of a `DMCOMPOSITE` 1125*dce8aebaSBarry Smith Use `DMCompositeRestoreLocalVectors()` to return them. 112647c6ae99SBarry Smith 112747c6ae99SBarry Smith Not Collective 112847c6ae99SBarry Smith 112947c6ae99SBarry Smith Input Parameter: 1130*dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` object 113147c6ae99SBarry Smith 113247c6ae99SBarry Smith Output Parameter: 11339ae5db72SJed Brown . Vec ... - the individual sequential Vecs 113447c6ae99SBarry Smith 113547c6ae99SBarry Smith Level: advanced 113647c6ae99SBarry Smith 1137*dce8aebaSBarry Smith Fortran Note: 1138f5f57ec0SBarry Smith Not available from Fortran 1139f5f57ec0SBarry Smith 1140*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMDestroy()`, `DMCompositeAddDM()`, `DMCreateGlobalVector()`, 1141db781477SPatrick Sanan `DMCompositeGather()`, `DMCompositeCreate()`, `DMCompositeGetISLocalToGlobalMappings()`, `DMCompositeGetAccess()`, 1142db781477SPatrick Sanan `DMCompositeRestoreLocalVectors()`, `DMCompositeScatter()`, `DMCompositeGetEntries()` 114347c6ae99SBarry Smith @*/ 1144d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeGetLocalVectors(DM dm, ...) 1145d71ae5a4SJacob Faibussowitsch { 114647c6ae99SBarry Smith va_list Argp; 114747c6ae99SBarry Smith struct DMCompositeLink *next; 114847c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 114971b14b3eSStefano Zampini PetscBool flg; 115047c6ae99SBarry Smith 115147c6ae99SBarry Smith PetscFunctionBegin; 115247c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 11539566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 11547a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 115547c6ae99SBarry Smith next = com->next; 115647c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 115747c6ae99SBarry Smith va_start(Argp, dm); 115847c6ae99SBarry Smith while (next) { 115947c6ae99SBarry Smith Vec *vec; 116047c6ae99SBarry Smith vec = va_arg(Argp, Vec *); 11619566063dSJacob Faibussowitsch if (vec) PetscCall(DMGetLocalVector(next->dm, vec)); 116247c6ae99SBarry Smith next = next->next; 116347c6ae99SBarry Smith } 116447c6ae99SBarry Smith va_end(Argp); 116547c6ae99SBarry Smith PetscFunctionReturn(0); 116647c6ae99SBarry Smith } 116747c6ae99SBarry Smith 116847c6ae99SBarry Smith /*@C 1169*dce8aebaSBarry Smith DMCompositeRestoreLocalVectors - Restores local vectors for each part of a `DMCOMPOSITE` 117047c6ae99SBarry Smith 117147c6ae99SBarry Smith Not Collective 117247c6ae99SBarry Smith 117347c6ae99SBarry Smith Input Parameter: 1174*dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` object 117547c6ae99SBarry Smith 117647c6ae99SBarry Smith Output Parameter: 1177*dce8aebaSBarry Smith . Vec ... - the individual sequential `Vec` 117847c6ae99SBarry Smith 117947c6ae99SBarry Smith Level: advanced 118047c6ae99SBarry Smith 1181*dce8aebaSBarry Smith Fortran Note: 1182f5f57ec0SBarry Smith Not available from Fortran 1183f5f57ec0SBarry Smith 1184*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMDestroy()`, `DMCompositeAddDM()`, `DMCreateGlobalVector()`, 1185db781477SPatrick Sanan `DMCompositeGather()`, `DMCompositeCreate()`, `DMCompositeGetISLocalToGlobalMappings()`, `DMCompositeGetAccess()`, 1186db781477SPatrick Sanan `DMCompositeGetLocalVectors()`, `DMCompositeScatter()`, `DMCompositeGetEntries()` 118747c6ae99SBarry Smith @*/ 1188d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeRestoreLocalVectors(DM dm, ...) 1189d71ae5a4SJacob Faibussowitsch { 119047c6ae99SBarry Smith va_list Argp; 119147c6ae99SBarry Smith struct DMCompositeLink *next; 119247c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 119371b14b3eSStefano Zampini PetscBool flg; 119447c6ae99SBarry Smith 119547c6ae99SBarry Smith PetscFunctionBegin; 119647c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 11979566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 11987a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 119947c6ae99SBarry Smith next = com->next; 120047c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 120147c6ae99SBarry Smith va_start(Argp, dm); 120247c6ae99SBarry Smith while (next) { 120347c6ae99SBarry Smith Vec *vec; 120447c6ae99SBarry Smith vec = va_arg(Argp, Vec *); 12059566063dSJacob Faibussowitsch if (vec) PetscCall(DMRestoreLocalVector(next->dm, vec)); 120647c6ae99SBarry Smith next = next->next; 120747c6ae99SBarry Smith } 120847c6ae99SBarry Smith va_end(Argp); 120947c6ae99SBarry Smith PetscFunctionReturn(0); 121047c6ae99SBarry Smith } 121147c6ae99SBarry Smith 121247c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 121347c6ae99SBarry Smith /*@C 1214*dce8aebaSBarry Smith DMCompositeGetEntries - Gets the `DM` for each entry in a `DMCOMPOSITE`. 121547c6ae99SBarry Smith 121647c6ae99SBarry Smith Not Collective 121747c6ae99SBarry Smith 121847c6ae99SBarry Smith Input Parameter: 1219*dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` object 122047c6ae99SBarry Smith 122147c6ae99SBarry Smith Output Parameter: 1222*dce8aebaSBarry Smith . DM ... - the individual entries `DM` 122347c6ae99SBarry Smith 122447c6ae99SBarry Smith Level: advanced 122547c6ae99SBarry Smith 1226*dce8aebaSBarry Smith Fortran Note: 1227*dce8aebaSBarry Smith Available as `DMCompositeGetEntries()` for one output `DM`, DMCompositeGetEntries2() for 2, etc 1228f5f57ec0SBarry Smith 1229*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMDestroy()`, `DMCompositeAddDM()`, `DMCreateGlobalVector()`, `DMCompositeGetEntriesArray()` 1230db781477SPatrick Sanan `DMCompositeGather()`, `DMCompositeCreate()`, `DMCompositeGetISLocalToGlobalMappings()`, `DMCompositeGetAccess()`, 1231db781477SPatrick Sanan `DMCompositeRestoreLocalVectors()`, `DMCompositeGetLocalVectors()`, `DMCompositeScatter()`, 1232db781477SPatrick Sanan `DMCompositeGetLocalVectors()`, `DMCompositeRestoreLocalVectors()` 123347c6ae99SBarry Smith @*/ 1234d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeGetEntries(DM dm, ...) 1235d71ae5a4SJacob Faibussowitsch { 123647c6ae99SBarry Smith va_list Argp; 123747c6ae99SBarry Smith struct DMCompositeLink *next; 123847c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 123971b14b3eSStefano Zampini PetscBool flg; 124047c6ae99SBarry Smith 124147c6ae99SBarry Smith PetscFunctionBegin; 124247c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 12439566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 12447a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 124547c6ae99SBarry Smith next = com->next; 124647c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 124747c6ae99SBarry Smith va_start(Argp, dm); 124847c6ae99SBarry Smith while (next) { 124947c6ae99SBarry Smith DM *dmn; 125047c6ae99SBarry Smith dmn = va_arg(Argp, DM *); 12519ae5db72SJed Brown if (dmn) *dmn = next->dm; 125247c6ae99SBarry Smith next = next->next; 125347c6ae99SBarry Smith } 125447c6ae99SBarry Smith va_end(Argp); 125547c6ae99SBarry Smith PetscFunctionReturn(0); 125647c6ae99SBarry Smith } 125747c6ae99SBarry Smith 1258dbab29e1SMark F. Adams /*@C 1259*dce8aebaSBarry Smith DMCompositeGetEntriesArray - Gets the DM for each entry in a `DMCOMPOSITE` 12602fa5ba8aSJed Brown 12612fa5ba8aSJed Brown Not Collective 12622fa5ba8aSJed Brown 12632fa5ba8aSJed Brown Input Parameter: 1264*dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` object 1265907376e6SBarry Smith 1266907376e6SBarry Smith Output Parameter: 1267*dce8aebaSBarry Smith . dms - array of sufficient length (see `DMCompositeGetNumberDM()`) to hold the individual `DM` 12682fa5ba8aSJed Brown 12692fa5ba8aSJed Brown Level: advanced 12702fa5ba8aSJed Brown 1271*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMDestroy()`, `DMCompositeAddDM()`, `DMCreateGlobalVector()`, `DMCompositeGetEntries()` 1272db781477SPatrick Sanan `DMCompositeGather()`, `DMCompositeCreate()`, `DMCompositeGetISLocalToGlobalMappings()`, `DMCompositeGetAccess()`, 1273db781477SPatrick Sanan `DMCompositeRestoreLocalVectors()`, `DMCompositeGetLocalVectors()`, `DMCompositeScatter()`, 1274db781477SPatrick Sanan `DMCompositeGetLocalVectors()`, `DMCompositeRestoreLocalVectors()` 12752fa5ba8aSJed Brown @*/ 1276d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeGetEntriesArray(DM dm, DM dms[]) 1277d71ae5a4SJacob Faibussowitsch { 12782fa5ba8aSJed Brown struct DMCompositeLink *next; 12792fa5ba8aSJed Brown DM_Composite *com = (DM_Composite *)dm->data; 12802fa5ba8aSJed Brown PetscInt i; 128171b14b3eSStefano Zampini PetscBool flg; 12822fa5ba8aSJed Brown 12832fa5ba8aSJed Brown PetscFunctionBegin; 12842fa5ba8aSJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 12859566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMCOMPOSITE, &flg)); 12867a8be351SBarry Smith PetscCheck(flg, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Not for type %s", ((PetscObject)dm)->type_name); 12872fa5ba8aSJed Brown /* loop over packed objects, handling one at at time */ 12882fa5ba8aSJed Brown for (next = com->next, i = 0; next; next = next->next, i++) dms[i] = next->dm; 12892fa5ba8aSJed Brown PetscFunctionReturn(0); 12902fa5ba8aSJed Brown } 12912fa5ba8aSJed Brown 1292e10fd815SStefano Zampini typedef struct { 1293e10fd815SStefano Zampini DM dm; 1294e10fd815SStefano Zampini PetscViewer *subv; 1295e10fd815SStefano Zampini Vec *vecs; 1296e10fd815SStefano Zampini } GLVisViewerCtx; 1297e10fd815SStefano Zampini 1298d71ae5a4SJacob Faibussowitsch static PetscErrorCode DestroyGLVisViewerCtx_Private(void *vctx) 1299d71ae5a4SJacob Faibussowitsch { 1300e10fd815SStefano Zampini GLVisViewerCtx *ctx = (GLVisViewerCtx *)vctx; 1301e10fd815SStefano Zampini PetscInt i, n; 1302e10fd815SStefano Zampini 1303e10fd815SStefano Zampini PetscFunctionBegin; 13049566063dSJacob Faibussowitsch PetscCall(DMCompositeGetNumberDM(ctx->dm, &n)); 130548a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(PetscViewerDestroy(&ctx->subv[i])); 13069566063dSJacob Faibussowitsch PetscCall(PetscFree2(ctx->subv, ctx->vecs)); 13079566063dSJacob Faibussowitsch PetscCall(DMDestroy(&ctx->dm)); 13089566063dSJacob Faibussowitsch PetscCall(PetscFree(ctx)); 1309e10fd815SStefano Zampini PetscFunctionReturn(0); 1310e10fd815SStefano Zampini } 1311e10fd815SStefano Zampini 1312d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCompositeSampleGLVisFields_Private(PetscObject oX, PetscInt nf, PetscObject oXfield[], void *vctx) 1313d71ae5a4SJacob Faibussowitsch { 1314e10fd815SStefano Zampini Vec X = (Vec)oX; 1315e10fd815SStefano Zampini GLVisViewerCtx *ctx = (GLVisViewerCtx *)vctx; 1316e10fd815SStefano Zampini PetscInt i, n, cumf; 1317e10fd815SStefano Zampini 1318e10fd815SStefano Zampini PetscFunctionBegin; 13199566063dSJacob Faibussowitsch PetscCall(DMCompositeGetNumberDM(ctx->dm, &n)); 13209566063dSJacob Faibussowitsch PetscCall(DMCompositeGetAccessArray(ctx->dm, X, n, NULL, ctx->vecs)); 1321e10fd815SStefano Zampini for (i = 0, cumf = 0; i < n; i++) { 1322e10fd815SStefano Zampini PetscErrorCode (*g2l)(PetscObject, PetscInt, PetscObject[], void *); 1323e10fd815SStefano Zampini void *fctx; 1324e10fd815SStefano Zampini PetscInt nfi; 1325e10fd815SStefano Zampini 13269566063dSJacob Faibussowitsch PetscCall(PetscViewerGLVisGetFields_Private(ctx->subv[i], &nfi, NULL, NULL, &g2l, NULL, &fctx)); 1327e10fd815SStefano Zampini if (!nfi) continue; 13281baa6e33SBarry Smith if (g2l) PetscCall((*g2l)((PetscObject)ctx->vecs[i], nfi, oXfield + cumf, fctx)); 13291baa6e33SBarry Smith else PetscCall(VecCopy(ctx->vecs[i], (Vec)(oXfield[cumf]))); 1330e10fd815SStefano Zampini cumf += nfi; 1331e10fd815SStefano Zampini } 13329566063dSJacob Faibussowitsch PetscCall(DMCompositeRestoreAccessArray(ctx->dm, X, n, NULL, ctx->vecs)); 1333e10fd815SStefano Zampini PetscFunctionReturn(0); 1334e10fd815SStefano Zampini } 1335e10fd815SStefano Zampini 1336d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSetUpGLVisViewer_Composite(PetscObject odm, PetscViewer viewer) 1337d71ae5a4SJacob Faibussowitsch { 1338e10fd815SStefano Zampini DM dm = (DM)odm, *dms; 1339e10fd815SStefano Zampini Vec *Ufds; 1340e10fd815SStefano Zampini GLVisViewerCtx *ctx; 1341e10fd815SStefano Zampini PetscInt i, n, tnf, *sdim; 1342e10fd815SStefano Zampini char **fecs; 1343e10fd815SStefano Zampini 1344e10fd815SStefano Zampini PetscFunctionBegin; 13459566063dSJacob Faibussowitsch PetscCall(PetscNew(&ctx)); 13469566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 1347e10fd815SStefano Zampini ctx->dm = dm; 13489566063dSJacob Faibussowitsch PetscCall(DMCompositeGetNumberDM(dm, &n)); 13499566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &dms)); 13509566063dSJacob Faibussowitsch PetscCall(DMCompositeGetEntriesArray(dm, dms)); 13519566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(n, &ctx->subv, n, &ctx->vecs)); 1352e10fd815SStefano Zampini for (i = 0, tnf = 0; i < n; i++) { 1353e10fd815SStefano Zampini PetscInt nf; 1354e10fd815SStefano Zampini 13559566063dSJacob Faibussowitsch PetscCall(PetscViewerCreate(PetscObjectComm(odm), &ctx->subv[i])); 13569566063dSJacob Faibussowitsch PetscCall(PetscViewerSetType(ctx->subv[i], PETSCVIEWERGLVIS)); 13579566063dSJacob Faibussowitsch PetscCall(PetscViewerGLVisSetDM_Private(ctx->subv[i], (PetscObject)dms[i])); 13589566063dSJacob Faibussowitsch PetscCall(PetscViewerGLVisGetFields_Private(ctx->subv[i], &nf, NULL, NULL, NULL, NULL, NULL)); 1359e10fd815SStefano Zampini tnf += nf; 1360e10fd815SStefano Zampini } 13619566063dSJacob Faibussowitsch PetscCall(PetscFree(dms)); 13629566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(tnf, &fecs, tnf, &sdim, tnf, &Ufds)); 1363e10fd815SStefano Zampini for (i = 0, tnf = 0; i < n; i++) { 1364e10fd815SStefano Zampini PetscInt *sd, nf, f; 1365e10fd815SStefano Zampini const char **fec; 1366e10fd815SStefano Zampini Vec *Uf; 1367e10fd815SStefano Zampini 13689566063dSJacob Faibussowitsch PetscCall(PetscViewerGLVisGetFields_Private(ctx->subv[i], &nf, &fec, &sd, NULL, (PetscObject **)&Uf, NULL)); 1369e10fd815SStefano Zampini for (f = 0; f < nf; f++) { 13709566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(fec[f], &fecs[tnf + f])); 1371e10fd815SStefano Zampini Ufds[tnf + f] = Uf[f]; 1372e10fd815SStefano Zampini sdim[tnf + f] = sd[f]; 1373e10fd815SStefano Zampini } 1374e10fd815SStefano Zampini tnf += nf; 1375e10fd815SStefano Zampini } 13769566063dSJacob Faibussowitsch PetscCall(PetscViewerGLVisSetFields(viewer, tnf, (const char **)fecs, sdim, DMCompositeSampleGLVisFields_Private, (PetscObject *)Ufds, ctx, DestroyGLVisViewerCtx_Private)); 137748a46eb9SPierre Jolivet for (i = 0; i < tnf; i++) PetscCall(PetscFree(fecs[i])); 13789566063dSJacob Faibussowitsch PetscCall(PetscFree3(fecs, sdim, Ufds)); 1379e10fd815SStefano Zampini PetscFunctionReturn(0); 1380e10fd815SStefano Zampini } 1381e10fd815SStefano Zampini 1382d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefine_Composite(DM dmi, MPI_Comm comm, DM *fine) 1383d71ae5a4SJacob Faibussowitsch { 138447c6ae99SBarry Smith struct DMCompositeLink *next; 138547c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dmi->data; 138647c6ae99SBarry Smith DM dm; 138747c6ae99SBarry Smith 138847c6ae99SBarry Smith PetscFunctionBegin; 138947c6ae99SBarry Smith PetscValidHeaderSpecific(dmi, DM_CLASSID, 1); 139048a46eb9SPierre Jolivet if (comm == MPI_COMM_NULL) PetscCall(PetscObjectGetComm((PetscObject)dmi, &comm)); 13919566063dSJacob Faibussowitsch PetscCall(DMSetUp(dmi)); 139247c6ae99SBarry Smith next = com->next; 13939566063dSJacob Faibussowitsch PetscCall(DMCompositeCreate(comm, fine)); 139447c6ae99SBarry Smith 139547c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 139647c6ae99SBarry Smith while (next) { 13979566063dSJacob Faibussowitsch PetscCall(DMRefine(next->dm, comm, &dm)); 13989566063dSJacob Faibussowitsch PetscCall(DMCompositeAddDM(*fine, dm)); 13999566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)dm)); 140047c6ae99SBarry Smith next = next->next; 140147c6ae99SBarry Smith } 140247c6ae99SBarry Smith PetscFunctionReturn(0); 140347c6ae99SBarry Smith } 140447c6ae99SBarry Smith 1405d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsen_Composite(DM dmi, MPI_Comm comm, DM *fine) 1406d71ae5a4SJacob Faibussowitsch { 140714354c39SJed Brown struct DMCompositeLink *next; 140814354c39SJed Brown DM_Composite *com = (DM_Composite *)dmi->data; 140914354c39SJed Brown DM dm; 141014354c39SJed Brown 141114354c39SJed Brown PetscFunctionBegin; 141214354c39SJed Brown PetscValidHeaderSpecific(dmi, DM_CLASSID, 1); 14139566063dSJacob Faibussowitsch PetscCall(DMSetUp(dmi)); 141448a46eb9SPierre Jolivet if (comm == MPI_COMM_NULL) PetscCall(PetscObjectGetComm((PetscObject)dmi, &comm)); 141514354c39SJed Brown next = com->next; 14169566063dSJacob Faibussowitsch PetscCall(DMCompositeCreate(comm, fine)); 141714354c39SJed Brown 141814354c39SJed Brown /* loop over packed objects, handling one at at time */ 141914354c39SJed Brown while (next) { 14209566063dSJacob Faibussowitsch PetscCall(DMCoarsen(next->dm, comm, &dm)); 14219566063dSJacob Faibussowitsch PetscCall(DMCompositeAddDM(*fine, dm)); 14229566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)dm)); 142314354c39SJed Brown next = next->next; 142414354c39SJed Brown } 142514354c39SJed Brown PetscFunctionReturn(0); 142614354c39SJed Brown } 142747c6ae99SBarry Smith 1428d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateInterpolation_Composite(DM coarse, DM fine, Mat *A, Vec *v) 1429d71ae5a4SJacob Faibussowitsch { 14309ae5db72SJed Brown PetscInt m, n, M, N, nDM, i; 143147c6ae99SBarry Smith struct DMCompositeLink *nextc; 143247c6ae99SBarry Smith struct DMCompositeLink *nextf; 143325296bd5SBarry Smith Vec gcoarse, gfine, *vecs; 143447c6ae99SBarry Smith DM_Composite *comcoarse = (DM_Composite *)coarse->data; 143547c6ae99SBarry Smith DM_Composite *comfine = (DM_Composite *)fine->data; 14369ae5db72SJed Brown Mat *mats; 143747c6ae99SBarry Smith 143847c6ae99SBarry Smith PetscFunctionBegin; 143947c6ae99SBarry Smith PetscValidHeaderSpecific(coarse, DM_CLASSID, 1); 144047c6ae99SBarry Smith PetscValidHeaderSpecific(fine, DM_CLASSID, 2); 14419566063dSJacob Faibussowitsch PetscCall(DMSetUp(coarse)); 14429566063dSJacob Faibussowitsch PetscCall(DMSetUp(fine)); 144347c6ae99SBarry Smith /* use global vectors only for determining matrix layout */ 14449566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(coarse, &gcoarse)); 14459566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(fine, &gfine)); 14469566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(gcoarse, &n)); 14479566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(gfine, &m)); 14489566063dSJacob Faibussowitsch PetscCall(VecGetSize(gcoarse, &N)); 14499566063dSJacob Faibussowitsch PetscCall(VecGetSize(gfine, &M)); 14509566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(coarse, &gcoarse)); 14519566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(fine, &gfine)); 145247c6ae99SBarry Smith 14539ae5db72SJed Brown nDM = comfine->nDM; 145463a3b9bcSJacob Faibussowitsch PetscCheck(nDM == comcoarse->nDM, PetscObjectComm((PetscObject)fine), PETSC_ERR_ARG_INCOMP, "Fine DMComposite has %" PetscInt_FMT " entries, but coarse has %" PetscInt_FMT, nDM, comcoarse->nDM); 14559566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nDM * nDM, &mats)); 145648a46eb9SPierre Jolivet if (v) PetscCall(PetscCalloc1(nDM, &vecs)); 145747c6ae99SBarry Smith 145847c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 14599ae5db72SJed Brown for (nextc = comcoarse->next, nextf = comfine->next, i = 0; nextc; nextc = nextc->next, nextf = nextf->next, i++) { 14601baa6e33SBarry Smith if (!v) PetscCall(DMCreateInterpolation(nextc->dm, nextf->dm, &mats[i * nDM + i], NULL)); 14611baa6e33SBarry Smith else PetscCall(DMCreateInterpolation(nextc->dm, nextf->dm, &mats[i * nDM + i], &vecs[i])); 146247c6ae99SBarry Smith } 14639566063dSJacob Faibussowitsch PetscCall(MatCreateNest(PetscObjectComm((PetscObject)fine), nDM, NULL, nDM, NULL, mats, A)); 14641baa6e33SBarry Smith if (v) PetscCall(VecCreateNest(PetscObjectComm((PetscObject)fine), nDM, NULL, vecs, v)); 14659566063dSJacob Faibussowitsch for (i = 0; i < nDM * nDM; i++) PetscCall(MatDestroy(&mats[i])); 14669566063dSJacob Faibussowitsch PetscCall(PetscFree(mats)); 146725296bd5SBarry Smith if (v) { 14689566063dSJacob Faibussowitsch for (i = 0; i < nDM; i++) PetscCall(VecDestroy(&vecs[i])); 14699566063dSJacob Faibussowitsch PetscCall(PetscFree(vecs)); 147025296bd5SBarry Smith } 147147c6ae99SBarry Smith PetscFunctionReturn(0); 147247c6ae99SBarry Smith } 147347c6ae99SBarry Smith 1474d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMGetLocalToGlobalMapping_Composite(DM dm) 1475d71ae5a4SJacob Faibussowitsch { 14761411c6eeSJed Brown DM_Composite *com = (DM_Composite *)dm->data; 14771411c6eeSJed Brown ISLocalToGlobalMapping *ltogs; 1478f7efa3c7SJed Brown PetscInt i; 14791411c6eeSJed Brown 14801411c6eeSJed Brown PetscFunctionBegin; 14811411c6eeSJed Brown /* Set the ISLocalToGlobalMapping on the new matrix */ 14829566063dSJacob Faibussowitsch PetscCall(DMCompositeGetISLocalToGlobalMappings(dm, <ogs)); 14839566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingConcatenate(PetscObjectComm((PetscObject)dm), com->nDM, ltogs, &dm->ltogmap)); 14849566063dSJacob Faibussowitsch for (i = 0; i < com->nDM; i++) PetscCall(ISLocalToGlobalMappingDestroy(<ogs[i])); 14859566063dSJacob Faibussowitsch PetscCall(PetscFree(ltogs)); 14861411c6eeSJed Brown PetscFunctionReturn(0); 14871411c6eeSJed Brown } 14881411c6eeSJed Brown 1489d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateColoring_Composite(DM dm, ISColoringType ctype, ISColoring *coloring) 1490d71ae5a4SJacob Faibussowitsch { 149147c6ae99SBarry Smith PetscInt n, i, cnt; 149247c6ae99SBarry Smith ISColoringValue *colors; 149347c6ae99SBarry Smith PetscBool dense = PETSC_FALSE; 149447c6ae99SBarry Smith ISColoringValue maxcol = 0; 149547c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 149647c6ae99SBarry Smith 149747c6ae99SBarry Smith PetscFunctionBegin; 149847c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 149908401ef6SPierre Jolivet PetscCheck(ctype != IS_COLORING_LOCAL, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Only global coloring supported"); 1500f7d195e4SLawrence Mitchell if (ctype == IS_COLORING_GLOBAL) { 150147c6ae99SBarry Smith n = com->n; 1502ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Unknown ISColoringType"); 15039566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &colors)); /* freed in ISColoringDestroy() */ 150447c6ae99SBarry Smith 15059566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(((PetscObject)dm)->options, ((PetscObject)dm)->prefix, "-dmcomposite_dense_jacobian", &dense, NULL)); 150647c6ae99SBarry Smith if (dense) { 1507ad540459SPierre Jolivet for (i = 0; i < n; i++) colors[i] = (ISColoringValue)(com->rstart + i); 150847c6ae99SBarry Smith maxcol = com->N; 150947c6ae99SBarry Smith } else { 151047c6ae99SBarry Smith struct DMCompositeLink *next = com->next; 151147c6ae99SBarry Smith PetscMPIInt rank; 151247c6ae99SBarry Smith 15139566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank)); 151447c6ae99SBarry Smith cnt = 0; 151547c6ae99SBarry Smith while (next) { 151647c6ae99SBarry Smith ISColoring lcoloring; 151747c6ae99SBarry Smith 15189566063dSJacob Faibussowitsch PetscCall(DMCreateColoring(next->dm, IS_COLORING_GLOBAL, &lcoloring)); 1519ad540459SPierre Jolivet for (i = 0; i < lcoloring->N; i++) colors[cnt++] = maxcol + lcoloring->colors[i]; 152047c6ae99SBarry Smith maxcol += lcoloring->n; 15219566063dSJacob Faibussowitsch PetscCall(ISColoringDestroy(&lcoloring)); 152247c6ae99SBarry Smith next = next->next; 152347c6ae99SBarry Smith } 152447c6ae99SBarry Smith } 15259566063dSJacob Faibussowitsch PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)dm), maxcol, n, colors, PETSC_OWN_POINTER, coloring)); 152647c6ae99SBarry Smith PetscFunctionReturn(0); 152747c6ae99SBarry Smith } 152847c6ae99SBarry Smith 1529d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalBegin_Composite(DM dm, Vec gvec, InsertMode mode, Vec lvec) 1530d71ae5a4SJacob Faibussowitsch { 153147c6ae99SBarry Smith struct DMCompositeLink *next; 153247c6ae99SBarry Smith PetscScalar *garray, *larray; 153347c6ae99SBarry Smith DM_Composite *com = (DM_Composite *)dm->data; 153447c6ae99SBarry Smith 153547c6ae99SBarry Smith PetscFunctionBegin; 153647c6ae99SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 153747c6ae99SBarry Smith PetscValidHeaderSpecific(gvec, VEC_CLASSID, 2); 153839d35262SVincent Le Chenadec 153948a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 154039d35262SVincent Le Chenadec 15419566063dSJacob Faibussowitsch PetscCall(VecGetArray(gvec, &garray)); 15429566063dSJacob Faibussowitsch PetscCall(VecGetArray(lvec, &larray)); 154347c6ae99SBarry Smith 154447c6ae99SBarry Smith /* loop over packed objects, handling one at at time */ 154539d35262SVincent Le Chenadec next = com->next; 154647c6ae99SBarry Smith while (next) { 154747c6ae99SBarry Smith Vec local, global; 154847c6ae99SBarry Smith PetscInt N; 154947c6ae99SBarry Smith 15509566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(next->dm, &global)); 15519566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(global, &N)); 15529566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(global, garray)); 15539566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(next->dm, &local)); 15549566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(local, larray)); 15559566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(next->dm, global, mode, local)); 15569566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(next->dm, global, mode, local)); 15579566063dSJacob Faibussowitsch PetscCall(VecResetArray(global)); 15589566063dSJacob Faibussowitsch PetscCall(VecResetArray(local)); 15599566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(next->dm, &global)); 15609566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(next->dm, &local)); 156139d35262SVincent Le Chenadec 156206ebdd98SJed Brown larray += next->nlocal; 156339d35262SVincent Le Chenadec garray += next->n; 156447c6ae99SBarry Smith next = next->next; 156547c6ae99SBarry Smith } 156647c6ae99SBarry Smith 15679566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(gvec, NULL)); 15689566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(lvec, NULL)); 156947c6ae99SBarry Smith PetscFunctionReturn(0); 157047c6ae99SBarry Smith } 157147c6ae99SBarry Smith 1572d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalEnd_Composite(DM dm, Vec gvec, InsertMode mode, Vec lvec) 1573d71ae5a4SJacob Faibussowitsch { 15740c010503SBarry Smith PetscFunctionBegin; 157539d35262SVincent Le Chenadec PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 157639d35262SVincent Le Chenadec PetscValidHeaderSpecific(gvec, VEC_CLASSID, 2); 157739d35262SVincent Le Chenadec PetscValidHeaderSpecific(lvec, VEC_CLASSID, 4); 157839d35262SVincent Le Chenadec PetscFunctionReturn(0); 157939d35262SVincent Le Chenadec } 158039d35262SVincent Le Chenadec 1581d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalBegin_Composite(DM dm, Vec lvec, InsertMode mode, Vec gvec) 1582d71ae5a4SJacob Faibussowitsch { 158339d35262SVincent Le Chenadec struct DMCompositeLink *next; 158439d35262SVincent Le Chenadec PetscScalar *larray, *garray; 158539d35262SVincent Le Chenadec DM_Composite *com = (DM_Composite *)dm->data; 158639d35262SVincent Le Chenadec 158739d35262SVincent Le Chenadec PetscFunctionBegin; 158839d35262SVincent Le Chenadec PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 158939d35262SVincent Le Chenadec PetscValidHeaderSpecific(lvec, VEC_CLASSID, 2); 159039d35262SVincent Le Chenadec PetscValidHeaderSpecific(gvec, VEC_CLASSID, 4); 159139d35262SVincent Le Chenadec 159248a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 159339d35262SVincent Le Chenadec 15949566063dSJacob Faibussowitsch PetscCall(VecGetArray(lvec, &larray)); 15959566063dSJacob Faibussowitsch PetscCall(VecGetArray(gvec, &garray)); 159639d35262SVincent Le Chenadec 159739d35262SVincent Le Chenadec /* loop over packed objects, handling one at at time */ 159839d35262SVincent Le Chenadec next = com->next; 159939d35262SVincent Le Chenadec while (next) { 160039d35262SVincent Le Chenadec Vec global, local; 160139d35262SVincent Le Chenadec 16029566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(next->dm, &local)); 16039566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(local, larray)); 16049566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(next->dm, &global)); 16059566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(global, garray)); 16069566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(next->dm, local, mode, global)); 16079566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(next->dm, local, mode, global)); 16089566063dSJacob Faibussowitsch PetscCall(VecResetArray(local)); 16099566063dSJacob Faibussowitsch PetscCall(VecResetArray(global)); 16109566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(next->dm, &global)); 16119566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(next->dm, &local)); 161239d35262SVincent Le Chenadec 161339d35262SVincent Le Chenadec garray += next->n; 161439d35262SVincent Le Chenadec larray += next->nlocal; 161539d35262SVincent Le Chenadec next = next->next; 161639d35262SVincent Le Chenadec } 161739d35262SVincent Le Chenadec 16189566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(gvec, NULL)); 16199566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(lvec, NULL)); 162039d35262SVincent Le Chenadec 162139d35262SVincent Le Chenadec PetscFunctionReturn(0); 162239d35262SVincent Le Chenadec } 162339d35262SVincent Le Chenadec 1624d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalEnd_Composite(DM dm, Vec lvec, InsertMode mode, Vec gvec) 1625d71ae5a4SJacob Faibussowitsch { 162639d35262SVincent Le Chenadec PetscFunctionBegin; 162739d35262SVincent Le Chenadec PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 162839d35262SVincent Le Chenadec PetscValidHeaderSpecific(lvec, VEC_CLASSID, 2); 162939d35262SVincent Le Chenadec PetscValidHeaderSpecific(gvec, VEC_CLASSID, 4); 163039d35262SVincent Le Chenadec PetscFunctionReturn(0); 163139d35262SVincent Le Chenadec } 163239d35262SVincent Le Chenadec 1633d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalBegin_Composite(DM dm, Vec vec1, InsertMode mode, Vec vec2) 1634d71ae5a4SJacob Faibussowitsch { 163539d35262SVincent Le Chenadec struct DMCompositeLink *next; 163639d35262SVincent Le Chenadec PetscScalar *array1, *array2; 163739d35262SVincent Le Chenadec DM_Composite *com = (DM_Composite *)dm->data; 163839d35262SVincent Le Chenadec 163939d35262SVincent Le Chenadec PetscFunctionBegin; 164039d35262SVincent Le Chenadec PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 164139d35262SVincent Le Chenadec PetscValidHeaderSpecific(vec1, VEC_CLASSID, 2); 164239d35262SVincent Le Chenadec PetscValidHeaderSpecific(vec2, VEC_CLASSID, 4); 164339d35262SVincent Le Chenadec 164448a46eb9SPierre Jolivet if (!com->setup) PetscCall(DMSetUp(dm)); 164539d35262SVincent Le Chenadec 16469566063dSJacob Faibussowitsch PetscCall(VecGetArray(vec1, &array1)); 16479566063dSJacob Faibussowitsch PetscCall(VecGetArray(vec2, &array2)); 164839d35262SVincent Le Chenadec 164939d35262SVincent Le Chenadec /* loop over packed objects, handling one at at time */ 165039d35262SVincent Le Chenadec next = com->next; 165139d35262SVincent Le Chenadec while (next) { 165239d35262SVincent Le Chenadec Vec local1, local2; 165339d35262SVincent Le Chenadec 16549566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(next->dm, &local1)); 16559566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(local1, array1)); 16569566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(next->dm, &local2)); 16579566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(local2, array2)); 16589566063dSJacob Faibussowitsch PetscCall(DMLocalToLocalBegin(next->dm, local1, mode, local2)); 16599566063dSJacob Faibussowitsch PetscCall(DMLocalToLocalEnd(next->dm, local1, mode, local2)); 16609566063dSJacob Faibussowitsch PetscCall(VecResetArray(local2)); 16619566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(next->dm, &local2)); 16629566063dSJacob Faibussowitsch PetscCall(VecResetArray(local1)); 16639566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(next->dm, &local1)); 166439d35262SVincent Le Chenadec 166539d35262SVincent Le Chenadec array1 += next->nlocal; 166639d35262SVincent Le Chenadec array2 += next->nlocal; 166739d35262SVincent Le Chenadec next = next->next; 166839d35262SVincent Le Chenadec } 166939d35262SVincent Le Chenadec 16709566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(vec1, NULL)); 16719566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(vec2, NULL)); 167239d35262SVincent Le Chenadec 167339d35262SVincent Le Chenadec PetscFunctionReturn(0); 167439d35262SVincent Le Chenadec } 167539d35262SVincent Le Chenadec 1676d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalEnd_Composite(DM dm, Vec lvec, InsertMode mode, Vec gvec) 1677d71ae5a4SJacob Faibussowitsch { 167839d35262SVincent Le Chenadec PetscFunctionBegin; 167939d35262SVincent Le Chenadec PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 168039d35262SVincent Le Chenadec PetscValidHeaderSpecific(lvec, VEC_CLASSID, 2); 168139d35262SVincent Le Chenadec PetscValidHeaderSpecific(gvec, VEC_CLASSID, 4); 16820c010503SBarry Smith PetscFunctionReturn(0); 16830c010503SBarry Smith } 168447c6ae99SBarry Smith 16856ae3a549SBarry Smith /*MC 1686*dce8aebaSBarry Smith DMCOMPOSITE = "composite" - A `DM` object that is used to manage data for a collection of `DM` 16876ae3a549SBarry Smith 16886ae3a549SBarry Smith Level: intermediate 16896ae3a549SBarry Smith 1690db781477SPatrick Sanan .seealso: `DMType`, `DM`, `DMDACreate()`, `DMCreate()`, `DMSetType()`, `DMCompositeCreate()` 16916ae3a549SBarry Smith M*/ 16926ae3a549SBarry Smith 1693d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMCreate_Composite(DM p) 1694d71ae5a4SJacob Faibussowitsch { 1695a4121054SBarry Smith DM_Composite *com; 1696a4121054SBarry Smith 1697a4121054SBarry Smith PetscFunctionBegin; 16984dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&com)); 1699a4121054SBarry Smith p->data = com; 1700a4121054SBarry Smith com->n = 0; 17017ac2b803SAlex Fikl com->nghost = 0; 17020298fd71SBarry Smith com->next = NULL; 1703a4121054SBarry Smith com->nDM = 0; 1704a4121054SBarry Smith 1705a4121054SBarry Smith p->ops->createglobalvector = DMCreateGlobalVector_Composite; 1706a4121054SBarry Smith p->ops->createlocalvector = DMCreateLocalVector_Composite; 1707184d77edSJed Brown p->ops->getlocaltoglobalmapping = DMGetLocalToGlobalMapping_Composite; 17084d343eeaSMatthew G Knepley p->ops->createfieldis = DMCreateFieldIS_Composite; 170916621825SDmitry Karpeev p->ops->createfielddecomposition = DMCreateFieldDecomposition_Composite; 1710a4121054SBarry Smith p->ops->refine = DMRefine_Composite; 171114354c39SJed Brown p->ops->coarsen = DMCoarsen_Composite; 171225296bd5SBarry Smith p->ops->createinterpolation = DMCreateInterpolation_Composite; 171325296bd5SBarry Smith p->ops->creatematrix = DMCreateMatrix_Composite; 1714e727c939SJed Brown p->ops->getcoloring = DMCreateColoring_Composite; 1715a4121054SBarry Smith p->ops->globaltolocalbegin = DMGlobalToLocalBegin_Composite; 1716a4121054SBarry Smith p->ops->globaltolocalend = DMGlobalToLocalEnd_Composite; 171739d35262SVincent Le Chenadec p->ops->localtoglobalbegin = DMLocalToGlobalBegin_Composite; 171839d35262SVincent Le Chenadec p->ops->localtoglobalend = DMLocalToGlobalEnd_Composite; 171939d35262SVincent Le Chenadec p->ops->localtolocalbegin = DMLocalToLocalBegin_Composite; 172039d35262SVincent Le Chenadec p->ops->localtolocalend = DMLocalToLocalEnd_Composite; 1721a4121054SBarry Smith p->ops->destroy = DMDestroy_Composite; 1722a4121054SBarry Smith p->ops->view = DMView_Composite; 1723a4121054SBarry Smith p->ops->setup = DMSetUp_Composite; 1724e10fd815SStefano Zampini 17259566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)p, "DMSetUpGLVisViewer_C", DMSetUpGLVisViewer_Composite)); 1726a4121054SBarry Smith PetscFunctionReturn(0); 1727a4121054SBarry Smith } 1728a4121054SBarry Smith 17291fd49c25SBarry Smith /*@ 1730*dce8aebaSBarry Smith DMCompositeCreate - Creates a `DMCOMPOSITE`, used to generate "composite" 17310c010503SBarry Smith vectors made up of several subvectors. 17320c010503SBarry Smith 1733d083f849SBarry Smith Collective 173447c6ae99SBarry Smith 173547c6ae99SBarry Smith Input Parameter: 17360c010503SBarry Smith . comm - the processors that will share the global vector 17370c010503SBarry Smith 17380c010503SBarry Smith Output Parameters: 1739*dce8aebaSBarry Smith . packer - the `DMCOMPOSITE` object 174047c6ae99SBarry Smith 174147c6ae99SBarry Smith Level: advanced 174247c6ae99SBarry Smith 1743*dce8aebaSBarry Smith .seealso: `DMCOMPOSITE`, `DM`, `DMDestroy()`, `DMCompositeAddDM()`, `DMCompositeScatter()`, `DMCOMPOSITE`, `DMCreate()` 1744db781477SPatrick Sanan `DMCompositeGather()`, `DMCreateGlobalVector()`, `DMCompositeGetISLocalToGlobalMappings()`, `DMCompositeGetAccess()` 1745db781477SPatrick Sanan `DMCompositeGetLocalVectors()`, `DMCompositeRestoreLocalVectors()`, `DMCompositeGetEntries()` 174647c6ae99SBarry Smith @*/ 1747d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCompositeCreate(MPI_Comm comm, DM *packer) 1748d71ae5a4SJacob Faibussowitsch { 174947c6ae99SBarry Smith PetscFunctionBegin; 17500c010503SBarry Smith PetscValidPointer(packer, 2); 17519566063dSJacob Faibussowitsch PetscCall(DMCreate(comm, packer)); 17529566063dSJacob Faibussowitsch PetscCall(DMSetType(*packer, DMCOMPOSITE)); 175347c6ae99SBarry Smith PetscFunctionReturn(0); 175447c6ae99SBarry Smith } 1755