Actual source code: matreg.c

petsc-3.12.5 2020-03-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: }