Actual source code: ex37.c


  2: static char help[] = "Tests MatCopy() and MatStore/RetrieveValues().\n\n";

  4: #include <petscmat.h>

  6: int main(int argc, char **args)
  7: {
  8:   Mat         C, A;
  9:   PetscInt    i, n = 10, midx[3], bs = 1;
 10:   PetscScalar v[3];
 11:   PetscBool   flg, isAIJ;
 12:   MatType     type;
 13:   PetscMPIInt size;

 16:   PetscInitialize(&argc, &args, (char *)0, help);
 17:   MPI_Comm_size(PETSC_COMM_WORLD, &size);
 18:   PetscOptionsGetInt(NULL, NULL, "-n", &n, NULL);
 19:   PetscOptionsGetInt(NULL, NULL, "-mat_block_size", &bs, NULL);

 21:   MatCreate(PETSC_COMM_WORLD, &C);
 22:   MatSetSizes(C, PETSC_DECIDE, PETSC_DECIDE, n, n);
 23:   MatSetType(C, MATAIJ);
 24:   MatSetFromOptions(C);
 25:   PetscObjectSetName((PetscObject)C, "initial");

 27:   MatGetType(C, &type);
 28:   if (size == 1) {
 29:     PetscObjectTypeCompare((PetscObject)C, MATSEQAIJ, &isAIJ);
 30:   } else {
 31:     PetscObjectTypeCompare((PetscObject)C, MATMPIAIJ, &isAIJ);
 32:   }
 33:   MatSeqAIJSetPreallocation(C, 3, NULL);
 34:   MatMPIAIJSetPreallocation(C, 3, NULL, 3, NULL);
 35:   MatSeqBAIJSetPreallocation(C, bs, 3, NULL);
 36:   MatMPIBAIJSetPreallocation(C, bs, 3, NULL, 3, NULL);
 37:   MatSeqSBAIJSetPreallocation(C, bs, 3, NULL);
 38:   MatMPISBAIJSetPreallocation(C, bs, 3, NULL, 3, NULL);

 40:   v[0] = -1.;
 41:   v[1] = 2.;
 42:   v[2] = -1.;
 43:   for (i = 1; i < n - 1; i++) {
 44:     midx[2] = i - 1;
 45:     midx[1] = i;
 46:     midx[0] = i + 1;
 47:     MatSetValues(C, 1, &i, 3, midx, v, INSERT_VALUES);
 48:   }
 49:   i       = 0;
 50:   midx[0] = 0;
 51:   midx[1] = 1;
 52:   v[0]    = 2.0;
 53:   v[1]    = -1.;
 54:   MatSetValues(C, 1, &i, 2, midx, v, INSERT_VALUES);
 55:   i       = n - 1;
 56:   midx[0] = n - 2;
 57:   midx[1] = n - 1;
 58:   v[0]    = -1.0;
 59:   v[1]    = 2.;
 60:   MatSetValues(C, 1, &i, 2, midx, v, INSERT_VALUES);

 62:   MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY);
 63:   MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY);
 64:   MatView(C, NULL);
 65:   MatViewFromOptions(C, NULL, "-view");

 67:   /* test matduplicate */
 68:   MatDuplicate(C, MAT_COPY_VALUES, &A);
 69:   PetscObjectSetName((PetscObject)A, "duplicate_copy");
 70:   MatViewFromOptions(A, NULL, "-view");
 71:   MatEqual(A, C, &flg);
 73:   MatDestroy(&A);

 75:   /* test matrices with different nonzero patterns - Note: A is created with different nonzero pattern of C! */
 76:   MatCreate(PETSC_COMM_WORLD, &A);
 77:   MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n);
 78:   MatSetFromOptions(A);
 79:   MatSetUp(A);
 80:   MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);
 81:   MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);

 83:   MatCopy(C, A, DIFFERENT_NONZERO_PATTERN);
 84:   PetscObjectSetName((PetscObject)A, "copy_diffnnz");
 85:   MatViewFromOptions(A, NULL, "-view");
 86:   MatEqual(A, C, &flg);

 89:   /* test matrices with same nonzero pattern */
 90:   MatDestroy(&A);
 91:   MatDuplicate(C, MAT_DO_NOT_COPY_VALUES, &A);
 92:   MatCopy(C, A, SAME_NONZERO_PATTERN);
 93:   PetscObjectSetName((PetscObject)A, "copy_samennz");
 94:   MatViewFromOptions(A, NULL, "-view");
 95:   MatEqual(A, C, &flg);

 98:   /* test subset nonzero pattern */
 99:   MatCopy(C, A, SUBSET_NONZERO_PATTERN);
100:   PetscObjectSetName((PetscObject)A, "copy_subnnz");
101:   MatViewFromOptions(A, NULL, "-view");
102:   MatEqual(A, C, &flg);

105:   /* Test MatCopy on a matrix obtained after MatConvert from AIJ
106:      see https://lists.mcs.anl.gov/pipermail/petsc-dev/2019-April/024289.html */
107:   MatHasCongruentLayouts(C, &flg);
108:   if (flg) {
109:     Mat     Cs, Cse;
110:     MatType Ctype, Cstype;

112:     MatGetType(C, &Ctype);
113:     MatTranspose(C, MAT_INITIAL_MATRIX, &Cs);
114:     MatAXPY(Cs, 1.0, C, DIFFERENT_NONZERO_PATTERN);
115:     MatConvert(Cs, MATAIJ, MAT_INPLACE_MATRIX, &Cs);
116:     MatSetOption(Cs, MAT_SYMMETRIC, PETSC_TRUE);
117:     MatGetType(Cs, &Cstype);

119:     PetscObjectSetName((PetscObject)Cs, "symm_initial");
120:     MatViewFromOptions(Cs, NULL, "-view");

122:     MatConvert(Cs, Ctype, MAT_INITIAL_MATRIX, &Cse);
123:     PetscObjectSetName((PetscObject)Cse, "symm_conv_init");
124:     MatViewFromOptions(Cse, NULL, "-view");
125:     MatMultEqual(Cs, Cse, 5, &flg);

128:     MatConvert(Cs, Ctype, MAT_REUSE_MATRIX, &Cse);
129:     PetscObjectSetName((PetscObject)Cse, "symm_conv_reuse");
130:     MatViewFromOptions(Cse, NULL, "-view");
131:     MatMultEqual(Cs, Cse, 5, &flg);

134:     MatCopy(Cs, Cse, SAME_NONZERO_PATTERN);
135:     PetscObjectSetName((PetscObject)Cse, "symm_conv_copy_samennz");
136:     MatViewFromOptions(Cse, NULL, "-view");
137:     MatMultEqual(Cs, Cse, 5, &flg);

140:     MatCopy(Cs, Cse, SUBSET_NONZERO_PATTERN);
141:     PetscObjectSetName((PetscObject)Cse, "symm_conv_copy_subnnz");
142:     MatViewFromOptions(Cse, NULL, "-view");
143:     MatMultEqual(Cs, Cse, 5, &flg);

146:     MatCopy(Cs, Cse, DIFFERENT_NONZERO_PATTERN);
147:     PetscObjectSetName((PetscObject)Cse, "symm_conv_copy_diffnnz");
148:     MatViewFromOptions(Cse, NULL, "-view");
149:     MatMultEqual(Cs, Cse, 5, &flg);

152:     MatDestroy(&Cse);
153:     MatDestroy(&Cs);
154:   }

156:   /* test MatStore/RetrieveValues() */
157:   if (isAIJ) {
158:     MatSetOption(A, MAT_NEW_NONZERO_LOCATIONS, PETSC_FALSE);
159:     MatStoreValues(A);
160:     MatZeroEntries(A);
161:     MatRetrieveValues(A);
162:   }

164:   MatDestroy(&C);
165:   MatDestroy(&A);
166:   PetscFinalize();
167:   return 0;
168: }

170: /*TEST

172:    testset:
173:       nsize: {{1 2}separate output}
174:       args: -view ::ascii_info -mat_type {{aij baij sbaij mpiaij mpibaij mpisbaij}separate output} -mat_block_size {{1 2}separate output}

176: TEST*/