Actual source code: ex8.c


  2: static char help[] = "Shows how to add a new MatOperation to AIJ MatType\n\n";

  4: #include <petscmat.h>
  5: #include <petscblaslapack.h>

  7: static PetscErrorCode MatScaleUserImpl_SeqAIJ(Mat inA, PetscScalar alpha)
  8: {
  9:   MatScale(inA, alpha);
 10:   return 0;
 11: }

 13: extern PetscErrorCode MatScaleUserImpl(Mat, PetscScalar);

 15: static PetscErrorCode MatScaleUserImpl_MPIAIJ(Mat A, PetscScalar aa)
 16: {
 17:   Mat AA, AB;

 19:   MatMPIAIJGetSeqAIJ(A, &AA, &AB, NULL);
 20:   MatScaleUserImpl(AA, aa);
 21:   MatScaleUserImpl(AB, aa);
 22:   return 0;
 23: }

 25: /* This routine registers MatScaleUserImpl_SeqAIJ() and
 26:    MatScaleUserImpl_MPIAIJ() as methods providing MatScaleUserImpl()
 27:    functionality for SeqAIJ and MPIAIJ matrix-types */
 28: PetscErrorCode RegisterMatScaleUserImpl(Mat mat)
 29: {
 30:   PetscMPIInt size;

 32:   MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
 33:   if (size == 1) { /* SeqAIJ Matrix */
 34:     PetscObjectComposeFunction((PetscObject)mat, "MatScaleUserImpl_C", MatScaleUserImpl_SeqAIJ);
 35:   } else { /* MPIAIJ Matrix */
 36:     Mat AA, AB;
 37:     MatMPIAIJGetSeqAIJ(mat, &AA, &AB, NULL);
 38:     PetscObjectComposeFunction((PetscObject)mat, "MatScaleUserImpl_C", MatScaleUserImpl_MPIAIJ);
 39:     PetscObjectComposeFunction((PetscObject)AA, "MatScaleUserImpl_C", MatScaleUserImpl_SeqAIJ);
 40:     PetscObjectComposeFunction((PetscObject)AB, "MatScaleUserImpl_C", MatScaleUserImpl_SeqAIJ);
 41:   }
 42:   return 0;
 43: }

 45: /* This routine deregisters MatScaleUserImpl_SeqAIJ() and
 46:    MatScaleUserImpl_MPIAIJ() as methods providing MatScaleUserImpl()
 47:    functionality for SeqAIJ and MPIAIJ matrix-types */
 48: PetscErrorCode DeRegisterMatScaleUserImpl(Mat mat)
 49: {
 50:   PetscMPIInt size;

 52:   MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
 53:   if (size == 1) { /* SeqAIJ Matrix */
 54:     PetscObjectComposeFunction((PetscObject)mat, "MatScaleUserImpl_C", NULL);
 55:   } else { /* MPIAIJ Matrix */
 56:     Mat AA, AB;
 57:     MatMPIAIJGetSeqAIJ(mat, &AA, &AB, NULL);
 58:     PetscObjectComposeFunction((PetscObject)mat, "MatScaleUserImpl_C", NULL);
 59:     PetscObjectComposeFunction((PetscObject)AA, "MatScaleUserImpl_C", NULL);
 60:     PetscObjectComposeFunction((PetscObject)AB, "MatScaleUserImpl_C", NULL);
 61:   }
 62:   return 0;
 63: }

 65: /* this routines queries the already registered MatScaleUserImp_XXX
 66:    implementations for the given matrix, and calls the correct
 67:    routine. i.e if MatType is SeqAIJ, MatScaleUserImpl_SeqAIJ() gets
 68:    called, and if MatType is MPIAIJ, MatScaleUserImpl_MPIAIJ() gets
 69:    called */
 70: PetscErrorCode MatScaleUserImpl(Mat mat, PetscScalar a)
 71: {
 72:   PetscErrorCode (*f)(Mat, PetscScalar);

 74:   PetscObjectQueryFunction((PetscObject)mat, "MatScaleUserImpl_C", &f);
 75:   if (f) (*f)(mat, a);
 76:   return 0;
 77: }

 79: /* Main user code that uses MatScaleUserImpl() */

 81: int main(int argc, char **args)
 82: {
 83:   Mat         mat;
 84:   PetscInt    i, j, m = 2, n, Ii, J;
 85:   PetscScalar v, none = -1.0;
 86:   PetscMPIInt rank, size;

 89:   PetscInitialize(&argc, &args, (char *)0, help);
 90:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
 91:   MPI_Comm_size(PETSC_COMM_WORLD, &size);
 92:   n = 2 * size;

 94:   /* create the matrix */
 95:   MatCreate(PETSC_COMM_WORLD, &mat);
 96:   MatSetSizes(mat, PETSC_DECIDE, PETSC_DECIDE, m * n, m * n);
 97:   MatSetType(mat, MATAIJ);
 98:   MatSetUp(mat);

100:   /* register user defined MatScaleUser() operation for both SeqAIJ
101:      and MPIAIJ types */
102:   RegisterMatScaleUserImpl(mat);

104:   /* assemble the matrix */
105:   for (i = 0; i < m; i++) {
106:     for (j = 2 * rank; j < 2 * rank + 2; j++) {
107:       v  = -1.0;
108:       Ii = j + n * i;
109:       if (i > 0) {
110:         J = Ii - n;
111:         MatSetValues(mat, 1, &Ii, 1, &J, &v, INSERT_VALUES);
112:       }
113:       if (i < m - 1) {
114:         J = Ii + n;
115:         MatSetValues(mat, 1, &Ii, 1, &J, &v, INSERT_VALUES);
116:       }
117:       if (j > 0) {
118:         J = Ii - 1;
119:         MatSetValues(mat, 1, &Ii, 1, &J, &v, INSERT_VALUES);
120:       }
121:       if (j < n - 1) {
122:         J = Ii + 1;
123:         MatSetValues(mat, 1, &Ii, 1, &J, &v, INSERT_VALUES);
124:       }
125:       v = 4.0;
126:       MatSetValues(mat, 1, &Ii, 1, &Ii, &v, INSERT_VALUES);
127:     }
128:   }
129:   MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY);
130:   MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY);

132:   /* check the matrix before and after scaling by -1.0 */
133:   PetscPrintf(PETSC_COMM_WORLD, "Matrix _before_ MatScaleUserImpl() operation\n");
134:   MatView(mat, PETSC_VIEWER_STDOUT_WORLD);
135:   MatScaleUserImpl(mat, none);
136:   PetscPrintf(PETSC_COMM_WORLD, "Matrix _after_ MatScaleUserImpl() operation\n");
137:   MatView(mat, PETSC_VIEWER_STDOUT_WORLD);

139:   /* deregister user defined MatScaleUser() operation for both SeqAIJ
140:      and MPIAIJ types */
141:   DeRegisterMatScaleUserImpl(mat);
142:   MatDestroy(&mat);
143:   PetscFinalize();
144:   return 0;
145: }

147: /*TEST

149:    test:

151:    test:
152:       suffix: 2
153:       nsize: 2

155: TEST*/