1 static char help[] = "Demonstrates VecStrideSubSetScatter() and VecStrideSubSetGather().\n\n"; 2 3 /* 4 Allows one to easily pull out some components of a multi-component vector and put them in another vector. 5 6 Note that these are special cases of VecScatter 7 */ 8 9 /* 10 Include "petscvec.h" so that we can use vectors. Note that this file 11 automatically includes: 12 petscsys.h - base PETSc routines petscis.h - index sets 13 petscviewer.h - viewers 14 */ 15 16 #include <petscvec.h> 17 18 int main(int argc, char **argv) 19 { 20 Vec v, s; 21 PetscInt i, start, end, n = 8; 22 PetscScalar value; 23 const PetscInt vidx[] = {1, 2}, sidx[] = {1, 0}; 24 PetscInt miidx[2]; 25 PetscReal mvidx[2]; 26 27 PetscFunctionBeginUser; 28 PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 29 PetscCall(PetscOptionsGetInt(NULL, NULL, "-n", &n, NULL)); 30 31 /* 32 Create multi-component vector with 4 components 33 */ 34 PetscCall(VecCreate(PETSC_COMM_WORLD, &v)); 35 PetscCall(VecSetSizes(v, PETSC_DECIDE, n)); 36 PetscCall(VecSetBlockSize(v, 4)); 37 PetscCall(VecSetFromOptions(v)); 38 39 /* 40 Create double-component vectors 41 */ 42 PetscCall(VecCreate(PETSC_COMM_WORLD, &s)); 43 PetscCall(VecSetSizes(s, PETSC_DECIDE, n / 2)); 44 PetscCall(VecSetBlockSize(s, 2)); 45 PetscCall(VecSetFromOptions(s)); 46 47 /* 48 Set the vector values 49 */ 50 PetscCall(VecGetOwnershipRange(v, &start, &end)); 51 for (i = start; i < end; i++) { 52 value = i; 53 PetscCall(VecSetValues(v, 1, &i, &value, INSERT_VALUES)); 54 } 55 PetscCall(VecAssemblyBegin(v)); 56 PetscCall(VecAssemblyEnd(v)); 57 58 /* 59 Get the components from the large multi-component vector to the small multi-component vector, 60 scale the smaller vector and then move values back to the large vector 61 */ 62 PetscCall(VecStrideSubSetGather(v, PETSC_DETERMINE, vidx, NULL, s, INSERT_VALUES)); 63 PetscCall(VecView(s, PETSC_VIEWER_STDOUT_WORLD)); 64 PetscCall(VecScale(s, 100.0)); 65 66 PetscCall(VecStrideSubSetScatter(s, PETSC_DETERMINE, NULL, vidx, v, ADD_VALUES)); 67 PetscCall(VecView(v, PETSC_VIEWER_STDOUT_WORLD)); 68 69 /* 70 Get the components from the large multi-component vector to the small multi-component vector, 71 scale the smaller vector and then move values back to the large vector 72 */ 73 PetscCall(VecStrideSubSetGather(v, 2, vidx, sidx, s, INSERT_VALUES)); 74 PetscCall(VecView(s, PETSC_VIEWER_STDOUT_WORLD)); 75 PetscCall(VecScale(s, 100.0)); 76 77 PetscCall(VecStrideSubSetScatter(s, 2, sidx, vidx, v, ADD_VALUES)); 78 PetscCall(VecView(v, PETSC_VIEWER_STDOUT_WORLD)); 79 80 PetscCall(VecStrideMax(v, 1, &miidx[0], &mvidx[0])); 81 PetscCall(VecStrideMin(v, 1, &miidx[1], &mvidx[1])); 82 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Min/Max: %" PetscInt_FMT " %g, %" PetscInt_FMT " %g\n", miidx[0], (double)mvidx[0], miidx[1], (double)mvidx[1])); 83 /* 84 Free work space. All PETSc objects should be destroyed when they 85 are no longer needed. 86 */ 87 PetscCall(VecDestroy(&v)); 88 PetscCall(VecDestroy(&s)); 89 PetscCall(PetscFinalize()); 90 return 0; 91 } 92 93 /*TEST 94 95 test: 96 filter: grep -v type | grep -v " MPI process" | grep -v Process 97 diff_args: -j 98 nsize: 2 99 100 test: 101 filter: grep -v type | grep -v " MPI process" | grep -v Process 102 output_file: output/ex45_1.out 103 diff_args: -j 104 suffix: 2 105 nsize: 1 106 args: -vec_type {{seq mpi}} 107 108 TEST*/ 109