/* Code for manipulating distributed regular arrays in parallel. */ #include /*I "petscdmda.h" I*/ PetscErrorCode VecDuplicate_MPI_DA(Vec g, Vec *gg) { DM da; PetscLayout map; PetscFunctionBegin; PetscCall(VecGetDM(g, &da)); PetscCall(DMCreateGlobalVector(da, gg)); PetscCall(VecGetLayout(g, &map)); PetscCall(VecSetLayout(*gg, map)); PetscFunctionReturn(0); } PetscErrorCode DMCreateGlobalVector_DA(DM da, Vec *g) { DM_DA *dd = (DM_DA *)da->data; PetscFunctionBegin; PetscValidHeaderSpecific(da, DM_CLASSID, 1); PetscValidPointer(g, 2); PetscCall(VecCreate(PetscObjectComm((PetscObject)da), g)); PetscCall(VecSetSizes(*g, dd->Nlocal, PETSC_DETERMINE)); PetscCall(VecSetBlockSize(*g, dd->w)); PetscCall(VecSetType(*g, da->vectype)); if (dd->Nlocal < da->bind_below) { PetscCall(VecSetBindingPropagates(*g, PETSC_TRUE)); PetscCall(VecBindToCPU(*g, PETSC_TRUE)); } PetscCall(VecSetDM(*g, da)); PetscCall(VecSetLocalToGlobalMapping(*g, da->ltogmap)); PetscCall(VecSetOperation(*g, VECOP_VIEW, (void (*)(void))VecView_MPI_DA)); PetscCall(VecSetOperation(*g, VECOP_LOAD, (void (*)(void))VecLoad_Default_DA)); PetscCall(VecSetOperation(*g, VECOP_DUPLICATE, (void (*)(void))VecDuplicate_MPI_DA)); PetscFunctionReturn(0); } /*@ DMDACreateNaturalVector - Creates a parallel PETSc vector that will hold vector values in the natural numbering, rather than in the PETSc parallel numbering associated with the DMDA. Collective Input Parameter: . da - the distributed array Output Parameter: . g - the distributed global vector Level: developer Note: The output parameter, g, is a regular PETSc vector that should be destroyed with a call to VecDestroy() when usage is finished. The number of local entries in the vector on each process is the same as in a vector created with DMCreateGlobalVector(). .seealso: `DMCreateLocalVector()`, `VecDuplicate()`, `VecDuplicateVecs()`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`, `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMLocalToGlobalBegin()` @*/ PetscErrorCode DMDACreateNaturalVector(DM da, Vec *g) { PetscInt cnt; DM_DA *dd = (DM_DA *)da->data; PetscFunctionBegin; PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA); PetscValidPointer(g, 2); if (dd->natural) { PetscCall(PetscObjectGetReference((PetscObject)dd->natural, &cnt)); if (cnt == 1) { /* object is not currently used by anyone */ PetscCall(PetscObjectReference((PetscObject)dd->natural)); *g = dd->natural; } else PetscCall(VecDuplicate(dd->natural, g)); } else { /* create the first version of this guy */ PetscCall(VecCreate(PetscObjectComm((PetscObject)da), g)); PetscCall(VecSetSizes(*g, dd->Nlocal, PETSC_DETERMINE)); PetscCall(VecSetBlockSize(*g, dd->w)); PetscCall(VecSetType(*g, da->vectype)); PetscCall(PetscObjectReference((PetscObject)*g)); dd->natural = *g; } PetscFunctionReturn(0); }