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