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 6647c6ae99SBarry Smith /* 67aa219208SBarry Smith DMDAGlobalToNatural_Create - Create the global to natural scatter object 6847c6ae99SBarry Smith 6920f4b53cSBarry Smith Collective 7047c6ae99SBarry Smith 7147c6ae99SBarry Smith Input Parameter: 72*72fd0fbdSBarry Smith . da - the `DMDA` context 7347c6ae99SBarry Smith 7447c6ae99SBarry Smith Level: developer 7547c6ae99SBarry Smith 76dce8aebaSBarry Smith Note: 77dce8aebaSBarry Smith This is an internal routine called by `DMDAGlobalToNatural()` to 7847c6ae99SBarry Smith create the scatter context. 7947c6ae99SBarry Smith 8012b4a537SBarry Smith .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 81db781477SPatrick Sanan `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 8247c6ae99SBarry Smith */ 83a4e35b19SJacob Faibussowitsch static PetscErrorCode DMDAGlobalToNatural_Create(DM da) 84d71ae5a4SJacob Faibussowitsch { 8547c6ae99SBarry Smith PetscInt m, start, Nlocal; 8647c6ae99SBarry Smith IS from, to; 8747c6ae99SBarry Smith Vec global; 8847c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 8947c6ae99SBarry Smith 9047c6ae99SBarry Smith PetscFunctionBegin; 9147c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 927a8be351SBarry Smith PetscCheck(dd->natural, PetscObjectComm((PetscObject)da), PETSC_ERR_ORDER, "Natural layout vector not yet created; cannot scatter into it"); 9347c6ae99SBarry Smith 9447c6ae99SBarry Smith /* create the scatter context */ 959566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(dd->natural, &m)); 969566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(dd->natural, &start, NULL)); 9747c6ae99SBarry Smith 989566063dSJacob Faibussowitsch PetscCall(DMDAGetNatural_Private(da, &Nlocal, &to)); 9963a3b9bcSJacob Faibussowitsch PetscCheck(Nlocal == m, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error: Nlocal %" PetscInt_FMT " local vector size %" PetscInt_FMT, Nlocal, m); 1009566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PetscObjectComm((PetscObject)da), m, start, 1, &from)); 1019566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)da), dd->w, dd->Nlocal, PETSC_DETERMINE, NULL, &global)); 1029566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(global, from, dd->natural, to, &dd->gton)); 1039566063dSJacob Faibussowitsch PetscCall(VecDestroy(&global)); 1049566063dSJacob Faibussowitsch PetscCall(ISDestroy(&from)); 1059566063dSJacob Faibussowitsch PetscCall(ISDestroy(&to)); 1063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10747c6ae99SBarry Smith } 10847c6ae99SBarry Smith 10947c6ae99SBarry Smith /*@ 110*72fd0fbdSBarry Smith DMDAGlobalToNaturalBegin - Maps values from the global vector obtained with `DMCreateGlobalVector()` to a global vector 11147c6ae99SBarry Smith in the "natural" grid ordering. Must be followed by 112dce8aebaSBarry Smith `DMDAGlobalToNaturalEnd()` to complete the exchange. 11347c6ae99SBarry Smith 11420f4b53cSBarry Smith Neighbor-wise Collective 11547c6ae99SBarry Smith 11647c6ae99SBarry Smith Input Parameters: 117*72fd0fbdSBarry Smith + da - the `DMDA` context 11812b4a537SBarry Smith . g - the global vector, see `DMCreateGlobalVector()` 119dce8aebaSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 12047c6ae99SBarry Smith 12147c6ae99SBarry Smith Output Parameter: 12212b4a537SBarry Smith . n - the natural ordering values, see `DMDACreateNaturalVector()` 12347c6ae99SBarry Smith 12447c6ae99SBarry Smith Level: advanced 12547c6ae99SBarry Smith 12647c6ae99SBarry Smith Notes: 127da81f932SPierre Jolivet The global and natural vectors used here need not be the same as those 128dce8aebaSBarry Smith obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they 12947c6ae99SBarry Smith must have the same parallel data layout; they could, for example, be 130dce8aebaSBarry Smith obtained with `VecDuplicate()` from the `DMDA` originating vectors. 13147c6ae99SBarry Smith 132dce8aebaSBarry Smith You must call `DMDACreateNaturalVector()` before using this routine 13347c6ae99SBarry Smith 13412b4a537SBarry Smith .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 135db781477SPatrick Sanan `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 13647c6ae99SBarry Smith @*/ 137d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGlobalToNaturalBegin(DM da, Vec g, InsertMode mode, Vec n) 138d71ae5a4SJacob Faibussowitsch { 13947c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 14047c6ae99SBarry Smith 14147c6ae99SBarry Smith PetscFunctionBegin; 142a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 143dd9d0712SPatrick Sanan PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 144dd9d0712SPatrick Sanan PetscValidHeaderSpecific(n, VEC_CLASSID, 4); 14547c6ae99SBarry Smith if (!dd->gton) { 14647c6ae99SBarry Smith /* create the scatter context */ 1479566063dSJacob Faibussowitsch PetscCall(DMDAGlobalToNatural_Create(da)); 14847c6ae99SBarry Smith } 1499566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(dd->gton, g, n, mode, SCATTER_FORWARD)); 1503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15147c6ae99SBarry Smith } 15247c6ae99SBarry Smith 15347c6ae99SBarry Smith /*@ 154*72fd0fbdSBarry Smith DMDAGlobalToNaturalEnd - Maps values from the global vector obtained with `DMCreateGlobalVector()` to a global vector 155dce8aebaSBarry Smith in the natural ordering. Must be preceded by `DMDAGlobalToNaturalBegin()`. 15647c6ae99SBarry Smith 15720f4b53cSBarry Smith Neighbor-wise Collective 15847c6ae99SBarry Smith 15947c6ae99SBarry Smith Input Parameters: 160*72fd0fbdSBarry Smith + da - the `DMDA` context 16112b4a537SBarry Smith . g - the global vector, see `DMCreateGlobalVector()` 162dce8aebaSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 16347c6ae99SBarry Smith 16447c6ae99SBarry Smith Output Parameter: 16512b4a537SBarry Smith . n - the global values in the natural ordering, see `DMDACreateNaturalVector()` 16647c6ae99SBarry Smith 16747c6ae99SBarry Smith Level: advanced 16847c6ae99SBarry Smith 169*72fd0fbdSBarry Smith Note: 17047c6ae99SBarry Smith The global and local vectors used here need not be the same as those 171dce8aebaSBarry Smith obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they 17247c6ae99SBarry Smith must have the same parallel data layout; they could, for example, be 173dce8aebaSBarry Smith obtained with VecDuplicate() from the `DMDA` originating vectors. 17447c6ae99SBarry Smith 17512b4a537SBarry Smith .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 176db781477SPatrick Sanan `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 17747c6ae99SBarry Smith @*/ 178d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGlobalToNaturalEnd(DM da, Vec g, InsertMode mode, Vec n) 179d71ae5a4SJacob Faibussowitsch { 18047c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 18147c6ae99SBarry Smith 18247c6ae99SBarry Smith PetscFunctionBegin; 183a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 184dd9d0712SPatrick Sanan PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 185dd9d0712SPatrick Sanan PetscValidHeaderSpecific(n, VEC_CLASSID, 4); 1869566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(dd->gton, g, n, mode, SCATTER_FORWARD)); 1873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18847c6ae99SBarry Smith } 18947c6ae99SBarry Smith 19047c6ae99SBarry Smith /*@ 191aa219208SBarry Smith DMDANaturalToGlobalBegin - Maps values from a global vector in the "natural" ordering 192dce8aebaSBarry Smith to a global vector in the PETSc `DMDA` grid ordering. Must be followed by 193dce8aebaSBarry Smith `DMDANaturalToGlobalEnd()` to complete the exchange. 19447c6ae99SBarry Smith 19520f4b53cSBarry Smith Neighbor-wise Collective 19647c6ae99SBarry Smith 19747c6ae99SBarry Smith Input Parameters: 198*72fd0fbdSBarry Smith + da - the `DMDA` context 19912b4a537SBarry Smith . g - the global vector in a natural ordering, see `DMDACreateNaturalVector()` 200dce8aebaSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 20147c6ae99SBarry Smith 20247c6ae99SBarry Smith Output Parameter: 20360225df5SJacob Faibussowitsch . n - the values in the `DMDA` ordering 20447c6ae99SBarry Smith 20547c6ae99SBarry Smith Level: advanced 20647c6ae99SBarry Smith 207*72fd0fbdSBarry Smith Note: 20847c6ae99SBarry Smith The global and natural vectors used here need not be the same as those 209dce8aebaSBarry Smith obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they 21047c6ae99SBarry Smith must have the same parallel data layout; they could, for example, be 211dce8aebaSBarry Smith obtained with `VecDuplicate()` from the `DMDA` originating vectors. 21247c6ae99SBarry Smith 21312b4a537SBarry Smith .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalEnd()`, `DMDAGlobalToNaturalBegin()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 214db781477SPatrick Sanan `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 21547c6ae99SBarry Smith @*/ 216d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDANaturalToGlobalBegin(DM da, Vec n, InsertMode mode, Vec g) 217d71ae5a4SJacob Faibussowitsch { 21847c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 21947c6ae99SBarry Smith 22047c6ae99SBarry Smith PetscFunctionBegin; 221a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 222dd9d0712SPatrick Sanan PetscValidHeaderSpecific(n, VEC_CLASSID, 2); 22347c6ae99SBarry Smith PetscValidHeaderSpecific(g, VEC_CLASSID, 4); 22447c6ae99SBarry Smith if (!dd->gton) { 22547c6ae99SBarry Smith /* create the scatter context */ 2269566063dSJacob Faibussowitsch PetscCall(DMDAGlobalToNatural_Create(da)); 22747c6ae99SBarry Smith } 2289566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(dd->gton, n, g, mode, SCATTER_REVERSE)); 2293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23047c6ae99SBarry Smith } 23147c6ae99SBarry Smith 23247c6ae99SBarry Smith /*@ 233aa219208SBarry Smith DMDANaturalToGlobalEnd - Maps values from the natural ordering global vector 234dce8aebaSBarry Smith to a global vector in the PETSc `DMDA` ordering. Must be preceded by `DMDANaturalToGlobalBegin()`. 23547c6ae99SBarry Smith 23620f4b53cSBarry Smith Neighbor-wise Collective 23747c6ae99SBarry Smith 23847c6ae99SBarry Smith Input Parameters: 239*72fd0fbdSBarry Smith + da - the `DMDA` context 24047c6ae99SBarry Smith . g - the global vector in a natural ordering 241dce8aebaSBarry Smith - mode - one of `INSERT_VALUES` or `ADD_VALUES` 24247c6ae99SBarry Smith 24347c6ae99SBarry Smith Output Parameter: 24460225df5SJacob Faibussowitsch . n - the global values in the PETSc `DMDA` ordering 24547c6ae99SBarry Smith 246a47bb602SJed Brown Level: advanced 24747c6ae99SBarry Smith 248*72fd0fbdSBarry Smith Note: 24947c6ae99SBarry Smith The global and local vectors used here need not be the same as those 250dce8aebaSBarry Smith obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they 25147c6ae99SBarry Smith must have the same parallel data layout; they could, for example, be 252dce8aebaSBarry Smith obtained with `VecDuplicate()` from the `DMDA` originating vectors. 25347c6ae99SBarry Smith 25412b4a537SBarry Smith .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 255db781477SPatrick Sanan `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 25647c6ae99SBarry Smith @*/ 257d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDANaturalToGlobalEnd(DM da, Vec n, InsertMode mode, Vec g) 258d71ae5a4SJacob Faibussowitsch { 25947c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 26047c6ae99SBarry Smith 26147c6ae99SBarry Smith PetscFunctionBegin; 262a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 263dd9d0712SPatrick Sanan PetscValidHeaderSpecific(n, VEC_CLASSID, 2); 26447c6ae99SBarry Smith PetscValidHeaderSpecific(g, VEC_CLASSID, 4); 2659566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(dd->gton, n, g, mode, SCATTER_REVERSE)); 2663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26747c6ae99SBarry Smith } 268