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 32c2bf8781Svictorle .keywords: Mat, MatType, set, method 337e14e8a7SBarry Smith 346e0d5acbSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 357e14e8a7SBarry Smith @*/ 3619fd82e9SBarry Smith PetscErrorCode MatSetType(Mat mat, MatType matype) 377e14e8a7SBarry Smith { 38dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(Mat); 39*3dcd2dd8SBarry Smith PetscBool sametype,found,subclass = PETSC_FALSE; 4001bebe75SBarry Smith MatBaseName names = MatBaseNameList; 417e14e8a7SBarry Smith 427e14e8a7SBarry Smith PetscFunctionBegin; 430700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 44117016b1SBarry Smith 4501bebe75SBarry Smith while (names) { 4601bebe75SBarry Smith ierr = PetscStrcmp(matype,names->bname,&found);CHKERRQ(ierr); 4701bebe75SBarry Smith if (found) { 4801bebe75SBarry Smith PetscMPIInt size; 49ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 5001bebe75SBarry Smith if (size == 1) matype = names->sname; 5101bebe75SBarry Smith else matype = names->mname; 5201bebe75SBarry Smith break; 5301bebe75SBarry Smith } 5401bebe75SBarry Smith names = names->next; 5501bebe75SBarry Smith } 5601bebe75SBarry Smith 57251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 5892ff6ae8SBarry Smith if (sametype) PetscFunctionReturn(0); 5992ff6ae8SBarry Smith 601c9cd337SJed Brown ierr = PetscFunctionListFind(MatList,matype,&r);CHKERRQ(ierr); 61e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 627e14e8a7SBarry Smith 63*3dcd2dd8SBarry Smith if (((PetscObject)mat)->type_name) { 64*3dcd2dd8SBarry Smith ierr = PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass);CHKERRQ(ierr); 65*3dcd2dd8SBarry Smith } 66*3dcd2dd8SBarry Smith if (subclass) { 67*3dcd2dd8SBarry Smith ierr = MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 68*3dcd2dd8SBarry Smith PetscFunctionReturn(0); 69*3dcd2dd8SBarry Smith } if (mat->ops->destroy) { 7035d8aa7fSBarry Smith /* free the old data structure if it existed */ 7135d8aa7fSBarry Smith ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr); 720298fd71SBarry Smith mat->ops->destroy = NULL; 7382e0f345SBarry Smith 7432e7c8b0SBarry Smith /* should these null spaces be removed? */ 7532e7c8b0SBarry Smith ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 7632e7c8b0SBarry Smith ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 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 */ 8682e0f345SBarry Smith ++mat->nonzerostate; 8782e0f345SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8835d8aa7fSBarry Smith } 8967d6de01SJed Brown mat->preallocated = PETSC_FALSE; 9032e7c8b0SBarry Smith mat->assembled = PETSC_FALSE; 9132e7c8b0SBarry Smith mat->was_assembled = PETSC_FALSE; 9232e7c8b0SBarry Smith 9332e7c8b0SBarry Smith /* increase the state so that any code holding the current state knows the matrix has been changed */ 9432e7c8b0SBarry Smith mat->nonzerostate++; 9532e7c8b0SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 96a2ec6df8SKris Buschelman 9735d8aa7fSBarry Smith /* create the new data structure */ 9899cd5145SBarry Smith ierr = (*r)(mat);CHKERRQ(ierr); 997e14e8a7SBarry Smith PetscFunctionReturn(0); 1007e14e8a7SBarry Smith } 1017e14e8a7SBarry Smith 1027e14e8a7SBarry Smith /*@C 103f87b78b8SBarry Smith MatGetType - Gets the matrix type as a string from the matrix object. 1047e14e8a7SBarry Smith 1057e14e8a7SBarry Smith Not Collective 1067e14e8a7SBarry Smith 1077e14e8a7SBarry Smith Input Parameter: 10899cd5145SBarry Smith . mat - the matrix 1097e14e8a7SBarry Smith 1107e14e8a7SBarry Smith Output Parameter: 11199cd5145SBarry Smith . name - name of matrix type 1127e14e8a7SBarry Smith 1137e14e8a7SBarry Smith Level: intermediate 1147e14e8a7SBarry Smith 115c2bf8781Svictorle .keywords: Mat, MatType, get, method, name 1167e14e8a7SBarry Smith 11799cd5145SBarry Smith .seealso: MatSetType() 1187e14e8a7SBarry Smith @*/ 11919fd82e9SBarry Smith PetscErrorCode MatGetType(Mat mat,MatType *type) 1207e14e8a7SBarry Smith { 1217e14e8a7SBarry Smith PetscFunctionBegin; 1220700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 123c4e43342SLisandro Dalcin PetscValidPointer(type,2); 1247adad957SLisandro Dalcin *type = ((PetscObject)mat)->type_name; 1257e14e8a7SBarry Smith PetscFunctionReturn(0); 1267e14e8a7SBarry Smith } 1277e14e8a7SBarry Smith 1287e14e8a7SBarry Smith 1293cea93caSBarry Smith /*@C 1301c84c290SBarry Smith MatRegister - - Adds a new matrix type 1311c84c290SBarry Smith 1321c84c290SBarry Smith Not Collective 1331c84c290SBarry Smith 1341c84c290SBarry Smith Input Parameters: 1351c84c290SBarry Smith + name - name of a new user-defined matrix type 1361c84c290SBarry Smith - routine_create - routine to create method context 1371c84c290SBarry Smith 1381c84c290SBarry Smith Notes: 1391c84c290SBarry Smith MatRegister() may be called multiple times to add several user-defined solvers. 1401c84c290SBarry Smith 1411c84c290SBarry Smith Sample usage: 1421c84c290SBarry Smith .vb 143bdf89e91SBarry Smith MatRegister("my_mat",MyMatCreate); 1441c84c290SBarry Smith .ve 1451c84c290SBarry Smith 1461c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 1471c84c290SBarry Smith $ MatSetType(Mat,"my_mat") 1481c84c290SBarry Smith or at runtime via the option 1491c84c290SBarry Smith $ -mat_type my_mat 1501c84c290SBarry Smith 1511c84c290SBarry Smith Level: advanced 1521c84c290SBarry Smith 1531c84c290SBarry Smith .keywords: Mat, register 1541c84c290SBarry Smith 155d7ee760dSBarry Smith .seealso: MatRegisterAll() 1561c84c290SBarry Smith 1573cea93caSBarry Smith 1587f6c08e0SMatthew Knepley Level: advanced 1593cea93caSBarry Smith @*/ 160bdf89e91SBarry Smith PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat)) 1617e14e8a7SBarry Smith { 162dfbe8321SBarry Smith PetscErrorCode ierr; 1637e14e8a7SBarry Smith 1647e14e8a7SBarry Smith PetscFunctionBegin; 165a240a19fSJed Brown ierr = PetscFunctionListAdd(&MatList,sname,function);CHKERRQ(ierr); 16699cd5145SBarry Smith PetscFunctionReturn(0); 16799cd5145SBarry Smith } 16899cd5145SBarry Smith 16901bebe75SBarry Smith MatBaseName MatBaseNameList = 0; 17001bebe75SBarry Smith 17101bebe75SBarry Smith /*@C 17201bebe75SBarry Smith MatRegisterBaseName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. 17301bebe75SBarry Smith 17401bebe75SBarry Smith Input Parameters: 17501bebe75SBarry Smith + bname - the basename, for example, MATAIJ 17601bebe75SBarry Smith . sname - the name of the sequential matrix type, for example, MATSEQAIJ 17701bebe75SBarry Smith - mname - the name of the parallel matrix type, for example, MATMPIAIJ 17801bebe75SBarry Smith 17901bebe75SBarry Smith 18001bebe75SBarry Smith Level: advanced 18101bebe75SBarry Smith @*/ 18201bebe75SBarry Smith PetscErrorCode MatRegisterBaseName(const char bname[],const char sname[],const char mname[]) 18301bebe75SBarry Smith { 18401bebe75SBarry Smith PetscErrorCode ierr; 18501bebe75SBarry Smith MatBaseName names; 18601bebe75SBarry Smith 18701bebe75SBarry Smith PetscFunctionBegin; 188b00a9115SJed Brown ierr = PetscNew(&names);CHKERRQ(ierr); 18901bebe75SBarry Smith ierr = PetscStrallocpy(bname,&names->bname);CHKERRQ(ierr); 19001bebe75SBarry Smith ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr); 19101bebe75SBarry Smith ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr); 19201bebe75SBarry Smith if (!MatBaseNameList) { 19301bebe75SBarry Smith MatBaseNameList = names; 19401bebe75SBarry Smith } else { 19501bebe75SBarry Smith MatBaseName next = MatBaseNameList; 19601bebe75SBarry Smith while (next->next) next = next->next; 19701bebe75SBarry Smith next->next = names; 19801bebe75SBarry Smith } 19901bebe75SBarry Smith PetscFunctionReturn(0); 20001bebe75SBarry Smith } 20101bebe75SBarry Smith 20299cd5145SBarry Smith 203273d9f13SBarry Smith 204273d9f13SBarry Smith 205273d9f13SBarry Smith 206273d9f13SBarry Smith 207273d9f13SBarry Smith 208