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