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