static char help[] ="Extract a 2D slice in natural ordering from a 3D vector, Command line options :\n\ Mx/My/Mz - set the dimensions of the parent vector\n\ sliceaxis - Integer describing the axis along which the sice will be selected (0-X, 1-Y, 2-Z)\n\ sliceid - set the location where the slice will be extraced from the parent vector\n"; /* This example shows to extract a 2D slice in natural ordering from a 3D DMDA vector (first by extracting the slice and then by converting it to natural ordering) */ #include #include int main(int argc,char **argv) { DM da3D; /* 3D DMDA object */ DM da2D; /* 2D DMDA object */ Vec vec_full; /* Parent vector */ Vec vec_extracted; /* Slice vector */ Vec vec_slice; /* vector in natural ordering */ Vec vec_slice_g; /* aliased vector in natural ordering */ IS patchis_3d; /* IS to select slice and extract subvector */ IS patchis_2d; /* Patch IS for 2D vector, will be converted to application ordering */ IS scatis_extracted_slice; /* PETSc indexed IS for extracted slice */ IS scatis_natural_slice; /* natural/application ordered IS for slice*/ IS scatis_natural_slice_g; /* aliased natural/application ordered IS for slice */ VecScatter vscat; /* scatter slice in DMDA ordering <-> slice in column major ordering */ AO da2D_ao; /* AO associated with 2D DMDA */ MPI_Comm subset_mpi_comm=MPI_COMM_NULL; /* MPI communicator where the slice lives */ PetscScalar ***vecdata3d; /* Pointer to access 3d parent vector */ const PetscScalar *array; /* pointer to create aliased Vec */ PetscInt Mx=4,My=4,Mz=4; /* Dimensions for 3D DMDA */ const PetscInt *l1,*l2; /* 3D DMDA layout */ PetscInt M1=-1,M2=-1; /* Dimensions for 2D DMDA */ PetscInt m1=-1,m2=-1; /* Layouts for 2D DMDA */ PetscInt sliceid=2; /* slice index to pick the slice */ PetscInt sliceaxis=0; /* Select axis along which the slice will be extracted */ PetscInt i,j,k; /* Iteration indices */ PetscInt ixs,iys,izs; /* Corner indices for 3D vector */ PetscInt ixm,iym,izm; /* Widths of parent vector */ PetscInt low, high; /* ownership range indices */ PetscInt in; /* local size index for IS*/ PetscInt vn; /* local size index */ const PetscInt *is_array; /* pointer to create aliased IS */ MatStencil lower, upper; /* Stencils to select slice for Vec */ PetscBool patchis_offproc = PETSC_FALSE; /* flag to DMDACreatePatchIS indicating that off-proc values are to be ignored */ PetscMPIInt rank,size; /* MPI rank and size */ PetscErrorCode ierr; /* error checking */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program and set problem parameters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc, &argv, (char*)0, help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL, NULL, "-Mx", &Mx, NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL, NULL, "-My", &My, NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL, NULL, "-Mz", &Mz, NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL, NULL, "-sliceid", &sliceid, NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL, NULL, "-sliceaxis", &sliceaxis, NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create 3D DMDA object. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ ierr = DMDACreate3d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_STAR, Mx, My, Mz, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, 1, 1, NULL, NULL, NULL, &da3D);CHKERRQ(ierr); ierr = DMSetFromOptions(da3D);CHKERRQ(ierr); ierr = DMSetUp(da3D);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the parent vector - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ ierr = DMCreateGlobalVector(da3D, &vec_full);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) vec_full, "full_vector");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Populate the 3D vector - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDAGetCorners(da3D, &ixs, &iys, &izs, &ixm, &iym, &izm);CHKERRQ(ierr); ierr = DMDAVecGetArray(da3D, vec_full, &vecdata3d);CHKERRQ(ierr); for (k=izs; k natural 2D slice vector - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecScatterCreate(vec_extracted, scatis_extracted_slice, vec_slice_g, scatis_natural_slice_g, &vscat);CHKERRQ(ierr); ierr = VecScatterBegin(vscat, vec_extracted, vec_slice_g, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(vscat, vec_extracted, vec_slice_g, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - View the natural 2D slice vector - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_DENSE);CHKERRQ(ierr); ierr = VecView(vec_slice_g, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Restore subvector, destroy data structures and exit. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecRestoreSubVector(vec_full, patchis_3d, &vec_extracted);CHKERRQ(ierr); ierr = VecDestroy(&vec_full);CHKERRQ(ierr); ierr = VecScatterDestroy(&vscat);CHKERRQ(ierr); ierr = ISDestroy(&scatis_extracted_slice);CHKERRQ(ierr); ierr = ISDestroy(&scatis_natural_slice_g);CHKERRQ(ierr); ierr = VecDestroy(&vec_slice_g);CHKERRQ(ierr); ierr = ISDestroy(&patchis_3d);CHKERRQ(ierr); ierr = DMDestroy(&da3D);CHKERRQ(ierr); if (subset_mpi_comm != MPI_COMM_NULL) { ierr = ISDestroy(&scatis_natural_slice);CHKERRQ(ierr); ierr = VecDestroy(&vec_slice);CHKERRQ(ierr); ierr = DMDestroy(&da2D);CHKERRQ(ierr); } ierr = PetscFinalize(); return ierr; }