Actual source code: matreg.c
petsc-3.13.6 2020-09-29
Report Typos and Errors

      2: /*
      3:      Mechanism for register PETSc matrix types
      4: */
      5:  #include <petsc/private/matimpl.h>

      7: PetscBool MatRegisterAllCalled = PETSC_FALSE;

      9: /*
     10:    Contains the list of registered Mat routines
     11: */
     12: PetscFunctionList MatList = 0;

     14: /*@C
     15:    MatSetType - Builds matrix object for a particular matrix type

     17:    Collective on Mat

     19:    Input Parameters:
     20: +  mat      - the matrix object
     21: -  matype   - matrix type

     23:    Options Database Key:
     24: .  -mat_type  <method> - Sets the type; use -help for a list
     25:     of available methods (for instance, seqaij)

     27:    Notes:
     28:    See "${PETSC_DIR}/include/petscmat.h" for available methods

     30:   Level: intermediate

     32: .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat
     33: @*/
     34: PetscErrorCode  MatSetType(Mat mat, MatType matype)
     35: {
     36:   PetscErrorCode ierr,(*r)(Mat);
     37:   PetscBool      sametype,found,subclass = PETSC_FALSE;
     38:   MatRootName    names = MatRootNameList;

     43:   while (names) {
     44:     PetscStrcmp(matype,names->rname,&found);
     45:     if (found) {
     46:       PetscMPIInt size;
     47:       MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
     48:       if (size == 1) matype = names->sname;
     49:       else matype = names->mname;
     50:       break;
     51:     }
     52:     names = names->next;
     53:   }

     55:   PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);
     56:   if (sametype) return(0);

     58:   PetscFunctionListFind(MatList,matype,&r);
     59:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype);

     61:   if (mat->assembled && ((PetscObject)mat)->type_name) {
     62:     PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass);
     63:   }
     64:   if (subclass) {
     65:     MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat);
     66:     return(0);
     67:   } if (mat->ops->destroy) {
     68:     /* free the old data structure if it existed */
     69:     (*mat->ops->destroy)(mat);
     70:     mat->ops->destroy = NULL;

     72:     /* should these null spaces be removed? */
     73:     MatNullSpaceDestroy(&mat->nullsp);
     74:     MatNullSpaceDestroy(&mat->nearnullsp);
     75:     mat->preallocated = PETSC_FALSE;
     76:     mat->assembled = PETSC_FALSE;
     77:     mat->was_assembled = PETSC_FALSE;

     79:     /*
     80:      Increment, rather than reset these: the object is logically the same, so its logging and
     81:      state is inherited.  Furthermore, resetting makes it possible for the same state to be
     82:      obtained with a different structure, confusing the PC.
     83:     */
     84:     ++mat->nonzerostate;
     85:     PetscObjectStateIncrease((PetscObject)mat);
     86:   }
     87:   mat->preallocated  = PETSC_FALSE;
     88:   mat->assembled     = PETSC_FALSE;
     89:   mat->was_assembled = PETSC_FALSE;

     91:   /* increase the state so that any code holding the current state knows the matrix has been changed */
     92:   mat->nonzerostate++;
     93:   PetscObjectStateIncrease((PetscObject)mat);

     95:   /* create the new data structure */
     96:   (*r)(mat);
     97:   return(0);
     98: }

    100: /*@C
    101:    MatGetType - Gets the matrix type as a string from the matrix object.

    103:    Not Collective

    105:    Input Parameter:
    106: .  mat - the matrix

    108:    Output Parameter:
    109: .  name - name of matrix type

    111:    Level: intermediate

    113: .seealso: MatSetType()
    114: @*/
    115: PetscErrorCode  MatGetType(Mat mat,MatType *type)
    116: {
    120:   *type = ((PetscObject)mat)->type_name;
    121:   return(0);
    122: }

    125: /*@C
    126:   MatRegister -  - Adds a new matrix type

    128:    Not Collective

    130:    Input Parameters:
    131: +  name - name of a new user-defined matrix type
    132: -  routine_create - routine to create method context

    134:    Notes:
    135:    MatRegister() may be called multiple times to add several user-defined solvers.

    137:    Sample usage:
    138: .vb
    139:    MatRegister("my_mat",MyMatCreate);
    140: .ve

    142:    Then, your solver can be chosen with the procedural interface via
    143: $     MatSetType(Mat,"my_mat")
    144:    or at runtime via the option
    145: $     -mat_type my_mat

    147:    Level: advanced

    149: .seealso: MatRegisterAll()

    152:   Level: advanced
    153: @*/
    154: PetscErrorCode  MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
    155: {

    159:   MatInitializePackage();
    160:   PetscFunctionListAdd(&MatList,sname,function);
    161:   return(0);
    162: }

    164: MatRootName MatRootNameList = 0;

    166: /*@C
    167:       MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType()
    168:         and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the
    169:         matrix.

    171:   Input Parameters:
    172: +     rname - the rootname, for example, MATAIJ
    173: .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
    174: -     mname - the name of the parallel matrix type, for example, MATMPIAIJ

    176:   Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare()

    178:   Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the
    179:       size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the
    180:       appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is
    181:       confusing.

    183:   Level: developer

    185: .seealso: PetscObjectBaseTypeCompare()

    187: @*/
    188: PetscErrorCode  MatRegisterRootName(const char rname[],const char sname[],const char mname[])
    189: {
    191:   MatRootName    names;

    194:   PetscNew(&names);
    195:   PetscStrallocpy(rname,&names->rname);
    196:   PetscStrallocpy(sname,&names->sname);
    197:   PetscStrallocpy(mname,&names->mname);
    198:   if (!MatRootNameList) {
    199:     MatRootNameList = names;
    200:   } else {
    201:     MatRootName next = MatRootNameList;
    202:     while (next->next) next = next->next;
    203:     next->next = names;
    204:   }
    205:   return(0);
    206: }