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 */ 12140e18c1SBarry Smith PetscFunctionList MatList = 0; 137e14e8a7SBarry Smith 147e14e8a7SBarry Smith /*@C 1599cd5145SBarry Smith MatSetType - Builds matrix object for a particular matrix type 167e14e8a7SBarry Smith 1799cd5145SBarry Smith Collective on Mat 187e14e8a7SBarry Smith 197e14e8a7SBarry Smith Input Parameters: 2099cd5145SBarry Smith + mat - the matrix object 2199cd5145SBarry Smith - matype - matrix type 227e14e8a7SBarry Smith 237e14e8a7SBarry Smith Options Database Key: 2499cd5145SBarry Smith . -mat_type <method> - Sets the type; use -help for a list 2599cd5145SBarry Smith of available methods (for instance, seqaij) 267e14e8a7SBarry Smith 277e14e8a7SBarry Smith Notes: 2899cd5145SBarry Smith See "${PETSC_DIR}/include/petscmat.h" for available methods 297e14e8a7SBarry Smith 307e14e8a7SBarry Smith Level: intermediate 317e14e8a7SBarry Smith 326e0d5acbSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 337e14e8a7SBarry Smith @*/ 3419fd82e9SBarry Smith PetscErrorCode MatSetType(Mat mat, MatType matype) 357e14e8a7SBarry Smith { 36dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(Mat); 373dcd2dd8SBarry Smith PetscBool sametype,found,subclass = PETSC_FALSE; 3823bebc0bSBarry Smith MatRootName names = MatRootNameList; 397e14e8a7SBarry Smith 407e14e8a7SBarry Smith PetscFunctionBegin; 410700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 42117016b1SBarry Smith 4301bebe75SBarry Smith while (names) { 4423bebc0bSBarry Smith ierr = PetscStrcmp(matype,names->rname,&found);CHKERRQ(ierr); 4501bebe75SBarry Smith if (found) { 4601bebe75SBarry Smith PetscMPIInt size; 47ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 4801bebe75SBarry Smith if (size == 1) matype = names->sname; 4901bebe75SBarry Smith else matype = names->mname; 5001bebe75SBarry Smith break; 5101bebe75SBarry Smith } 5201bebe75SBarry Smith names = names->next; 5301bebe75SBarry Smith } 5401bebe75SBarry Smith 55251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 5692ff6ae8SBarry Smith if (sametype) PetscFunctionReturn(0); 5792ff6ae8SBarry Smith 581c9cd337SJed Brown ierr = PetscFunctionListFind(MatList,matype,&r);CHKERRQ(ierr); 59e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 607e14e8a7SBarry Smith 61b49b7b76SBarry Smith if (mat->assembled && ((PetscObject)mat)->type_name) { 623dcd2dd8SBarry Smith ierr = PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass);CHKERRQ(ierr); 633dcd2dd8SBarry Smith } 643dcd2dd8SBarry Smith if (subclass) { 653dcd2dd8SBarry Smith ierr = MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 663dcd2dd8SBarry Smith PetscFunctionReturn(0); 67*28fc0bbcSJose E. Roman } 68*28fc0bbcSJose E. Roman if (mat->ops->destroy) { 6935d8aa7fSBarry Smith /* free the old data structure if it existed */ 7035d8aa7fSBarry Smith ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr); 710298fd71SBarry Smith mat->ops->destroy = NULL; 7282e0f345SBarry Smith 7332e7c8b0SBarry Smith /* should these null spaces be removed? */ 7432e7c8b0SBarry Smith ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 7532e7c8b0SBarry Smith ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 76*28fc0bbcSJose E. Roman } 7782e0f345SBarry Smith mat->preallocated = PETSC_FALSE; 7882e0f345SBarry Smith mat->assembled = PETSC_FALSE; 7982e0f345SBarry Smith mat->was_assembled = PETSC_FALSE; 8082e0f345SBarry Smith 8182e0f345SBarry Smith /* 8282e0f345SBarry Smith Increment, rather than reset these: the object is logically the same, so its logging and 8382e0f345SBarry Smith state is inherited. Furthermore, resetting makes it possible for the same state to be 8482e0f345SBarry Smith obtained with a different structure, confusing the PC. 8582e0f345SBarry Smith */ 8632e7c8b0SBarry Smith mat->nonzerostate++; 8732e7c8b0SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 88a2ec6df8SKris Buschelman 8935d8aa7fSBarry Smith /* create the new data structure */ 9099cd5145SBarry Smith ierr = (*r)(mat);CHKERRQ(ierr); 917e14e8a7SBarry Smith PetscFunctionReturn(0); 927e14e8a7SBarry Smith } 937e14e8a7SBarry Smith 947e14e8a7SBarry Smith /*@C 95f87b78b8SBarry Smith MatGetType - Gets the matrix type as a string from the matrix object. 967e14e8a7SBarry Smith 977e14e8a7SBarry Smith Not Collective 987e14e8a7SBarry Smith 997e14e8a7SBarry Smith Input Parameter: 10099cd5145SBarry Smith . mat - the matrix 1017e14e8a7SBarry Smith 1027e14e8a7SBarry Smith Output Parameter: 10399cd5145SBarry Smith . name - name of matrix type 1047e14e8a7SBarry Smith 1057e14e8a7SBarry Smith Level: intermediate 1067e14e8a7SBarry Smith 10799cd5145SBarry Smith .seealso: MatSetType() 1087e14e8a7SBarry Smith @*/ 10919fd82e9SBarry Smith PetscErrorCode MatGetType(Mat mat,MatType *type) 1107e14e8a7SBarry Smith { 1117e14e8a7SBarry Smith PetscFunctionBegin; 1120700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 113c4e43342SLisandro Dalcin PetscValidPointer(type,2); 1147adad957SLisandro Dalcin *type = ((PetscObject)mat)->type_name; 1157e14e8a7SBarry Smith PetscFunctionReturn(0); 1167e14e8a7SBarry Smith } 1177e14e8a7SBarry Smith 1180d229a57SStefano Zampini /*@C 1190d229a57SStefano Zampini MatGetVecType - Gets the vector type used by the matrix object. 1200d229a57SStefano Zampini 1210d229a57SStefano Zampini Not Collective 1220d229a57SStefano Zampini 1230d229a57SStefano Zampini Input Parameter: 1240d229a57SStefano Zampini . mat - the matrix 1250d229a57SStefano Zampini 1260d229a57SStefano Zampini Output Parameter: 1270d229a57SStefano Zampini . name - name of vector type 1280d229a57SStefano Zampini 1290d229a57SStefano Zampini Level: intermediate 1300d229a57SStefano Zampini 1310d229a57SStefano Zampini .seealso: MatSetVecType() 1320d229a57SStefano Zampini @*/ 1330d229a57SStefano Zampini PetscErrorCode MatGetVecType(Mat mat,VecType *vtype) 1340d229a57SStefano Zampini { 1350d229a57SStefano Zampini PetscFunctionBegin; 1360d229a57SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1370d229a57SStefano Zampini PetscValidPointer(vtype,2); 1380d229a57SStefano Zampini *vtype = mat->defaultvectype; 1390d229a57SStefano Zampini PetscFunctionReturn(0); 1400d229a57SStefano Zampini } 1410d229a57SStefano Zampini 1420d229a57SStefano Zampini /*@C 1430d229a57SStefano Zampini MatSetVecType - Set the vector type to be used for a matrix object 1440d229a57SStefano Zampini 1450d229a57SStefano Zampini Collective on Mat 1460d229a57SStefano Zampini 1470d229a57SStefano Zampini Input Parameters: 1480d229a57SStefano Zampini + mat - the matrix object 1490d229a57SStefano Zampini - vtype - vector type 1500d229a57SStefano Zampini 1510d229a57SStefano Zampini Notes: 1520d229a57SStefano Zampini This is rarely needed in practice since each matrix object internally sets the proper vector type. 1530d229a57SStefano Zampini 1540d229a57SStefano Zampini Level: intermediate 1550d229a57SStefano Zampini 1560d229a57SStefano Zampini .seealso: VecSetType(), MatGetVecType() 1570d229a57SStefano Zampini @*/ 1580d229a57SStefano Zampini PetscErrorCode MatSetVecType(Mat mat,VecType vtype) 1590d229a57SStefano Zampini { 1600d229a57SStefano Zampini PetscErrorCode ierr; 1610d229a57SStefano Zampini 1620d229a57SStefano Zampini PetscFunctionBegin; 1630d229a57SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1640d229a57SStefano Zampini ierr = PetscFree(mat->defaultvectype);CHKERRQ(ierr); 1650d229a57SStefano Zampini ierr = PetscStrallocpy(vtype,&mat->defaultvectype);CHKERRQ(ierr); 1660d229a57SStefano Zampini PetscFunctionReturn(0); 1670d229a57SStefano Zampini } 1687e14e8a7SBarry Smith 1693cea93caSBarry Smith /*@C 1701c84c290SBarry Smith MatRegister - - Adds a new matrix type 1711c84c290SBarry Smith 1721c84c290SBarry Smith Not Collective 1731c84c290SBarry Smith 1741c84c290SBarry Smith Input Parameters: 1751c84c290SBarry Smith + name - name of a new user-defined matrix type 1761c84c290SBarry Smith - routine_create - routine to create method context 1771c84c290SBarry Smith 1781c84c290SBarry Smith Notes: 1791c84c290SBarry Smith MatRegister() may be called multiple times to add several user-defined solvers. 1801c84c290SBarry Smith 1811c84c290SBarry Smith Sample usage: 1821c84c290SBarry Smith .vb 183bdf89e91SBarry Smith MatRegister("my_mat",MyMatCreate); 1841c84c290SBarry Smith .ve 1851c84c290SBarry Smith 1861c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 1871c84c290SBarry Smith $ MatSetType(Mat,"my_mat") 1881c84c290SBarry Smith or at runtime via the option 1891c84c290SBarry Smith $ -mat_type my_mat 1901c84c290SBarry Smith 1911c84c290SBarry Smith Level: advanced 1921c84c290SBarry Smith 193d7ee760dSBarry Smith .seealso: MatRegisterAll() 1941c84c290SBarry Smith 1953cea93caSBarry Smith 1967f6c08e0SMatthew Knepley Level: advanced 1973cea93caSBarry Smith @*/ 198bdf89e91SBarry Smith PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat)) 1997e14e8a7SBarry Smith { 200dfbe8321SBarry Smith PetscErrorCode ierr; 2017e14e8a7SBarry Smith 2027e14e8a7SBarry Smith PetscFunctionBegin; 2031d36bdfdSBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 204a240a19fSJed Brown ierr = PetscFunctionListAdd(&MatList,sname,function);CHKERRQ(ierr); 20599cd5145SBarry Smith PetscFunctionReturn(0); 20699cd5145SBarry Smith } 20799cd5145SBarry Smith 20823bebc0bSBarry Smith MatRootName MatRootNameList = 0; 20901bebe75SBarry Smith 21001bebe75SBarry Smith /*@C 21123bebc0bSBarry Smith MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType() 21223bebc0bSBarry Smith and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the 21323bebc0bSBarry Smith matrix. 21401bebe75SBarry Smith 21501bebe75SBarry Smith Input Parameters: 21623bebc0bSBarry Smith + rname - the rootname, for example, MATAIJ 21701bebe75SBarry Smith . sname - the name of the sequential matrix type, for example, MATSEQAIJ 21801bebe75SBarry Smith - mname - the name of the parallel matrix type, for example, MATMPIAIJ 21901bebe75SBarry Smith 22023bebc0bSBarry Smith Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare() 22101bebe75SBarry Smith 22223bebc0bSBarry Smith Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the 22323bebc0bSBarry Smith size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the 22423bebc0bSBarry Smith appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is 22523bebc0bSBarry Smith confusing. 22623bebc0bSBarry Smith 22723bebc0bSBarry Smith Level: developer 22823bebc0bSBarry Smith 22923bebc0bSBarry Smith .seealso: PetscObjectBaseTypeCompare() 23023bebc0bSBarry Smith 23101bebe75SBarry Smith @*/ 23223bebc0bSBarry Smith PetscErrorCode MatRegisterRootName(const char rname[],const char sname[],const char mname[]) 23301bebe75SBarry Smith { 23401bebe75SBarry Smith PetscErrorCode ierr; 23523bebc0bSBarry Smith MatRootName names; 23601bebe75SBarry Smith 23701bebe75SBarry Smith PetscFunctionBegin; 238b00a9115SJed Brown ierr = PetscNew(&names);CHKERRQ(ierr); 23923bebc0bSBarry Smith ierr = PetscStrallocpy(rname,&names->rname);CHKERRQ(ierr); 24001bebe75SBarry Smith ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr); 24101bebe75SBarry Smith ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr); 24223bebc0bSBarry Smith if (!MatRootNameList) { 24323bebc0bSBarry Smith MatRootNameList = names; 24401bebe75SBarry Smith } else { 24523bebc0bSBarry Smith MatRootName next = MatRootNameList; 24601bebe75SBarry Smith while (next->next) next = next->next; 24701bebe75SBarry Smith next->next = names; 24801bebe75SBarry Smith } 24901bebe75SBarry Smith PetscFunctionReturn(0); 25001bebe75SBarry Smith } 251