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