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 #undef __FUNCT__ 15 #define __FUNCT__ "MatSetType" 16 /*@C 17 MatSetType - Builds matrix object for a particular matrix type 18 19 Collective on Mat 20 21 Input Parameters: 22 + mat - the matrix object 23 - matype - matrix type 24 25 Options Database Key: 26 . -mat_type <method> - Sets the type; use -help for a list 27 of available methods (for instance, seqaij) 28 29 Notes: 30 See "${PETSC_DIR}/include/petscmat.h" for available methods 31 32 Level: intermediate 33 34 .keywords: Mat, MatType, set, method 35 36 .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 37 @*/ 38 PetscErrorCode MatSetType(Mat mat, MatType matype) 39 { 40 PetscErrorCode ierr,(*r)(Mat); 41 PetscBool sametype,found; 42 MatBaseName names = MatBaseNameList; 43 44 PetscFunctionBegin; 45 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 46 47 while (names) { 48 ierr = PetscStrcmp(matype,names->bname,&found);CHKERRQ(ierr); 49 if (found) { 50 PetscMPIInt size; 51 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 52 if (size == 1) matype = names->sname; 53 else matype = names->mname; 54 break; 55 } 56 names = names->next; 57 } 58 59 ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 60 if (sametype) PetscFunctionReturn(0); 61 62 ierr = PetscFunctionListFind(MatList,matype,&r);CHKERRQ(ierr); 63 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 64 65 /* free the old data structure if it existed */ 66 if (mat->ops->destroy) { 67 ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr); 68 mat->ops->destroy = NULL; 69 70 /* should these null spaces be removed? */ 71 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 72 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 73 mat->preallocated = PETSC_FALSE; 74 mat->assembled = PETSC_FALSE; 75 mat->was_assembled = PETSC_FALSE; 76 77 /* 78 Increment, rather than reset these: the object is logically the same, so its logging and 79 state is inherited. Furthermore, resetting makes it possible for the same state to be 80 obtained with a different structure, confusing the PC. 81 */ 82 ++mat->nonzerostate; 83 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 84 } 85 mat->preallocated = PETSC_FALSE; 86 mat->assembled = PETSC_FALSE; 87 mat->was_assembled = PETSC_FALSE; 88 89 /* increase the state so that any code holding the current state knows the matrix has been changed */ 90 mat->nonzerostate++; 91 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 92 93 /* create the new data structure */ 94 ierr = (*r)(mat);CHKERRQ(ierr); 95 PetscFunctionReturn(0); 96 } 97 98 #undef __FUNCT__ 99 #define __FUNCT__ "MatGetType" 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 .keywords: Mat, MatType, get, method, name 114 115 .seealso: MatSetType() 116 @*/ 117 PetscErrorCode MatGetType(Mat mat,MatType *type) 118 { 119 PetscFunctionBegin; 120 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 121 PetscValidPointer(type,2); 122 *type = ((PetscObject)mat)->type_name; 123 PetscFunctionReturn(0); 124 } 125 126 127 #undef __FUNCT__ 128 #define __FUNCT__ "MatRegister" 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 #undef __FUNCT__ 172 #define __FUNCT__ "MatRegisterBaseName" 173 /*@C 174 MatRegisterBaseName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. 175 176 Input Parameters: 177 + bname - the basename, for example, MATAIJ 178 . sname - the name of the sequential matrix type, for example, MATSEQAIJ 179 - mname - the name of the parallel matrix type, for example, MATMPIAIJ 180 181 182 Level: advanced 183 @*/ 184 PetscErrorCode MatRegisterBaseName(const char bname[],const char sname[],const char mname[]) 185 { 186 PetscErrorCode ierr; 187 MatBaseName names; 188 189 PetscFunctionBegin; 190 ierr = PetscNew(&names);CHKERRQ(ierr); 191 ierr = PetscStrallocpy(bname,&names->bname);CHKERRQ(ierr); 192 ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr); 193 ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr); 194 if (!MatBaseNameList) { 195 MatBaseNameList = names; 196 } else { 197 MatBaseName next = MatBaseNameList; 198 while (next->next) next = next->next; 199 next->next = names; 200 } 201 PetscFunctionReturn(0); 202 } 203 204 205 206 207 208 209 210