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: PetscObjectComposeFunction((PetscObject)B,"MatConvert_aij_seqaij_C","",PETSC_NULL);
35: PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_aij_C","",PETSC_NULL);
36: PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);
37: *newmat = B;
38: return(0);
39: }
45: PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_AIJ_MPIAIJ(Mat A, MatType type, MatReuse reuse, Mat *newmat)
46: {
48: Mat B=*newmat;
49: Mat_AIJ *aij=(Mat_AIJ *)A->spptr;
52: if (reuse == MAT_INITIAL_MATRIX) {
53: MatDuplicate(A,MAT_COPY_VALUES, &B);
54: }
56: B->ops->convert = aij->MatConvert;
57: B->ops->destroy = aij->MatDestroy;
59: PetscObjectComposeFunction((PetscObject)B,"MatConvert_aij_mpiaij_C","",PETSC_NULL);
60: PetscObjectComposeFunction((PetscObject)B,"MatConvert_mpiaij_aij_C","",PETSC_NULL);
61: PetscObjectChangeTypeName((PetscObject)B,MATMPIAIJ);
62: *newmat = B;
63: return(0);
64: }
69: PetscErrorCode MatDestroy_AIJ(Mat A)
70: {
71: PetscMPIInt size;
75: MPI_Comm_size(A->comm,&size);
76: if (size == 1) {
77: MatConvert_AIJ_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A);
78: } else {
79: MatConvert_AIJ_MPIAIJ(A,MATMPIAIJ,MAT_REUSE_MATRIX,&A);
80: }
81: (*A->ops->destroy)(A);
82: return(0);
83: }
87: PetscErrorCode MatConvertFrom_AIJviaSeqAIJ(Mat A, MatType type,MatReuse reuse,Mat *newmat)
88: {
92: MatConvert_AIJ_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A);
93: MatConvert(A,type,reuse,newmat);
94: if (reuse == MAT_INITIAL_MATRIX) {
95: MatConvert_SeqAIJ_AIJ(A,MATAIJ,MAT_REUSE_MATRIX,&A);
96: }
97: return(0);
98: }
102: PetscErrorCode MatConvertFrom_AIJviaMPIAIJ(Mat A, MatType type,MatReuse reuse,Mat *newmat)
103: {
107: MatConvert_AIJ_MPIAIJ(A,PETSC_NULL,MAT_REUSE_MATRIX,&A);
108: MatConvert(A,type,reuse,newmat);
109: if (reuse == MAT_INITIAL_MATRIX) {
110: MatConvert_MPIAIJ_AIJ(A,MATAIJ,MAT_REUSE_MATRIX,&A);
111: }
112: return(0);
113: }
118: PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_AIJ(Mat A, MatType type,MatReuse reuse,Mat *newmat)
119: {
121: Mat B=*newmat;
122: Mat_AIJ *aij;
125: if (reuse == MAT_INITIAL_MATRIX) {
126: MatDuplicate(A,MAT_COPY_VALUES, &B);
127: }
128:
129: PetscNew(Mat_AIJ,&aij);
130: aij->MatConvert = A->ops->convert;
131: aij->MatDestroy = A->ops->destroy;
132:
133: /* Free previously allocated memory - if it exists */
134: PetscFree(B->spptr);
135: B->spptr = (void *)aij;
136: B->ops->convert = MatConvertFrom_AIJviaSeqAIJ;
137: B->ops->destroy = MatDestroy_AIJ;
139: PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_aij_seqaij_C",
140: "MatConvert_AIJ_SeqAIJ",MatConvert_AIJ_SeqAIJ);
141: PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_aij_C",
142: "MatConvert_SeqAIJ_AIJ",MatConvert_SeqAIJ_AIJ);
143: PetscObjectChangeTypeName((PetscObject)B,MATAIJ);
144: *newmat = B;
145: return(0);
146: }
152: PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_MPIAIJ_AIJ(Mat A, MatType type,MatReuse reuse,Mat *newmat)
153: {
155: Mat B=*newmat;
156: Mat_AIJ *aij;
159: if (reuse == MAT_INITIAL_MATRIX) {
160: MatDuplicate(A,MAT_COPY_VALUES, &B);
161: }
163: PetscNew(Mat_AIJ,&aij);
164: aij->MatConvert = A->ops->convert;
165: aij->MatDestroy = A->ops->destroy;
167: /* Free previously allocated memory - if it exists */
168: PetscFree(B->spptr);
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: }
253: /*MC
254: MATCRL - MATCRL = "crl" - A matrix type to be used for sparse matrices.
256: This matrix type is identical to MATSEQCRL when constructed with a single process communicator,
257: and MATMPICRL otherwise. As a result, for single process communicators,
258: MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported
259: for communicators controlling multiple processes. It is recommended that you call both of
260: the above preallocation routines for simplicity.
262: Options Database Keys:
263: . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions()
265: Level: beginner
267: .seealso: MatCreateMPICRL,MATSEQCRL,MATMPICRL, MATSEQCRL, MATMPICRL
268: M*/
273: PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_CRL(Mat A)
274: {
276: PetscMPIInt size;
279: PetscObjectChangeTypeName((PetscObject)A,MATCRL);
280: MPI_Comm_size(A->comm,&size);
281: /* this is not really correct; should do all the complicated stuff like for MatCreate_AIJ() */
282: if (size == 1) {
283: MatSetType(A,MATSEQCRL);
284: } else {
285: MatSetType(A,MATMPICRL);
286: }
287: return(0);
288: }