1 #include <petsc-private/dmimpl.h> /*I "petscdm.h" I*/ 2 3 #undef __FUNCT__ 4 #define __FUNCT__ "DMGetLocalVector" 5 /*@ 6 DMGetLocalVector - Gets a Seq PETSc vector that 7 may be used with the DMXXX routines. This vector has spaces for the ghost values. 8 9 Not Collective 10 11 Input Parameter: 12 . dm - the distributed array 13 14 Output Parameter: 15 . g - the local vector 16 17 Level: beginner 18 19 Note: 20 The vector values are NOT initialized and may have garbage in them, so you may need 21 to zero them. 22 23 The output parameter, g, is a regular PETSc vector that should be returned with 24 DMRestoreLocalVector() DO NOT call VecDestroy() on it. 25 26 VecStride*() operations can be useful when using DM with dof > 1 27 28 .keywords: distributed array, create, local, vector 29 30 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(), 31 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(), 32 DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(), 33 VecStrideMax(), VecStrideMin(), VecStrideNorm() 34 @*/ 35 PetscErrorCode DMGetLocalVector(DM dm,Vec *g) 36 { 37 PetscErrorCode ierr,i; 38 39 PetscFunctionBegin; 40 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 41 PetscValidPointer(g,2); 42 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 43 if (dm->localin[i]) { 44 *g = dm->localin[i]; 45 dm->localin[i] = NULL; 46 goto alldone; 47 } 48 } 49 ierr = DMCreateLocalVector(dm,g);CHKERRQ(ierr); 50 51 alldone: 52 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 53 if (!dm->localout[i]) { 54 dm->localout[i] = *g; 55 break; 56 } 57 } 58 PetscFunctionReturn(0); 59 } 60 61 #undef __FUNCT__ 62 #define __FUNCT__ "DMRestoreLocalVector" 63 /*@ 64 DMRestoreLocalVector - Returns a Seq PETSc vector that 65 obtained from DMGetLocalVector(). Do not use with vector obtained via 66 DMCreateLocalVector(). 67 68 Not Collective 69 70 Input Parameter: 71 + dm - the distributed array 72 - g - the local vector 73 74 Level: beginner 75 76 .keywords: distributed array, create, local, vector 77 78 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(), 79 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(), 80 DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector() 81 @*/ 82 PetscErrorCode DMRestoreLocalVector(DM dm,Vec *g) 83 { 84 PetscErrorCode ierr; 85 PetscInt i,j; 86 87 PetscFunctionBegin; 88 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 89 PetscValidPointer(g,2); 90 for (j=0; j<DM_MAX_WORK_VECTORS; j++) { 91 if (*g == dm->localout[j]) { 92 dm->localout[j] = NULL; 93 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 94 if (!dm->localin[i]) { 95 dm->localin[i] = *g; 96 goto alldone; 97 } 98 } 99 } 100 } 101 ierr = VecDestroy(g);CHKERRQ(ierr); 102 alldone: 103 *g = NULL; 104 PetscFunctionReturn(0); 105 } 106 107 #undef __FUNCT__ 108 #define __FUNCT__ "DMGetGlobalVector" 109 /*@ 110 DMGetGlobalVector - Gets a MPI PETSc vector that 111 may be used with the DMXXX routines. 112 113 Collective on DM 114 115 Input Parameter: 116 . dm - the distributed array 117 118 Output Parameter: 119 . g - the global vector 120 121 Level: beginner 122 123 Note: 124 The vector values are NOT initialized and may have garbage in them, so you may need 125 to zero them. 126 127 The output parameter, g, is a regular PETSc vector that should be returned with 128 DMRestoreGlobalVector() DO NOT call VecDestroy() on it. 129 130 VecStride*() operations can be useful when using DM with dof > 1 131 132 .keywords: distributed array, create, Global, vector 133 134 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(), 135 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(), 136 DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector() 137 VecStrideMax(), VecStrideMin(), VecStrideNorm() 138 139 @*/ 140 PetscErrorCode DMGetGlobalVector(DM dm,Vec *g) 141 { 142 PetscErrorCode ierr; 143 PetscInt i; 144 145 PetscFunctionBegin; 146 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 147 PetscValidPointer(g,2); 148 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 149 if (dm->globalin[i]) { 150 *g = dm->globalin[i]; 151 dm->globalin[i] = NULL; 152 goto alldone; 153 } 154 } 155 ierr = DMCreateGlobalVector(dm,g);CHKERRQ(ierr); 156 157 alldone: 158 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 159 if (!dm->globalout[i]) { 160 dm->globalout[i] = *g; 161 break; 162 } 163 } 164 PetscFunctionReturn(0); 165 } 166 167 #undef __FUNCT__ 168 #define __FUNCT__ "DMClearGlobalVectors" 169 /*@ 170 DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM 171 172 Collective on DM 173 174 Input Parameter: 175 . dm - the distributed array 176 177 Level: developer 178 179 .keywords: distributed array, create, Global, vector 180 181 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(), 182 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(), 183 DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector() 184 VecStrideMax(), VecStrideMin(), VecStrideNorm() 185 186 @*/ 187 PetscErrorCode DMClearGlobalVectors(DM dm) 188 { 189 PetscErrorCode ierr; 190 PetscInt i; 191 192 PetscFunctionBegin; 193 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 194 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 195 Vec g; 196 if (dm->globalout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()"); 197 g = dm->globalin[i]; 198 dm->globalin[i] = NULL; 199 ierr = VecDestroy(&g);CHKERRQ(ierr); 200 } 201 PetscFunctionReturn(0); 202 } 203 204 #undef __FUNCT__ 205 #define __FUNCT__ "DMRestoreGlobalVector" 206 /*@ 207 DMRestoreGlobalVector - Returns a Seq PETSc vector that 208 obtained from DMGetGlobalVector(). Do not use with vector obtained via 209 DMCreateGlobalVector(). 210 211 Not Collective 212 213 Input Parameter: 214 + dm - the distributed array 215 - g - the global vector 216 217 Level: beginner 218 219 .keywords: distributed array, create, global, vector 220 221 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(), 222 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(), 223 DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector() 224 @*/ 225 PetscErrorCode DMRestoreGlobalVector(DM dm,Vec *g) 226 { 227 PetscErrorCode ierr; 228 PetscInt i,j; 229 230 PetscFunctionBegin; 231 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 232 PetscValidPointer(g,2); 233 for (j=0; j<DM_MAX_WORK_VECTORS; j++) { 234 if (*g == dm->globalout[j]) { 235 dm->globalout[j] = NULL; 236 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 237 if (!dm->globalin[i]) { 238 dm->globalin[i] = *g; 239 goto alldone; 240 } 241 } 242 } 243 } 244 ierr = VecDestroy(g);CHKERRQ(ierr); 245 alldone: 246 *g = NULL; 247 PetscFunctionReturn(0); 248 } 249 250 #undef __FUNCT__ 251 #define __FUNCT__ "DMGetNamedGlobalVector" 252 /*@C 253 DMGetNamedGlobalVector - get access to a named, persistent global vector 254 255 Collective on DM 256 257 Input Arguments: 258 + dm - DM to hold named vectors 259 - name - unique name for Vec 260 261 Output Arguments: 262 . X - named Vec 263 264 Level: developer 265 266 Note: If a Vec with the given name does not exist, it is created. 267 268 .seealso: DMRestoreNamedGlobalVector() 269 @*/ 270 PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X) 271 { 272 PetscErrorCode ierr; 273 DMNamedVecLink link; 274 275 PetscFunctionBegin; 276 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 277 PetscValidCharPointer(name,2); 278 PetscValidPointer(X,3); 279 for (link=dm->namedglobal; link; link=link->next) { 280 PetscBool match; 281 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr); 282 if (match) { 283 if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name); 284 goto found; 285 } 286 } 287 288 /* Create the Vec */ 289 ierr = PetscNew(&link);CHKERRQ(ierr); 290 ierr = PetscStrallocpy(name,&link->name);CHKERRQ(ierr); 291 ierr = DMCreateGlobalVector(dm,&link->X);CHKERRQ(ierr); 292 link->next = dm->namedglobal; 293 dm->namedglobal = link; 294 295 found: 296 *X = link->X; 297 link->status = DMVEC_STATUS_OUT; 298 PetscFunctionReturn(0); 299 } 300 301 #undef __FUNCT__ 302 #define __FUNCT__ "DMRestoreNamedGlobalVector" 303 /*@C 304 DMRestoreNamedGlobalVector - restore access to a named, persistent global vector 305 306 Collective on DM 307 308 Input Arguments: 309 + dm - DM on which the vector was gotten 310 . name - name under which the vector was gotten 311 - X - Vec to restore 312 313 Output Arguments: 314 315 Level: developer 316 317 .seealso: DMGetNamedGlobalVector() 318 @*/ 319 PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X) 320 { 321 PetscErrorCode ierr; 322 DMNamedVecLink link; 323 324 PetscFunctionBegin; 325 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 326 PetscValidCharPointer(name,2); 327 PetscValidPointer(X,3); 328 PetscValidHeaderSpecific(*X,VEC_CLASSID,3); 329 for (link=dm->namedglobal; link; link=link->next) { 330 PetscBool match; 331 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr); 332 if (match) { 333 if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name); 334 if (link->X != *X) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Attempt to restore Vec name '%s', but Vec does not match the cache",name); 335 link->status = DMVEC_STATUS_IN; 336 *X = NULL; 337 PetscFunctionReturn(0); 338 } 339 } 340 SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name); 341 PetscFunctionReturn(0); 342 } 343 344 #undef __FUNCT__ 345 #define __FUNCT__ "DMGetNamedLocalVector" 346 /*@C 347 DMGetNamedLocalVector - get access to a named, persistent local vector 348 349 Not Collective 350 351 Input Arguments: 352 + dm - DM to hold named vectors 353 - name - unique name for Vec 354 355 Output Arguments: 356 . X - named Vec 357 358 Level: developer 359 360 Note: If a Vec with the given name does not exist, it is created. 361 362 .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector() 363 @*/ 364 PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X) 365 { 366 PetscErrorCode ierr; 367 DMNamedVecLink link; 368 369 PetscFunctionBegin; 370 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 371 PetscValidCharPointer(name,2); 372 PetscValidPointer(X,3); 373 for (link=dm->namedlocal; link; link=link->next) { 374 PetscBool match; 375 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr); 376 if (match) { 377 if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name); 378 goto found; 379 } 380 } 381 382 /* Create the Vec */ 383 ierr = PetscNew(&link);CHKERRQ(ierr); 384 ierr = PetscStrallocpy(name,&link->name);CHKERRQ(ierr); 385 ierr = DMCreateLocalVector(dm,&link->X);CHKERRQ(ierr); 386 link->next = dm->namedlocal; 387 dm->namedlocal = link; 388 389 found: 390 *X = link->X; 391 link->status = DMVEC_STATUS_OUT; 392 PetscFunctionReturn(0); 393 } 394 395 #undef __FUNCT__ 396 #define __FUNCT__ "DMRestoreNamedLocalVector" 397 /*@C 398 DMRestoreNamedLocalVector - restore access to a named, persistent local vector 399 400 Not Collective 401 402 Input Arguments: 403 + dm - DM on which the vector was gotten 404 . name - name under which the vector was gotten 405 - X - Vec to restore 406 407 Output Arguments: 408 409 Level: developer 410 411 .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector() 412 @*/ 413 PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X) 414 { 415 PetscErrorCode ierr; 416 DMNamedVecLink link; 417 418 PetscFunctionBegin; 419 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 420 PetscValidCharPointer(name,2); 421 PetscValidPointer(X,3); 422 PetscValidHeaderSpecific(*X,VEC_CLASSID,3); 423 for (link=dm->namedlocal; link; link=link->next) { 424 PetscBool match; 425 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr); 426 if (match) { 427 if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name); 428 if (link->X != *X) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Attempt to restore Vec name '%s', but Vec does not match the cache",name); 429 link->status = DMVEC_STATUS_IN; 430 *X = NULL; 431 PetscFunctionReturn(0); 432 } 433 } 434 SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name); 435 PetscFunctionReturn(0); 436 } 437