Actual source code: aijtype.c
1: #define PETSCMAT_DLL
3: #include src/mat/matimpl.h
5: typedef struct {
6: PetscErrorCode (*MatConvert)(Mat, MatType,MatReuse,Mat*);
7: PetscErrorCode (*MatDestroy)(Mat);
8: } Mat_AIJ;
11: EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_AIJ(Mat, MatType,MatReuse,Mat *);
12: EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_MPIAIJ_AIJ(Mat, MatType,MatReuse,Mat *);
13: EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_AIJ_SeqAIJ(Mat, MatType,MatReuse,Mat *);
14: EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_AIJ_MPIAIJ(Mat, MatType,MatReuse,Mat *);
20: PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_AIJ_SeqAIJ(Mat A, MatType type, MatReuse reuse,Mat *newmat)
21: {
23: Mat B=*newmat;
24: Mat_AIJ *aij=(Mat_AIJ *)A->spptr;
27: if (reuse == MAT_INITIAL_MATRIX) {
28: MatDuplicate(A,MAT_COPY_VALUES, &B);
29: }
31: B->ops->convert = aij->MatConvert;
32: B->ops->destroy = aij->MatDestroy;
34: PetscFree(aij);
36: PetscObjectComposeFunction((PetscObject)B,"MatConvert_aij_seqaij_C","",PETSC_NULL);
37: PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_aij_C","",PETSC_NULL);
38: PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);
39: *newmat = B;
40: return(0);
41: }
47: PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_AIJ_MPIAIJ(Mat A, MatType type, MatReuse reuse, Mat *newmat)
48: {
50: Mat B=*newmat;
51: Mat_AIJ *aij=(Mat_AIJ *)A->spptr;
54: if (reuse == MAT_INITIAL_MATRIX) {
55: MatDuplicate(A,MAT_COPY_VALUES, &B);
56: }
58: B->ops->convert = aij->MatConvert;
59: B->ops->destroy = aij->MatDestroy;
61: PetscFree(aij);
63: PetscObjectComposeFunction((PetscObject)B,"MatConvert_aij_mpiaij_C","",PETSC_NULL);
64: PetscObjectComposeFunction((PetscObject)B,"MatConvert_mpiaij_aij_C","",PETSC_NULL);
65: PetscObjectChangeTypeName((PetscObject)B,MATMPIAIJ);
66: *newmat = B;
67: return(0);
68: }
73: PetscErrorCode MatDestroy_AIJ(Mat A)
74: {
75: PetscMPIInt size;
79: MPI_Comm_size(A->comm,&size);
80: if (size == 1) {
81: MatConvert_AIJ_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A);
82: } else {
83: MatConvert_AIJ_MPIAIJ(A,MATMPIAIJ,MAT_REUSE_MATRIX,&A);
84: }
85: (*A->ops->destroy)(A);
86: return(0);
87: }
91: PetscErrorCode MatConvertFrom_AIJviaSeqAIJ(Mat A, MatType type,MatReuse reuse,Mat *newmat)
92: {
96: MatConvert_AIJ_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A);
97: MatConvert(A,type,reuse,newmat);
98: if (reuse == MAT_INITIAL_MATRIX) {
99: MatConvert_SeqAIJ_AIJ(A,MATAIJ,MAT_REUSE_MATRIX,&A);
100: }
101: return(0);
102: }
106: PetscErrorCode MatConvertFrom_AIJviaMPIAIJ(Mat A, MatType type,MatReuse reuse,Mat *newmat)
107: {
111: MatConvert_AIJ_MPIAIJ(A,PETSC_NULL,MAT_REUSE_MATRIX,&A);
112: MatConvert(A,type,reuse,newmat);
113: if (reuse == MAT_INITIAL_MATRIX) {
114: MatConvert_MPIAIJ_AIJ(A,MATAIJ,MAT_REUSE_MATRIX,&A);
115: }
116: return(0);
117: }
122: PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_AIJ(Mat A, MatType type,MatReuse reuse,Mat *newmat)
123: {
125: Mat B=*newmat;
126: Mat_AIJ *aij;
129: if (reuse == MAT_INITIAL_MATRIX) {
130: MatDuplicate(A,MAT_COPY_VALUES, &B);
131: }
132:
133: PetscNew(Mat_AIJ,&aij);
134: aij->MatConvert = A->ops->convert;
135: aij->MatDestroy = A->ops->destroy;
137: B->spptr = (void *)aij;
138: B->ops->convert = MatConvertFrom_AIJviaSeqAIJ;
139: B->ops->destroy = MatDestroy_AIJ;
141: PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_aij_seqaij_C",
142: "MatConvert_AIJ_SeqAIJ",MatConvert_AIJ_SeqAIJ);
143: PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_aij_C",
144: "MatConvert_SeqAIJ_AIJ",MatConvert_SeqAIJ_AIJ);
145: PetscObjectChangeTypeName((PetscObject)B,MATAIJ);
146: *newmat = B;
147: return(0);
148: }
154: PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_MPIAIJ_AIJ(Mat A, MatType type,MatReuse reuse,Mat *newmat)
155: {
157: Mat B=*newmat;
158: Mat_AIJ *aij;
161: if (reuse == MAT_INITIAL_MATRIX) {
162: MatDuplicate(A,MAT_COPY_VALUES, &B);
163: }
165: PetscNew(Mat_AIJ,&aij);
166: aij->MatConvert = A->ops->convert;
167: aij->MatDestroy = A->ops->destroy;
169: B->spptr = (void *)aij;
170: B->ops->convert = MatConvertFrom_AIJviaMPIAIJ;
171: B->ops->destroy = MatDestroy_AIJ;
173: PetscObjectComposeFunction((PetscObject)B,"MatConvert_aij_mpiaij_C",
174: "MatConvert_AIJ_MPIAIJ",
175: (void (*)(void))MatConvert_AIJ_MPIAIJ);
176: PetscObjectComposeFunction((PetscObject)B,"MatConvert_mpiaij_aij_C",
177: "MatConvert_MPIAIJ_AIJ",
178: (void (*)(void))MatConvert_MPIAIJ_AIJ);
179: PetscObjectChangeTypeName((PetscObject)B,MATAIJ);
180: *newmat = B;
181: return(0);
182: }
188: PetscErrorCode PETSCMAT_DLLEXPORT MatConvertTo_AIJ(Mat A, MatType type,MatReuse reuse,Mat *newmat)
189: {
190: /*
191: This method is to be registered using MatConvertRegisterDynamic. Perhaps a better mechanism would be to
192: add a second MatConvert function pointer (one for "from" -- which we already have, and a second for "to").
193: We should maintain the current registry list as well in order to provide a measure of backwards compatibility
194: if indeed we make this change.
195: */
197: PetscMPIInt size;
198: Mat B=*newmat;
201: MPI_Comm_size(A->comm,&size);
202: if (size == 1) {
203: MatConvert(A,MATSEQAIJ,reuse,&B);
204: MatConvert_SeqAIJ_AIJ(B,MATAIJ,MAT_REUSE_MATRIX,&B);
205: } else {
206: MatConvert(A,MATMPIAIJ,reuse,&B);
207: MatConvert_MPIAIJ_AIJ(B,MATAIJ,MAT_REUSE_MATRIX,&B);
208: }
209: *newmat = B;
210: return(0);
211: }
214: /*MC
215: MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices.
217: This matrix type is identical to MATSEQAIJ when constructed with a single process communicator,
218: and MATMPIAIJ otherwise. As a result, for single process communicators,
219: MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
220: for communicators controlling multiple processes. It is recommended that you call both of
221: the above preallocation routines for simplicity.
223: Options Database Keys:
224: . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
226: Level: beginner
228: .seealso: MatCreateMPIAIJ,MATSEQAIJ,MATMPIAIJ
229: M*/
234: PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_AIJ(Mat A)
235: {
237: PetscMPIInt size;
240: PetscObjectChangeTypeName((PetscObject)A,MATAIJ);
241: MPI_Comm_size(A->comm,&size);
242: if (size == 1) {
243: MatSetType(A,MATSEQAIJ);
244: MatConvert_SeqAIJ_AIJ(A,MATAIJ,MAT_REUSE_MATRIX,&A);
245: } else {
246: MatSetType(A,MATMPIAIJ);
247: MatConvert_MPIAIJ_AIJ(A,MATAIJ,MAT_REUSE_MATRIX,&A);
248: }
249: return(0);
250: }