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
DMGlobalToLocalBegin_DA(DM da,Vec g,InsertMode mode,Vec l)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
DMGlobalToLocalEnd_DA(DM da,Vec g,InsertMode mode,Vec l)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
DMLocalToGlobalBegin_DA(DM da,Vec l,InsertMode mode,Vec g)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
DMLocalToGlobalEnd_DA(DM da,Vec l,InsertMode mode,Vec g)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 */
DMDAGlobalToNatural_Create(DM da)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 @*/
DMDAGlobalToNaturalBegin(DM da,Vec g,InsertMode mode,Vec n)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 @*/
DMDAGlobalToNaturalEnd(DM da,Vec g,InsertMode mode,Vec n)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 @*/
DMDANaturalToGlobalBegin(DM da,Vec n,InsertMode mode,Vec g)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 @*/
DMDANaturalToGlobalEnd(DM da,Vec n,InsertMode mode,Vec g)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