1 2 /* 3 Mechanism for register PETSc matrix types 4 */ 5 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 6 7 PetscBool MatRegisterAllCalled = PETSC_FALSE; 8 9 /* 10 Contains the list of registered Mat routines 11 */ 12 PetscFunctionList MatList = NULL; 13 14 /*@C 15 MatSetType - Builds matrix object for a particular matrix type 16 17 Collective on Mat 18 19 Input Parameters: 20 + mat - the matrix object 21 - matype - matrix type 22 23 Options Database Key: 24 . -mat_type <method> - Sets the type; use -help for a list 25 of available methods (for instance, seqaij) 26 27 Notes: 28 See "${PETSC_DIR}/include/petscmat.h" for available methods 29 30 Level: intermediate 31 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; 39 40 PetscFunctionBegin; 41 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 42 43 while (names) { 44 ierr = PetscStrcmp(matype,names->rname,&found);CHKERRQ(ierr); 45 if (found) { 46 PetscMPIInt size; 47 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr); 48 if (size == 1) matype = names->sname; 49 else matype = names->mname; 50 break; 51 } 52 names = names->next; 53 } 54 55 ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 56 if (sametype) PetscFunctionReturn(0); 57 58 ierr = PetscFunctionListFind(MatList,matype,&r);CHKERRQ(ierr); 59 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 60 61 if (mat->assembled && ((PetscObject)mat)->type_name) { 62 ierr = PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass);CHKERRQ(ierr); 63 } 64 if (subclass) { 65 ierr = MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 66 PetscFunctionReturn(0); 67 } 68 if (mat->ops->destroy) { 69 /* free the old data structure if it existed */ 70 ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr); 71 mat->ops->destroy = NULL; 72 73 /* should these null spaces be removed? */ 74 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 75 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 76 } 77 ierr = PetscMemzero(mat->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 78 mat->preallocated = PETSC_FALSE; 79 mat->assembled = PETSC_FALSE; 80 mat->was_assembled = PETSC_FALSE; 81 82 /* 83 Increment, rather than reset these: the object is logically the same, so its logging and 84 state is inherited. Furthermore, resetting makes it possible for the same state to be 85 obtained with a different structure, confusing the PC. 86 */ 87 mat->nonzerostate++; 88 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 89 90 /* create the new data structure */ 91 ierr = (*r)(mat);CHKERRQ(ierr); 92 PetscFunctionReturn(0); 93 } 94 95 /*@C 96 MatGetType - Gets the matrix type as a string from the matrix object. 97 98 Not Collective 99 100 Input Parameter: 101 . mat - the matrix 102 103 Output Parameter: 104 . name - name of matrix type 105 106 Level: intermediate 107 108 .seealso: MatSetType() 109 @*/ 110 PetscErrorCode MatGetType(Mat mat,MatType *type) 111 { 112 PetscFunctionBegin; 113 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 114 PetscValidPointer(type,2); 115 *type = ((PetscObject)mat)->type_name; 116 PetscFunctionReturn(0); 117 } 118 119 /*@C 120 MatGetVecType - Gets the vector type used by the matrix object. 121 122 Not Collective 123 124 Input Parameter: 125 . mat - the matrix 126 127 Output Parameter: 128 . name - name of vector type 129 130 Level: intermediate 131 132 .seealso: MatSetVecType() 133 @*/ 134 PetscErrorCode MatGetVecType(Mat mat,VecType *vtype) 135 { 136 PetscFunctionBegin; 137 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 138 PetscValidPointer(vtype,2); 139 *vtype = mat->defaultvectype; 140 PetscFunctionReturn(0); 141 } 142 143 /*@C 144 MatSetVecType - Set the vector type to be used for a matrix object 145 146 Collective on Mat 147 148 Input Parameters: 149 + mat - the matrix object 150 - vtype - vector type 151 152 Notes: 153 This is rarely needed in practice since each matrix object internally sets the proper vector type. 154 155 Level: intermediate 156 157 .seealso: VecSetType(), MatGetVecType() 158 @*/ 159 PetscErrorCode MatSetVecType(Mat mat,VecType vtype) 160 { 161 PetscErrorCode ierr; 162 163 PetscFunctionBegin; 164 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 165 ierr = PetscFree(mat->defaultvectype);CHKERRQ(ierr); 166 ierr = PetscStrallocpy(vtype,&mat->defaultvectype);CHKERRQ(ierr); 167 PetscFunctionReturn(0); 168 } 169 170 /*@C 171 MatRegister - - Adds a new matrix type 172 173 Not Collective 174 175 Input Parameters: 176 + name - name of a new user-defined matrix type 177 - routine_create - routine to create method context 178 179 Notes: 180 MatRegister() may be called multiple times to add several user-defined solvers. 181 182 Sample usage: 183 .vb 184 MatRegister("my_mat",MyMatCreate); 185 .ve 186 187 Then, your solver can be chosen with the procedural interface via 188 $ MatSetType(Mat,"my_mat") 189 or at runtime via the option 190 $ -mat_type my_mat 191 192 Level: advanced 193 194 .seealso: MatRegisterAll() 195 196 Level: advanced 197 @*/ 198 PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat)) 199 { 200 PetscErrorCode ierr; 201 202 PetscFunctionBegin; 203 ierr = MatInitializePackage();CHKERRQ(ierr); 204 ierr = PetscFunctionListAdd(&MatList,sname,function);CHKERRQ(ierr); 205 PetscFunctionReturn(0); 206 } 207 208 MatRootName MatRootNameList = NULL; 209 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. 214 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 219 220 Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare() 221 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. 226 227 Level: developer 228 229 .seealso: PetscObjectBaseTypeCompare() 230 231 @*/ 232 PetscErrorCode MatRegisterRootName(const char rname[],const char sname[],const char mname[]) 233 { 234 PetscErrorCode ierr; 235 MatRootName names; 236 237 PetscFunctionBegin; 238 ierr = PetscNew(&names);CHKERRQ(ierr); 239 ierr = PetscStrallocpy(rname,&names->rname);CHKERRQ(ierr); 240 ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr); 241 ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr); 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 PetscFunctionReturn(0); 250 } 251