1 /* 2 Code for manipulating distributed regular arrays in parallel. 3 */ 4 5 #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 6 7 PetscErrorCode DMGlobalToLocalBegin_DA(DM da, Vec g, InsertMode mode, Vec l) 8 { 9 DM_DA *dd = (DM_DA *)da->data; 10 11 PetscFunctionBegin; 12 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 13 PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 14 PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 15 PetscCall(VecScatterBegin(dd->gtol, g, l, mode, SCATTER_FORWARD)); 16 PetscFunctionReturn(PETSC_SUCCESS); 17 } 18 19 PetscErrorCode DMGlobalToLocalEnd_DA(DM da, Vec g, InsertMode mode, Vec l) 20 { 21 DM_DA *dd = (DM_DA *)da->data; 22 23 PetscFunctionBegin; 24 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 25 PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 26 PetscValidHeaderSpecific(l, VEC_CLASSID, 4); 27 PetscCall(VecScatterEnd(dd->gtol, g, l, mode, SCATTER_FORWARD)); 28 PetscFunctionReturn(PETSC_SUCCESS); 29 } 30 31 PetscErrorCode DMLocalToGlobalBegin_DA(DM da, Vec l, InsertMode mode, Vec g) 32 { 33 DM_DA *dd = (DM_DA *)da->data; 34 35 PetscFunctionBegin; 36 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 37 PetscValidHeaderSpecific(l, VEC_CLASSID, 2); 38 PetscValidHeaderSpecific(g, VEC_CLASSID, 4); 39 if (mode == ADD_VALUES) { 40 PetscCall(VecScatterBegin(dd->gtol, l, g, ADD_VALUES, SCATTER_REVERSE)); 41 } else if (mode == INSERT_VALUES) { 42 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"); 43 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"); 44 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"); 45 PetscCall(VecScatterBegin(dd->gtol, l, g, INSERT_VALUES, SCATTER_REVERSE_LOCAL)); 46 } else SETERRQ(PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Not yet implemented"); 47 PetscFunctionReturn(PETSC_SUCCESS); 48 } 49 50 PetscErrorCode DMLocalToGlobalEnd_DA(DM da, Vec l, InsertMode mode, Vec g) 51 { 52 DM_DA *dd = (DM_DA *)da->data; 53 54 PetscFunctionBegin; 55 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 56 PetscValidHeaderSpecific(l, VEC_CLASSID, 2); 57 PetscValidHeaderSpecific(g, VEC_CLASSID, 4); 58 if (mode == ADD_VALUES) { 59 PetscCall(VecScatterEnd(dd->gtol, l, g, ADD_VALUES, SCATTER_REVERSE)); 60 } else if (mode == INSERT_VALUES) { 61 PetscCall(VecScatterEnd(dd->gtol, l, g, INSERT_VALUES, SCATTER_REVERSE_LOCAL)); 62 } else SETERRQ(PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Not yet implemented"); 63 PetscFunctionReturn(PETSC_SUCCESS); 64 } 65 66 /* 67 DMDAGlobalToNatural_Create - Create the global to natural scatter object 68 69 Collective 70 71 Input Parameter: 72 . da - the `DMDA` context 73 74 Level: developer 75 76 Note: 77 This is an internal routine called by `DMDAGlobalToNatural()` to 78 create the scatter context. 79 80 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 81 `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 82 */ 83 static PetscErrorCode DMDAGlobalToNatural_Create(DM da) 84 { 85 PetscInt m, start, Nlocal; 86 IS from, to; 87 Vec global; 88 DM_DA *dd = (DM_DA *)da->data; 89 90 PetscFunctionBegin; 91 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 92 PetscCheck(dd->natural, PetscObjectComm((PetscObject)da), PETSC_ERR_ORDER, "Natural layout vector not yet created; cannot scatter into it"); 93 94 /* create the scatter context */ 95 PetscCall(VecGetLocalSize(dd->natural, &m)); 96 PetscCall(VecGetOwnershipRange(dd->natural, &start, NULL)); 97 98 PetscCall(DMDAGetNatural_Private(da, &Nlocal, &to)); 99 PetscCheck(Nlocal == m, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error: Nlocal %" PetscInt_FMT " local vector size %" PetscInt_FMT, Nlocal, m); 100 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)da), m, start, 1, &from)); 101 PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)da), dd->w, dd->Nlocal, PETSC_DETERMINE, NULL, &global)); 102 PetscCall(VecScatterCreate(global, from, dd->natural, to, &dd->gton)); 103 PetscCall(VecDestroy(&global)); 104 PetscCall(ISDestroy(&from)); 105 PetscCall(ISDestroy(&to)); 106 PetscFunctionReturn(PETSC_SUCCESS); 107 } 108 109 /*@ 110 DMDAGlobalToNaturalBegin - Maps values from the global vector obtained with `DMCreateGlobalVector()` to a global vector 111 in the "natural" grid ordering. Must be followed by 112 `DMDAGlobalToNaturalEnd()` to complete the exchange. 113 114 Neighbor-wise Collective 115 116 Input Parameters: 117 + da - the `DMDA` context 118 . g - the global vector, see `DMCreateGlobalVector()` 119 - mode - one of `INSERT_VALUES` or `ADD_VALUES` 120 121 Output Parameter: 122 . n - the natural ordering values, see `DMDACreateNaturalVector()` 123 124 Level: advanced 125 126 Notes: 127 The global and natural vectors used here need not be the same as those 128 obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they 129 must have the same parallel data layout; they could, for example, be 130 obtained with `VecDuplicate()` from the `DMDA` originating vectors. 131 132 You must call `DMDACreateNaturalVector()` before using this routine 133 134 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 135 `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 136 @*/ 137 PetscErrorCode DMDAGlobalToNaturalBegin(DM da, Vec g, InsertMode mode, Vec n) 138 { 139 DM_DA *dd = (DM_DA *)da->data; 140 141 PetscFunctionBegin; 142 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 143 PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 144 PetscValidHeaderSpecific(n, VEC_CLASSID, 4); 145 if (!dd->gton) { 146 /* create the scatter context */ 147 PetscCall(DMDAGlobalToNatural_Create(da)); 148 } 149 PetscCall(VecScatterBegin(dd->gton, g, n, mode, SCATTER_FORWARD)); 150 PetscFunctionReturn(PETSC_SUCCESS); 151 } 152 153 /*@ 154 DMDAGlobalToNaturalEnd - Maps values from the global vector obtained with `DMCreateGlobalVector()` to a global vector 155 in the natural ordering. Must be preceded by `DMDAGlobalToNaturalBegin()`. 156 157 Neighbor-wise Collective 158 159 Input Parameters: 160 + da - the `DMDA` context 161 . g - the global vector, see `DMCreateGlobalVector()` 162 - mode - one of `INSERT_VALUES` or `ADD_VALUES` 163 164 Output Parameter: 165 . n - the global values in the natural ordering, see `DMDACreateNaturalVector()` 166 167 Level: advanced 168 169 Note: 170 The global and local vectors used here need not be the same as those 171 obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they 172 must have the same parallel data layout; they could, for example, be 173 obtained with VecDuplicate() from the `DMDA` originating vectors. 174 175 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 176 `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 177 @*/ 178 PetscErrorCode DMDAGlobalToNaturalEnd(DM da, Vec g, InsertMode mode, Vec n) 179 { 180 DM_DA *dd = (DM_DA *)da->data; 181 182 PetscFunctionBegin; 183 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 184 PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 185 PetscValidHeaderSpecific(n, VEC_CLASSID, 4); 186 PetscCall(VecScatterEnd(dd->gton, g, n, mode, SCATTER_FORWARD)); 187 PetscFunctionReturn(PETSC_SUCCESS); 188 } 189 190 /*@ 191 DMDANaturalToGlobalBegin - Maps values from a global vector in the "natural" ordering 192 to a global vector in the PETSc `DMDA` grid ordering. Must be followed by 193 `DMDANaturalToGlobalEnd()` to complete the exchange. 194 195 Neighbor-wise Collective 196 197 Input Parameters: 198 + da - the `DMDA` context 199 . g - the global vector in a natural ordering, see `DMDACreateNaturalVector()` 200 - mode - one of `INSERT_VALUES` or `ADD_VALUES` 201 202 Output Parameter: 203 . n - the values in the `DMDA` ordering 204 205 Level: advanced 206 207 Note: 208 The global and natural vectors used here need not be the same as those 209 obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they 210 must have the same parallel data layout; they could, for example, be 211 obtained with `VecDuplicate()` from the `DMDA` originating vectors. 212 213 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalEnd()`, `DMDAGlobalToNaturalBegin()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 214 `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 215 @*/ 216 PetscErrorCode DMDANaturalToGlobalBegin(DM da, Vec n, InsertMode mode, Vec g) 217 { 218 DM_DA *dd = (DM_DA *)da->data; 219 220 PetscFunctionBegin; 221 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 222 PetscValidHeaderSpecific(n, VEC_CLASSID, 2); 223 PetscValidHeaderSpecific(g, VEC_CLASSID, 4); 224 if (!dd->gton) { 225 /* create the scatter context */ 226 PetscCall(DMDAGlobalToNatural_Create(da)); 227 } 228 PetscCall(VecScatterBegin(dd->gton, n, g, mode, SCATTER_REVERSE)); 229 PetscFunctionReturn(PETSC_SUCCESS); 230 } 231 232 /*@ 233 DMDANaturalToGlobalEnd - Maps values from the natural ordering global vector 234 to a global vector in the PETSc `DMDA` ordering. Must be preceded by `DMDANaturalToGlobalBegin()`. 235 236 Neighbor-wise Collective 237 238 Input Parameters: 239 + da - the `DMDA` context 240 . g - the global vector in a natural ordering 241 - mode - one of `INSERT_VALUES` or `ADD_VALUES` 242 243 Output Parameter: 244 . n - the global values in the PETSc `DMDA` ordering 245 246 Level: advanced 247 248 Note: 249 The global and local vectors used here need not be the same as those 250 obtained from `DMCreateGlobalVector()` and `DMDACreateNaturalVector()`, BUT they 251 must have the same parallel data layout; they could, for example, be 252 obtained with `VecDuplicate()` from the `DMDA` originating vectors. 253 254 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMDAGlobalToNaturalEnd()`, `DMLocalToGlobalBegin()`, `DMDACreate2d()`, 255 `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMDACreateNaturalVector()` 256 @*/ 257 PetscErrorCode DMDANaturalToGlobalEnd(DM da, Vec n, InsertMode mode, Vec g) 258 { 259 DM_DA *dd = (DM_DA *)da->data; 260 261 PetscFunctionBegin; 262 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 263 PetscValidHeaderSpecific(n, VEC_CLASSID, 2); 264 PetscValidHeaderSpecific(g, VEC_CLASSID, 4); 265 PetscCall(VecScatterEnd(dd->gton, n, g, mode, SCATTER_REVERSE)); 266 PetscFunctionReturn(PETSC_SUCCESS); 267 } 268