xref: /petsc/src/mat/interface/matreg.c (revision 609bdbee21ea3be08735c64dbe00a9ab27759925)
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;
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   /* free the old data structure if it existed */
64   if (mat->ops->destroy) {
65     ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr);
66     mat->ops->destroy = NULL;
67 
68     /* should these null spaces be removed? */
69     ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
70     ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
71     mat->preallocated = PETSC_FALSE;
72     mat->assembled = PETSC_FALSE;
73     mat->was_assembled = PETSC_FALSE;
74 
75     /*
76      Increment, rather than reset these: the object is logically the same, so its logging and
77      state is inherited.  Furthermore, resetting makes it possible for the same state to be
78      obtained with a different structure, confusing the PC.
79     */
80     ++mat->nonzerostate;
81     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
82   }
83   mat->preallocated  = PETSC_FALSE;
84   mat->assembled     = PETSC_FALSE;
85   mat->was_assembled = PETSC_FALSE;
86 
87   /* increase the state so that any code holding the current state knows the matrix has been changed */
88   mat->nonzerostate++;
89   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
90 
91   /* create the new data structure */
92   ierr = (*r)(mat);CHKERRQ(ierr);
93   PetscFunctionReturn(0);
94 }
95 
96 /*@C
97    MatGetType - Gets the matrix type as a string from the matrix object.
98 
99    Not Collective
100 
101    Input Parameter:
102 .  mat - the matrix
103 
104    Output Parameter:
105 .  name - name of matrix type
106 
107    Level: intermediate
108 
109 .keywords: Mat, MatType, get, method, name
110 
111 .seealso: MatSetType()
112 @*/
113 PetscErrorCode  MatGetType(Mat mat,MatType *type)
114 {
115   PetscFunctionBegin;
116   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
117   PetscValidPointer(type,2);
118   *type = ((PetscObject)mat)->type_name;
119   PetscFunctionReturn(0);
120 }
121 
122 
123 /*@C
124   MatRegister -  - Adds a new matrix type
125 
126    Not Collective
127 
128    Input Parameters:
129 +  name - name of a new user-defined matrix type
130 -  routine_create - routine to create method context
131 
132    Notes:
133    MatRegister() may be called multiple times to add several user-defined solvers.
134 
135    Sample usage:
136 .vb
137    MatRegister("my_mat",MyMatCreate);
138 .ve
139 
140    Then, your solver can be chosen with the procedural interface via
141 $     MatSetType(Mat,"my_mat")
142    or at runtime via the option
143 $     -mat_type my_mat
144 
145    Level: advanced
146 
147 .keywords: Mat, register
148 
149 .seealso: MatRegisterAll()
150 
151 
152   Level: advanced
153 @*/
154 PetscErrorCode  MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
155 {
156   PetscErrorCode ierr;
157 
158   PetscFunctionBegin;
159   ierr = PetscFunctionListAdd(&MatList,sname,function);CHKERRQ(ierr);
160   PetscFunctionReturn(0);
161 }
162 
163 MatBaseName MatBaseNameList = 0;
164 
165 /*@C
166       MatRegisterBaseName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type.
167 
168   Input Parameters:
169 +     bname - the basename, for example, MATAIJ
170 .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
171 -     mname - the name of the parallel matrix type, for example, MATMPIAIJ
172 
173 
174   Level: advanced
175 @*/
176 PetscErrorCode  MatRegisterBaseName(const char bname[],const char sname[],const char mname[])
177 {
178   PetscErrorCode ierr;
179   MatBaseName    names;
180 
181   PetscFunctionBegin;
182   ierr = PetscNew(&names);CHKERRQ(ierr);
183   ierr = PetscStrallocpy(bname,&names->bname);CHKERRQ(ierr);
184   ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr);
185   ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr);
186   if (!MatBaseNameList) {
187     MatBaseNameList = names;
188   } else {
189     MatBaseName next = MatBaseNameList;
190     while (next->next) next = next->next;
191     next->next = names;
192   }
193   PetscFunctionReturn(0);
194 }
195 
196 
197 
198 
199 
200 
201 
202