xref: /petsc/src/mat/interface/matreg.c (revision 5b6bfdb9644f185dbf5e5a09b808ec241507e1e7)
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 /*@C
15    MatSetType - Builds matrix object for a particular matrix type
16 
17    Collective on Mat
18 
19    Input Parameters:
20 +  mat      - the matrix object
21 -  matype   - matrix type
22 
23    Options Database Key:
24 .  -mat_type  <method> - Sets the type; use -help for a list
25     of available methods (for instance, seqaij)
26 
27    Notes:
28    See "${PETSC_DIR}/include/petscmat.h" for available methods
29 
30   Level: intermediate
31 
32 .keywords: Mat, MatType, set, method
33 
34 .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat
35 @*/
36 PetscErrorCode  MatSetType(Mat mat, MatType matype)
37 {
38   PetscErrorCode ierr,(*r)(Mat);
39   PetscBool      sametype,found,subclass = PETSC_FALSE;
40   MatBaseName    names = MatBaseNameList;
41 
42   PetscFunctionBegin;
43   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
44 
45   while (names) {
46     ierr = PetscStrcmp(matype,names->bname,&found);CHKERRQ(ierr);
47     if (found) {
48       PetscMPIInt size;
49       ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
50       if (size == 1) matype = names->sname;
51       else matype = names->mname;
52       break;
53     }
54     names = names->next;
55   }
56 
57   ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr);
58   if (sametype) PetscFunctionReturn(0);
59 
60   ierr =  PetscFunctionListFind(MatList,matype,&r);CHKERRQ(ierr);
61   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype);
62 
63   if (((PetscObject)mat)->type_name) {
64     ierr = PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass);CHKERRQ(ierr);
65   }
66   if (subclass) {
67     ierr = MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr);
68     PetscFunctionReturn(0);
69   } if (mat->ops->destroy) {
70     /* free the old data structure if it existed */
71     ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr);
72     mat->ops->destroy = NULL;
73 
74     /* should these null spaces be removed? */
75     ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
76     ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
77     mat->preallocated = PETSC_FALSE;
78     mat->assembled = PETSC_FALSE;
79     mat->was_assembled = PETSC_FALSE;
80 
81     /*
82      Increment, rather than reset these: the object is logically the same, so its logging and
83      state is inherited.  Furthermore, resetting makes it possible for the same state to be
84      obtained with a different structure, confusing the PC.
85     */
86     ++mat->nonzerostate;
87     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
88   }
89   mat->preallocated  = PETSC_FALSE;
90   mat->assembled     = PETSC_FALSE;
91   mat->was_assembled = PETSC_FALSE;
92 
93   /* increase the state so that any code holding the current state knows the matrix has been changed */
94   mat->nonzerostate++;
95   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
96 
97   /* create the new data structure */
98   ierr = (*r)(mat);CHKERRQ(ierr);
99   PetscFunctionReturn(0);
100 }
101 
102 /*@C
103    MatGetType - Gets the matrix type as a string from the matrix object.
104 
105    Not Collective
106 
107    Input Parameter:
108 .  mat - the matrix
109 
110    Output Parameter:
111 .  name - name of matrix type
112 
113    Level: intermediate
114 
115 .keywords: Mat, MatType, get, method, name
116 
117 .seealso: MatSetType()
118 @*/
119 PetscErrorCode  MatGetType(Mat mat,MatType *type)
120 {
121   PetscFunctionBegin;
122   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
123   PetscValidPointer(type,2);
124   *type = ((PetscObject)mat)->type_name;
125   PetscFunctionReturn(0);
126 }
127 
128 
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 /*@C
172       MatRegisterBaseName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type.
173 
174   Input Parameters:
175 +     bname - the basename, for example, MATAIJ
176 .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
177 -     mname - the name of the parallel matrix type, for example, MATMPIAIJ
178 
179 
180   Level: advanced
181 @*/
182 PetscErrorCode  MatRegisterBaseName(const char bname[],const char sname[],const char mname[])
183 {
184   PetscErrorCode ierr;
185   MatBaseName    names;
186 
187   PetscFunctionBegin;
188   ierr = PetscNew(&names);CHKERRQ(ierr);
189   ierr = PetscStrallocpy(bname,&names->bname);CHKERRQ(ierr);
190   ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr);
191   ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr);
192   if (!MatBaseNameList) {
193     MatBaseNameList = names;
194   } else {
195     MatBaseName next = MatBaseNameList;
196     while (next->next) next = next->next;
197     next->next = names;
198   }
199   PetscFunctionReturn(0);
200 }
201 
202 
203 
204 
205 
206 
207 
208