Actual source code: matreg.c
petsc-3.14.0 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 = NULL;
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: }
68: if (mat->ops->destroy) {
69: /* free the old data structure if it existed */
70: (*mat->ops->destroy)(mat);
71: mat->ops->destroy = NULL;
73: /* should these null spaces be removed? */
74: MatNullSpaceDestroy(&mat->nullsp);
75: MatNullSpaceDestroy(&mat->nearnullsp);
76: }
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);
89: /* create the new data structure */
90: (*r)(mat);
91: return(0);
92: }
94: /*@C
95: MatGetType - Gets the matrix type as a string from the matrix object.
97: Not Collective
99: Input Parameter:
100: . mat - the matrix
102: Output Parameter:
103: . name - name of matrix type
105: Level: intermediate
107: .seealso: MatSetType()
108: @*/
109: PetscErrorCode MatGetType(Mat mat,MatType *type)
110: {
114: *type = ((PetscObject)mat)->type_name;
115: return(0);
116: }
118: /*@C
119: MatGetVecType - Gets the vector type used by the matrix object.
121: Not Collective
123: Input Parameter:
124: . mat - the matrix
126: Output Parameter:
127: . name - name of vector type
129: Level: intermediate
131: .seealso: MatSetVecType()
132: @*/
133: PetscErrorCode MatGetVecType(Mat mat,VecType *vtype)
134: {
138: *vtype = mat->defaultvectype;
139: return(0);
140: }
142: /*@C
143: MatSetVecType - Set the vector type to be used for a matrix object
145: Collective on Mat
147: Input Parameters:
148: + mat - the matrix object
149: - vtype - vector type
151: Notes:
152: This is rarely needed in practice since each matrix object internally sets the proper vector type.
154: Level: intermediate
156: .seealso: VecSetType(), MatGetVecType()
157: @*/
158: PetscErrorCode MatSetVecType(Mat mat,VecType vtype)
159: {
164: PetscFree(mat->defaultvectype);
165: PetscStrallocpy(vtype,&mat->defaultvectype);
166: return(0);
167: }
169: /*@C
170: MatRegister - - Adds a new matrix type
172: Not Collective
174: Input Parameters:
175: + name - name of a new user-defined matrix type
176: - routine_create - routine to create method context
178: Notes:
179: MatRegister() may be called multiple times to add several user-defined solvers.
181: Sample usage:
182: .vb
183: MatRegister("my_mat",MyMatCreate);
184: .ve
186: Then, your solver can be chosen with the procedural interface via
187: $ MatSetType(Mat,"my_mat")
188: or at runtime via the option
189: $ -mat_type my_mat
191: Level: advanced
193: .seealso: MatRegisterAll()
196: Level: advanced
197: @*/
198: PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat))
199: {
203: MatInitializePackage();
204: PetscFunctionListAdd(&MatList,sname,function);
205: return(0);
206: }
208: MatRootName MatRootNameList = NULL;
210: /*@C
211: MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType()
212: and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the
213: matrix.
215: Input Parameters:
216: + rname - the rootname, for example, MATAIJ
217: . sname - the name of the sequential matrix type, for example, MATSEQAIJ
218: - mname - the name of the parallel matrix type, for example, MATMPIAIJ
220: Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare()
222: Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the
223: size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the
224: appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is
225: confusing.
227: Level: developer
229: .seealso: PetscObjectBaseTypeCompare()
231: @*/
232: PetscErrorCode MatRegisterRootName(const char rname[],const char sname[],const char mname[])
233: {
235: MatRootName names;
238: PetscNew(&names);
239: PetscStrallocpy(rname,&names->rname);
240: PetscStrallocpy(sname,&names->sname);
241: PetscStrallocpy(mname,&names->mname);
242: if (!MatRootNameList) {
243: MatRootNameList = names;
244: } else {
245: MatRootName next = MatRootNameList;
246: while (next->next) next = next->next;
247: next->next = names;
248: }
249: return(0);
250: }