xref: /petsc/src/mat/interface/matreg.c (revision 5f80ce2ab25dff0f4601e710601cbbcecf323266)
1be1d678aSKris Buschelman 
27e14e8a7SBarry Smith /*
399cd5145SBarry Smith      Mechanism for register PETSc matrix types
47e14e8a7SBarry Smith */
5af0996ceSBarry Smith #include <petsc/private/matimpl.h>      /*I "petscmat.h" I*/
67e14e8a7SBarry Smith 
7ace3abfcSBarry Smith PetscBool MatRegisterAllCalled = PETSC_FALSE;
87e14e8a7SBarry Smith 
97e14e8a7SBarry Smith /*
1099cd5145SBarry Smith    Contains the list of registered Mat routines
117e14e8a7SBarry Smith */
12f4259b30SLisandro Dalcin PetscFunctionList MatList = NULL;
137e14e8a7SBarry Smith 
142c99ec25SJunchao Zhang /* MatGetRootType_Private - Gets the root type of the input matrix's type (e.g., MATAIJ for MATSEQAIJ)
152c99ec25SJunchao Zhang 
162c99ec25SJunchao Zhang    Not Collective
172c99ec25SJunchao Zhang 
182c99ec25SJunchao Zhang    Input Parameters:
192c99ec25SJunchao Zhang .  mat      - the input matrix, could be sequential or MPI
202c99ec25SJunchao Zhang 
212c99ec25SJunchao Zhang    Output Parameters:
222c99ec25SJunchao Zhang .  rootType  - the root matrix type
232c99ec25SJunchao Zhang 
242c99ec25SJunchao Zhang    Level: developer
252c99ec25SJunchao Zhang 
262c99ec25SJunchao Zhang .seealso: MatGetType(), MatSetType(), MatType, Mat
272c99ec25SJunchao Zhang */
282c99ec25SJunchao Zhang PetscErrorCode MatGetRootType_Private(Mat mat, MatType *rootType)
292c99ec25SJunchao Zhang {
302c99ec25SJunchao Zhang   PetscBool      found = PETSC_FALSE;
312c99ec25SJunchao Zhang   MatRootName    names = MatRootNameList;
322c99ec25SJunchao Zhang   MatType        inType;
332c99ec25SJunchao Zhang 
342c99ec25SJunchao Zhang   PetscFunctionBegin;
352c99ec25SJunchao Zhang   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
36*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatGetType(mat,&inType));
372c99ec25SJunchao Zhang   while (names) {
38*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcmp(inType,names->mname,&found));
39*5f80ce2aSJacob Faibussowitsch     if (!found) CHKERRQ(PetscStrcmp(inType,names->sname,&found));
402c99ec25SJunchao Zhang     if (found) {
412c99ec25SJunchao Zhang       found     = PETSC_TRUE;
422c99ec25SJunchao Zhang       *rootType = names->rname;
432c99ec25SJunchao Zhang       break;
442c99ec25SJunchao Zhang     }
452c99ec25SJunchao Zhang     names = names->next;
462c99ec25SJunchao Zhang   }
472c99ec25SJunchao Zhang   if (!found) *rootType = inType;
482c99ec25SJunchao Zhang   PetscFunctionReturn(0);
492c99ec25SJunchao Zhang }
502c99ec25SJunchao Zhang 
517e14e8a7SBarry Smith /*@C
5299cd5145SBarry Smith    MatSetType - Builds matrix object for a particular matrix type
537e14e8a7SBarry Smith 
5499cd5145SBarry Smith    Collective on Mat
557e14e8a7SBarry Smith 
567e14e8a7SBarry Smith    Input Parameters:
5799cd5145SBarry Smith +  mat      - the matrix object
5899cd5145SBarry Smith -  matype   - matrix type
597e14e8a7SBarry Smith 
607e14e8a7SBarry Smith    Options Database Key:
6199cd5145SBarry Smith .  -mat_type  <method> - Sets the type; use -help for a list
6299cd5145SBarry Smith     of available methods (for instance, seqaij)
637e14e8a7SBarry Smith 
647e14e8a7SBarry Smith    Notes:
6599cd5145SBarry Smith    See "${PETSC_DIR}/include/petscmat.h" for available methods
667e14e8a7SBarry Smith 
677e14e8a7SBarry Smith   Level: intermediate
687e14e8a7SBarry Smith 
696e0d5acbSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat
707e14e8a7SBarry Smith @*/
7119fd82e9SBarry Smith PetscErrorCode  MatSetType(Mat mat, MatType matype)
727e14e8a7SBarry Smith {
733dcd2dd8SBarry Smith   PetscBool      sametype,found,subclass = PETSC_FALSE;
7423bebc0bSBarry Smith   MatRootName    names = MatRootNameList;
75*5f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(Mat);
767e14e8a7SBarry Smith 
777e14e8a7SBarry Smith   PetscFunctionBegin;
780700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
79117016b1SBarry Smith 
8001bebe75SBarry Smith   while (names) {
81*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcmp(matype,names->rname,&found));
8201bebe75SBarry Smith     if (found) {
8301bebe75SBarry Smith       PetscMPIInt size;
84*5f80ce2aSJacob Faibussowitsch       CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size));
8501bebe75SBarry Smith       if (size == 1) matype = names->sname;
8601bebe75SBarry Smith       else matype = names->mname;
8701bebe75SBarry Smith       break;
8801bebe75SBarry Smith     }
8901bebe75SBarry Smith     names = names->next;
9001bebe75SBarry Smith   }
9101bebe75SBarry Smith 
92*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)mat,matype,&sametype));
9392ff6ae8SBarry Smith   if (sametype) PetscFunctionReturn(0);
9492ff6ae8SBarry Smith 
95*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFunctionListFind(MatList,matype,&r));
96*5f80ce2aSJacob Faibussowitsch   PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype);
977e14e8a7SBarry Smith 
98*5f80ce2aSJacob Faibussowitsch   if (mat->assembled && ((PetscObject)mat)->type_name) CHKERRQ(PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass));
993dcd2dd8SBarry Smith   if (subclass) {
100*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat));
1013dcd2dd8SBarry Smith     PetscFunctionReturn(0);
10228fc0bbcSJose E. Roman   }
10328fc0bbcSJose E. Roman   if (mat->ops->destroy) {
10435d8aa7fSBarry Smith     /* free the old data structure if it existed */
105*5f80ce2aSJacob Faibussowitsch     CHKERRQ((*mat->ops->destroy)(mat));
1060298fd71SBarry Smith     mat->ops->destroy = NULL;
10782e0f345SBarry Smith 
10832e7c8b0SBarry Smith     /* should these null spaces be removed? */
109*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNullSpaceDestroy(&mat->nullsp));
110*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNullSpaceDestroy(&mat->nearnullsp));
11128fc0bbcSJose E. Roman   }
112*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscMemzero(mat->ops,sizeof(struct _MatOps)));
11382e0f345SBarry Smith   mat->preallocated  = PETSC_FALSE;
11482e0f345SBarry Smith   mat->assembled     = PETSC_FALSE;
11582e0f345SBarry Smith   mat->was_assembled = PETSC_FALSE;
11682e0f345SBarry Smith 
11782e0f345SBarry Smith   /*
11882e0f345SBarry Smith    Increment, rather than reset these: the object is logically the same, so its logging and
11982e0f345SBarry Smith    state is inherited.  Furthermore, resetting makes it possible for the same state to be
12082e0f345SBarry Smith    obtained with a different structure, confusing the PC.
12182e0f345SBarry Smith   */
12232e7c8b0SBarry Smith   mat->nonzerostate++;
123*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectStateIncrease((PetscObject)mat));
124a2ec6df8SKris Buschelman 
12535d8aa7fSBarry Smith   /* create the new data structure */
126*5f80ce2aSJacob Faibussowitsch   CHKERRQ((*r)(mat));
1277e14e8a7SBarry Smith   PetscFunctionReturn(0);
1287e14e8a7SBarry Smith }
1297e14e8a7SBarry Smith 
1307e14e8a7SBarry Smith /*@C
131f87b78b8SBarry Smith    MatGetType - Gets the matrix type as a string from the matrix object.
1327e14e8a7SBarry Smith 
1337e14e8a7SBarry Smith    Not Collective
1347e14e8a7SBarry Smith 
1357e14e8a7SBarry Smith    Input Parameter:
13699cd5145SBarry Smith .  mat - the matrix
1377e14e8a7SBarry Smith 
1387e14e8a7SBarry Smith    Output Parameter:
13999cd5145SBarry Smith .  name - name of matrix type
1407e14e8a7SBarry Smith 
1417e14e8a7SBarry Smith    Level: intermediate
1427e14e8a7SBarry Smith 
14399cd5145SBarry Smith .seealso: MatSetType()
1447e14e8a7SBarry Smith @*/
14519fd82e9SBarry Smith PetscErrorCode  MatGetType(Mat mat,MatType *type)
1467e14e8a7SBarry Smith {
1477e14e8a7SBarry Smith   PetscFunctionBegin;
1480700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
149c4e43342SLisandro Dalcin   PetscValidPointer(type,2);
1507adad957SLisandro Dalcin   *type = ((PetscObject)mat)->type_name;
1517e14e8a7SBarry Smith   PetscFunctionReturn(0);
1527e14e8a7SBarry Smith }
1537e14e8a7SBarry Smith 
1540d229a57SStefano Zampini /*@C
1550d229a57SStefano Zampini    MatGetVecType - Gets the vector type used by the matrix object.
1560d229a57SStefano Zampini 
1570d229a57SStefano Zampini    Not Collective
1580d229a57SStefano Zampini 
1590d229a57SStefano Zampini    Input Parameter:
1600d229a57SStefano Zampini .  mat - the matrix
1610d229a57SStefano Zampini 
1620d229a57SStefano Zampini    Output Parameter:
1630d229a57SStefano Zampini .  name - name of vector type
1640d229a57SStefano Zampini 
1650d229a57SStefano Zampini    Level: intermediate
1660d229a57SStefano Zampini 
1670d229a57SStefano Zampini .seealso: MatSetVecType()
1680d229a57SStefano Zampini @*/
1690d229a57SStefano Zampini PetscErrorCode MatGetVecType(Mat mat,VecType *vtype)
1700d229a57SStefano Zampini {
1710d229a57SStefano Zampini   PetscFunctionBegin;
1720d229a57SStefano Zampini   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1730d229a57SStefano Zampini   PetscValidPointer(vtype,2);
1740d229a57SStefano Zampini   *vtype = mat->defaultvectype;
1750d229a57SStefano Zampini   PetscFunctionReturn(0);
1760d229a57SStefano Zampini }
1770d229a57SStefano Zampini 
1780d229a57SStefano Zampini /*@C
1790d229a57SStefano Zampini    MatSetVecType - Set the vector type to be used for a matrix object
1800d229a57SStefano Zampini 
1810d229a57SStefano Zampini    Collective on Mat
1820d229a57SStefano Zampini 
1830d229a57SStefano Zampini    Input Parameters:
1840d229a57SStefano Zampini +  mat   - the matrix object
1850d229a57SStefano Zampini -  vtype - vector type
1860d229a57SStefano Zampini 
1870d229a57SStefano Zampini    Notes:
1880d229a57SStefano Zampini      This is rarely needed in practice since each matrix object internally sets the proper vector type.
1890d229a57SStefano Zampini 
1900d229a57SStefano Zampini   Level: intermediate
1910d229a57SStefano Zampini 
1920d229a57SStefano Zampini .seealso: VecSetType(), MatGetVecType()
1930d229a57SStefano Zampini @*/
1940d229a57SStefano Zampini PetscErrorCode MatSetVecType(Mat mat,VecType vtype)
1950d229a57SStefano Zampini {
1960d229a57SStefano Zampini   PetscFunctionBegin;
1970d229a57SStefano Zampini   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
198*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(mat->defaultvectype));
199*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrallocpy(vtype,&mat->defaultvectype));
2000d229a57SStefano Zampini   PetscFunctionReturn(0);
2010d229a57SStefano Zampini }
2027e14e8a7SBarry Smith 
2033cea93caSBarry Smith /*@C
2041c84c290SBarry Smith   MatRegister -  - Adds a new matrix type
2051c84c290SBarry Smith 
2061c84c290SBarry Smith    Not Collective
2071c84c290SBarry Smith 
2081c84c290SBarry Smith    Input Parameters:
2091c84c290SBarry Smith +  name - name of a new user-defined matrix type
2101c84c290SBarry Smith -  routine_create - routine to create method context
2111c84c290SBarry Smith 
2121c84c290SBarry Smith    Notes:
2131c84c290SBarry Smith    MatRegister() may be called multiple times to add several user-defined solvers.
2141c84c290SBarry Smith 
2151c84c290SBarry Smith    Sample usage:
2161c84c290SBarry Smith .vb
217bdf89e91SBarry Smith    MatRegister("my_mat",MyMatCreate);
2181c84c290SBarry Smith .ve
2191c84c290SBarry Smith 
2201c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
2211c84c290SBarry Smith $     MatSetType(Mat,"my_mat")
2221c84c290SBarry Smith    or at runtime via the option
2231c84c290SBarry Smith $     -mat_type my_mat
2241c84c290SBarry Smith 
2251c84c290SBarry Smith    Level: advanced
2261c84c290SBarry Smith 
227d7ee760dSBarry Smith .seealso: MatRegisterAll()
2281c84c290SBarry Smith 
2297f6c08e0SMatthew Knepley   Level: advanced
2303cea93caSBarry Smith @*/
231bdf89e91SBarry Smith PetscErrorCode  MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
2327e14e8a7SBarry Smith {
2337e14e8a7SBarry Smith   PetscFunctionBegin;
234*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatInitializePackage());
235*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFunctionListAdd(&MatList,sname,function));
23699cd5145SBarry Smith   PetscFunctionReturn(0);
23799cd5145SBarry Smith }
23899cd5145SBarry Smith 
239f4259b30SLisandro Dalcin MatRootName MatRootNameList = NULL;
24001bebe75SBarry Smith 
24101bebe75SBarry Smith /*@C
24223bebc0bSBarry Smith       MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType()
24323bebc0bSBarry Smith         and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the
24423bebc0bSBarry Smith         matrix.
24501bebe75SBarry Smith 
24601bebe75SBarry Smith   Input Parameters:
24723bebc0bSBarry Smith +     rname - the rootname, for example, MATAIJ
24801bebe75SBarry Smith .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
24901bebe75SBarry Smith -     mname - the name of the parallel matrix type, for example, MATMPIAIJ
25001bebe75SBarry Smith 
25123bebc0bSBarry Smith   Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare()
25201bebe75SBarry Smith 
25323bebc0bSBarry Smith   Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the
25423bebc0bSBarry Smith       size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the
25523bebc0bSBarry Smith       appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is
25623bebc0bSBarry Smith       confusing.
25723bebc0bSBarry Smith 
25823bebc0bSBarry Smith   Level: developer
25923bebc0bSBarry Smith 
26023bebc0bSBarry Smith .seealso: PetscObjectBaseTypeCompare()
26123bebc0bSBarry Smith 
26201bebe75SBarry Smith @*/
26323bebc0bSBarry Smith PetscErrorCode  MatRegisterRootName(const char rname[],const char sname[],const char mname[])
26401bebe75SBarry Smith {
26523bebc0bSBarry Smith   MatRootName    names;
26601bebe75SBarry Smith 
26701bebe75SBarry Smith   PetscFunctionBegin;
268*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscNew(&names));
269*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrallocpy(rname,&names->rname));
270*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrallocpy(sname,&names->sname));
271*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrallocpy(mname,&names->mname));
27223bebc0bSBarry Smith   if (!MatRootNameList) {
27323bebc0bSBarry Smith     MatRootNameList = names;
27401bebe75SBarry Smith   } else {
27523bebc0bSBarry Smith     MatRootName next = MatRootNameList;
27601bebe75SBarry Smith     while (next->next) next = next->next;
27701bebe75SBarry Smith     next->next = names;
27801bebe75SBarry Smith   }
27901bebe75SBarry Smith   PetscFunctionReturn(0);
28001bebe75SBarry Smith }
281