1 /* 2 Code for manipulating distributed regular arrays in parallel. 3 */ 4 5 #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 6 7 PetscErrorCode DMCreateGlobalVector_DA(DM da, Vec *g) 8 { 9 DM_DA *dd = (DM_DA *)da->data; 10 11 PetscFunctionBegin; 12 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 13 PetscAssertPointer(g, 2); 14 PetscCall(VecCreate(PetscObjectComm((PetscObject)da), g)); 15 PetscCall(VecSetSizes(*g, dd->Nlocal, PETSC_DETERMINE)); 16 PetscCall(VecSetBlockSize(*g, dd->w)); 17 PetscCall(VecSetType(*g, da->vectype)); 18 if (dd->Nlocal < da->bind_below) { 19 PetscCall(VecSetBindingPropagates(*g, PETSC_TRUE)); 20 PetscCall(VecBindToCPU(*g, PETSC_TRUE)); 21 } 22 PetscCall(VecSetDM(*g, da)); 23 PetscCall(VecSetLocalToGlobalMapping(*g, da->ltogmap)); 24 PetscCall(VecSetOperation(*g, VECOP_VIEW, (void (*)(void))VecView_MPI_DA)); 25 PetscCall(VecSetOperation(*g, VECOP_LOAD, (void (*)(void))VecLoad_Default_DA)); 26 PetscFunctionReturn(PETSC_SUCCESS); 27 } 28 29 /*@ 30 DMDACreateNaturalVector - Creates a parallel PETSc vector that 31 will hold vector values in the natural numbering, rather than in 32 the PETSc parallel numbering associated with the `DMDA`. 33 34 Collective 35 36 Input Parameter: 37 . da - the `DMDA` 38 39 Output Parameter: 40 . g - the distributed global vector 41 42 Level: advanced 43 44 Notes: 45 The natural numbering is a number of grid nodes that starts with, in three dimensions, with (0,0,0), (1,0,0), (2,0,0), ..., (m-1,0,0) followed by 46 (0,1,0), (1,1,0), (2,1,0), ..., (m,1,0) etc up to (0,n-1,p-1), (1,n-1,p-1), (2,n-1,p-1), ..., (m-1,n-1,p-1). 47 48 The output parameter, `g`, is a regular `Vec` that should be destroyed 49 with a call to `VecDestroy()` when usage is finished. 50 51 The number of local entries in the vector on each process is the same 52 as in a vector created with `DMCreateGlobalVector()`. 53 54 .seealso: [](sec_struct), `DM`, `DMDA`, `DMDAGlobalToNaturalBegin()`, `DMDAGlobalToNaturalEnd()`, `DMDANaturalToGlobalBegin()`, `DMDANaturalToGlobalEnd()`, 55 `DMCreateLocalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`, 56 `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` 57 @*/ 58 PetscErrorCode DMDACreateNaturalVector(DM da, Vec *g) 59 { 60 PetscInt cnt; 61 DM_DA *dd = (DM_DA *)da->data; 62 63 PetscFunctionBegin; 64 PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); 65 PetscAssertPointer(g, 2); 66 if (dd->natural) { 67 PetscCall(PetscObjectGetReference((PetscObject)dd->natural, &cnt)); 68 if (cnt == 1) { /* object is not currently used by anyone */ 69 PetscCall(PetscObjectReference((PetscObject)dd->natural)); 70 *g = dd->natural; 71 } else PetscCall(VecDuplicate(dd->natural, g)); 72 } else { /* create the first version of this guy */ 73 PetscCall(VecCreate(PetscObjectComm((PetscObject)da), g)); 74 PetscCall(VecSetSizes(*g, dd->Nlocal, PETSC_DETERMINE)); 75 PetscCall(VecSetBlockSize(*g, dd->w)); 76 PetscCall(VecSetType(*g, da->vectype)); 77 PetscCall(PetscObjectReference((PetscObject)*g)); 78 dd->natural = *g; 79 } 80 PetscFunctionReturn(PETSC_SUCCESS); 81 } 82