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