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); 673dcd2dd8SBarry Smith } if (mat->ops->destroy) { 6835d8aa7fSBarry Smith /* free the old data structure if it existed */ 6935d8aa7fSBarry Smith ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr); 700298fd71SBarry Smith mat->ops->destroy = NULL; 7182e0f345SBarry Smith 7232e7c8b0SBarry Smith /* should these null spaces be removed? */ 7332e7c8b0SBarry Smith ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 7432e7c8b0SBarry Smith ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 7582e0f345SBarry Smith mat->preallocated = PETSC_FALSE; 7682e0f345SBarry Smith mat->assembled = PETSC_FALSE; 7782e0f345SBarry Smith mat->was_assembled = PETSC_FALSE; 7882e0f345SBarry Smith 7982e0f345SBarry Smith /* 8082e0f345SBarry Smith Increment, rather than reset these: the object is logically the same, so its logging and 8182e0f345SBarry Smith state is inherited. Furthermore, resetting makes it possible for the same state to be 8282e0f345SBarry Smith obtained with a different structure, confusing the PC. 8382e0f345SBarry Smith */ 8482e0f345SBarry Smith ++mat->nonzerostate; 8582e0f345SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8635d8aa7fSBarry Smith } 8767d6de01SJed Brown mat->preallocated = PETSC_FALSE; 8832e7c8b0SBarry Smith mat->assembled = PETSC_FALSE; 8932e7c8b0SBarry Smith mat->was_assembled = PETSC_FALSE; 9032e7c8b0SBarry Smith 9132e7c8b0SBarry Smith /* increase the state so that any code holding the current state knows the matrix has been changed */ 9232e7c8b0SBarry Smith mat->nonzerostate++; 9332e7c8b0SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 94a2ec6df8SKris Buschelman 9535d8aa7fSBarry Smith /* create the new data structure */ 9699cd5145SBarry Smith ierr = (*r)(mat);CHKERRQ(ierr); 977e14e8a7SBarry Smith PetscFunctionReturn(0); 987e14e8a7SBarry Smith } 997e14e8a7SBarry Smith 1007e14e8a7SBarry Smith /*@C 101f87b78b8SBarry Smith MatGetType - Gets the matrix type as a string from the matrix object. 1027e14e8a7SBarry Smith 1037e14e8a7SBarry Smith Not Collective 1047e14e8a7SBarry Smith 1057e14e8a7SBarry Smith Input Parameter: 10699cd5145SBarry Smith . mat - the matrix 1077e14e8a7SBarry Smith 1087e14e8a7SBarry Smith Output Parameter: 10999cd5145SBarry Smith . name - name of matrix type 1107e14e8a7SBarry Smith 1117e14e8a7SBarry Smith Level: intermediate 1127e14e8a7SBarry Smith 11399cd5145SBarry Smith .seealso: MatSetType() 1147e14e8a7SBarry Smith @*/ 11519fd82e9SBarry Smith PetscErrorCode MatGetType(Mat mat,MatType *type) 1167e14e8a7SBarry Smith { 1177e14e8a7SBarry Smith PetscFunctionBegin; 1180700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 119c4e43342SLisandro Dalcin PetscValidPointer(type,2); 1207adad957SLisandro Dalcin *type = ((PetscObject)mat)->type_name; 1217e14e8a7SBarry Smith PetscFunctionReturn(0); 1227e14e8a7SBarry Smith } 1237e14e8a7SBarry Smith 124*0d229a57SStefano Zampini /*@C 125*0d229a57SStefano Zampini MatGetVecType - Gets the vector type used by the matrix object. 126*0d229a57SStefano Zampini 127*0d229a57SStefano Zampini Not Collective 128*0d229a57SStefano Zampini 129*0d229a57SStefano Zampini Input Parameter: 130*0d229a57SStefano Zampini . mat - the matrix 131*0d229a57SStefano Zampini 132*0d229a57SStefano Zampini Output Parameter: 133*0d229a57SStefano Zampini . name - name of vector type 134*0d229a57SStefano Zampini 135*0d229a57SStefano Zampini Level: intermediate 136*0d229a57SStefano Zampini 137*0d229a57SStefano Zampini .seealso: MatSetVecType() 138*0d229a57SStefano Zampini @*/ 139*0d229a57SStefano Zampini PetscErrorCode MatGetVecType(Mat mat,VecType *vtype) 140*0d229a57SStefano Zampini { 141*0d229a57SStefano Zampini PetscFunctionBegin; 142*0d229a57SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 143*0d229a57SStefano Zampini PetscValidPointer(vtype,2); 144*0d229a57SStefano Zampini *vtype = mat->defaultvectype; 145*0d229a57SStefano Zampini PetscFunctionReturn(0); 146*0d229a57SStefano Zampini } 147*0d229a57SStefano Zampini 148*0d229a57SStefano Zampini /*@C 149*0d229a57SStefano Zampini MatSetVecType - Set the vector type to be used for a matrix object 150*0d229a57SStefano Zampini 151*0d229a57SStefano Zampini Collective on Mat 152*0d229a57SStefano Zampini 153*0d229a57SStefano Zampini Input Parameters: 154*0d229a57SStefano Zampini + mat - the matrix object 155*0d229a57SStefano Zampini - vtype - vector type 156*0d229a57SStefano Zampini 157*0d229a57SStefano Zampini Notes: 158*0d229a57SStefano Zampini This is rarely needed in practice since each matrix object internally sets the proper vector type. 159*0d229a57SStefano Zampini 160*0d229a57SStefano Zampini Level: intermediate 161*0d229a57SStefano Zampini 162*0d229a57SStefano Zampini .seealso: VecSetType(), MatGetVecType() 163*0d229a57SStefano Zampini @*/ 164*0d229a57SStefano Zampini PetscErrorCode MatSetVecType(Mat mat,VecType vtype) 165*0d229a57SStefano Zampini { 166*0d229a57SStefano Zampini PetscErrorCode ierr; 167*0d229a57SStefano Zampini 168*0d229a57SStefano Zampini PetscFunctionBegin; 169*0d229a57SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 170*0d229a57SStefano Zampini ierr = PetscFree(mat->defaultvectype);CHKERRQ(ierr); 171*0d229a57SStefano Zampini ierr = PetscStrallocpy(vtype,&mat->defaultvectype);CHKERRQ(ierr); 172*0d229a57SStefano Zampini PetscFunctionReturn(0); 173*0d229a57SStefano Zampini } 1747e14e8a7SBarry Smith 1753cea93caSBarry Smith /*@C 1761c84c290SBarry Smith MatRegister - - Adds a new matrix type 1771c84c290SBarry Smith 1781c84c290SBarry Smith Not Collective 1791c84c290SBarry Smith 1801c84c290SBarry Smith Input Parameters: 1811c84c290SBarry Smith + name - name of a new user-defined matrix type 1821c84c290SBarry Smith - routine_create - routine to create method context 1831c84c290SBarry Smith 1841c84c290SBarry Smith Notes: 1851c84c290SBarry Smith MatRegister() may be called multiple times to add several user-defined solvers. 1861c84c290SBarry Smith 1871c84c290SBarry Smith Sample usage: 1881c84c290SBarry Smith .vb 189bdf89e91SBarry Smith MatRegister("my_mat",MyMatCreate); 1901c84c290SBarry Smith .ve 1911c84c290SBarry Smith 1921c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 1931c84c290SBarry Smith $ MatSetType(Mat,"my_mat") 1941c84c290SBarry Smith or at runtime via the option 1951c84c290SBarry Smith $ -mat_type my_mat 1961c84c290SBarry Smith 1971c84c290SBarry Smith Level: advanced 1981c84c290SBarry Smith 199d7ee760dSBarry Smith .seealso: MatRegisterAll() 2001c84c290SBarry Smith 2013cea93caSBarry Smith 2027f6c08e0SMatthew Knepley Level: advanced 2033cea93caSBarry Smith @*/ 204bdf89e91SBarry Smith PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat)) 2057e14e8a7SBarry Smith { 206dfbe8321SBarry Smith PetscErrorCode ierr; 2077e14e8a7SBarry Smith 2087e14e8a7SBarry Smith PetscFunctionBegin; 2091d36bdfdSBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 210a240a19fSJed Brown ierr = PetscFunctionListAdd(&MatList,sname,function);CHKERRQ(ierr); 21199cd5145SBarry Smith PetscFunctionReturn(0); 21299cd5145SBarry Smith } 21399cd5145SBarry Smith 21423bebc0bSBarry Smith MatRootName MatRootNameList = 0; 21501bebe75SBarry Smith 21601bebe75SBarry Smith /*@C 21723bebc0bSBarry Smith MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType() 21823bebc0bSBarry Smith and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the 21923bebc0bSBarry Smith matrix. 22001bebe75SBarry Smith 22101bebe75SBarry Smith Input Parameters: 22223bebc0bSBarry Smith + rname - the rootname, for example, MATAIJ 22301bebe75SBarry Smith . sname - the name of the sequential matrix type, for example, MATSEQAIJ 22401bebe75SBarry Smith - mname - the name of the parallel matrix type, for example, MATMPIAIJ 22501bebe75SBarry Smith 22623bebc0bSBarry Smith Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare() 22701bebe75SBarry Smith 22823bebc0bSBarry Smith Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the 22923bebc0bSBarry Smith size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the 23023bebc0bSBarry Smith appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is 23123bebc0bSBarry Smith confusing. 23223bebc0bSBarry Smith 23323bebc0bSBarry Smith Level: developer 23423bebc0bSBarry Smith 23523bebc0bSBarry Smith .seealso: PetscObjectBaseTypeCompare() 23623bebc0bSBarry Smith 23701bebe75SBarry Smith @*/ 23823bebc0bSBarry Smith PetscErrorCode MatRegisterRootName(const char rname[],const char sname[],const char mname[]) 23901bebe75SBarry Smith { 24001bebe75SBarry Smith PetscErrorCode ierr; 24123bebc0bSBarry Smith MatRootName names; 24201bebe75SBarry Smith 24301bebe75SBarry Smith PetscFunctionBegin; 244b00a9115SJed Brown ierr = PetscNew(&names);CHKERRQ(ierr); 24523bebc0bSBarry Smith ierr = PetscStrallocpy(rname,&names->rname);CHKERRQ(ierr); 24601bebe75SBarry Smith ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr); 24701bebe75SBarry Smith ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr); 24823bebc0bSBarry Smith if (!MatRootNameList) { 24923bebc0bSBarry Smith MatRootNameList = names; 25001bebe75SBarry Smith } else { 25123bebc0bSBarry Smith MatRootName next = MatRootNameList; 25201bebe75SBarry Smith while (next->next) next = next->next; 25301bebe75SBarry Smith next->next = names; 25401bebe75SBarry Smith } 25501bebe75SBarry Smith PetscFunctionReturn(0); 25601bebe75SBarry Smith } 257