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 9dce8aebaSBarry 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 19dce8aebaSBarry Smith Note: 20dce8aebaSBarry Smith See `DMSetApplicationContext()` and `DMGetApplicationContext()` for how to get user information into 2147c6ae99SBarry Smith this routine 2247c6ae99SBarry Smith 23dce8aebaSBarry Smith Fortran Note: 24dce8aebaSBarry Smith Not available from Fortran 25dce8aebaSBarry Smith 26dce8aebaSBarry 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; 37*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 57*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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 } 82*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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; 117*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11847c6ae99SBarry Smith } 11947c6ae99SBarry Smith 12047c6ae99SBarry Smith /* ----------------------------------------------------------------------------------*/ 12147c6ae99SBarry Smith 12273e31fe2SJed Brown /*@ 123dce8aebaSBarry 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: 129dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` object 13047c6ae99SBarry Smith 13147c6ae99SBarry Smith Output Parameter: 132dce8aebaSBarry Smith . nDM - the number of `DM` 13347c6ae99SBarry Smith 13447c6ae99SBarry Smith Level: beginner 13547c6ae99SBarry Smith 136dce8aebaSBarry 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; 148*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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: 158dce8aebaSBarry 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 166dce8aebaSBarry Smith Note: 167dce8aebaSBarry Smith Use `DMCompositeRestoreAccess()` to return the vectors when you no longer need them 168dce8aebaSBarry Smith 169dce8aebaSBarry Smith Fortran Note: 170dce8aebaSBarry Smith Fortran callers must use numbered versions of this routine, e.g., DMCompositeGetAccess4(dm,gvec,vec1,vec2,vec3,vec4) 171dce8aebaSBarry Smith or use the alternative interface `DMCompositeGetAccessArray()`. 172dce8aebaSBarry Smith 173dce8aebaSBarry 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); 215*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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: 225dce8aebaSBarry 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 235dce8aebaSBarry Smith Note: 236dce8aebaSBarry Smith Use `DMCompositeRestoreAccessArray()` to return the vectors when you no longer need them 237dce8aebaSBarry Smith 238dce8aebaSBarry 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 } 275*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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: 285dce8aebaSBarry 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 295dce8aebaSBarry Smith Note: 296dce8aebaSBarry Smith Use `DMCompositeRestoreLocalAccessArray()` to return the vectors 297dce8aebaSBarry Smith when you no longer need them. 298dce8aebaSBarry Smith 299dce8aebaSBarry 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 342*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3437ac2b803SAlex Fikl } 3447ac2b803SAlex Fikl 34547c6ae99SBarry Smith /*@C 346dce8aebaSBarry Smith DMCompositeRestoreAccess - Returns the vectors obtained with `DMCompositeGetAccess()` 34747c6ae99SBarry Smith representation. 34847c6ae99SBarry Smith 349d083f849SBarry Smith Collective on dm 35047c6ae99SBarry Smith 3519ae5db72SJed Brown Input Parameters: 352dce8aebaSBarry 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 358dce8aebaSBarry 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); 392*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39347c6ae99SBarry Smith } 39447c6ae99SBarry Smith 395f73e5cebSJed Brown /*@C 396dce8aebaSBarry Smith DMCompositeRestoreAccessArray - Returns the vectors obtained with `DMCompositeGetAccessArray()` 397f73e5cebSJed Brown 398d083f849SBarry Smith Collective on dm 399f73e5cebSJed Brown 400f73e5cebSJed Brown Input Parameters: 401dce8aebaSBarry 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 409dce8aebaSBarry 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 } 435*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 436f73e5cebSJed Brown } 437f73e5cebSJed Brown 4387ac2b803SAlex Fikl /*@C 439dce8aebaSBarry Smith DMCompositeRestoreLocalAccessArray - Returns the vectors obtained with `DMCompositeGetLocalAccessArray()`. 4407ac2b803SAlex Fikl 441d083f849SBarry Smith Collective on dm. 4427ac2b803SAlex Fikl 4437ac2b803SAlex Fikl Input Parameters: 444dce8aebaSBarry 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 452dce8aebaSBarry Smith Note: 453dce8aebaSBarry Smith nwanted and wanted must match the values given to `DMCompositeGetLocalAccessArray()` 4547ac2b803SAlex Fikl otherwise the call will fail. 4557ac2b803SAlex Fikl 456dce8aebaSBarry 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 } 484*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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: 493dce8aebaSBarry 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 499dce8aebaSBarry Smith Note: 500dce8aebaSBarry Smith `DMCompositeScatterArray()` is a non-variadic alternative that is often more convenient for library callers and is 5016f3c3dcfSJed Brown accessible from Fortran. 5026f3c3dcfSJed Brown 503dce8aebaSBarry 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); 543*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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: 552dce8aebaSBarry 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: 559dce8aebaSBarry Smith This is a non-variadic alternative to `DMCompositeScatter()` 5606f3c3dcfSJed Brown 561dce8aebaSBarry 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 } 595*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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: 604dce8aebaSBarry Smith + dm - the `DMCOMPOSITE` object 60547c6ae99SBarry Smith . gvec - the global vector 606dce8aebaSBarry 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 611dce8aebaSBarry Smith Fortran Note: 612dce8aebaSBarry Smith Fortran users should use `DMCompositeGatherArray()` 613f5f57ec0SBarry Smith 614dce8aebaSBarry 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); 653*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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: 662dce8aebaSBarry Smith + dm - the `DMCOMPOSITE` object 6636f3c3dcfSJed Brown . gvec - the global vector 664dce8aebaSBarry 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 669dce8aebaSBarry Smith Note: 670dce8aebaSBarry Smith This is a non-variadic alternative to `DMCompositeGather()`. 6716f3c3dcfSJed Brown 672dce8aebaSBarry 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 } 706*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7076f3c3dcfSJed Brown } 7086f3c3dcfSJed Brown 709f5f57ec0SBarry Smith /*@ 710dce8aebaSBarry Smith DMCompositeAddDM - adds a `DM` vector to a `DMCOMPOSITE` 71147c6ae99SBarry Smith 712d083f849SBarry Smith Collective on dm 71347c6ae99SBarry Smith 714d8d19677SJose E. Roman Input Parameters: 715dce8aebaSBarry Smith + dmc - the `DMCOMPOSITE` object 716dce8aebaSBarry Smith - dm - the `DM` object 71747c6ae99SBarry Smith 71847c6ae99SBarry Smith Level: advanced 71947c6ae99SBarry Smith 720dce8aebaSBarry 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++; 765*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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 } 811*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 827*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 844*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 84547c6ae99SBarry Smith } 84647c6ae99SBarry Smith 84747c6ae99SBarry Smith /*@C 848dce8aebaSBarry Smith DMCompositeGetISLocalToGlobalMappings - gets an `ISLocalToGlobalMapping` for each `DM` in the `DMCOMPOSITE`, maps to the composite global space 84947c6ae99SBarry Smith 850dce8aebaSBarry Smith Collective on dm 85147c6ae99SBarry Smith 85247c6ae99SBarry Smith Input Parameter: 853dce8aebaSBarry 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 857dce8aebaSBarry Smith all the ghost points that individual ghosted `DMDA` may have. 85847c6ae99SBarry Smith 85947c6ae99SBarry Smith Level: advanced 86047c6ae99SBarry Smith 861dce8aebaSBarry Smith Note: 862dce8aebaSBarry Smith Each entry of ltogs should be destroyed with `ISLocalToGlobalMappingDestroy()`, the ltogs array should be freed with `PetscFree()`. 86347c6ae99SBarry Smith 864dce8aebaSBarry Smith Fortran Note: 865f5f57ec0SBarry Smith Not available from Fortran 866f5f57ec0SBarry Smith 867dce8aebaSBarry 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 } 930*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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: 939dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` 94087c85e80SJed Brown 9414165533cSJose E. Roman Output Parameter: 942dce8aebaSBarry 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 948dce8aebaSBarry 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 951dce8aebaSBarry Smith To get the composite global indices at all local points (including ghosts), use `DMCompositeGetISLocalToGlobalMappings()`. 95287c85e80SJed Brown 953dce8aebaSBarry Smith To get index sets for pieces of the composite global vector, use `DMCompositeGetGlobalISs()`. 95487c85e80SJed Brown 955dce8aebaSBarry Smith Each returned `IS` should be destroyed with `ISDestroy()`, the array should be freed with `PetscFree()`. 95687c85e80SJed Brown 957dce8aebaSBarry Smith Fortran Note: 958f5f57ec0SBarry Smith Not available from Fortran 959f5f57ec0SBarry Smith 960dce8aebaSBarry 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 } 981*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 98287c85e80SJed Brown } 98387c85e80SJed Brown 98447c6ae99SBarry Smith /*@C 985dce8aebaSBarry 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: 990dce8aebaSBarry 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: 998dce8aebaSBarry 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 1002dce8aebaSBarry Smith Use `DMCompositeGetLocalISs()` for index sets in the packed local numbering, and 1003dce8aebaSBarry Smith `DMCompositeGetISLocalToGlobalMappings()` for to map local sub-`DM` (including ghost) indices to packed global 10046eb61c8cSJed Brown indices. 100547c6ae99SBarry Smith 1006dce8aebaSBarry Smith Fortran Note: 1007dce8aebaSBarry Smith The output argument 'is' must be an allocated array of sufficient length, which can be learned using `DMCompositeGetNumberDM()`. 1008f3cb0f7eSJed Brown 1009dce8aebaSBarry 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 } 1056*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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 } 1098*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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 } 1119*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1120e7c4fc90SDmitry Karpeev } 1121e7c4fc90SDmitry Karpeev 112247c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 112347c6ae99SBarry Smith /*@C 1124dce8aebaSBarry Smith DMCompositeGetLocalVectors - Gets local vectors for each part of a `DMCOMPOSITE` 1125dce8aebaSBarry Smith Use `DMCompositeRestoreLocalVectors()` to return them. 112647c6ae99SBarry Smith 112747c6ae99SBarry Smith Not Collective 112847c6ae99SBarry Smith 112947c6ae99SBarry Smith Input Parameter: 1130dce8aebaSBarry 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 1137dce8aebaSBarry Smith Fortran Note: 1138f5f57ec0SBarry Smith Not available from Fortran 1139f5f57ec0SBarry Smith 1140dce8aebaSBarry 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); 1165*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 116647c6ae99SBarry Smith } 116747c6ae99SBarry Smith 116847c6ae99SBarry Smith /*@C 1169dce8aebaSBarry Smith DMCompositeRestoreLocalVectors - Restores local vectors for each part of a `DMCOMPOSITE` 117047c6ae99SBarry Smith 117147c6ae99SBarry Smith Not Collective 117247c6ae99SBarry Smith 117347c6ae99SBarry Smith Input Parameter: 1174dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` object 117547c6ae99SBarry Smith 117647c6ae99SBarry Smith Output Parameter: 1177dce8aebaSBarry Smith . Vec ... - the individual sequential `Vec` 117847c6ae99SBarry Smith 117947c6ae99SBarry Smith Level: advanced 118047c6ae99SBarry Smith 1181dce8aebaSBarry Smith Fortran Note: 1182f5f57ec0SBarry Smith Not available from Fortran 1183f5f57ec0SBarry Smith 1184dce8aebaSBarry 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); 1209*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 121047c6ae99SBarry Smith } 121147c6ae99SBarry Smith 121247c6ae99SBarry Smith /* -------------------------------------------------------------------------------------*/ 121347c6ae99SBarry Smith /*@C 1214dce8aebaSBarry Smith DMCompositeGetEntries - Gets the `DM` for each entry in a `DMCOMPOSITE`. 121547c6ae99SBarry Smith 121647c6ae99SBarry Smith Not Collective 121747c6ae99SBarry Smith 121847c6ae99SBarry Smith Input Parameter: 1219dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` object 122047c6ae99SBarry Smith 122147c6ae99SBarry Smith Output Parameter: 1222dce8aebaSBarry Smith . DM ... - the individual entries `DM` 122347c6ae99SBarry Smith 122447c6ae99SBarry Smith Level: advanced 122547c6ae99SBarry Smith 1226dce8aebaSBarry Smith Fortran Note: 1227dce8aebaSBarry Smith Available as `DMCompositeGetEntries()` for one output `DM`, DMCompositeGetEntries2() for 2, etc 1228f5f57ec0SBarry Smith 1229dce8aebaSBarry 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); 1255*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 125647c6ae99SBarry Smith } 125747c6ae99SBarry Smith 1258dbab29e1SMark F. Adams /*@C 1259dce8aebaSBarry Smith DMCompositeGetEntriesArray - Gets the DM for each entry in a `DMCOMPOSITE` 12602fa5ba8aSJed Brown 12612fa5ba8aSJed Brown Not Collective 12622fa5ba8aSJed Brown 12632fa5ba8aSJed Brown Input Parameter: 1264dce8aebaSBarry Smith . dm - the `DMCOMPOSITE` object 1265907376e6SBarry Smith 1266907376e6SBarry Smith Output Parameter: 1267dce8aebaSBarry Smith . dms - array of sufficient length (see `DMCompositeGetNumberDM()`) to hold the individual `DM` 12682fa5ba8aSJed Brown 12692fa5ba8aSJed Brown Level: advanced 12702fa5ba8aSJed Brown 1271dce8aebaSBarry 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; 1289*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 1309*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 1333*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 1379*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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 } 1402*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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 } 1425*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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 } 1471*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 1486*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 1526*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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)); 1569*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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); 1578*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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 1621*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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); 1630*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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 1673*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 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); 1682*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16830c010503SBarry Smith } 168447c6ae99SBarry Smith 16856ae3a549SBarry Smith /*MC 1686dce8aebaSBarry 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)); 1726*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1727a4121054SBarry Smith } 1728a4121054SBarry Smith 17291fd49c25SBarry Smith /*@ 1730dce8aebaSBarry 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: 1739dce8aebaSBarry Smith . packer - the `DMCOMPOSITE` object 174047c6ae99SBarry Smith 174147c6ae99SBarry Smith Level: advanced 174247c6ae99SBarry Smith 1743dce8aebaSBarry 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)); 1753*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 175447c6ae99SBarry Smith } 1755