xref: /petsc/src/mat/interface/matreg.c (revision 3e1910f1ab6113d8365e15c6b8c907ccce7ce4ea)
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 
69     mat->ops->destroy = NULL;
70   }
71   mat->preallocated = PETSC_FALSE;
72 
73   /* create the new data structure */
74   ierr = (*r)(mat);CHKERRQ(ierr);
75   PetscFunctionReturn(0);
76 }
77 
78 
79 #undef __FUNCT__
80 #define __FUNCT__ "MatRegisterDestroy"
81 /*@C
82    MatRegisterDestroy - Frees the list of matrix types that were
83    registered by MatRegister().
84 
85    Not Collective
86 
87    Level: advanced
88 
89 .keywords: Mat, register, destroy
90 
91 .seealso: MatRegister(), MatRegisterAll()
92 @*/
93 PetscErrorCode  MatRegisterDestroy(void)
94 {
95   PetscErrorCode ierr;
96 
97   PetscFunctionBegin;
98   ierr = PetscFunctionListDestroy(&MatList);CHKERRQ(ierr);
99 
100   MatRegisterAllCalled = PETSC_FALSE;
101   PetscFunctionReturn(0);
102 }
103 
104 #undef __FUNCT__
105 #define __FUNCT__ "MatGetType"
106 /*@C
107    MatGetType - Gets the matrix type as a string from the matrix object.
108 
109    Not Collective
110 
111    Input Parameter:
112 .  mat - the matrix
113 
114    Output Parameter:
115 .  name - name of matrix type
116 
117    Level: intermediate
118 
119 .keywords: Mat, MatType, get, method, name
120 
121 .seealso: MatSetType()
122 @*/
123 PetscErrorCode  MatGetType(Mat mat,MatType *type)
124 {
125   PetscFunctionBegin;
126   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
127   PetscValidPointer(type,2);
128   *type = ((PetscObject)mat)->type_name;
129   PetscFunctionReturn(0);
130 }
131 
132 
133 #undef __FUNCT__
134 #define __FUNCT__ "MatRegister"
135 /*@C
136   MatRegister -  - Adds a new matrix type
137 
138    Not Collective
139 
140    Input Parameters:
141 +  name - name of a new user-defined matrix type
142 -  routine_create - routine to create method context
143 
144    Notes:
145    MatRegister() may be called multiple times to add several user-defined solvers.
146 
147    Sample usage:
148 .vb
149    MatRegister("my_mat",MyMatCreate);
150 .ve
151 
152    Then, your solver can be chosen with the procedural interface via
153 $     MatSetType(Mat,"my_mat")
154    or at runtime via the option
155 $     -mat_type my_mat
156 
157    Level: advanced
158 
159 .keywords: Mat, register
160 
161 .seealso: MatRegisterAll(), MatRegisterDestroy()
162 
163 
164   Level: advanced
165 @*/
166 PetscErrorCode  MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
167 {
168   PetscErrorCode ierr;
169 
170   PetscFunctionBegin;
171   ierr = PetscFunctionListAdd(&MatList,sname,function);CHKERRQ(ierr);
172   PetscFunctionReturn(0);
173 }
174 
175 MatBaseName MatBaseNameList = 0;
176 
177 #undef __FUNCT__
178 #define __FUNCT__ "MatRegisterBaseName"
179 /*@C
180       MatRegisterBaseName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type.
181 
182   Input Parameters:
183 +     bname - the basename, for example, MATAIJ
184 .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
185 -     mname - the name of the parallel matrix type, for example, MATMPIAIJ
186 
187 
188   Level: advanced
189 @*/
190 PetscErrorCode  MatRegisterBaseName(const char bname[],const char sname[],const char mname[])
191 {
192   PetscErrorCode ierr;
193   MatBaseName    names;
194 
195   PetscFunctionBegin;
196   ierr = PetscNew(struct _p_MatBaseName,&names);CHKERRQ(ierr);
197   ierr = PetscStrallocpy(bname,&names->bname);CHKERRQ(ierr);
198   ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr);
199   ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr);
200   if (!MatBaseNameList) {
201     MatBaseNameList = names;
202   } else {
203     MatBaseName next = MatBaseNameList;
204     while (next->next) next = next->next;
205     next->next = names;
206   }
207   PetscFunctionReturn(0);
208 }
209 
210 
211 
212 
213 
214 
215 
216