1 /*
2 Tools to help solve the coarse grid problem redundantly.
3 Provides two scatter contexts that (1) map from the usual global vector
4 to all processors the entire vector in NATURAL numbering and (2)
5 from the entire vector on each processor in natural numbering extracts
6 out this processors piece in GLOBAL numbering
7 */
8
9 #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/
10
11 /*@
12 DMDAGlobalToNaturalAllCreate - Creates a scatter context that maps from a
13 global vector, obtained with `DMCreateGlobalVector()`, to the entire vector to each processor in natural numbering
14
15 Collective
16
17 Input Parameter:
18 . da - the `DMDA` context
19
20 Output Parameter:
21 . scatter - the scatter context
22
23 Level: advanced
24
25 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDANaturalAllToGlobalCreate()`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`,
26 `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()`
27 @*/
DMDAGlobalToNaturalAllCreate(DM da,VecScatter * scatter)28 PetscErrorCode DMDAGlobalToNaturalAllCreate(DM da, VecScatter *scatter)
29 {
30 PetscInt N;
31 IS from, to;
32 Vec tmplocal, global;
33 AO ao;
34 DM_DA *dd = (DM_DA *)da->data;
35
36 PetscFunctionBegin;
37 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
38 PetscAssertPointer(scatter, 2);
39 PetscCall(DMDAGetAO(da, &ao));
40
41 /* create the scatter context */
42 PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)da), dd->w, dd->Nlocal, PETSC_DETERMINE, NULL, &global));
43 PetscCall(VecGetSize(global, &N));
44 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)da), N, 0, 1, &to));
45 PetscCall(AOPetscToApplicationIS(ao, to));
46 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)da), N, 0, 1, &from));
47 PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, dd->w, N, NULL, &tmplocal));
48 PetscCall(VecScatterCreate(global, from, tmplocal, to, scatter));
49 PetscCall(VecDestroy(&tmplocal));
50 PetscCall(VecDestroy(&global));
51 PetscCall(ISDestroy(&from));
52 PetscCall(ISDestroy(&to));
53 PetscFunctionReturn(PETSC_SUCCESS);
54 }
55
56 /*@
57 DMDANaturalAllToGlobalCreate - Creates a scatter context that maps from a copy
58 of the entire vector on each processor (in the natural ordering) to its local part in the global vector, obtained with `DMCreateGlobalVector()`.
59
60 Collective
61
62 Input Parameter:
63 . da - the `DMDA` context
64
65 Output Parameter:
66 . scatter - the scatter context
67
68 Level: advanced
69
70 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalAllCreate()`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`,
71 `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()`
72 @*/
DMDANaturalAllToGlobalCreate(DM da,VecScatter * scatter)73 PetscErrorCode DMDANaturalAllToGlobalCreate(DM da, VecScatter *scatter)
74 {
75 DM_DA *dd = (DM_DA *)da->data;
76 PetscInt M, m = dd->Nlocal, start;
77 IS from, to;
78 Vec tmplocal, global;
79 AO ao;
80
81 PetscFunctionBegin;
82 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
83 PetscAssertPointer(scatter, 2);
84 PetscCall(DMDAGetAO(da, &ao));
85
86 /* create the scatter context */
87 PetscCallMPI(MPIU_Allreduce(&m, &M, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)da)));
88 PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)da), dd->w, m, PETSC_DETERMINE, NULL, &global));
89 PetscCall(VecGetOwnershipRange(global, &start, NULL));
90 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)da), m, start, 1, &from));
91 PetscCall(AOPetscToApplicationIS(ao, from));
92 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)da), m, start, 1, &to));
93 PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, dd->w, M, NULL, &tmplocal));
94 PetscCall(VecScatterCreate(tmplocal, from, global, to, scatter));
95 PetscCall(VecDestroy(&tmplocal));
96 PetscCall(VecDestroy(&global));
97 PetscCall(ISDestroy(&from));
98 PetscCall(ISDestroy(&to));
99 PetscFunctionReturn(PETSC_SUCCESS);
100 }
101