147c6ae99SBarry Smith /* 247c6ae99SBarry Smith Code for manipulating distributed regular arrays in parallel. 347c6ae99SBarry Smith */ 447c6ae99SBarry Smith 5af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 647c6ae99SBarry Smith 7d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalBegin_DA(DM da, Vec g, InsertMode mode, Vec l) 8d71ae5a4SJacob Faibussowitsch { 947c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 1047c6ae99SBarry Smith 1147c6ae99SBarry Smith PetscFunctionBegin; 1247c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 1347c6ae99SBarry Smith PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 1447c6ae99SBarry Smith PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 159566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(dd->gtol, g, l, mode, SCATTER_FORWARD)); 163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1747c6ae99SBarry Smith } 1847c6ae99SBarry Smith 19d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGlobalToLocalEnd_DA(DM da, Vec g, InsertMode mode, Vec l) 20d71ae5a4SJacob Faibussowitsch { 2147c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 2247c6ae99SBarry Smith 2347c6ae99SBarry Smith PetscFunctionBegin; 2447c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 2547c6ae99SBarry Smith PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 2647c6ae99SBarry Smith PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 279566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(dd->gtol, g, l, mode, SCATTER_FORWARD)); 283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2947c6ae99SBarry Smith } 3047c6ae99SBarry Smith 31d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalBegin_DA(DM da, Vec l, InsertMode mode, Vec g) 32d71ae5a4SJacob Faibussowitsch { 339a42bb27SBarry Smith DM_DA *dd = (DM_DA *)da->data; 349a42bb27SBarry Smith 359a42bb27SBarry Smith PetscFunctionBegin; 369a42bb27SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 379a42bb27SBarry Smith PetscValidHeaderSpecific(l, VEC_CLASSID, 2); 38dd9d0712SPatrick Sanan PetscValidHeaderSpecific(g, VEC_CLASSID, 4); 399a42bb27SBarry Smith if (mode == ADD_VALUES) { 409566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(dd->gtol, l, g, ADD_VALUES, SCATTER_REVERSE)); 419a42bb27SBarry Smith } else if (mode == INSERT_VALUES) { 421dca8a05SBarry Smith PetscCheck(dd->bx == DM_BOUNDARY_GHOSTED || dd->bx == DM_BOUNDARY_NONE || dd->s <= 0 || dd->m != 1, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Available only for boundary none or with parallelism in x direction"); 431dca8a05SBarry Smith PetscCheck(dd->bx == DM_BOUNDARY_GHOSTED || dd->by == DM_BOUNDARY_NONE || dd->s <= 0 || dd->n != 1, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Available only for boundary none or with parallelism in y direction"); 441dca8a05SBarry Smith PetscCheck(dd->bx == DM_BOUNDARY_GHOSTED || dd->bz == DM_BOUNDARY_NONE || dd->s <= 0 || dd->p != 1, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Available only for boundary none or with parallelism in z direction"); 459566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(dd->gtol, l, g, INSERT_VALUES, SCATTER_REVERSE_LOCAL)); 46ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Not yet implemented"); 473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 489a42bb27SBarry Smith } 499a42bb27SBarry Smith 50d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToGlobalEnd_DA(DM da, Vec l, InsertMode mode, Vec g) 51d71ae5a4SJacob Faibussowitsch { 529a42bb27SBarry Smith DM_DA *dd = (DM_DA *)da->data; 539a42bb27SBarry Smith 549a42bb27SBarry Smith PetscFunctionBegin; 559a42bb27SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 569a42bb27SBarry Smith PetscValidHeaderSpecific(l, VEC_CLASSID, 2); 57dd9d0712SPatrick Sanan PetscValidHeaderSpecific(g, VEC_CLASSID, 4); 589a42bb27SBarry Smith if (mode == ADD_VALUES) { 599566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(dd->gtol, l, g, ADD_VALUES, SCATTER_REVERSE)); 609a42bb27SBarry Smith } else if (mode == INSERT_VALUES) { 619566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(dd->gtol, l, g, INSERT_VALUES, SCATTER_REVERSE_LOCAL)); 62ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Not yet implemented"); 633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 649a42bb27SBarry Smith } 659a42bb27SBarry Smith 6609573ac7SBarry Smith extern PetscErrorCode DMDAGetNatural_Private(DM, PetscInt *, IS *); 6747c6ae99SBarry Smith /* 68aa219208SBarry Smith DMDAGlobalToNatural_Create - Create the global to natural scatter object 6947c6ae99SBarry Smith 7020f4b53cSBarry Smith Collective 7147c6ae99SBarry Smith 7247c6ae99SBarry Smith Input Parameter: 7347c6ae99SBarry Smith . da - the distributed array context 7447c6ae99SBarry Smith 7547c6ae99SBarry Smith Level: developer 7647c6ae99SBarry Smith 77dce8aebaSBarry Smith Note: 78dce8aebaSBarry Smith This is an internal routine called by `DMDAGlobalToNatural()` to 7947c6ae99SBarry Smith create the scatter context. 8047c6ae99SBarry Smith 81dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 82db781477SPatrick Sanan `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 8347c6ae99SBarry Smith */ 84*a4e35b19SJacob Faibussowitsch static PetscErrorCode DMDAGlobalToNatural_Create(DM da) 85d71ae5a4SJacob Faibussowitsch { 8647c6ae99SBarry Smith PetscInt m, start, Nlocal; 8747c6ae99SBarry Smith IS from, to; 8847c6ae99SBarry Smith Vec global; 8947c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 9047c6ae99SBarry Smith 9147c6ae99SBarry Smith PetscFunctionBegin; 9247c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 937a8be351SBarry Smith PetscCheck(dd->natural, PetscObjectComm((PetscObject)da), PETSC_ERR_ORDER, "Natural layout vector not yet created; cannot scatter into it"); 9447c6ae99SBarry Smith 9547c6ae99SBarry Smith /* create the scatter context */ 969566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(dd->natural, &m)); 979566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(dd->natural, &start, NULL)); 9847c6ae99SBarry Smith 999566063dSJacob Faibussowitsch PetscCall(DMDAGetNatural_Private(da, &Nlocal, &to)); 10063a3b9bcSJacob Faibussowitsch PetscCheck(Nlocal == m, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error: Nlocal %" PetscInt_FMT " local vector size %" PetscInt_FMT, Nlocal, m); 1019566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PetscObjectComm((PetscObject)da), m, start, 1, &from)); 1029566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)da), dd->w, dd->Nlocal, PETSC_DETERMINE, NULL, &global)); 1039566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(global, from, dd->natural, to, &dd->gton)); 1049566063dSJacob Faibussowitsch PetscCall(VecDestroy(&global)); 1059566063dSJacob Faibussowitsch PetscCall(ISDestroy(&from)); 1069566063dSJacob Faibussowitsch PetscCall(ISDestroy(&to)); 1073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10847c6ae99SBarry Smith } 10947c6ae99SBarry Smith 11047c6ae99SBarry Smith /*@ 111aa219208SBarry Smith DMDAGlobalToNaturalBegin - Maps values from the global vector to a global vector 11247c6ae99SBarry Smith in the "natural" grid ordering. Must be followed by 113dce8aebaSBarry Smith `DMDAGlobalToNaturalEnd()` to complete the exchange. 11447c6ae99SBarry Smith 11520f4b53cSBarry Smith Neighbor-wise Collective 11647c6ae99SBarry Smith 11747c6ae99SBarry Smith Input Parameters: 11847c6ae99SBarry Smith + da - the distributed array context 11947c6ae99SBarry Smith . g - the global vector 120dce8aebaSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 12147c6ae99SBarry Smith 12247c6ae99SBarry Smith Output Parameter: 12360225df5SJacob Faibussowitsch . n - the natural ordering values 12447c6ae99SBarry Smith 12547c6ae99SBarry Smith Level: advanced 12647c6ae99SBarry Smith 12747c6ae99SBarry Smith Notes: 128da81f932SPierre Jolivet The global and natural vectors used here need not be the same as those 129dce8aebaSBarry Smith obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they 13047c6ae99SBarry Smith must have the same parallel data layout; they could, for example, be 131dce8aebaSBarry Smith obtained with `VecDuplicate()` from the `DMDA` originating vectors. 13247c6ae99SBarry Smith 133dce8aebaSBarry Smith You must call `DMDACreateNaturalVector()` before using this routine 13447c6ae99SBarry Smith 135dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 136db781477SPatrick Sanan `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 13747c6ae99SBarry Smith @*/ 138d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGlobalToNaturalBegin(DM da, Vec g, InsertMode mode, Vec n) 139d71ae5a4SJacob Faibussowitsch { 14047c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 14147c6ae99SBarry Smith 14247c6ae99SBarry Smith PetscFunctionBegin; 143a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 144dd9d0712SPatrick Sanan PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 145dd9d0712SPatrick Sanan PetscValidHeaderSpecific(n, VEC_CLASSID, 4); 14647c6ae99SBarry Smith if (!dd->gton) { 14747c6ae99SBarry Smith /* create the scatter context */ 1489566063dSJacob Faibussowitsch PetscCall(DMDAGlobalToNatural_Create(da)); 14947c6ae99SBarry Smith } 1509566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(dd->gton, g, n, mode, SCATTER_FORWARD)); 1513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15247c6ae99SBarry Smith } 15347c6ae99SBarry Smith 15447c6ae99SBarry Smith /*@ 155aa219208SBarry Smith DMDAGlobalToNaturalEnd - Maps values from the global vector to a global vector 156dce8aebaSBarry Smith in the natural ordering. Must be preceded by `DMDAGlobalToNaturalBegin()`. 15747c6ae99SBarry Smith 15820f4b53cSBarry Smith Neighbor-wise Collective 15947c6ae99SBarry Smith 16047c6ae99SBarry Smith Input Parameters: 16147c6ae99SBarry Smith + da - the distributed array context 16247c6ae99SBarry Smith . g - the global vector 163dce8aebaSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 16447c6ae99SBarry Smith 16547c6ae99SBarry Smith Output Parameter: 16660225df5SJacob Faibussowitsch . n - the global values in the natural ordering 16747c6ae99SBarry Smith 16847c6ae99SBarry Smith Level: advanced 16947c6ae99SBarry Smith 17047c6ae99SBarry Smith Notes: 17147c6ae99SBarry Smith The global and local vectors used here need not be the same as those 172dce8aebaSBarry Smith obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they 17347c6ae99SBarry Smith must have the same parallel data layout; they could, for example, be 174dce8aebaSBarry Smith obtained with VecDuplicate() from the `DMDA` originating vectors. 17547c6ae99SBarry Smith 176dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 177db781477SPatrick Sanan `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 17847c6ae99SBarry Smith @*/ 179d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGlobalToNaturalEnd(DM da, Vec g, InsertMode mode, Vec n) 180d71ae5a4SJacob Faibussowitsch { 18147c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 18247c6ae99SBarry Smith 18347c6ae99SBarry Smith PetscFunctionBegin; 184a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 185dd9d0712SPatrick Sanan PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 186dd9d0712SPatrick Sanan PetscValidHeaderSpecific(n, VEC_CLASSID, 4); 1879566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(dd->gton, g, n, mode, SCATTER_FORWARD)); 1883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18947c6ae99SBarry Smith } 19047c6ae99SBarry Smith 19147c6ae99SBarry Smith /*@ 192aa219208SBarry Smith DMDANaturalToGlobalBegin - Maps values from a global vector in the "natural" ordering 193dce8aebaSBarry Smith to a global vector in the PETSc `DMDA` grid ordering. Must be followed by 194dce8aebaSBarry Smith `DMDANaturalToGlobalEnd()` to complete the exchange. 19547c6ae99SBarry Smith 19620f4b53cSBarry Smith Neighbor-wise Collective 19747c6ae99SBarry Smith 19847c6ae99SBarry Smith Input Parameters: 19947c6ae99SBarry Smith + da - the distributed array context 20047c6ae99SBarry Smith . g - the global vector in a natural ordering 201dce8aebaSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 20247c6ae99SBarry Smith 20347c6ae99SBarry Smith Output Parameter: 20460225df5SJacob Faibussowitsch . n - the values in the `DMDA` ordering 20547c6ae99SBarry Smith 20647c6ae99SBarry Smith Level: advanced 20747c6ae99SBarry Smith 20847c6ae99SBarry Smith Notes: 20947c6ae99SBarry Smith The global and natural vectors used here need not be the same as those 210dce8aebaSBarry Smith obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they 21147c6ae99SBarry Smith must have the same parallel data layout; they could, for example, be 212dce8aebaSBarry Smith obtained with `VecDuplicate()` from the `DMDA` originating vectors. 21347c6ae99SBarry Smith 214dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGlobalToNaturalEnd()`, `DMDAGlobalToNaturalBegin()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 215db781477SPatrick Sanan `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 21647c6ae99SBarry Smith @*/ 217d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDANaturalToGlobalBegin(DM da, Vec n, InsertMode mode, Vec g) 218d71ae5a4SJacob Faibussowitsch { 21947c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 22047c6ae99SBarry Smith 22147c6ae99SBarry Smith PetscFunctionBegin; 222a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 223dd9d0712SPatrick Sanan PetscValidHeaderSpecific(n, VEC_CLASSID, 2); 22447c6ae99SBarry Smith PetscValidHeaderSpecific(g, VEC_CLASSID, 4); 22547c6ae99SBarry Smith if (!dd->gton) { 22647c6ae99SBarry Smith /* create the scatter context */ 2279566063dSJacob Faibussowitsch PetscCall(DMDAGlobalToNatural_Create(da)); 22847c6ae99SBarry Smith } 2299566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(dd->gton, n, g, mode, SCATTER_REVERSE)); 2303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23147c6ae99SBarry Smith } 23247c6ae99SBarry Smith 23347c6ae99SBarry Smith /*@ 234aa219208SBarry Smith DMDANaturalToGlobalEnd - Maps values from the natural ordering global vector 235dce8aebaSBarry Smith to a global vector in the PETSc `DMDA` ordering. Must be preceded by `DMDANaturalToGlobalBegin()`. 23647c6ae99SBarry Smith 23720f4b53cSBarry Smith Neighbor-wise Collective 23847c6ae99SBarry Smith 23947c6ae99SBarry Smith Input Parameters: 24047c6ae99SBarry Smith + da - the distributed array context 24147c6ae99SBarry Smith . g - the global vector in a natural ordering 242dce8aebaSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 24347c6ae99SBarry Smith 24447c6ae99SBarry Smith Output Parameter: 24560225df5SJacob Faibussowitsch . n - the global values in the PETSc `DMDA` ordering 24647c6ae99SBarry Smith 247a47bb602SJed Brown Level: advanced 24847c6ae99SBarry Smith 24947c6ae99SBarry Smith Notes: 25047c6ae99SBarry Smith The global and local vectors used here need not be the same as those 251dce8aebaSBarry Smith obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they 25247c6ae99SBarry Smith must have the same parallel data layout; they could, for example, be 253dce8aebaSBarry Smith obtained with `VecDuplicate()` from the `DMDA` originating vectors. 25447c6ae99SBarry Smith 255dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 256db781477SPatrick Sanan `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 25747c6ae99SBarry Smith @*/ 258d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDANaturalToGlobalEnd(DM da, Vec n, InsertMode mode, Vec g) 259d71ae5a4SJacob Faibussowitsch { 26047c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 26147c6ae99SBarry Smith 26247c6ae99SBarry Smith PetscFunctionBegin; 263a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 264dd9d0712SPatrick Sanan PetscValidHeaderSpecific(n, VEC_CLASSID, 2); 26547c6ae99SBarry Smith PetscValidHeaderSpecific(g, VEC_CLASSID, 4); 2669566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(dd->gton, n, g, mode, SCATTER_REVERSE)); 2673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26847c6ae99SBarry Smith } 269