Actual source code: matreg.c
petsc-3.13.6 2020-09-29
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: .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat
33: @*/
34: PetscErrorCode MatSetType(Mat mat, MatType matype)
35: {
36: PetscErrorCode ierr,(*r)(Mat);
37: PetscBool sametype,found,subclass = PETSC_FALSE;
38: MatRootName names = MatRootNameList;
43: while (names) {
44: PetscStrcmp(matype,names->rname,&found);
45: if (found) {
46: PetscMPIInt size;
47: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
48: if (size == 1) matype = names->sname;
49: else matype = names->mname;
50: break;
51: }
52: names = names->next;
53: }
55: PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);
56: if (sametype) return(0);
58: PetscFunctionListFind(MatList,matype,&r);
59: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype);
61: if (mat->assembled && ((PetscObject)mat)->type_name) {
62: PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass);
63: }
64: if (subclass) {
65: MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat);
66: return(0);
67: } if (mat->ops->destroy) {
68: /* free the old data structure if it existed */
69: (*mat->ops->destroy)(mat);
70: mat->ops->destroy = NULL;
72: /* should these null spaces be removed? */
73: MatNullSpaceDestroy(&mat->nullsp);
74: MatNullSpaceDestroy(&mat->nearnullsp);
75: mat->preallocated = PETSC_FALSE;
76: mat->assembled = PETSC_FALSE;
77: mat->was_assembled = PETSC_FALSE;
79: /*
80: Increment, rather than reset these: the object is logically the same, so its logging and
81: state is inherited. Furthermore, resetting makes it possible for the same state to be
82: obtained with a different structure, confusing the PC.
83: */
84: ++mat->nonzerostate;
85: PetscObjectStateIncrease((PetscObject)mat);
86: }
87: mat->preallocated = PETSC_FALSE;
88: mat->assembled = PETSC_FALSE;
89: mat->was_assembled = PETSC_FALSE;
91: /* increase the state so that any code holding the current state knows the matrix has been changed */
92: mat->nonzerostate++;
93: PetscObjectStateIncrease((PetscObject)mat);
95: /* create the new data structure */
96: (*r)(mat);
97: return(0);
98: }
100: /*@C
101: MatGetType - Gets the matrix type as a string from the matrix object.
103: Not Collective
105: Input Parameter:
106: . mat - the matrix
108: Output Parameter:
109: . name - name of matrix type
111: Level: intermediate
113: .seealso: MatSetType()
114: @*/
115: PetscErrorCode MatGetType(Mat mat,MatType *type)
116: {
120: *type = ((PetscObject)mat)->type_name;
121: return(0);
122: }
125: /*@C
126: MatRegister - - Adds a new matrix type
128: Not Collective
130: Input Parameters:
131: + name - name of a new user-defined matrix type
132: - routine_create - routine to create method context
134: Notes:
135: MatRegister() may be called multiple times to add several user-defined solvers.
137: Sample usage:
138: .vb
139: MatRegister("my_mat",MyMatCreate);
140: .ve
142: Then, your solver can be chosen with the procedural interface via
143: $ MatSetType(Mat,"my_mat")
144: or at runtime via the option
145: $ -mat_type my_mat
147: Level: advanced
149: .seealso: MatRegisterAll()
152: Level: advanced
153: @*/
154: PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
155: {
159: MatInitializePackage();
160: PetscFunctionListAdd(&MatList,sname,function);
161: return(0);
162: }
164: MatRootName MatRootNameList = 0;
166: /*@C
167: MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType()
168: and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the
169: matrix.
171: Input Parameters:
172: + rname - the rootname, for example, MATAIJ
173: . sname - the name of the sequential matrix type, for example, MATSEQAIJ
174: - mname - the name of the parallel matrix type, for example, MATMPIAIJ
176: Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare()
178: Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the
179: size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the
180: appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is
181: confusing.
183: Level: developer
185: .seealso: PetscObjectBaseTypeCompare()
187: @*/
188: PetscErrorCode MatRegisterRootName(const char rname[],const char sname[],const char mname[])
189: {
191: MatRootName names;
194: PetscNew(&names);
195: PetscStrallocpy(rname,&names->rname);
196: PetscStrallocpy(sname,&names->sname);
197: PetscStrallocpy(mname,&names->mname);
198: if (!MatRootNameList) {
199: MatRootNameList = names;
200: } else {
201: MatRootName next = MatRootNameList;
202: while (next->next) next = next->next;
203: next->next = names;
204: }
205: return(0);
206: }