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