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