Actual source code: ex132.c
petsc-3.8.4 2018-03-24
2: static char help[] = "Test MatAXPY(), and illustrate how to reduce number of mallocs used during MatSetValues() calls \n\
3: Matrix C is copied from ~petsc/src/ksp/ksp/examples/tutorials/ex5.c\n\n";
4: /*
5: Example: ./ex132 -mat_view ascii::ascii_info
6: */
8: #include <petscmat.h>
10: int main(int argc,char **args)
11: {
12: Mat C,C1,C2; /* matrix */
13: PetscScalar v;
14: PetscInt Ii,J,Istart,Iend;
16: PetscInt i,j,m = 3,n = 2;
17: PetscMPIInt size,rank;
18: PetscBool mat_nonsymmetric = PETSC_FALSE;
19: MatInfo info;
21: PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
22: PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);
23: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
24: MPI_Comm_size(PETSC_COMM_WORLD,&size);
25: n = 2*size;
27: /* Set flag if we are doing a nonsymmetric problem; the default is symmetric. */
28: PetscOptionsGetBool(NULL,NULL,"-mat_nonsym",&mat_nonsymmetric,NULL);
30: MatCreate(PETSC_COMM_WORLD,&C);
31: MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);
32: MatSetFromOptions(C);
33: MatSeqAIJSetPreallocation(C,5,NULL);
35: MatGetOwnershipRange(C,&Istart,&Iend);
36: for (Ii=Istart; Ii<Iend; Ii++) {
37: v = -1.0; i = Ii/n; j = Ii - i*n;
38: if (i>0) {J = Ii - n; MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);}
39: if (i<m-1) {J = Ii + n; MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);}
40: if (j>0) {J = Ii - 1; MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);}
41: if (j<n-1) {J = Ii + 1; MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);}
42: v = 4.0; MatSetValues(C,1,&Ii,1,&Ii,&v,ADD_VALUES);
43: }
45: /* Make the matrix nonsymmetric if desired */
46: if (mat_nonsymmetric) {
47: for (Ii=Istart; Ii<Iend; Ii++) {
48: v = -1.5; i = Ii/n;
49: if (i>1) {J = Ii-n-1; MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);}
50: }
51: } else {
52: MatSetOption(C,MAT_SYMMETRIC,PETSC_TRUE);
53: MatSetOption(C,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
54: }
55: MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);
56: MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);
58: /* First, create C1 = 2.0*C1 + C, C1 has less non-zeros than C */
59: PetscPrintf(PETSC_COMM_WORLD, "\ncreate C1 = 2.0*C1 + C, C1 has less non-zeros than C \n");
60: MatCreate(PETSC_COMM_WORLD,&C1);
61: MatSetSizes(C1,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);
62: MatSetFromOptions(C1);
63: MatSeqAIJSetPreallocation(C1,1,NULL);
64: for (Ii=Istart; Ii<Iend; Ii++) {
65: MatSetValues(C1,1,&Ii,1,&Ii,&v,ADD_VALUES);
66: }
67: MatAssemblyBegin(C1,MAT_FINAL_ASSEMBLY);
68: MatAssemblyEnd(C1,MAT_FINAL_ASSEMBLY);
69: PetscPrintf(PETSC_COMM_WORLD," MatAXPY(C1,2.0,C,DIFFERENT_NONZERO_PATTERN)...\n");
70: MatAXPY(C1,2.0,C,DIFFERENT_NONZERO_PATTERN);
71: MatGetInfo(C1,MAT_GLOBAL_SUM,&info);
72: PetscPrintf(PETSC_COMM_WORLD," C1: nz_allocated = %g; nz_used = %g; nz_unneeded = %g\n",info.nz_allocated,info.nz_used, info.nz_unneeded);
74: /* Secondly, create C2 = 2.0*C2 + C, C2 has non-zero pattern of C2 + C */
75: PetscPrintf(PETSC_COMM_WORLD, "\ncreate C2 = 2.0*C2 + C, C2 has non-zero pattern of C2 + C \n");
76: MatDuplicate(C,MAT_DO_NOT_COPY_VALUES,&C2);
78: for (Ii=Istart; Ii<Iend; Ii++) {
79: v = 1.0;
80: MatSetValues(C2,1,&Ii,1,&Ii,&v,ADD_VALUES);
81: }
82: MatAssemblyBegin(C2,MAT_FINAL_ASSEMBLY);
83: MatAssemblyEnd(C2,MAT_FINAL_ASSEMBLY);
84: PetscPrintf(PETSC_COMM_WORLD," MatAXPY(C2,2.0,C,SUBSET_NONZERO_PATTERN)...\n");
85: MatAXPY(C2,2.0,C,SUBSET_NONZERO_PATTERN);
86: MatGetInfo(C2,MAT_GLOBAL_SUM,&info);
87: PetscPrintf(PETSC_COMM_WORLD," C2: nz_allocated = %g; nz_used = %g; nz_unneeded = %g\n",info.nz_allocated,info.nz_used, info.nz_unneeded);
89: MatDestroy(&C1);
90: MatDestroy(&C2);
91: MatDestroy(&C);
93: PetscFinalize();
94: return ierr;
95: }