xref: /petsc/src/mat/interface/matreg.c (revision ac81f253c291d73aa24c71f383f24a6d3045a40c)
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);
369566063dSJacob Faibussowitsch   PetscCall(MatGetType(mat,&inType));
372c99ec25SJunchao Zhang   while (names) {
389566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(inType,names->mname,&found));
399566063dSJacob Faibussowitsch     if (!found) PetscCall(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 
51*ac81f253SRichard Tran Mills /* MatGetMPIMatType_Private - Gets the MPI type corresponding to the input matrix's type (e.g., MATMPIAIJ for MATSEQAIJ)
52*ac81f253SRichard Tran Mills 
53*ac81f253SRichard Tran Mills    Not Collective
54*ac81f253SRichard Tran Mills 
55*ac81f253SRichard Tran Mills    Input Parameters:
56*ac81f253SRichard Tran Mills .  mat      - the input matrix, could be sequential or MPI
57*ac81f253SRichard Tran Mills 
58*ac81f253SRichard Tran Mills    Output Parameters:
59*ac81f253SRichard Tran Mills .  MPIType  - the parallel (MPI) matrix type
60*ac81f253SRichard Tran Mills 
61*ac81f253SRichard Tran Mills    Level: developer
62*ac81f253SRichard Tran Mills 
63*ac81f253SRichard Tran Mills .seealso: `MatGetType()`, `MatSetType()`, `MatType`, `Mat`
64*ac81f253SRichard Tran Mills */
65*ac81f253SRichard Tran Mills PetscErrorCode MatGetMPIMatType_Private(Mat mat, MatType *MPIType)
66*ac81f253SRichard Tran Mills {
67*ac81f253SRichard Tran Mills   PetscBool      found = PETSC_FALSE;
68*ac81f253SRichard Tran Mills   MatRootName    names = MatRootNameList;
69*ac81f253SRichard Tran Mills   MatType        inType;
70*ac81f253SRichard Tran Mills 
71*ac81f253SRichard Tran Mills   PetscFunctionBegin;
72*ac81f253SRichard Tran Mills   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
73*ac81f253SRichard Tran Mills   PetscCall(MatGetType(mat,&inType));
74*ac81f253SRichard Tran Mills   while (names) {
75*ac81f253SRichard Tran Mills     PetscCall(PetscStrcmp(inType,names->sname,&found));
76*ac81f253SRichard Tran Mills     if (!found) PetscCall(PetscStrcmp(inType,names->mname,&found));
77*ac81f253SRichard Tran Mills     if (!found) PetscCall(PetscStrcmp(inType,names->rname,&found));
78*ac81f253SRichard Tran Mills     if (found) {
79*ac81f253SRichard Tran Mills       found     = PETSC_TRUE;
80*ac81f253SRichard Tran Mills       *MPIType = names->mname;
81*ac81f253SRichard Tran Mills       break;
82*ac81f253SRichard Tran Mills     }
83*ac81f253SRichard Tran Mills     names = names->next;
84*ac81f253SRichard Tran Mills   }
85*ac81f253SRichard Tran Mills   PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_SUP,"No corresponding parallel (MPI) type for this matrix");
86*ac81f253SRichard Tran Mills   PetscFunctionReturn(0);
87*ac81f253SRichard Tran Mills }
88*ac81f253SRichard Tran Mills 
897e14e8a7SBarry Smith /*@C
9099cd5145SBarry Smith    MatSetType - Builds matrix object for a particular matrix type
917e14e8a7SBarry Smith 
9299cd5145SBarry Smith    Collective on Mat
937e14e8a7SBarry Smith 
947e14e8a7SBarry Smith    Input Parameters:
9599cd5145SBarry Smith +  mat      - the matrix object
9699cd5145SBarry Smith -  matype   - matrix type
977e14e8a7SBarry Smith 
987e14e8a7SBarry Smith    Options Database Key:
9999cd5145SBarry Smith .  -mat_type  <method> - Sets the type; use -help for a list
10099cd5145SBarry Smith     of available methods (for instance, seqaij)
1017e14e8a7SBarry Smith 
1027e14e8a7SBarry Smith    Notes:
10399cd5145SBarry Smith    See "${PETSC_DIR}/include/petscmat.h" for available methods
1047e14e8a7SBarry Smith 
1057e14e8a7SBarry Smith   Level: intermediate
1067e14e8a7SBarry Smith 
1076e0d5acbSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat
1087e14e8a7SBarry Smith @*/
10919fd82e9SBarry Smith PetscErrorCode  MatSetType(Mat mat, MatType matype)
1107e14e8a7SBarry Smith {
1113dcd2dd8SBarry Smith   PetscBool      sametype,found,subclass = PETSC_FALSE;
11223bebc0bSBarry Smith   MatRootName    names = MatRootNameList;
1135f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(Mat);
1147e14e8a7SBarry Smith 
1157e14e8a7SBarry Smith   PetscFunctionBegin;
1160700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
117117016b1SBarry Smith 
11801bebe75SBarry Smith   while (names) {
1199566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(matype,names->rname,&found));
12001bebe75SBarry Smith     if (found) {
12101bebe75SBarry Smith       PetscMPIInt size;
1229566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size));
12301bebe75SBarry Smith       if (size == 1) matype = names->sname;
12401bebe75SBarry Smith       else matype = names->mname;
12501bebe75SBarry Smith       break;
12601bebe75SBarry Smith     }
12701bebe75SBarry Smith     names = names->next;
12801bebe75SBarry Smith   }
12901bebe75SBarry Smith 
1309566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)mat,matype,&sametype));
13192ff6ae8SBarry Smith   if (sametype) PetscFunctionReturn(0);
13292ff6ae8SBarry Smith 
1339566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(MatList,matype,&r));
1345f80ce2aSJacob Faibussowitsch   PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype);
1357e14e8a7SBarry Smith 
1369566063dSJacob Faibussowitsch   if (mat->assembled && ((PetscObject)mat)->type_name) PetscCall(PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass));
1373dcd2dd8SBarry Smith   if (subclass) {
1389566063dSJacob Faibussowitsch     PetscCall(MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat));
1393dcd2dd8SBarry Smith     PetscFunctionReturn(0);
14028fc0bbcSJose E. Roman   }
14128fc0bbcSJose E. Roman   if (mat->ops->destroy) {
14235d8aa7fSBarry Smith     /* free the old data structure if it existed */
1439566063dSJacob Faibussowitsch     PetscCall((*mat->ops->destroy)(mat));
1440298fd71SBarry Smith     mat->ops->destroy = NULL;
14582e0f345SBarry Smith 
14632e7c8b0SBarry Smith     /* should these null spaces be removed? */
1479566063dSJacob Faibussowitsch     PetscCall(MatNullSpaceDestroy(&mat->nullsp));
1489566063dSJacob Faibussowitsch     PetscCall(MatNullSpaceDestroy(&mat->nearnullsp));
14928fc0bbcSJose E. Roman   }
1509566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(mat->ops,sizeof(struct _MatOps)));
15182e0f345SBarry Smith   mat->preallocated  = PETSC_FALSE;
15282e0f345SBarry Smith   mat->assembled     = PETSC_FALSE;
15382e0f345SBarry Smith   mat->was_assembled = PETSC_FALSE;
15482e0f345SBarry Smith 
15582e0f345SBarry Smith   /*
15682e0f345SBarry Smith    Increment, rather than reset these: the object is logically the same, so its logging and
15782e0f345SBarry Smith    state is inherited.  Furthermore, resetting makes it possible for the same state to be
15882e0f345SBarry Smith    obtained with a different structure, confusing the PC.
15982e0f345SBarry Smith   */
16032e7c8b0SBarry Smith   mat->nonzerostate++;
1619566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
162a2ec6df8SKris Buschelman 
16335d8aa7fSBarry Smith   /* create the new data structure */
1649566063dSJacob Faibussowitsch   PetscCall((*r)(mat));
1657e14e8a7SBarry Smith   PetscFunctionReturn(0);
1667e14e8a7SBarry Smith }
1677e14e8a7SBarry Smith 
1687e14e8a7SBarry Smith /*@C
169f87b78b8SBarry Smith    MatGetType - Gets the matrix type as a string from the matrix object.
1707e14e8a7SBarry Smith 
1717e14e8a7SBarry Smith    Not Collective
1727e14e8a7SBarry Smith 
1737e14e8a7SBarry Smith    Input Parameter:
17499cd5145SBarry Smith .  mat - the matrix
1757e14e8a7SBarry Smith 
1767e14e8a7SBarry Smith    Output Parameter:
17799cd5145SBarry Smith .  name - name of matrix type
1787e14e8a7SBarry Smith 
1797e14e8a7SBarry Smith    Level: intermediate
1807e14e8a7SBarry Smith 
18199cd5145SBarry Smith .seealso: MatSetType()
1827e14e8a7SBarry Smith @*/
18319fd82e9SBarry Smith PetscErrorCode  MatGetType(Mat mat,MatType *type)
1847e14e8a7SBarry Smith {
1857e14e8a7SBarry Smith   PetscFunctionBegin;
1860700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
187c4e43342SLisandro Dalcin   PetscValidPointer(type,2);
1887adad957SLisandro Dalcin   *type = ((PetscObject)mat)->type_name;
1897e14e8a7SBarry Smith   PetscFunctionReturn(0);
1907e14e8a7SBarry Smith }
1917e14e8a7SBarry Smith 
1920d229a57SStefano Zampini /*@C
1930d229a57SStefano Zampini    MatGetVecType - Gets the vector type used by the matrix object.
1940d229a57SStefano Zampini 
1950d229a57SStefano Zampini    Not Collective
1960d229a57SStefano Zampini 
1970d229a57SStefano Zampini    Input Parameter:
1980d229a57SStefano Zampini .  mat - the matrix
1990d229a57SStefano Zampini 
2000d229a57SStefano Zampini    Output Parameter:
2010d229a57SStefano Zampini .  name - name of vector type
2020d229a57SStefano Zampini 
2030d229a57SStefano Zampini    Level: intermediate
2040d229a57SStefano Zampini 
2050d229a57SStefano Zampini .seealso: MatSetVecType()
2060d229a57SStefano Zampini @*/
2070d229a57SStefano Zampini PetscErrorCode MatGetVecType(Mat mat,VecType *vtype)
2080d229a57SStefano Zampini {
2090d229a57SStefano Zampini   PetscFunctionBegin;
2100d229a57SStefano Zampini   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2110d229a57SStefano Zampini   PetscValidPointer(vtype,2);
2120d229a57SStefano Zampini   *vtype = mat->defaultvectype;
2130d229a57SStefano Zampini   PetscFunctionReturn(0);
2140d229a57SStefano Zampini }
2150d229a57SStefano Zampini 
2160d229a57SStefano Zampini /*@C
2170d229a57SStefano Zampini    MatSetVecType - Set the vector type to be used for a matrix object
2180d229a57SStefano Zampini 
2190d229a57SStefano Zampini    Collective on Mat
2200d229a57SStefano Zampini 
2210d229a57SStefano Zampini    Input Parameters:
2220d229a57SStefano Zampini +  mat   - the matrix object
2230d229a57SStefano Zampini -  vtype - vector type
2240d229a57SStefano Zampini 
2250d229a57SStefano Zampini    Notes:
2260d229a57SStefano Zampini      This is rarely needed in practice since each matrix object internally sets the proper vector type.
2270d229a57SStefano Zampini 
2280d229a57SStefano Zampini   Level: intermediate
2290d229a57SStefano Zampini 
2300d229a57SStefano Zampini .seealso: VecSetType(), MatGetVecType()
2310d229a57SStefano Zampini @*/
2320d229a57SStefano Zampini PetscErrorCode MatSetVecType(Mat mat,VecType vtype)
2330d229a57SStefano Zampini {
2340d229a57SStefano Zampini   PetscFunctionBegin;
2350d229a57SStefano Zampini   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2369566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->defaultvectype));
2379566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(vtype,&mat->defaultvectype));
2380d229a57SStefano Zampini   PetscFunctionReturn(0);
2390d229a57SStefano Zampini }
2407e14e8a7SBarry Smith 
2413cea93caSBarry Smith /*@C
2421c84c290SBarry Smith   MatRegister -  - Adds a new matrix type
2431c84c290SBarry Smith 
2441c84c290SBarry Smith    Not Collective
2451c84c290SBarry Smith 
2461c84c290SBarry Smith    Input Parameters:
2471c84c290SBarry Smith +  name - name of a new user-defined matrix type
2481c84c290SBarry Smith -  routine_create - routine to create method context
2491c84c290SBarry Smith 
2501c84c290SBarry Smith    Notes:
2511c84c290SBarry Smith    MatRegister() may be called multiple times to add several user-defined solvers.
2521c84c290SBarry Smith 
2531c84c290SBarry Smith    Sample usage:
2541c84c290SBarry Smith .vb
255bdf89e91SBarry Smith    MatRegister("my_mat",MyMatCreate);
2561c84c290SBarry Smith .ve
2571c84c290SBarry Smith 
2581c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
2591c84c290SBarry Smith $     MatSetType(Mat,"my_mat")
2601c84c290SBarry Smith    or at runtime via the option
2611c84c290SBarry Smith $     -mat_type my_mat
2621c84c290SBarry Smith 
2631c84c290SBarry Smith    Level: advanced
2641c84c290SBarry Smith 
265d7ee760dSBarry Smith .seealso: MatRegisterAll()
2661c84c290SBarry Smith 
2677f6c08e0SMatthew Knepley   Level: advanced
2683cea93caSBarry Smith @*/
269bdf89e91SBarry Smith PetscErrorCode  MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
2707e14e8a7SBarry Smith {
2717e14e8a7SBarry Smith   PetscFunctionBegin;
2729566063dSJacob Faibussowitsch   PetscCall(MatInitializePackage());
2739566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&MatList,sname,function));
27499cd5145SBarry Smith   PetscFunctionReturn(0);
27599cd5145SBarry Smith }
27699cd5145SBarry Smith 
277f4259b30SLisandro Dalcin MatRootName MatRootNameList = NULL;
27801bebe75SBarry Smith 
27901bebe75SBarry Smith /*@C
28023bebc0bSBarry Smith       MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType()
28123bebc0bSBarry Smith         and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the
28223bebc0bSBarry Smith         matrix.
28301bebe75SBarry Smith 
28401bebe75SBarry Smith   Input Parameters:
28523bebc0bSBarry Smith +     rname - the rootname, for example, MATAIJ
28601bebe75SBarry Smith .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
28701bebe75SBarry Smith -     mname - the name of the parallel matrix type, for example, MATMPIAIJ
28801bebe75SBarry Smith 
28923bebc0bSBarry Smith   Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare()
29001bebe75SBarry Smith 
29123bebc0bSBarry Smith   Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the
29223bebc0bSBarry Smith       size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the
29323bebc0bSBarry Smith       appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is
29423bebc0bSBarry Smith       confusing.
29523bebc0bSBarry Smith 
29623bebc0bSBarry Smith   Level: developer
29723bebc0bSBarry Smith 
29823bebc0bSBarry Smith .seealso: PetscObjectBaseTypeCompare()
29923bebc0bSBarry Smith 
30001bebe75SBarry Smith @*/
30123bebc0bSBarry Smith PetscErrorCode  MatRegisterRootName(const char rname[],const char sname[],const char mname[])
30201bebe75SBarry Smith {
30323bebc0bSBarry Smith   MatRootName    names;
30401bebe75SBarry Smith 
30501bebe75SBarry Smith   PetscFunctionBegin;
3069566063dSJacob Faibussowitsch   PetscCall(PetscNew(&names));
3079566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(rname,&names->rname));
3089566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(sname,&names->sname));
3099566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(mname,&names->mname));
31023bebc0bSBarry Smith   if (!MatRootNameList) {
31123bebc0bSBarry Smith     MatRootNameList = names;
31201bebe75SBarry Smith   } else {
31323bebc0bSBarry Smith     MatRootName next = MatRootNameList;
31401bebe75SBarry Smith     while (next->next) next = next->next;
31501bebe75SBarry Smith     next->next = names;
31601bebe75SBarry Smith   }
31701bebe75SBarry Smith   PetscFunctionReturn(0);
31801bebe75SBarry Smith }
319