Actual source code: matreg.c
petsc-3.11.4 2019-09-28
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 = 0;
14: /*@C
15: MatSetType - Builds matrix object for a particular matrix type
17: Collective on Mat
19: Input Parameters:
20: + mat - the matrix object
21: - matype - matrix type
23: Options Database Key:
24: . -mat_type <method> - Sets the type; use -help for a list
25: of available methods (for instance, seqaij)
27: Notes:
28: See "${PETSC_DIR}/include/petscmat.h" for available methods
30: Level: intermediate
32: .keywords: Mat, MatType, set, method
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: MatRootName names = MatRootNameList;
45: while (names) {
46: PetscStrcmp(matype,names->rname,&found);
47: if (found) {
48: PetscMPIInt size;
49: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
50: if (size == 1) matype = names->sname;
51: else matype = names->mname;
52: break;
53: }
54: names = names->next;
55: }
57: PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);
58: if (sametype) return(0);
60: PetscFunctionListFind(MatList,matype,&r);
61: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype);
63: if (mat->assembled && ((PetscObject)mat)->type_name) {
64: PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass);
65: }
66: if (subclass) {
67: MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat);
68: return(0);
69: } if (mat->ops->destroy) {
70: /* free the old data structure if it existed */
71: (*mat->ops->destroy)(mat);
72: mat->ops->destroy = NULL;
74: /* should these null spaces be removed? */
75: MatNullSpaceDestroy(&mat->nullsp);
76: MatNullSpaceDestroy(&mat->nearnullsp);
77: mat->preallocated = PETSC_FALSE;
78: mat->assembled = PETSC_FALSE;
79: mat->was_assembled = PETSC_FALSE;
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: PetscObjectStateIncrease((PetscObject)mat);
88: }
89: mat->preallocated = PETSC_FALSE;
90: mat->assembled = PETSC_FALSE;
91: mat->was_assembled = PETSC_FALSE;
93: /* increase the state so that any code holding the current state knows the matrix has been changed */
94: mat->nonzerostate++;
95: PetscObjectStateIncrease((PetscObject)mat);
97: /* create the new data structure */
98: (*r)(mat);
99: return(0);
100: }
102: /*@C
103: MatGetType - Gets the matrix type as a string from the matrix object.
105: Not Collective
107: Input Parameter:
108: . mat - the matrix
110: Output Parameter:
111: . name - name of matrix type
113: Level: intermediate
115: .keywords: Mat, MatType, get, method, name
117: .seealso: MatSetType()
118: @*/
119: PetscErrorCode MatGetType(Mat mat,MatType *type)
120: {
124: *type = ((PetscObject)mat)->type_name;
125: return(0);
126: }
129: /*@C
130: MatRegister - - Adds a new matrix type
132: Not Collective
134: Input Parameters:
135: + name - name of a new user-defined matrix type
136: - routine_create - routine to create method context
138: Notes:
139: MatRegister() may be called multiple times to add several user-defined solvers.
141: Sample usage:
142: .vb
143: MatRegister("my_mat",MyMatCreate);
144: .ve
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
151: Level: advanced
153: .keywords: Mat, register
155: .seealso: MatRegisterAll()
158: Level: advanced
159: @*/
160: PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
161: {
165: MatInitializePackage();
166: PetscFunctionListAdd(&MatList,sname,function);
167: return(0);
168: }
170: MatRootName MatRootNameList = 0;
172: /*@C
173: MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType()
174: and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the
175: matrix.
177: Input Parameters:
178: + rname - the rootname, for example, MATAIJ
179: . sname - the name of the sequential matrix type, for example, MATSEQAIJ
180: - mname - the name of the parallel matrix type, for example, MATMPIAIJ
182: Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare()
184: Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the
185: size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the
186: appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is
187: confusing.
189: Level: developer
191: .seealso: PetscObjectBaseTypeCompare()
193: @*/
194: PetscErrorCode MatRegisterRootName(const char rname[],const char sname[],const char mname[])
195: {
197: MatRootName names;
200: PetscNew(&names);
201: PetscStrallocpy(rname,&names->rname);
202: PetscStrallocpy(sname,&names->sname);
203: PetscStrallocpy(mname,&names->mname);
204: if (!MatRootNameList) {
205: MatRootNameList = names;
206: } else {
207: MatRootName next = MatRootNameList;
208: while (next->next) next = next->next;
209: next->next = names;
210: }
211: return(0);
212: }