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: {
31: PetscBool found = PETSC_FALSE;
32: MatRootName names = MatRootNameList;
33: MatType inType;
34: PetscMPIInt size;
38: MatGetType(mat,&inType);
39: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
40: while (names) {
41: if (size > 1) {PetscStrcmp(inType,names->mname,&found);}
42: else {PetscStrcmp(inType,names->sname,&found);}
43: if (found) {
44: found = PETSC_TRUE;
45: *rootType = names->rname;
46: break;
47: }
48: names = names->next;
49: }
50: if (!found) *rootType = inType;
51: return(0);
52: }
54: /*@C
55: MatSetType - Builds matrix object for a particular matrix type
57: Collective on Mat
59: Input Parameters:
60: + mat - the matrix object
61: - matype - matrix type
63: Options Database Key:
64: . -mat_type <method> - Sets the type; use -help for a list
65: of available methods (for instance, seqaij)
67: Notes:
68: See "${PETSC_DIR}/include/petscmat.h" for available methods
70: Level: intermediate
72: .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat
73: @*/
74: PetscErrorCode MatSetType(Mat mat, MatType matype)
75: {
76: PetscErrorCode ierr,(*r)(Mat);
77: PetscBool sametype,found,subclass = PETSC_FALSE;
78: MatRootName names = MatRootNameList;
83: while (names) {
84: PetscStrcmp(matype,names->rname,&found);
85: if (found) {
86: PetscMPIInt size;
87: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
88: if (size == 1) matype = names->sname;
89: else matype = names->mname;
90: break;
91: }
92: names = names->next;
93: }
95: PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);
96: if (sametype) return(0);
98: PetscFunctionListFind(MatList,matype,&r);
99: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype);
101: if (mat->assembled && ((PetscObject)mat)->type_name) {
102: PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass);
103: }
104: if (subclass) {
105: MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat);
106: return(0);
107: }
108: if (mat->ops->destroy) {
109: /* free the old data structure if it existed */
110: (*mat->ops->destroy)(mat);
111: mat->ops->destroy = NULL;
113: /* should these null spaces be removed? */
114: MatNullSpaceDestroy(&mat->nullsp);
115: MatNullSpaceDestroy(&mat->nearnullsp);
116: }
117: PetscMemzero(mat->ops,sizeof(struct _MatOps));
118: mat->preallocated = PETSC_FALSE;
119: mat->assembled = PETSC_FALSE;
120: mat->was_assembled = PETSC_FALSE;
122: /*
123: Increment, rather than reset these: the object is logically the same, so its logging and
124: state is inherited. Furthermore, resetting makes it possible for the same state to be
125: obtained with a different structure, confusing the PC.
126: */
127: mat->nonzerostate++;
128: PetscObjectStateIncrease((PetscObject)mat);
130: /* create the new data structure */
131: (*r)(mat);
132: return(0);
133: }
135: /*@C
136: MatGetType - Gets the matrix type as a string from the matrix object.
138: Not Collective
140: Input Parameter:
141: . mat - the matrix
143: Output Parameter:
144: . name - name of matrix type
146: Level: intermediate
148: .seealso: MatSetType()
149: @*/
150: PetscErrorCode MatGetType(Mat mat,MatType *type)
151: {
155: *type = ((PetscObject)mat)->type_name;
156: return(0);
157: }
159: /*@C
160: MatGetVecType - Gets the vector type used by the matrix object.
162: Not Collective
164: Input Parameter:
165: . mat - the matrix
167: Output Parameter:
168: . name - name of vector type
170: Level: intermediate
172: .seealso: MatSetVecType()
173: @*/
174: PetscErrorCode MatGetVecType(Mat mat,VecType *vtype)
175: {
179: *vtype = mat->defaultvectype;
180: return(0);
181: }
183: /*@C
184: MatSetVecType - Set the vector type to be used for a matrix object
186: Collective on Mat
188: Input Parameters:
189: + mat - the matrix object
190: - vtype - vector type
192: Notes:
193: This is rarely needed in practice since each matrix object internally sets the proper vector type.
195: Level: intermediate
197: .seealso: VecSetType(), MatGetVecType()
198: @*/
199: PetscErrorCode MatSetVecType(Mat mat,VecType vtype)
200: {
205: PetscFree(mat->defaultvectype);
206: PetscStrallocpy(vtype,&mat->defaultvectype);
207: return(0);
208: }
210: /*@C
211: MatRegister - - Adds a new matrix type
213: Not Collective
215: Input Parameters:
216: + name - name of a new user-defined matrix type
217: - routine_create - routine to create method context
219: Notes:
220: MatRegister() may be called multiple times to add several user-defined solvers.
222: Sample usage:
223: .vb
224: MatRegister("my_mat",MyMatCreate);
225: .ve
227: Then, your solver can be chosen with the procedural interface via
228: $ MatSetType(Mat,"my_mat")
229: or at runtime via the option
230: $ -mat_type my_mat
232: Level: advanced
234: .seealso: MatRegisterAll()
236: Level: advanced
237: @*/
238: PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
239: {
243: MatInitializePackage();
244: PetscFunctionListAdd(&MatList,sname,function);
245: return(0);
246: }
248: MatRootName MatRootNameList = NULL;
250: /*@C
251: MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType()
252: and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the
253: matrix.
255: Input Parameters:
256: + rname - the rootname, for example, MATAIJ
257: . sname - the name of the sequential matrix type, for example, MATSEQAIJ
258: - mname - the name of the parallel matrix type, for example, MATMPIAIJ
260: Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare()
262: Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the
263: size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the
264: appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is
265: confusing.
267: Level: developer
269: .seealso: PetscObjectBaseTypeCompare()
271: @*/
272: PetscErrorCode MatRegisterRootName(const char rname[],const char sname[],const char mname[])
273: {
275: MatRootName names;
278: PetscNew(&names);
279: PetscStrallocpy(rname,&names->rname);
280: PetscStrallocpy(sname,&names->sname);
281: PetscStrallocpy(mname,&names->mname);
282: if (!MatRootNameList) {
283: MatRootNameList = names;
284: } else {
285: MatRootName next = MatRootNameList;
286: while (next->next) next = next->next;
287: next->next = names;
288: }
289: return(0);
290: }