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: }