Actual source code: matreg.c

petsc-master 2020-06-02
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: }

124: /*@C
125:    MatGetVecType - Gets the vector type used by the matrix object.

127:    Not Collective

129:    Input Parameter:
130: .  mat - the matrix

132:    Output Parameter:
133: .  name - name of vector type

135:    Level: intermediate

137: .seealso: MatSetVecType()
138: @*/
139: PetscErrorCode MatGetVecType(Mat mat,VecType *vtype)
140: {
144:   *vtype = mat->defaultvectype;
145:   return(0);
146: }

148: /*@C
149:    MatSetVecType - Set the vector type to be used for a matrix object

151:    Collective on Mat

153:    Input Parameters:
154: +  mat   - the matrix object
155: -  vtype - vector type

157:    Notes:
158:      This is rarely needed in practice since each matrix object internally sets the proper vector type.

160:   Level: intermediate

162: .seealso: VecSetType(), MatGetVecType()
163: @*/
164: PetscErrorCode MatSetVecType(Mat mat,VecType vtype)
165: {

170:   PetscFree(mat->defaultvectype);
171:   PetscStrallocpy(vtype,&mat->defaultvectype);
172:   return(0);
173: }

175: /*@C
176:   MatRegister -  - Adds a new matrix type

178:    Not Collective

180:    Input Parameters:
181: +  name - name of a new user-defined matrix type
182: -  routine_create - routine to create method context

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

187:    Sample usage:
188: .vb
189:    MatRegister("my_mat",MyMatCreate);
190: .ve

192:    Then, your solver can be chosen with the procedural interface via
193: $     MatSetType(Mat,"my_mat")
194:    or at runtime via the option
195: $     -mat_type my_mat

197:    Level: advanced

199: .seealso: MatRegisterAll()


202:   Level: advanced
203: @*/
204: PetscErrorCode  MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
205: {

209:   MatInitializePackage();
210:   PetscFunctionListAdd(&MatList,sname,function);
211:   return(0);
212: }

214: MatRootName MatRootNameList = 0;

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

221:   Input Parameters:
222: +     rname - the rootname, for example, MATAIJ
223: .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
224: -     mname - the name of the parallel matrix type, for example, MATMPIAIJ

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

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

233:   Level: developer

235: .seealso: PetscObjectBaseTypeCompare()

237: @*/
238: PetscErrorCode  MatRegisterRootName(const char rname[],const char sname[],const char mname[])
239: {
241:   MatRootName    names;

244:   PetscNew(&names);
245:   PetscStrallocpy(rname,&names->rname);
246:   PetscStrallocpy(sname,&names->sname);
247:   PetscStrallocpy(mname,&names->mname);
248:   if (!MatRootNameList) {
249:     MatRootNameList = names;
250:   } else {
251:     MatRootName next = MatRootNameList;
252:     while (next->next) next = next->next;
253:     next->next = names;
254:   }
255:   return(0);
256: }