Actual source code: ex8.c
petsc-3.3-p7 2013-05-11
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: /* This routine implments MatScaleUserImpl() functionality for MatType
8: SeqAIJ. MatScale_SeqAIJ() code duplicated here */
9: #include <../src/mat/impls/aij/seq/aij.h>
10: PetscErrorCode MatScaleUserImpl_SeqAIJ(Mat inA,PetscScalar alpha)
11: {
12: Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
13: PetscScalar oalpha = alpha;
14: PetscBLASInt one = 1,bnz = PetscBLASIntCast(a->nz);
17: BLASscal_(&bnz,&oalpha,a->a,&one);
18: return(0);
19: }
21: /* This routine implments MatScaleUserImpl() functionality for MatType
22: SeqAIJ. MatScale_MPIAIJ() code duplicated here */
23: extern PetscErrorCode MatScaleUserImpl(Mat,PetscScalar);
24: #include <../src/mat/impls/aij/mpi/mpiaij.h>
25: PetscErrorCode MatScaleUserImpl_MPIAIJ(Mat A,PetscScalar aa)
26: {
27: Mat_MPIAIJ *a = (Mat_MPIAIJ*)A->data;
31: /* we can call MatScaleUserImpl_SeqAIJ() directly here instead of
32: going through MatScaleUserImpl() wrapper */
33: MatScaleUserImpl(a->A,aa);
34: MatScaleUserImpl(a->B,aa);
35: return(0);
36: }
38: /* This routine registers MatScaleUserImpl_SeqAIJ() and
39: MatScaleUserImpl_MPIAIJ() as methods providing MatScaleUserImpl()
40: functionality for SeqAIJ and MPIAIJ matrix-types */
41: PetscErrorCode RegisterMatScaleUserImpl(Mat mat)
42: {
44: PetscMPIInt size;
46: MPI_Comm_size(((PetscObject)mat)->comm, &size);
47:
48: if (size == 1) { /* SeqAIJ Matrix */
49: PetscObjectComposeFunctionDynamic((PetscObject)mat,"MatScaleUserImpl_C",
50: "MatScaleUserImpl_SeqAIJ",
51: MatScaleUserImpl_SeqAIJ);
53: } else { /* MPIAIJ Matrix */
54: Mat_MPIAIJ *a = (Mat_MPIAIJ*)mat->data;
55: PetscObjectComposeFunctionDynamic((PetscObject)mat,"MatScaleUserImpl_C",
56: "MatScaleUserImpl_MPIAIJ",
57: MatScaleUserImpl_MPIAIJ);
58: PetscObjectComposeFunctionDynamic((PetscObject)(a->A),"MatScaleUserImpl_C",
59: "MatScaleUserImpl_SeqAIJ",
60: MatScaleUserImpl_SeqAIJ);
61: PetscObjectComposeFunctionDynamic((PetscObject)(a->B),"MatScaleUserImpl_C",
62: "MatScaleUserImpl_SeqAIJ",
63: MatScaleUserImpl_SeqAIJ);
64: }
66: return(0);
67: }
69: /* this routines queries the already registered MatScaleUserImp_XXX
70: implementations for the given matrix, and calls the correct
71: routine. i.e if MatType is SeqAIJ, MatScaleUserImpl_SeqAIJ() gets
72: called, and if MatType is MPIAIJ, MatScaleUserImpl_MPIAIJ() gets
73: called */
74: PetscErrorCode MatScaleUserImpl(Mat mat,PetscScalar a)
75: {
76: PetscErrorCode ierr,(*f)(Mat,PetscScalar);
79: PetscObjectQueryFunction((PetscObject)mat,"MatScaleUserImpl_C",(void (**)(void))&f);
80: if (f) {
81: (*f)(mat,a);
82: }
83: return(0);
84: }
86: /* Main user code that uses MatScaleUserImpl() */
90: int main(int argc,char **args)
91: {
92: Mat mat;
93: PetscInt i,j,m = 2,n,Ii,J;
95: PetscScalar v,none = -1.0;
96: PetscMPIInt rank,size;
97:
99: PetscInitialize(&argc,&args,(char *)0,help);
101: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
102: MPI_Comm_size(PETSC_COMM_WORLD,&size);
103: n = 2*size;
105: /* create the matrix */
106: MatCreate(PETSC_COMM_WORLD,&mat);
107: MatSetSizes(mat,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);
108: MatSetType(mat,MATAIJ);
109: MatSetUp(mat);
111: /* register user defined MatScaleUser() operation for both SeqAIJ
112: and MPIAIJ types */
113: RegisterMatScaleUserImpl(mat);
115: /* assemble the matrix */
116: for (i=0; i<m; i++) {
117: for (j=2*rank; j<2*rank+2; j++) {
118: v = -1.0; Ii = j + n*i;
119: if (i>0) {J = Ii - n; MatSetValues(mat,1,&Ii,1,&J,&v,INSERT_VALUES);}
120: if (i<m-1) {J = Ii + n; MatSetValues(mat,1,&Ii,1,&J,&v,INSERT_VALUES);}
121: if (j>0) {J = Ii - 1; MatSetValues(mat,1,&Ii,1,&J,&v,INSERT_VALUES);}
122: if (j<n-1) {J = Ii + 1; MatSetValues(mat,1,&Ii,1,&J,&v,INSERT_VALUES);}
123: v = 4.0; MatSetValues(mat,1,&Ii,1,&Ii,&v,INSERT_VALUES);
124: }
125: }
126: MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);
127: MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);
129: /* check the matrix before and after scaling by -1.0 */
130: PetscPrintf(PETSC_COMM_WORLD,"Matrix _before_ MatScaleUserImpl() operation\n");
131: MatView(mat,PETSC_VIEWER_STDOUT_WORLD);
132: MatScaleUserImpl(mat,none);
133: PetscPrintf(PETSC_COMM_WORLD,"Matrix _after_ MatScaleUserImpl() operation\n");
134: MatView(mat,PETSC_VIEWER_STDOUT_WORLD);
136: MatDestroy(&mat);
137: PetscFinalize();
138: return 0;
139: }