xref: /petsc/src/mat/interface/matreg.c (revision 607a6623fc3ebf1ec03868e90ff90ff3b0120740)
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(PetscObjectComm((PetscObject)mat),MatList,matype,PETSC_TRUE,(void(**)(void))&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 .  name_create - name of routine to create method context
143 -  routine_create - routine to create method context
144 
145    Notes:
146    MatRegister() may be called multiple times to add several user-defined solvers.
147 
148    Sample usage:
149 .vb
150    MatRegister("my_mat","MyMatCreate",MyMatCreate);
151 .ve
152 
153    Then, your solver can be chosen with the procedural interface via
154 $     MatSetType(Mat,"my_mat")
155    or at runtime via the option
156 $     -mat_type my_mat
157 
158    Level: advanced
159 
160 .keywords: Mat, register
161 
162 .seealso: MatRegisterAll(), MatRegisterDestroy()
163 
164 
165   Level: advanced
166 @*/
167 PetscErrorCode  MatRegister(const char sname[],const char name[],PetscErrorCode (*function)(Mat))
168 {
169   PetscErrorCode ierr;
170 
171   PetscFunctionBegin;
172   ierr = PetscFunctionListAdd(PETSC_COMM_WORLD,&MatList,sname,name,(void (*)(void))function);CHKERRQ(ierr);
173   PetscFunctionReturn(0);
174 }
175 
176 MatBaseName MatBaseNameList = 0;
177 
178 #undef __FUNCT__
179 #define __FUNCT__ "MatRegisterBaseName"
180 /*@C
181       MatRegisterBaseName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type.
182 
183   Input Parameters:
184 +     bname - the basename, for example, MATAIJ
185 .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
186 -     mname - the name of the parallel matrix type, for example, MATMPIAIJ
187 
188 
189   Level: advanced
190 @*/
191 PetscErrorCode  MatRegisterBaseName(const char bname[],const char sname[],const char mname[])
192 {
193   PetscErrorCode ierr;
194   MatBaseName    names;
195 
196   PetscFunctionBegin;
197   ierr = PetscNew(struct _p_MatBaseName,&names);CHKERRQ(ierr);
198   ierr = PetscStrallocpy(bname,&names->bname);CHKERRQ(ierr);
199   ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr);
200   ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr);
201   if (!MatBaseNameList) {
202     MatBaseNameList = names;
203   } else {
204     MatBaseName next = MatBaseNameList;
205     while (next->next) next = next->next;
206     next->next = names;
207   }
208   PetscFunctionReturn(0);
209 }
210 
211 
212 
213 
214 
215 
216 
217