Actual source code: matreg.c
2: /*
3: Mechanism for register PETSc matrix types
4: */
5: #include <petsc/private/matimpl.h>
7: PetscBool MatRegisterAllCalled = PETSC_FALSE;
9: /*
10: Contains the list of registered Mat routines
11: */
12: PetscFunctionList MatList = NULL;
14: /* MatGetRootType_Private - Gets the root type of the input matrix's type (e.g., MATAIJ for MATSEQAIJ)
16: Not Collective
18: Input Parameters:
19: . mat - the input matrix, could be sequential or MPI
21: Output Parameters:
22: . rootType - the root matrix type
24: Level: developer
26: .seealso: MatGetType(), MatSetType(), MatType, Mat
27: */
28: PetscErrorCode MatGetRootType_Private(Mat mat, MatType *rootType)
29: {
30: PetscBool found = PETSC_FALSE;
31: MatRootName names = MatRootNameList;
32: MatType inType;
35: MatGetType(mat,&inType);
36: while (names) {
37: PetscStrcmp(inType,names->mname,&found);
38: if (!found) PetscStrcmp(inType,names->sname,&found);
39: if (found) {
40: found = PETSC_TRUE;
41: *rootType = names->rname;
42: break;
43: }
44: names = names->next;
45: }
46: if (!found) *rootType = inType;
47: return 0;
48: }
50: /* MatGetMPIMatType_Private - Gets the MPI type corresponding to the input matrix's type (e.g., MATMPIAIJ for MATSEQAIJ)
52: Not Collective
54: Input Parameters:
55: . mat - the input matrix, could be sequential or MPI
57: Output Parameters:
58: . MPIType - the parallel (MPI) matrix type
60: Level: developer
62: .seealso: `MatGetType()`, `MatSetType()`, `MatType`, `Mat`
63: */
64: PetscErrorCode MatGetMPIMatType_Private(Mat mat, MatType *MPIType)
65: {
66: PetscBool found = PETSC_FALSE;
67: MatRootName names = MatRootNameList;
68: MatType inType;
71: MatGetType(mat,&inType);
72: while (names) {
73: PetscStrcmp(inType,names->sname,&found);
74: if (!found) PetscStrcmp(inType,names->mname,&found);
75: if (!found) PetscStrcmp(inType,names->rname,&found);
76: if (found) {
77: found = PETSC_TRUE;
78: *MPIType = names->mname;
79: break;
80: }
81: names = names->next;
82: }
84: return 0;
85: }
87: /*@C
88: MatSetType - Builds matrix object for a particular matrix type
90: Collective on Mat
92: Input Parameters:
93: + mat - the matrix object
94: - matype - matrix type
96: Options Database Key:
97: . -mat_type <method> - Sets the type; use -help for a list
98: of available methods (for instance, seqaij)
100: Notes:
101: See "${PETSC_DIR}/include/petscmat.h" for available methods
103: Level: intermediate
105: .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat
106: @*/
107: PetscErrorCode MatSetType(Mat mat, MatType matype)
108: {
109: PetscBool sametype,found,subclass = PETSC_FALSE;
110: MatRootName names = MatRootNameList;
111: PetscErrorCode (*r)(Mat);
115: while (names) {
116: PetscStrcmp(matype,names->rname,&found);
117: if (found) {
118: PetscMPIInt size;
119: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
120: if (size == 1) matype = names->sname;
121: else matype = names->mname;
122: break;
123: }
124: names = names->next;
125: }
127: PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);
128: if (sametype) return 0;
130: PetscFunctionListFind(MatList,matype,&r);
133: if (mat->assembled && ((PetscObject)mat)->type_name) PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass);
134: if (subclass) {
135: MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat);
136: return 0;
137: }
138: if (mat->ops->destroy) {
139: /* free the old data structure if it existed */
140: (*mat->ops->destroy)(mat);
141: mat->ops->destroy = NULL;
143: /* should these null spaces be removed? */
144: MatNullSpaceDestroy(&mat->nullsp);
145: MatNullSpaceDestroy(&mat->nearnullsp);
146: }
147: PetscMemzero(mat->ops,sizeof(struct _MatOps));
148: mat->preallocated = PETSC_FALSE;
149: mat->assembled = PETSC_FALSE;
150: mat->was_assembled = PETSC_FALSE;
152: /*
153: Increment, rather than reset these: the object is logically the same, so its logging and
154: state is inherited. Furthermore, resetting makes it possible for the same state to be
155: obtained with a different structure, confusing the PC.
156: */
157: mat->nonzerostate++;
158: PetscObjectStateIncrease((PetscObject)mat);
160: /* create the new data structure */
161: (*r)(mat);
162: return 0;
163: }
165: /*@C
166: MatGetType - Gets the matrix type as a string from the matrix object.
168: Not Collective
170: Input Parameter:
171: . mat - the matrix
173: Output Parameter:
174: . name - name of matrix type
176: Level: intermediate
178: .seealso: MatSetType()
179: @*/
180: PetscErrorCode MatGetType(Mat mat,MatType *type)
181: {
184: *type = ((PetscObject)mat)->type_name;
185: return 0;
186: }
188: /*@C
189: MatGetVecType - Gets the vector type used by the matrix object.
191: Not Collective
193: Input Parameter:
194: . mat - the matrix
196: Output Parameter:
197: . name - name of vector type
199: Level: intermediate
201: .seealso: MatSetVecType()
202: @*/
203: PetscErrorCode MatGetVecType(Mat mat,VecType *vtype)
204: {
207: *vtype = mat->defaultvectype;
208: return 0;
209: }
211: /*@C
212: MatSetVecType - Set the vector type to be used for a matrix object
214: Collective on Mat
216: Input Parameters:
217: + mat - the matrix object
218: - vtype - vector type
220: Notes:
221: This is rarely needed in practice since each matrix object internally sets the proper vector type.
223: Level: intermediate
225: .seealso: VecSetType(), MatGetVecType()
226: @*/
227: PetscErrorCode MatSetVecType(Mat mat,VecType vtype)
228: {
230: PetscFree(mat->defaultvectype);
231: PetscStrallocpy(vtype,&mat->defaultvectype);
232: return 0;
233: }
235: /*@C
236: MatRegister - - Adds a new matrix type
238: Not Collective
240: Input Parameters:
241: + name - name of a new user-defined matrix type
242: - routine_create - routine to create method context
244: Notes:
245: MatRegister() may be called multiple times to add several user-defined solvers.
247: Sample usage:
248: .vb
249: MatRegister("my_mat",MyMatCreate);
250: .ve
252: Then, your solver can be chosen with the procedural interface via
253: $ MatSetType(Mat,"my_mat")
254: or at runtime via the option
255: $ -mat_type my_mat
257: Level: advanced
259: .seealso: MatRegisterAll()
261: Level: advanced
262: @*/
263: PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
264: {
265: MatInitializePackage();
266: PetscFunctionListAdd(&MatList,sname,function);
267: return 0;
268: }
270: MatRootName MatRootNameList = NULL;
272: /*@C
273: MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType()
274: and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the
275: matrix.
277: Input Parameters:
278: + rname - the rootname, for example, MATAIJ
279: . sname - the name of the sequential matrix type, for example, MATSEQAIJ
280: - mname - the name of the parallel matrix type, for example, MATMPIAIJ
282: Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare()
284: Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the
285: size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the
286: appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is
287: confusing.
289: Level: developer
291: .seealso: PetscObjectBaseTypeCompare()
293: @*/
294: PetscErrorCode MatRegisterRootName(const char rname[],const char sname[],const char mname[])
295: {
296: MatRootName names;
298: PetscNew(&names);
299: PetscStrallocpy(rname,&names->rname);
300: PetscStrallocpy(sname,&names->sname);
301: PetscStrallocpy(mname,&names->mname);
302: if (!MatRootNameList) {
303: MatRootNameList = names;
304: } else {
305: MatRootName next = MatRootNameList;
306: while (next->next) next = next->next;
307: next->next = names;
308: }
309: return 0;
310: }