xref: /petsc/src/mat/tests/ex19.c (revision c4762a1b19cd2af06abeed90e8f9d34fb975dd94)
1*c4762a1bSJed Brown 
2*c4762a1bSJed Brown static char help[] = "Tests reusing MPI parallel matrices and MatGetValues().\n\
3*c4762a1bSJed Brown To test the parallel matrix assembly, this example intentionally lays out\n\
4*c4762a1bSJed Brown the matrix across processors differently from the way it is assembled.\n\
5*c4762a1bSJed Brown This example uses bilinear elements on the unit square.  Input arguments are:\n\
6*c4762a1bSJed Brown   -m <size> : problem size\n\n";
7*c4762a1bSJed Brown 
8*c4762a1bSJed Brown #include <petscmat.h>
9*c4762a1bSJed Brown 
10*c4762a1bSJed Brown int FormElementStiffness(PetscReal H,PetscScalar *Ke)
11*c4762a1bSJed Brown {
12*c4762a1bSJed Brown   PetscFunctionBegin;
13*c4762a1bSJed Brown   Ke[0]  = H/6.0;    Ke[1]  = -.125*H; Ke[2]  = H/12.0;   Ke[3]  = -.125*H;
14*c4762a1bSJed Brown   Ke[4]  = -.125*H;  Ke[5]  = H/6.0;   Ke[6]  = -.125*H;  Ke[7]  = H/12.0;
15*c4762a1bSJed Brown   Ke[8]  = H/12.0;   Ke[9]  = -.125*H; Ke[10] = H/6.0;    Ke[11] = -.125*H;
16*c4762a1bSJed Brown   Ke[12] = -.125*H;  Ke[13] = H/12.0;  Ke[14] = -.125*H;  Ke[15] = H/6.0;
17*c4762a1bSJed Brown   PetscFunctionReturn(0);
18*c4762a1bSJed Brown }
19*c4762a1bSJed Brown 
20*c4762a1bSJed Brown int main(int argc,char **args)
21*c4762a1bSJed Brown {
22*c4762a1bSJed Brown   Mat            C;
23*c4762a1bSJed Brown   Vec            u,b;
24*c4762a1bSJed Brown   PetscErrorCode ierr;
25*c4762a1bSJed Brown   PetscMPIInt    size,rank;
26*c4762a1bSJed Brown   PetscInt       i,m = 5,N,start,end,M,idx[4];
27*c4762a1bSJed Brown   PetscInt       j,nrsub,ncsub,*rsub,*csub,mystart,myend;
28*c4762a1bSJed Brown   PetscBool      flg;
29*c4762a1bSJed Brown   PetscScalar    one = 1.0,Ke[16],*vals;
30*c4762a1bSJed Brown   PetscReal      h,norm;
31*c4762a1bSJed Brown 
32*c4762a1bSJed Brown   ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
33*c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);CHKERRQ(ierr);
34*c4762a1bSJed Brown 
35*c4762a1bSJed Brown   N    = (m+1)*(m+1); /* dimension of matrix */
36*c4762a1bSJed Brown   M    = m*m;      /* number of elements */
37*c4762a1bSJed Brown   h    = 1.0/m;    /* mesh width */
38*c4762a1bSJed Brown   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
39*c4762a1bSJed Brown   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
40*c4762a1bSJed Brown 
41*c4762a1bSJed Brown   /* Create stiffness matrix */
42*c4762a1bSJed Brown   ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr);
43*c4762a1bSJed Brown   ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,N,N);CHKERRQ(ierr);
44*c4762a1bSJed Brown   ierr = MatSetFromOptions(C);CHKERRQ(ierr);
45*c4762a1bSJed Brown   ierr = MatSetUp(C);CHKERRQ(ierr);
46*c4762a1bSJed Brown 
47*c4762a1bSJed Brown   start = rank*(M/size) + ((M%size) < rank ? (M%size) : rank);
48*c4762a1bSJed Brown   end   = start + M/size + ((M%size) > rank);
49*c4762a1bSJed Brown 
50*c4762a1bSJed Brown   /* Form the element stiffness for the Laplacian */
51*c4762a1bSJed Brown   ierr = FormElementStiffness(h*h,Ke);CHKERRQ(ierr);
52*c4762a1bSJed Brown   for (i=start; i<end; i++) {
53*c4762a1bSJed Brown     /* location of lower left corner of element */
54*c4762a1bSJed Brown     /* node numbers for the four corners of element */
55*c4762a1bSJed Brown     idx[0] = (m+1)*(i/m) + (i % m);
56*c4762a1bSJed Brown     idx[1] = idx[0]+1; idx[2] = idx[1] + m + 1; idx[3] = idx[2] - 1;
57*c4762a1bSJed Brown     ierr   = MatSetValues(C,4,idx,4,idx,Ke,ADD_VALUES);CHKERRQ(ierr);
58*c4762a1bSJed Brown   }
59*c4762a1bSJed Brown   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
60*c4762a1bSJed Brown   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
61*c4762a1bSJed Brown 
62*c4762a1bSJed Brown   /* Assemble the matrix again */
63*c4762a1bSJed Brown   ierr = MatZeroEntries(C);CHKERRQ(ierr);
64*c4762a1bSJed Brown 
65*c4762a1bSJed Brown   for (i=start; i<end; i++) {
66*c4762a1bSJed Brown     /* location of lower left corner of element */
67*c4762a1bSJed Brown     /* node numbers for the four corners of element */
68*c4762a1bSJed Brown     idx[0] = (m+1)*(i/m) + (i % m);
69*c4762a1bSJed Brown     idx[1] = idx[0]+1; idx[2] = idx[1] + m + 1; idx[3] = idx[2] - 1;
70*c4762a1bSJed Brown     ierr   = MatSetValues(C,4,idx,4,idx,Ke,ADD_VALUES);CHKERRQ(ierr);
71*c4762a1bSJed Brown   }
72*c4762a1bSJed Brown   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
73*c4762a1bSJed Brown   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
74*c4762a1bSJed Brown 
75*c4762a1bSJed Brown   /* Create test vectors */
76*c4762a1bSJed Brown   ierr = VecCreate(PETSC_COMM_WORLD,&u);CHKERRQ(ierr);
77*c4762a1bSJed Brown   ierr = VecSetSizes(u,PETSC_DECIDE,N);CHKERRQ(ierr);
78*c4762a1bSJed Brown   ierr = VecSetFromOptions(u);CHKERRQ(ierr);
79*c4762a1bSJed Brown   ierr = VecDuplicate(u,&b);CHKERRQ(ierr);
80*c4762a1bSJed Brown   ierr = VecSet(u,one);CHKERRQ(ierr);
81*c4762a1bSJed Brown 
82*c4762a1bSJed Brown   /* Check error */
83*c4762a1bSJed Brown   ierr = MatMult(C,u,b);CHKERRQ(ierr);
84*c4762a1bSJed Brown   ierr = VecNorm(b,NORM_2,&norm);CHKERRQ(ierr);
85*c4762a1bSJed Brown   if (norm > PETSC_SQRT_MACHINE_EPSILON) {
86*c4762a1bSJed Brown     ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error b %g should be near 0\n",(double)norm);CHKERRQ(ierr);
87*c4762a1bSJed Brown   }
88*c4762a1bSJed Brown 
89*c4762a1bSJed Brown   /* Now test MatGetValues() */
90*c4762a1bSJed Brown   ierr = PetscOptionsHasName(NULL,NULL,"-get_values",&flg);CHKERRQ(ierr);
91*c4762a1bSJed Brown   if (flg) {
92*c4762a1bSJed Brown     ierr  = MatGetOwnershipRange(C,&mystart,&myend);CHKERRQ(ierr);
93*c4762a1bSJed Brown     nrsub = myend - mystart; ncsub = 4;
94*c4762a1bSJed Brown     ierr  = PetscMalloc1(nrsub*ncsub,&vals);CHKERRQ(ierr);
95*c4762a1bSJed Brown     ierr  = PetscMalloc1(nrsub,&rsub);CHKERRQ(ierr);
96*c4762a1bSJed Brown     ierr  = PetscMalloc1(ncsub,&csub);CHKERRQ(ierr);
97*c4762a1bSJed Brown     for (i=myend-1; i>=mystart; i--) rsub[myend-i-1] = i;
98*c4762a1bSJed Brown     for (i=0; i<ncsub; i++) csub[i] = 2*(ncsub-i) + mystart;
99*c4762a1bSJed Brown     ierr = MatGetValues(C,nrsub,rsub,ncsub,csub,vals);CHKERRQ(ierr);
100*c4762a1bSJed Brown     ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
101*c4762a1bSJed Brown     ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,"processor number %d: start=%D, end=%D, mystart=%D, myend=%D\n",rank,start,end,mystart,myend);CHKERRQ(ierr);
102*c4762a1bSJed Brown     for (i=0; i<nrsub; i++) {
103*c4762a1bSJed Brown       for (j=0; j<ncsub; j++) {
104*c4762a1bSJed Brown         if (PetscImaginaryPart(vals[i*ncsub+j]) != 0.0) {
105*c4762a1bSJed Brown           ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,"  C[%D, %D] = %g + %g i\n",rsub[i],csub[j],(double)PetscRealPart(vals[i*ncsub+j]),(double)PetscImaginaryPart(vals[i*ncsub+j]));CHKERRQ(ierr);
106*c4762a1bSJed Brown         } else {
107*c4762a1bSJed Brown           ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,"  C[%D, %D] = %g\n",rsub[i],csub[j],(double)PetscRealPart(vals[i*ncsub+j]));CHKERRQ(ierr);
108*c4762a1bSJed Brown         }
109*c4762a1bSJed Brown       }
110*c4762a1bSJed Brown     }
111*c4762a1bSJed Brown     ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD,PETSC_STDOUT);CHKERRQ(ierr);
112*c4762a1bSJed Brown     ierr = PetscFree(rsub);CHKERRQ(ierr);
113*c4762a1bSJed Brown     ierr = PetscFree(csub);CHKERRQ(ierr);
114*c4762a1bSJed Brown     ierr = PetscFree(vals);CHKERRQ(ierr);
115*c4762a1bSJed Brown   }
116*c4762a1bSJed Brown 
117*c4762a1bSJed Brown   /* Free data structures */
118*c4762a1bSJed Brown   ierr = VecDestroy(&u);CHKERRQ(ierr);
119*c4762a1bSJed Brown   ierr = VecDestroy(&b);CHKERRQ(ierr);
120*c4762a1bSJed Brown   ierr = MatDestroy(&C);CHKERRQ(ierr);
121*c4762a1bSJed Brown   ierr = PetscFinalize();
122*c4762a1bSJed Brown   return ierr;
123*c4762a1bSJed Brown }
124*c4762a1bSJed Brown 
125*c4762a1bSJed Brown 
126*c4762a1bSJed Brown 
127*c4762a1bSJed Brown 
128*c4762a1bSJed Brown /*TEST
129*c4762a1bSJed Brown 
130*c4762a1bSJed Brown    test:
131*c4762a1bSJed Brown       nsize: 4
132*c4762a1bSJed Brown 
133*c4762a1bSJed Brown TEST*/
134