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 = 0; 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);CHKERRQ(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 } if (mat->ops->destroy) { 68 /* free the old data structure if it existed */ 69 ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr); 70 mat->ops->destroy = NULL; 71 72 /* should these null spaces be removed? */ 73 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 74 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 75 mat->preallocated = PETSC_FALSE; 76 mat->assembled = PETSC_FALSE; 77 mat->was_assembled = PETSC_FALSE; 78 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 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 86 } 87 mat->preallocated = PETSC_FALSE; 88 mat->assembled = PETSC_FALSE; 89 mat->was_assembled = PETSC_FALSE; 90 91 /* increase the state so that any code holding the current state knows the matrix has been changed */ 92 mat->nonzerostate++; 93 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 94 95 /* create the new data structure */ 96 ierr = (*r)(mat);CHKERRQ(ierr); 97 PetscFunctionReturn(0); 98 } 99 100 /*@C 101 MatGetType - Gets the matrix type as a string from the matrix object. 102 103 Not Collective 104 105 Input Parameter: 106 . mat - the matrix 107 108 Output Parameter: 109 . name - name of matrix type 110 111 Level: intermediate 112 113 .seealso: MatSetType() 114 @*/ 115 PetscErrorCode MatGetType(Mat mat,MatType *type) 116 { 117 PetscFunctionBegin; 118 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 119 PetscValidPointer(type,2); 120 *type = ((PetscObject)mat)->type_name; 121 PetscFunctionReturn(0); 122 } 123 124 /*@C 125 MatGetVecType - Gets the vector type used by the matrix object. 126 127 Not Collective 128 129 Input Parameter: 130 . mat - the matrix 131 132 Output Parameter: 133 . name - name of vector type 134 135 Level: intermediate 136 137 .seealso: MatSetVecType() 138 @*/ 139 PetscErrorCode MatGetVecType(Mat mat,VecType *vtype) 140 { 141 PetscFunctionBegin; 142 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 143 PetscValidPointer(vtype,2); 144 *vtype = mat->defaultvectype; 145 PetscFunctionReturn(0); 146 } 147 148 /*@C 149 MatSetVecType - Set the vector type to be used for a matrix object 150 151 Collective on Mat 152 153 Input Parameters: 154 + mat - the matrix object 155 - vtype - vector type 156 157 Notes: 158 This is rarely needed in practice since each matrix object internally sets the proper vector type. 159 160 Level: intermediate 161 162 .seealso: VecSetType(), MatGetVecType() 163 @*/ 164 PetscErrorCode MatSetVecType(Mat mat,VecType vtype) 165 { 166 PetscErrorCode ierr; 167 168 PetscFunctionBegin; 169 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 170 ierr = PetscFree(mat->defaultvectype);CHKERRQ(ierr); 171 ierr = PetscStrallocpy(vtype,&mat->defaultvectype);CHKERRQ(ierr); 172 PetscFunctionReturn(0); 173 } 174 175 /*@C 176 MatRegister - - Adds a new matrix type 177 178 Not Collective 179 180 Input Parameters: 181 + name - name of a new user-defined matrix type 182 - routine_create - routine to create method context 183 184 Notes: 185 MatRegister() may be called multiple times to add several user-defined solvers. 186 187 Sample usage: 188 .vb 189 MatRegister("my_mat",MyMatCreate); 190 .ve 191 192 Then, your solver can be chosen with the procedural interface via 193 $ MatSetType(Mat,"my_mat") 194 or at runtime via the option 195 $ -mat_type my_mat 196 197 Level: advanced 198 199 .seealso: MatRegisterAll() 200 201 202 Level: advanced 203 @*/ 204 PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat)) 205 { 206 PetscErrorCode ierr; 207 208 PetscFunctionBegin; 209 ierr = MatInitializePackage();CHKERRQ(ierr); 210 ierr = PetscFunctionListAdd(&MatList,sname,function);CHKERRQ(ierr); 211 PetscFunctionReturn(0); 212 } 213 214 MatRootName MatRootNameList = 0; 215 216 /*@C 217 MatRegisterRootName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. MatSetType() 218 and -mat_type will automatically use the sequential or parallel version based on the size of the MPI communicator associated with the 219 matrix. 220 221 Input Parameters: 222 + rname - the rootname, for example, MATAIJ 223 . sname - the name of the sequential matrix type, for example, MATSEQAIJ 224 - mname - the name of the parallel matrix type, for example, MATMPIAIJ 225 226 Notes: The matrix rootname should not be confused with the base type of the function PetscObjectBaseTypeCompare() 227 228 Developer Notes: PETSc vectors have a similar rootname that indicates PETSc should automatically select the appropriate VecType based on the 229 size of the communicator but it is implemented by simply having additional VecCreate_RootName() registerer routines that dispatch to the 230 appropriate creation routine. Why have two different ways of implementing the same functionality for different types of objects? It is 231 confusing. 232 233 Level: developer 234 235 .seealso: PetscObjectBaseTypeCompare() 236 237 @*/ 238 PetscErrorCode MatRegisterRootName(const char rname[],const char sname[],const char mname[]) 239 { 240 PetscErrorCode ierr; 241 MatRootName names; 242 243 PetscFunctionBegin; 244 ierr = PetscNew(&names);CHKERRQ(ierr); 245 ierr = PetscStrallocpy(rname,&names->rname);CHKERRQ(ierr); 246 ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr); 247 ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr); 248 if (!MatRootNameList) { 249 MatRootNameList = names; 250 } else { 251 MatRootName next = MatRootNameList; 252 while (next->next) next = next->next; 253 next->next = names; 254 } 255 PetscFunctionReturn(0); 256 } 257