xref: /petsc/src/mat/interface/matreg.c (revision 2c99ec2540b537ba6fab9d5e8db342199b0f826e)
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