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