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