Actual source code: matreg.c

petsc-master 2020-08-15
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:   }
 68:   if (mat->ops->destroy) {
 69:     /* free the old data structure if it existed */
 70:     (*mat->ops->destroy)(mat);
 71:     mat->ops->destroy = NULL;

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

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

 89:   /* create the new data structure */
 90:   (*r)(mat);
 91:   return(0);
 92: }

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

 97:    Not Collective

 99:    Input Parameter:
100: .  mat - the matrix

102:    Output Parameter:
103: .  name - name of matrix type

105:    Level: intermediate

107: .seealso: MatSetType()
108: @*/
109: PetscErrorCode  MatGetType(Mat mat,MatType *type)
110: {
114:   *type = ((PetscObject)mat)->type_name;
115:   return(0);
116: }

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

121:    Not Collective

123:    Input Parameter:
124: .  mat - the matrix

126:    Output Parameter:
127: .  name - name of vector type

129:    Level: intermediate

131: .seealso: MatSetVecType()
132: @*/
133: PetscErrorCode MatGetVecType(Mat mat,VecType *vtype)
134: {
138:   *vtype = mat->defaultvectype;
139:   return(0);
140: }

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

145:    Collective on Mat

147:    Input Parameters:
148: +  mat   - the matrix object
149: -  vtype - vector type

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

154:   Level: intermediate

156: .seealso: VecSetType(), MatGetVecType()
157: @*/
158: PetscErrorCode MatSetVecType(Mat mat,VecType vtype)
159: {

164:   PetscFree(mat->defaultvectype);
165:   PetscStrallocpy(vtype,&mat->defaultvectype);
166:   return(0);
167: }

169: /*@C
170:   MatRegister -  - Adds a new matrix type

172:    Not Collective

174:    Input Parameters:
175: +  name - name of a new user-defined matrix type
176: -  routine_create - routine to create method context

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

181:    Sample usage:
182: .vb
183:    MatRegister("my_mat",MyMatCreate);
184: .ve

186:    Then, your solver can be chosen with the procedural interface via
187: $     MatSetType(Mat,"my_mat")
188:    or at runtime via the option
189: $     -mat_type my_mat

191:    Level: advanced

193: .seealso: MatRegisterAll()


196:   Level: advanced
197: @*/
198: PetscErrorCode  MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
199: {

203:   MatInitializePackage();
204:   PetscFunctionListAdd(&MatList,sname,function);
205:   return(0);
206: }

208: MatRootName MatRootNameList = 0;

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

215:   Input Parameters:
216: +     rname - the rootname, for example, MATAIJ
217: .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
218: -     mname - the name of the parallel matrix type, for example, MATMPIAIJ

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

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

227:   Level: developer

229: .seealso: PetscObjectBaseTypeCompare()

231: @*/
232: PetscErrorCode  MatRegisterRootName(const char rname[],const char sname[],const char mname[])
233: {
235:   MatRootName    names;

238:   PetscNew(&names);
239:   PetscStrallocpy(rname,&names->rname);
240:   PetscStrallocpy(sname,&names->sname);
241:   PetscStrallocpy(mname,&names->mname);
242:   if (!MatRootNameList) {
243:     MatRootNameList = names;
244:   } else {
245:     MatRootName next = MatRootNameList;
246:     while (next->next) next = next->next;
247:     next->next = names;
248:   }
249:   return(0);
250: }