xref: /petsc/src/mat/interface/matreg.c (revision bfc4c25e64040512a7cdc7bcb995f785926f51e6)
1 
2 /*
3      Mechanism for register PETSc matrix types
4 */
5 #include <petsc/private/matimpl.h>      /*I "petscmat.h" I*/
6 
7 PetscBool MatRegisterAllCalled = PETSC_FALSE;
8 
9 /*
10    Contains the list of registered Mat routines
11 */
12 PetscFunctionList MatList = 0;
13 
14 #undef __FUNCT__
15 #define __FUNCT__ "MatSetType"
16 /*@C
17    MatSetType - Builds matrix object for a particular matrix type
18 
19    Collective on Mat
20 
21    Input Parameters:
22 +  mat      - the matrix object
23 -  matype   - matrix type
24 
25    Options Database Key:
26 .  -mat_type  <method> - Sets the type; use -help for a list
27     of available methods (for instance, seqaij)
28 
29    Notes:
30    See "${PETSC_DIR}/include/petscmat.h" for available methods
31 
32   Level: intermediate
33 
34 .keywords: Mat, MatType, set, method
35 
36 .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat
37 @*/
38 PetscErrorCode  MatSetType(Mat mat, MatType matype)
39 {
40   PetscErrorCode ierr,(*r)(Mat);
41   PetscBool      sametype,found;
42   MatBaseName    names = MatBaseNameList;
43 
44   PetscFunctionBegin;
45   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
46 
47   while (names) {
48     ierr = PetscStrcmp(matype,names->bname,&found);CHKERRQ(ierr);
49     if (found) {
50       PetscMPIInt size;
51       ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
52       if (size == 1) matype = names->sname;
53       else matype = names->mname;
54       break;
55     }
56     names = names->next;
57   }
58 
59   ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr);
60   if (sametype) PetscFunctionReturn(0);
61 
62   ierr =  PetscFunctionListFind(MatList,matype,&r);CHKERRQ(ierr);
63   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype);
64 
65   /* free the old data structure if it existed */
66   if (mat->ops->destroy) {
67     ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr);
68     mat->ops->destroy = NULL;
69 
70     /* should these null spaces be removed? */
71     ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
72     ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
73     mat->preallocated = PETSC_FALSE;
74     mat->assembled = PETSC_FALSE;
75     mat->was_assembled = PETSC_FALSE;
76 
77     /*
78      Increment, rather than reset these: the object is logically the same, so its logging and
79      state is inherited.  Furthermore, resetting makes it possible for the same state to be
80      obtained with a different structure, confusing the PC.
81     */
82     ++mat->nonzerostate;
83     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
84   }
85   mat->preallocated  = PETSC_FALSE;
86   mat->assembled     = PETSC_FALSE;
87   mat->was_assembled = PETSC_FALSE;
88 
89   /* increase the state so that any code holding the current state knows the matrix has been changed */
90   mat->nonzerostate++;
91   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
92 
93   /* create the new data structure */
94   ierr = (*r)(mat);CHKERRQ(ierr);
95   PetscFunctionReturn(0);
96 }
97 
98 #undef __FUNCT__
99 #define __FUNCT__ "MatGetType"
100 /*@C
101    MatGetType - Gets the matrix type as a string from the matrix object.
102 
103    Not Collective
104 
105    Input Parameter:
106 .  mat - the matrix
107 
108    Output Parameter:
109 .  name - name of matrix type
110 
111    Level: intermediate
112 
113 .keywords: Mat, MatType, get, method, name
114 
115 .seealso: MatSetType()
116 @*/
117 PetscErrorCode  MatGetType(Mat mat,MatType *type)
118 {
119   PetscFunctionBegin;
120   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
121   PetscValidPointer(type,2);
122   *type = ((PetscObject)mat)->type_name;
123   PetscFunctionReturn(0);
124 }
125 
126 
127 #undef __FUNCT__
128 #define __FUNCT__ "MatRegister"
129 /*@C
130   MatRegister -  - Adds a new matrix type
131 
132    Not Collective
133 
134    Input Parameters:
135 +  name - name of a new user-defined matrix type
136 -  routine_create - routine to create method context
137 
138    Notes:
139    MatRegister() may be called multiple times to add several user-defined solvers.
140 
141    Sample usage:
142 .vb
143    MatRegister("my_mat",MyMatCreate);
144 .ve
145 
146    Then, your solver can be chosen with the procedural interface via
147 $     MatSetType(Mat,"my_mat")
148    or at runtime via the option
149 $     -mat_type my_mat
150 
151    Level: advanced
152 
153 .keywords: Mat, register
154 
155 .seealso: MatRegisterAll()
156 
157 
158   Level: advanced
159 @*/
160 PetscErrorCode  MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
161 {
162   PetscErrorCode ierr;
163 
164   PetscFunctionBegin;
165   ierr = PetscFunctionListAdd(&MatList,sname,function);CHKERRQ(ierr);
166   PetscFunctionReturn(0);
167 }
168 
169 MatBaseName MatBaseNameList = 0;
170 
171 #undef __FUNCT__
172 #define __FUNCT__ "MatRegisterBaseName"
173 /*@C
174       MatRegisterBaseName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type.
175 
176   Input Parameters:
177 +     bname - the basename, for example, MATAIJ
178 .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
179 -     mname - the name of the parallel matrix type, for example, MATMPIAIJ
180 
181 
182   Level: advanced
183 @*/
184 PetscErrorCode  MatRegisterBaseName(const char bname[],const char sname[],const char mname[])
185 {
186   PetscErrorCode ierr;
187   MatBaseName    names;
188 
189   PetscFunctionBegin;
190   ierr = PetscNew(&names);CHKERRQ(ierr);
191   ierr = PetscStrallocpy(bname,&names->bname);CHKERRQ(ierr);
192   ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr);
193   ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr);
194   if (!MatBaseNameList) {
195     MatBaseNameList = names;
196   } else {
197     MatBaseName next = MatBaseNameList;
198     while (next->next) next = next->next;
199     next->next = names;
200   }
201   PetscFunctionReturn(0);
202 }
203 
204 
205 
206 
207 
208 
209 
210