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 .keywords: Mat, MatType, set, method 33 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 MatBaseName names = MatBaseNameList; 41 42 PetscFunctionBegin; 43 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 44 45 while (names) { 46 ierr = PetscStrcmp(matype,names->bname,&found);CHKERRQ(ierr); 47 if (found) { 48 PetscMPIInt size; 49 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 50 if (size == 1) matype = names->sname; 51 else matype = names->mname; 52 break; 53 } 54 names = names->next; 55 } 56 57 ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 58 if (sametype) PetscFunctionReturn(0); 59 60 ierr = PetscFunctionListFind(MatList,matype,&r);CHKERRQ(ierr); 61 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 62 63 if (((PetscObject)mat)->type_name) { 64 ierr = PetscStrbeginswith(matype,((PetscObject)mat)->type_name,&subclass);CHKERRQ(ierr); 65 } 66 if (subclass) { 67 ierr = MatConvert(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 68 PetscFunctionReturn(0); 69 } if (mat->ops->destroy) { 70 /* free the old data structure if it existed */ 71 ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr); 72 mat->ops->destroy = NULL; 73 74 /* should these null spaces be removed? */ 75 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 76 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 77 mat->preallocated = PETSC_FALSE; 78 mat->assembled = PETSC_FALSE; 79 mat->was_assembled = PETSC_FALSE; 80 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 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 88 } 89 mat->preallocated = PETSC_FALSE; 90 mat->assembled = PETSC_FALSE; 91 mat->was_assembled = PETSC_FALSE; 92 93 /* increase the state so that any code holding the current state knows the matrix has been changed */ 94 mat->nonzerostate++; 95 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 96 97 /* create the new data structure */ 98 ierr = (*r)(mat);CHKERRQ(ierr); 99 PetscFunctionReturn(0); 100 } 101 102 /*@C 103 MatGetType - Gets the matrix type as a string from the matrix object. 104 105 Not Collective 106 107 Input Parameter: 108 . mat - the matrix 109 110 Output Parameter: 111 . name - name of matrix type 112 113 Level: intermediate 114 115 .keywords: Mat, MatType, get, method, name 116 117 .seealso: MatSetType() 118 @*/ 119 PetscErrorCode MatGetType(Mat mat,MatType *type) 120 { 121 PetscFunctionBegin; 122 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 123 PetscValidPointer(type,2); 124 *type = ((PetscObject)mat)->type_name; 125 PetscFunctionReturn(0); 126 } 127 128 129 /*@C 130 MatRegister - - Adds a new matrix type 131 132 Not Collective 133 134 Input Parameters: 135 + name - name of a new user-defined matrix type 136 - routine_create - routine to create method context 137 138 Notes: 139 MatRegister() may be called multiple times to add several user-defined solvers. 140 141 Sample usage: 142 .vb 143 MatRegister("my_mat",MyMatCreate); 144 .ve 145 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 150 151 Level: advanced 152 153 .keywords: Mat, register 154 155 .seealso: MatRegisterAll() 156 157 158 Level: advanced 159 @*/ 160 PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat)) 161 { 162 PetscErrorCode ierr; 163 164 PetscFunctionBegin; 165 ierr = PetscFunctionListAdd(&MatList,sname,function);CHKERRQ(ierr); 166 PetscFunctionReturn(0); 167 } 168 169 MatBaseName MatBaseNameList = 0; 170 171 /*@C 172 MatRegisterBaseName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. 173 174 Input Parameters: 175 + bname - the basename, for example, MATAIJ 176 . sname - the name of the sequential matrix type, for example, MATSEQAIJ 177 - mname - the name of the parallel matrix type, for example, MATMPIAIJ 178 179 180 Level: advanced 181 @*/ 182 PetscErrorCode MatRegisterBaseName(const char bname[],const char sname[],const char mname[]) 183 { 184 PetscErrorCode ierr; 185 MatBaseName names; 186 187 PetscFunctionBegin; 188 ierr = PetscNew(&names);CHKERRQ(ierr); 189 ierr = PetscStrallocpy(bname,&names->bname);CHKERRQ(ierr); 190 ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr); 191 ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr); 192 if (!MatBaseNameList) { 193 MatBaseNameList = names; 194 } else { 195 MatBaseName next = MatBaseNameList; 196 while (next->next) next = next->next; 197 next->next = names; 198 } 199 PetscFunctionReturn(0); 200 } 201 202 203 204 205 206 207 208