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 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); 6728fc0bbcSJose E. Roman } 6828fc0bbcSJose 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); 7628fc0bbcSJose E. Roman } 77*5da7ac92SStefano Zampini ierr = PetscMemzero(mat->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 7882e0f345SBarry Smith mat->preallocated = PETSC_FALSE; 7982e0f345SBarry Smith mat->assembled = PETSC_FALSE; 8082e0f345SBarry Smith mat->was_assembled = PETSC_FALSE; 8182e0f345SBarry Smith 8282e0f345SBarry Smith /* 8382e0f345SBarry Smith Increment, rather than reset these: the object is logically the same, so its logging and 8482e0f345SBarry Smith state is inherited. Furthermore, resetting makes it possible for the same state to be 8582e0f345SBarry Smith obtained with a different structure, confusing the PC. 8682e0f345SBarry Smith */ 8732e7c8b0SBarry Smith mat->nonzerostate++; 8832e7c8b0SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 89a2ec6df8SKris Buschelman 9035d8aa7fSBarry Smith /* create the new data structure */ 9199cd5145SBarry Smith ierr = (*r)(mat);CHKERRQ(ierr); 927e14e8a7SBarry Smith PetscFunctionReturn(0); 937e14e8a7SBarry Smith } 947e14e8a7SBarry Smith 957e14e8a7SBarry Smith /*@C 96f87b78b8SBarry Smith MatGetType - Gets the matrix type as a string from the matrix object. 977e14e8a7SBarry Smith 987e14e8a7SBarry Smith Not Collective 997e14e8a7SBarry Smith 1007e14e8a7SBarry Smith Input Parameter: 10199cd5145SBarry Smith . mat - the matrix 1027e14e8a7SBarry Smith 1037e14e8a7SBarry Smith Output Parameter: 10499cd5145SBarry Smith . name - name of matrix type 1057e14e8a7SBarry Smith 1067e14e8a7SBarry Smith Level: intermediate 1077e14e8a7SBarry Smith 10899cd5145SBarry Smith .seealso: MatSetType() 1097e14e8a7SBarry Smith @*/ 11019fd82e9SBarry Smith PetscErrorCode MatGetType(Mat mat,MatType *type) 1117e14e8a7SBarry Smith { 1127e14e8a7SBarry Smith PetscFunctionBegin; 1130700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 114c4e43342SLisandro Dalcin PetscValidPointer(type,2); 1157adad957SLisandro Dalcin *type = ((PetscObject)mat)->type_name; 1167e14e8a7SBarry Smith PetscFunctionReturn(0); 1177e14e8a7SBarry Smith } 1187e14e8a7SBarry Smith 1190d229a57SStefano Zampini /*@C 1200d229a57SStefano Zampini MatGetVecType - Gets the vector type used by the matrix object. 1210d229a57SStefano Zampini 1220d229a57SStefano Zampini Not Collective 1230d229a57SStefano Zampini 1240d229a57SStefano Zampini Input Parameter: 1250d229a57SStefano Zampini . mat - the matrix 1260d229a57SStefano Zampini 1270d229a57SStefano Zampini Output Parameter: 1280d229a57SStefano Zampini . name - name of vector type 1290d229a57SStefano Zampini 1300d229a57SStefano Zampini Level: intermediate 1310d229a57SStefano Zampini 1320d229a57SStefano Zampini .seealso: MatSetVecType() 1330d229a57SStefano Zampini @*/ 1340d229a57SStefano Zampini PetscErrorCode MatGetVecType(Mat mat,VecType *vtype) 1350d229a57SStefano Zampini { 1360d229a57SStefano Zampini PetscFunctionBegin; 1370d229a57SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1380d229a57SStefano Zampini PetscValidPointer(vtype,2); 1390d229a57SStefano Zampini *vtype = mat->defaultvectype; 1400d229a57SStefano Zampini PetscFunctionReturn(0); 1410d229a57SStefano Zampini } 1420d229a57SStefano Zampini 1430d229a57SStefano Zampini /*@C 1440d229a57SStefano Zampini MatSetVecType - Set the vector type to be used for a matrix object 1450d229a57SStefano Zampini 1460d229a57SStefano Zampini Collective on Mat 1470d229a57SStefano Zampini 1480d229a57SStefano Zampini Input Parameters: 1490d229a57SStefano Zampini + mat - the matrix object 1500d229a57SStefano Zampini - vtype - vector type 1510d229a57SStefano Zampini 1520d229a57SStefano Zampini Notes: 1530d229a57SStefano Zampini This is rarely needed in practice since each matrix object internally sets the proper vector type. 1540d229a57SStefano Zampini 1550d229a57SStefano Zampini Level: intermediate 1560d229a57SStefano Zampini 1570d229a57SStefano Zampini .seealso: VecSetType(), MatGetVecType() 1580d229a57SStefano Zampini @*/ 1590d229a57SStefano Zampini PetscErrorCode MatSetVecType(Mat mat,VecType vtype) 1600d229a57SStefano Zampini { 1610d229a57SStefano Zampini PetscErrorCode ierr; 1620d229a57SStefano Zampini 1630d229a57SStefano Zampini PetscFunctionBegin; 1640d229a57SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1650d229a57SStefano Zampini ierr = PetscFree(mat->defaultvectype);CHKERRQ(ierr); 1660d229a57SStefano Zampini ierr = PetscStrallocpy(vtype,&mat->defaultvectype);CHKERRQ(ierr); 1670d229a57SStefano Zampini PetscFunctionReturn(0); 1680d229a57SStefano Zampini } 1697e14e8a7SBarry Smith 1703cea93caSBarry Smith /*@C 1711c84c290SBarry Smith MatRegister - - Adds a new matrix type 1721c84c290SBarry Smith 1731c84c290SBarry Smith Not Collective 1741c84c290SBarry Smith 1751c84c290SBarry Smith Input Parameters: 1761c84c290SBarry Smith + name - name of a new user-defined matrix type 1771c84c290SBarry Smith - routine_create - routine to create method context 1781c84c290SBarry Smith 1791c84c290SBarry Smith Notes: 1801c84c290SBarry Smith MatRegister() may be called multiple times to add several user-defined solvers. 1811c84c290SBarry Smith 1821c84c290SBarry Smith Sample usage: 1831c84c290SBarry Smith .vb 184bdf89e91SBarry Smith MatRegister("my_mat",MyMatCreate); 1851c84c290SBarry Smith .ve 1861c84c290SBarry Smith 1871c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 1881c84c290SBarry Smith $ MatSetType(Mat,"my_mat") 1891c84c290SBarry Smith or at runtime via the option 1901c84c290SBarry Smith $ -mat_type my_mat 1911c84c290SBarry Smith 1921c84c290SBarry Smith Level: advanced 1931c84c290SBarry Smith 194d7ee760dSBarry Smith .seealso: MatRegisterAll() 1951c84c290SBarry Smith 1963cea93caSBarry Smith 1977f6c08e0SMatthew Knepley Level: advanced 1983cea93caSBarry Smith @*/ 199bdf89e91SBarry Smith PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat)) 2007e14e8a7SBarry Smith { 201dfbe8321SBarry Smith PetscErrorCode ierr; 2027e14e8a7SBarry Smith 2037e14e8a7SBarry Smith PetscFunctionBegin; 2041d36bdfdSBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 205a240a19fSJed Brown ierr = PetscFunctionListAdd(&MatList,sname,function);CHKERRQ(ierr); 20699cd5145SBarry Smith PetscFunctionReturn(0); 20799cd5145SBarry Smith } 20899cd5145SBarry Smith 209f4259b30SLisandro Dalcin MatRootName MatRootNameList = NULL; 21001bebe75SBarry Smith 21101bebe75SBarry Smith /*@C 21223bebc0bSBarry Smith MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType() 21323bebc0bSBarry Smith and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the 21423bebc0bSBarry Smith matrix. 21501bebe75SBarry Smith 21601bebe75SBarry Smith Input Parameters: 21723bebc0bSBarry Smith + rname - the rootname, for example, MATAIJ 21801bebe75SBarry Smith . sname - the name of the sequential matrix type, for example, MATSEQAIJ 21901bebe75SBarry Smith - mname - the name of the parallel matrix type, for example, MATMPIAIJ 22001bebe75SBarry Smith 22123bebc0bSBarry Smith Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare() 22201bebe75SBarry Smith 22323bebc0bSBarry Smith Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the 22423bebc0bSBarry Smith size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the 22523bebc0bSBarry Smith appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is 22623bebc0bSBarry Smith confusing. 22723bebc0bSBarry Smith 22823bebc0bSBarry Smith Level: developer 22923bebc0bSBarry Smith 23023bebc0bSBarry Smith .seealso: PetscObjectBaseTypeCompare() 23123bebc0bSBarry Smith 23201bebe75SBarry Smith @*/ 23323bebc0bSBarry Smith PetscErrorCode MatRegisterRootName(const char rname[],const char sname[],const char mname[]) 23401bebe75SBarry Smith { 23501bebe75SBarry Smith PetscErrorCode ierr; 23623bebc0bSBarry Smith MatRootName names; 23701bebe75SBarry Smith 23801bebe75SBarry Smith PetscFunctionBegin; 239b00a9115SJed Brown ierr = PetscNew(&names);CHKERRQ(ierr); 24023bebc0bSBarry Smith ierr = PetscStrallocpy(rname,&names->rname);CHKERRQ(ierr); 24101bebe75SBarry Smith ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr); 24201bebe75SBarry Smith ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr); 24323bebc0bSBarry Smith if (!MatRootNameList) { 24423bebc0bSBarry Smith MatRootNameList = names; 24501bebe75SBarry Smith } else { 24623bebc0bSBarry Smith MatRootName next = MatRootNameList; 24701bebe75SBarry Smith while (next->next) next = next->next; 24801bebe75SBarry Smith next->next = names; 24901bebe75SBarry Smith } 25001bebe75SBarry Smith PetscFunctionReturn(0); 25101bebe75SBarry Smith } 252