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] = PETSC_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] = PETSC_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] = PETSC_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 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()"); 195 ierr = VecDestroy(&dm->globalin[i]);CHKERRQ(ierr); 196 } 197 PetscFunctionReturn(0); 198 } 199 200 #undef __FUNCT__ 201 #define __FUNCT__ "DMRestoreGlobalVector" 202 /*@ 203 DMRestoreGlobalVector - Returns a Seq PETSc vector that 204 obtained from DMGetGlobalVector(). Do not use with vector obtained via 205 DMCreateGlobalVector(). 206 207 Not Collective 208 209 Input Parameter: 210 + dm - the distributed array 211 - g - the global vector 212 213 Level: beginner 214 215 .keywords: distributed array, create, global, vector 216 217 .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(), 218 DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(), 219 DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector() 220 @*/ 221 PetscErrorCode DMRestoreGlobalVector(DM dm,Vec* g) 222 { 223 PetscErrorCode ierr; 224 PetscInt i,j; 225 226 PetscFunctionBegin; 227 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 228 PetscValidPointer(g,2); 229 for (j=0; j<DM_MAX_WORK_VECTORS; j++) { 230 if (*g == dm->globalout[j]) { 231 dm->globalout[j] = PETSC_NULL; 232 for (i=0; i<DM_MAX_WORK_VECTORS; i++) { 233 if (!dm->globalin[i]) { 234 dm->globalin[i] = *g; 235 goto alldone; 236 } 237 } 238 } 239 } 240 ierr = VecDestroy(g);CHKERRQ(ierr); 241 alldone: 242 PetscFunctionReturn(0); 243 } 244 245 #undef __FUNCT__ 246 #define __FUNCT__ "DMGetNamedGlobalVector" 247 /*@C 248 DMGetNamedGlobalVector - get access to a named, persistent global vector 249 250 Collective on DM 251 252 Input Arguments: 253 + dm - DM to hold named vectors 254 - name - unique name for Vec 255 256 Output Arguments: 257 . X - named Vec 258 259 Level: developer 260 261 Note: If a Vec with the given name does not exist, it is created. 262 263 .seealso: DMRestoreNamedGlobalVector() 264 @*/ 265 PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X) 266 { 267 PetscErrorCode ierr; 268 DMNamedVecLink link; 269 270 PetscFunctionBegin; 271 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 272 PetscValidCharPointer(name,2); 273 PetscValidPointer(X,3); 274 for (link=dm->namedglobal; link; link=link->next) { 275 PetscBool match; 276 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr); 277 if (match) { 278 if (link->status != DMVEC_STATUS_IN) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name); 279 goto found; 280 } 281 } 282 283 /* Create the Vec */ 284 ierr = PetscMalloc(sizeof *link,&link);CHKERRQ(ierr); 285 ierr = PetscStrallocpy(name,&link->name);CHKERRQ(ierr); 286 ierr = DMCreateGlobalVector(dm,&link->X);CHKERRQ(ierr); 287 link->next = dm->namedglobal; 288 dm->namedglobal = link; 289 290 found: 291 *X = link->X; 292 link->status = DMVEC_STATUS_OUT; 293 PetscFunctionReturn(0); 294 } 295 296 #undef __FUNCT__ 297 #define __FUNCT__ "DMRestoreNamedGlobalVector" 298 /*@C 299 DMRestoreNamedGlobalVector - restore access to a named, persistent global vector 300 301 Collective on DM 302 303 Input Arguments: 304 + dm - DM on which the vector was gotten 305 . name - name under which the vector was gotten 306 - X - Vec to restore 307 308 Output Arguments: 309 310 Level: developer 311 312 .seealso: DMGetNamedGlobalVector() 313 @*/ 314 PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X) 315 { 316 PetscErrorCode ierr; 317 DMNamedVecLink link; 318 319 PetscFunctionBegin; 320 PetscValidHeaderSpecific(dm,DM_CLASSID,1); 321 PetscValidCharPointer(name,2); 322 PetscValidPointer(X,3); 323 PetscValidHeaderSpecific(*X,VEC_CLASSID,3); 324 for (link=dm->namedglobal; link; link=link->next) { 325 PetscBool match; 326 ierr = PetscStrcmp(name,link->name,&match);CHKERRQ(ierr); 327 if (match) { 328 if (link->status != DMVEC_STATUS_OUT) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name); 329 if (link->X != *X) SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_INCOMP,"Attempt to restore Vec name '%s', but Vec does not match the cache",name); 330 link->status = DMVEC_STATUS_IN; 331 *X = PETSC_NULL; 332 PetscFunctionReturn(0); 333 } 334 } 335 SETERRQ1(((PetscObject)dm)->comm,PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name); 336 PetscFunctionReturn(0); 337 } 338