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 14*2c99ec25SJunchao Zhang /* MatGetRootType_Private - Gets the root type of the input matrix's type (e.g., MATAIJ for MATSEQAIJ) 15*2c99ec25SJunchao Zhang 16*2c99ec25SJunchao Zhang Not Collective 17*2c99ec25SJunchao Zhang 18*2c99ec25SJunchao Zhang Input Parameters: 19*2c99ec25SJunchao Zhang . mat - the input matrix, could be sequential or MPI 20*2c99ec25SJunchao Zhang 21*2c99ec25SJunchao Zhang Output Parameters: 22*2c99ec25SJunchao Zhang . rootType - the root matrix type 23*2c99ec25SJunchao Zhang 24*2c99ec25SJunchao Zhang Level: developer 25*2c99ec25SJunchao Zhang 26*2c99ec25SJunchao Zhang .seealso: MatGetType(), MatSetType(), MatType, Mat 27*2c99ec25SJunchao Zhang */ 28*2c99ec25SJunchao Zhang PetscErrorCode MatGetRootType_Private(Mat mat, MatType *rootType) 29*2c99ec25SJunchao Zhang { 30*2c99ec25SJunchao Zhang PetscErrorCode ierr; 31*2c99ec25SJunchao Zhang PetscBool found = PETSC_FALSE; 32*2c99ec25SJunchao Zhang MatRootName names = MatRootNameList; 33*2c99ec25SJunchao Zhang MatType inType; 34*2c99ec25SJunchao Zhang PetscMPIInt size; 35*2c99ec25SJunchao Zhang 36*2c99ec25SJunchao Zhang PetscFunctionBegin; 37*2c99ec25SJunchao Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 38*2c99ec25SJunchao Zhang ierr = MatGetType(mat,&inType);CHKERRQ(ierr); 39*2c99ec25SJunchao Zhang ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr); 40*2c99ec25SJunchao Zhang while (names) { 41*2c99ec25SJunchao Zhang if (size > 1) {ierr = PetscStrcmp(inType,names->mname,&found);CHKERRQ(ierr);} 42*2c99ec25SJunchao Zhang else {ierr = PetscStrcmp(inType,names->sname,&found);CHKERRQ(ierr);} 43*2c99ec25SJunchao Zhang if (found) { 44*2c99ec25SJunchao Zhang found = PETSC_TRUE; 45*2c99ec25SJunchao Zhang *rootType = names->rname; 46*2c99ec25SJunchao Zhang break; 47*2c99ec25SJunchao Zhang } 48*2c99ec25SJunchao Zhang names = names->next; 49*2c99ec25SJunchao Zhang } 50*2c99ec25SJunchao Zhang if (!found) *rootType = inType; 51*2c99ec25SJunchao Zhang PetscFunctionReturn(0); 52*2c99ec25SJunchao Zhang } 53*2c99ec25SJunchao Zhang 547e14e8a7SBarry Smith /*@C 5599cd5145SBarry Smith MatSetType - Builds matrix object for a particular matrix type 567e14e8a7SBarry Smith 5799cd5145SBarry Smith Collective on Mat 587e14e8a7SBarry Smith 597e14e8a7SBarry Smith Input Parameters: 6099cd5145SBarry Smith + mat - the matrix object 6199cd5145SBarry Smith - matype - matrix type 627e14e8a7SBarry Smith 637e14e8a7SBarry Smith Options Database Key: 6499cd5145SBarry Smith . -mat_type <method> - Sets the type; use -help for a list 6599cd5145SBarry Smith of available methods (for instance, seqaij) 667e14e8a7SBarry Smith 677e14e8a7SBarry Smith Notes: 6899cd5145SBarry Smith See "${PETSC_DIR}/include/petscmat.h" for available methods 697e14e8a7SBarry Smith 707e14e8a7SBarry Smith Level: intermediate 717e14e8a7SBarry Smith 726e0d5acbSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 737e14e8a7SBarry Smith @*/ 7419fd82e9SBarry Smith PetscErrorCode MatSetType(Mat mat, MatType matype) 757e14e8a7SBarry Smith { 76dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(Mat); 773dcd2dd8SBarry Smith PetscBool sametype,found,subclass = PETSC_FALSE; 7823bebc0bSBarry Smith MatRootName names = MatRootNameList; 797e14e8a7SBarry Smith 807e14e8a7SBarry Smith PetscFunctionBegin; 810700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 82117016b1SBarry Smith 8301bebe75SBarry Smith while (names) { 8423bebc0bSBarry Smith ierr = PetscStrcmp(matype,names->rname,&found);CHKERRQ(ierr); 8501bebe75SBarry Smith if (found) { 8601bebe75SBarry Smith PetscMPIInt size; 87ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr); 8801bebe75SBarry Smith if (size == 1) matype = names->sname; 8901bebe75SBarry Smith else matype = names->mname; 9001bebe75SBarry Smith break; 9101bebe75SBarry Smith } 9201bebe75SBarry Smith names = names->next; 9301bebe75SBarry Smith } 9401bebe75SBarry Smith 95251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 9692ff6ae8SBarry Smith if (sametype) PetscFunctionReturn(0); 9792ff6ae8SBarry Smith 981c9cd337SJed Brown ierr = PetscFunctionListFind(MatList,matype,&r);CHKERRQ(ierr); 99e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 1007e14e8a7SBarry Smith 101b49b7b76SBarry Smith if (mat->assembled && ((PetscObject)mat)->type_name) { 1023dcd2dd8SBarry Smith ierr = PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass);CHKERRQ(ierr); 1033dcd2dd8SBarry Smith } 1043dcd2dd8SBarry Smith if (subclass) { 1053dcd2dd8SBarry Smith ierr = MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 1063dcd2dd8SBarry Smith PetscFunctionReturn(0); 10728fc0bbcSJose E. Roman } 10828fc0bbcSJose E. Roman if (mat->ops->destroy) { 10935d8aa7fSBarry Smith /* free the old data structure if it existed */ 11035d8aa7fSBarry Smith ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr); 1110298fd71SBarry Smith mat->ops->destroy = NULL; 11282e0f345SBarry Smith 11332e7c8b0SBarry Smith /* should these null spaces be removed? */ 11432e7c8b0SBarry Smith ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 11532e7c8b0SBarry Smith ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 11628fc0bbcSJose E. Roman } 1175da7ac92SStefano Zampini ierr = PetscMemzero(mat->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 11882e0f345SBarry Smith mat->preallocated = PETSC_FALSE; 11982e0f345SBarry Smith mat->assembled = PETSC_FALSE; 12082e0f345SBarry Smith mat->was_assembled = PETSC_FALSE; 12182e0f345SBarry Smith 12282e0f345SBarry Smith /* 12382e0f345SBarry Smith Increment, rather than reset these: the object is logically the same, so its logging and 12482e0f345SBarry Smith state is inherited. Furthermore, resetting makes it possible for the same state to be 12582e0f345SBarry Smith obtained with a different structure, confusing the PC. 12682e0f345SBarry Smith */ 12732e7c8b0SBarry Smith mat->nonzerostate++; 12832e7c8b0SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 129a2ec6df8SKris Buschelman 13035d8aa7fSBarry Smith /* create the new data structure */ 13199cd5145SBarry Smith ierr = (*r)(mat);CHKERRQ(ierr); 1327e14e8a7SBarry Smith PetscFunctionReturn(0); 1337e14e8a7SBarry Smith } 1347e14e8a7SBarry Smith 1357e14e8a7SBarry Smith /*@C 136f87b78b8SBarry Smith MatGetType - Gets the matrix type as a string from the matrix object. 1377e14e8a7SBarry Smith 1387e14e8a7SBarry Smith Not Collective 1397e14e8a7SBarry Smith 1407e14e8a7SBarry Smith Input Parameter: 14199cd5145SBarry Smith . mat - the matrix 1427e14e8a7SBarry Smith 1437e14e8a7SBarry Smith Output Parameter: 14499cd5145SBarry Smith . name - name of matrix type 1457e14e8a7SBarry Smith 1467e14e8a7SBarry Smith Level: intermediate 1477e14e8a7SBarry Smith 14899cd5145SBarry Smith .seealso: MatSetType() 1497e14e8a7SBarry Smith @*/ 15019fd82e9SBarry Smith PetscErrorCode MatGetType(Mat mat,MatType *type) 1517e14e8a7SBarry Smith { 1527e14e8a7SBarry Smith PetscFunctionBegin; 1530700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 154c4e43342SLisandro Dalcin PetscValidPointer(type,2); 1557adad957SLisandro Dalcin *type = ((PetscObject)mat)->type_name; 1567e14e8a7SBarry Smith PetscFunctionReturn(0); 1577e14e8a7SBarry Smith } 1587e14e8a7SBarry Smith 1590d229a57SStefano Zampini /*@C 1600d229a57SStefano Zampini MatGetVecType - Gets the vector type used by the matrix object. 1610d229a57SStefano Zampini 1620d229a57SStefano Zampini Not Collective 1630d229a57SStefano Zampini 1640d229a57SStefano Zampini Input Parameter: 1650d229a57SStefano Zampini . mat - the matrix 1660d229a57SStefano Zampini 1670d229a57SStefano Zampini Output Parameter: 1680d229a57SStefano Zampini . name - name of vector type 1690d229a57SStefano Zampini 1700d229a57SStefano Zampini Level: intermediate 1710d229a57SStefano Zampini 1720d229a57SStefano Zampini .seealso: MatSetVecType() 1730d229a57SStefano Zampini @*/ 1740d229a57SStefano Zampini PetscErrorCode MatGetVecType(Mat mat,VecType *vtype) 1750d229a57SStefano Zampini { 1760d229a57SStefano Zampini PetscFunctionBegin; 1770d229a57SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1780d229a57SStefano Zampini PetscValidPointer(vtype,2); 1790d229a57SStefano Zampini *vtype = mat->defaultvectype; 1800d229a57SStefano Zampini PetscFunctionReturn(0); 1810d229a57SStefano Zampini } 1820d229a57SStefano Zampini 1830d229a57SStefano Zampini /*@C 1840d229a57SStefano Zampini MatSetVecType - Set the vector type to be used for a matrix object 1850d229a57SStefano Zampini 1860d229a57SStefano Zampini Collective on Mat 1870d229a57SStefano Zampini 1880d229a57SStefano Zampini Input Parameters: 1890d229a57SStefano Zampini + mat - the matrix object 1900d229a57SStefano Zampini - vtype - vector type 1910d229a57SStefano Zampini 1920d229a57SStefano Zampini Notes: 1930d229a57SStefano Zampini This is rarely needed in practice since each matrix object internally sets the proper vector type. 1940d229a57SStefano Zampini 1950d229a57SStefano Zampini Level: intermediate 1960d229a57SStefano Zampini 1970d229a57SStefano Zampini .seealso: VecSetType(), MatGetVecType() 1980d229a57SStefano Zampini @*/ 1990d229a57SStefano Zampini PetscErrorCode MatSetVecType(Mat mat,VecType vtype) 2000d229a57SStefano Zampini { 2010d229a57SStefano Zampini PetscErrorCode ierr; 2020d229a57SStefano Zampini 2030d229a57SStefano Zampini PetscFunctionBegin; 2040d229a57SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2050d229a57SStefano Zampini ierr = PetscFree(mat->defaultvectype);CHKERRQ(ierr); 2060d229a57SStefano Zampini ierr = PetscStrallocpy(vtype,&mat->defaultvectype);CHKERRQ(ierr); 2070d229a57SStefano Zampini PetscFunctionReturn(0); 2080d229a57SStefano Zampini } 2097e14e8a7SBarry Smith 2103cea93caSBarry Smith /*@C 2111c84c290SBarry Smith MatRegister - - Adds a new matrix type 2121c84c290SBarry Smith 2131c84c290SBarry Smith Not Collective 2141c84c290SBarry Smith 2151c84c290SBarry Smith Input Parameters: 2161c84c290SBarry Smith + name - name of a new user-defined matrix type 2171c84c290SBarry Smith - routine_create - routine to create method context 2181c84c290SBarry Smith 2191c84c290SBarry Smith Notes: 2201c84c290SBarry Smith MatRegister() may be called multiple times to add several user-defined solvers. 2211c84c290SBarry Smith 2221c84c290SBarry Smith Sample usage: 2231c84c290SBarry Smith .vb 224bdf89e91SBarry Smith MatRegister("my_mat",MyMatCreate); 2251c84c290SBarry Smith .ve 2261c84c290SBarry Smith 2271c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 2281c84c290SBarry Smith $ MatSetType(Mat,"my_mat") 2291c84c290SBarry Smith or at runtime via the option 2301c84c290SBarry Smith $ -mat_type my_mat 2311c84c290SBarry Smith 2321c84c290SBarry Smith Level: advanced 2331c84c290SBarry Smith 234d7ee760dSBarry Smith .seealso: MatRegisterAll() 2351c84c290SBarry Smith 2367f6c08e0SMatthew Knepley Level: advanced 2373cea93caSBarry Smith @*/ 238bdf89e91SBarry Smith PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat)) 2397e14e8a7SBarry Smith { 240dfbe8321SBarry Smith PetscErrorCode ierr; 2417e14e8a7SBarry Smith 2427e14e8a7SBarry Smith PetscFunctionBegin; 2431d36bdfdSBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 244a240a19fSJed Brown ierr = PetscFunctionListAdd(&MatList,sname,function);CHKERRQ(ierr); 24599cd5145SBarry Smith PetscFunctionReturn(0); 24699cd5145SBarry Smith } 24799cd5145SBarry Smith 248f4259b30SLisandro Dalcin MatRootName MatRootNameList = NULL; 24901bebe75SBarry Smith 25001bebe75SBarry Smith /*@C 25123bebc0bSBarry Smith MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType() 25223bebc0bSBarry Smith and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the 25323bebc0bSBarry Smith matrix. 25401bebe75SBarry Smith 25501bebe75SBarry Smith Input Parameters: 25623bebc0bSBarry Smith + rname - the rootname, for example, MATAIJ 25701bebe75SBarry Smith . sname - the name of the sequential matrix type, for example, MATSEQAIJ 25801bebe75SBarry Smith - mname - the name of the parallel matrix type, for example, MATMPIAIJ 25901bebe75SBarry Smith 26023bebc0bSBarry Smith Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare() 26101bebe75SBarry Smith 26223bebc0bSBarry Smith Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the 26323bebc0bSBarry Smith size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the 26423bebc0bSBarry Smith appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is 26523bebc0bSBarry Smith confusing. 26623bebc0bSBarry Smith 26723bebc0bSBarry Smith Level: developer 26823bebc0bSBarry Smith 26923bebc0bSBarry Smith .seealso: PetscObjectBaseTypeCompare() 27023bebc0bSBarry Smith 27101bebe75SBarry Smith @*/ 27223bebc0bSBarry Smith PetscErrorCode MatRegisterRootName(const char rname[],const char sname[],const char mname[]) 27301bebe75SBarry Smith { 27401bebe75SBarry Smith PetscErrorCode ierr; 27523bebc0bSBarry Smith MatRootName names; 27601bebe75SBarry Smith 27701bebe75SBarry Smith PetscFunctionBegin; 278b00a9115SJed Brown ierr = PetscNew(&names);CHKERRQ(ierr); 27923bebc0bSBarry Smith ierr = PetscStrallocpy(rname,&names->rname);CHKERRQ(ierr); 28001bebe75SBarry Smith ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr); 28101bebe75SBarry Smith ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr); 28223bebc0bSBarry Smith if (!MatRootNameList) { 28323bebc0bSBarry Smith MatRootNameList = names; 28401bebe75SBarry Smith } else { 28523bebc0bSBarry Smith MatRootName next = MatRootNameList; 28601bebe75SBarry Smith while (next->next) next = next->next; 28701bebe75SBarry Smith next->next = names; 28801bebe75SBarry Smith } 28901bebe75SBarry Smith PetscFunctionReturn(0); 29001bebe75SBarry Smith } 291