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