xref: /petsc/src/mat/interface/matreg.c (revision dbbe0bcd3f3a8fbab5a45420dc06f8387e5764c6)
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 
26db781477SPatrick Sanan .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 
51ac81f253SRichard Tran Mills /* MatGetMPIMatType_Private - Gets the MPI type corresponding to the input matrix's type (e.g., MATMPIAIJ for MATSEQAIJ)
52ac81f253SRichard Tran Mills 
53ac81f253SRichard Tran Mills    Not Collective
54ac81f253SRichard Tran Mills 
55ac81f253SRichard Tran Mills    Input Parameters:
56ac81f253SRichard Tran Mills .  mat      - the input matrix, could be sequential or MPI
57ac81f253SRichard Tran Mills 
58ac81f253SRichard Tran Mills    Output Parameters:
59ac81f253SRichard Tran Mills .  MPIType  - the parallel (MPI) matrix type
60ac81f253SRichard Tran Mills 
61ac81f253SRichard Tran Mills    Level: developer
62ac81f253SRichard Tran Mills 
63ac81f253SRichard Tran Mills .seealso: `MatGetType()`, `MatSetType()`, `MatType`, `Mat`
64ac81f253SRichard Tran Mills */
65ac81f253SRichard Tran Mills PetscErrorCode MatGetMPIMatType_Private(Mat mat, MatType *MPIType)
66ac81f253SRichard Tran Mills {
67ac81f253SRichard Tran Mills   PetscBool      found = PETSC_FALSE;
68ac81f253SRichard Tran Mills   MatRootName    names = MatRootNameList;
69ac81f253SRichard Tran Mills   MatType        inType;
70ac81f253SRichard Tran Mills 
71ac81f253SRichard Tran Mills   PetscFunctionBegin;
72ac81f253SRichard Tran Mills   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
73ac81f253SRichard Tran Mills   PetscCall(MatGetType(mat,&inType));
74ac81f253SRichard Tran Mills   while (names) {
75ac81f253SRichard Tran Mills     PetscCall(PetscStrcmp(inType,names->sname,&found));
76ac81f253SRichard Tran Mills     if (!found) PetscCall(PetscStrcmp(inType,names->mname,&found));
77ac81f253SRichard Tran Mills     if (!found) PetscCall(PetscStrcmp(inType,names->rname,&found));
78ac81f253SRichard Tran Mills     if (found) {
79ac81f253SRichard Tran Mills       found     = PETSC_TRUE;
80ac81f253SRichard Tran Mills       *MPIType = names->mname;
81ac81f253SRichard Tran Mills       break;
82ac81f253SRichard Tran Mills     }
83ac81f253SRichard Tran Mills     names = names->next;
84ac81f253SRichard Tran Mills   }
85ac81f253SRichard Tran Mills   PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_SUP,"No corresponding parallel (MPI) type for this matrix");
86ac81f253SRichard Tran Mills   PetscFunctionReturn(0);
87ac81f253SRichard Tran Mills }
88ac81f253SRichard 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 
107db781477SPatrick Sanan .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   }
141*dbbe0bcdSBarry Smith   PetscTryTypeMethod(mat,destroy);
1420298fd71SBarry Smith   mat->ops->destroy = NULL;
14382e0f345SBarry Smith 
14432e7c8b0SBarry Smith   /* should these null spaces be removed? */
1459566063dSJacob Faibussowitsch   PetscCall(MatNullSpaceDestroy(&mat->nullsp));
1469566063dSJacob Faibussowitsch   PetscCall(MatNullSpaceDestroy(&mat->nearnullsp));
147*dbbe0bcdSBarry Smith 
1489566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(mat->ops,sizeof(struct _MatOps)));
14982e0f345SBarry Smith   mat->preallocated  = PETSC_FALSE;
15082e0f345SBarry Smith   mat->assembled     = PETSC_FALSE;
15182e0f345SBarry Smith   mat->was_assembled = PETSC_FALSE;
15282e0f345SBarry Smith 
15382e0f345SBarry Smith   /*
15482e0f345SBarry Smith    Increment, rather than reset these: the object is logically the same, so its logging and
15582e0f345SBarry Smith    state is inherited.  Furthermore, resetting makes it possible for the same state to be
15682e0f345SBarry Smith    obtained with a different structure, confusing the PC.
15782e0f345SBarry Smith   */
15832e7c8b0SBarry Smith   mat->nonzerostate++;
1599566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)mat));
160a2ec6df8SKris Buschelman 
16135d8aa7fSBarry Smith   /* create the new data structure */
1629566063dSJacob Faibussowitsch   PetscCall((*r)(mat));
1637e14e8a7SBarry Smith   PetscFunctionReturn(0);
1647e14e8a7SBarry Smith }
1657e14e8a7SBarry Smith 
1667e14e8a7SBarry Smith /*@C
167f87b78b8SBarry Smith    MatGetType - Gets the matrix type as a string from the matrix object.
1687e14e8a7SBarry Smith 
1697e14e8a7SBarry Smith    Not Collective
1707e14e8a7SBarry Smith 
1717e14e8a7SBarry Smith    Input Parameter:
17299cd5145SBarry Smith .  mat - the matrix
1737e14e8a7SBarry Smith 
1747e14e8a7SBarry Smith    Output Parameter:
17599cd5145SBarry Smith .  name - name of matrix type
1767e14e8a7SBarry Smith 
1777e14e8a7SBarry Smith    Level: intermediate
1787e14e8a7SBarry Smith 
179db781477SPatrick Sanan .seealso: `MatSetType()`
1807e14e8a7SBarry Smith @*/
18119fd82e9SBarry Smith PetscErrorCode  MatGetType(Mat mat,MatType *type)
1827e14e8a7SBarry Smith {
1837e14e8a7SBarry Smith   PetscFunctionBegin;
1840700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
185c4e43342SLisandro Dalcin   PetscValidPointer(type,2);
1867adad957SLisandro Dalcin   *type = ((PetscObject)mat)->type_name;
1877e14e8a7SBarry Smith   PetscFunctionReturn(0);
1887e14e8a7SBarry Smith }
1897e14e8a7SBarry Smith 
1900d229a57SStefano Zampini /*@C
1910d229a57SStefano Zampini    MatGetVecType - Gets the vector type used by the matrix object.
1920d229a57SStefano Zampini 
1930d229a57SStefano Zampini    Not Collective
1940d229a57SStefano Zampini 
1950d229a57SStefano Zampini    Input Parameter:
1960d229a57SStefano Zampini .  mat - the matrix
1970d229a57SStefano Zampini 
1980d229a57SStefano Zampini    Output Parameter:
1990d229a57SStefano Zampini .  name - name of vector type
2000d229a57SStefano Zampini 
2010d229a57SStefano Zampini    Level: intermediate
2020d229a57SStefano Zampini 
203db781477SPatrick Sanan .seealso: `MatSetVecType()`
2040d229a57SStefano Zampini @*/
2050d229a57SStefano Zampini PetscErrorCode MatGetVecType(Mat mat,VecType *vtype)
2060d229a57SStefano Zampini {
2070d229a57SStefano Zampini   PetscFunctionBegin;
2080d229a57SStefano Zampini   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2090d229a57SStefano Zampini   PetscValidPointer(vtype,2);
2100d229a57SStefano Zampini   *vtype = mat->defaultvectype;
2110d229a57SStefano Zampini   PetscFunctionReturn(0);
2120d229a57SStefano Zampini }
2130d229a57SStefano Zampini 
2140d229a57SStefano Zampini /*@C
2150d229a57SStefano Zampini    MatSetVecType - Set the vector type to be used for a matrix object
2160d229a57SStefano Zampini 
2170d229a57SStefano Zampini    Collective on Mat
2180d229a57SStefano Zampini 
2190d229a57SStefano Zampini    Input Parameters:
2200d229a57SStefano Zampini +  mat   - the matrix object
2210d229a57SStefano Zampini -  vtype - vector type
2220d229a57SStefano Zampini 
2230d229a57SStefano Zampini    Notes:
2240d229a57SStefano Zampini      This is rarely needed in practice since each matrix object internally sets the proper vector type.
2250d229a57SStefano Zampini 
2260d229a57SStefano Zampini   Level: intermediate
2270d229a57SStefano Zampini 
228db781477SPatrick Sanan .seealso: `VecSetType()`, `MatGetVecType()`
2290d229a57SStefano Zampini @*/
2300d229a57SStefano Zampini PetscErrorCode MatSetVecType(Mat mat,VecType vtype)
2310d229a57SStefano Zampini {
2320d229a57SStefano Zampini   PetscFunctionBegin;
2330d229a57SStefano Zampini   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2349566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->defaultvectype));
2359566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(vtype,&mat->defaultvectype));
2360d229a57SStefano Zampini   PetscFunctionReturn(0);
2370d229a57SStefano Zampini }
2387e14e8a7SBarry Smith 
2393cea93caSBarry Smith /*@C
2401c84c290SBarry Smith   MatRegister -  - Adds a new matrix type
2411c84c290SBarry Smith 
2421c84c290SBarry Smith    Not Collective
2431c84c290SBarry Smith 
2441c84c290SBarry Smith    Input Parameters:
2451c84c290SBarry Smith +  name - name of a new user-defined matrix type
2461c84c290SBarry Smith -  routine_create - routine to create method context
2471c84c290SBarry Smith 
2481c84c290SBarry Smith    Notes:
2491c84c290SBarry Smith    MatRegister() may be called multiple times to add several user-defined solvers.
2501c84c290SBarry Smith 
2511c84c290SBarry Smith    Sample usage:
2521c84c290SBarry Smith .vb
253bdf89e91SBarry Smith    MatRegister("my_mat",MyMatCreate);
2541c84c290SBarry Smith .ve
2551c84c290SBarry Smith 
2561c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
2571c84c290SBarry Smith $     MatSetType(Mat,"my_mat")
2581c84c290SBarry Smith    or at runtime via the option
2591c84c290SBarry Smith $     -mat_type my_mat
2601c84c290SBarry Smith 
2611c84c290SBarry Smith    Level: advanced
2621c84c290SBarry Smith 
263db781477SPatrick Sanan .seealso: `MatRegisterAll()`
2641c84c290SBarry Smith 
2657f6c08e0SMatthew Knepley   Level: advanced
2663cea93caSBarry Smith @*/
267bdf89e91SBarry Smith PetscErrorCode  MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
2687e14e8a7SBarry Smith {
2697e14e8a7SBarry Smith   PetscFunctionBegin;
2709566063dSJacob Faibussowitsch   PetscCall(MatInitializePackage());
2719566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&MatList,sname,function));
27299cd5145SBarry Smith   PetscFunctionReturn(0);
27399cd5145SBarry Smith }
27499cd5145SBarry Smith 
275f4259b30SLisandro Dalcin MatRootName MatRootNameList = NULL;
27601bebe75SBarry Smith 
27701bebe75SBarry Smith /*@C
27823bebc0bSBarry Smith       MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType()
27923bebc0bSBarry Smith         and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the
28023bebc0bSBarry Smith         matrix.
28101bebe75SBarry Smith 
28201bebe75SBarry Smith   Input Parameters:
28323bebc0bSBarry Smith +     rname - the rootname, for example, MATAIJ
28401bebe75SBarry Smith .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
28501bebe75SBarry Smith -     mname - the name of the parallel matrix type, for example, MATMPIAIJ
28601bebe75SBarry Smith 
28723bebc0bSBarry Smith   Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare()
28801bebe75SBarry Smith 
28923bebc0bSBarry Smith   Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the
29023bebc0bSBarry Smith       size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the
29123bebc0bSBarry Smith       appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is
29223bebc0bSBarry Smith       confusing.
29323bebc0bSBarry Smith 
29423bebc0bSBarry Smith   Level: developer
29523bebc0bSBarry Smith 
296db781477SPatrick Sanan .seealso: `PetscObjectBaseTypeCompare()`
29723bebc0bSBarry Smith 
29801bebe75SBarry Smith @*/
29923bebc0bSBarry Smith PetscErrorCode  MatRegisterRootName(const char rname[],const char sname[],const char mname[])
30001bebe75SBarry Smith {
30123bebc0bSBarry Smith   MatRootName    names;
30201bebe75SBarry Smith 
30301bebe75SBarry Smith   PetscFunctionBegin;
3049566063dSJacob Faibussowitsch   PetscCall(PetscNew(&names));
3059566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(rname,&names->rname));
3069566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(sname,&names->sname));
3079566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(mname,&names->mname));
30823bebc0bSBarry Smith   if (!MatRootNameList) {
30923bebc0bSBarry Smith     MatRootNameList = names;
31001bebe75SBarry Smith   } else {
31123bebc0bSBarry Smith     MatRootName next = MatRootNameList;
31201bebe75SBarry Smith     while (next->next) next = next->next;
31301bebe75SBarry Smith     next->next = names;
31401bebe75SBarry Smith   }
31501bebe75SBarry Smith   PetscFunctionReturn(0);
31601bebe75SBarry Smith }
317