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 69 mat->ops->destroy = NULL; 70 /* should these null spaces be removed? */ 71 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 72 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 73 } 74 mat->preallocated = PETSC_FALSE; 75 mat->assembled = PETSC_FALSE; 76 mat->was_assembled = PETSC_FALSE; 77 78 /* increase the state so that any code holding the current state knows the matrix has been changed */ 79 mat->nonzerostate++; 80 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 81 82 /* create the new data structure */ 83 ierr = (*r)(mat);CHKERRQ(ierr); 84 PetscFunctionReturn(0); 85 } 86 87 #undef __FUNCT__ 88 #define __FUNCT__ "MatGetType" 89 /*@C 90 MatGetType - Gets the matrix type as a string from the matrix object. 91 92 Not Collective 93 94 Input Parameter: 95 . mat - the matrix 96 97 Output Parameter: 98 . name - name of matrix type 99 100 Level: intermediate 101 102 .keywords: Mat, MatType, get, method, name 103 104 .seealso: MatSetType() 105 @*/ 106 PetscErrorCode MatGetType(Mat mat,MatType *type) 107 { 108 PetscFunctionBegin; 109 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 110 PetscValidPointer(type,2); 111 *type = ((PetscObject)mat)->type_name; 112 PetscFunctionReturn(0); 113 } 114 115 116 #undef __FUNCT__ 117 #define __FUNCT__ "MatRegister" 118 /*@C 119 MatRegister - - Adds a new matrix type 120 121 Not Collective 122 123 Input Parameters: 124 + name - name of a new user-defined matrix type 125 - routine_create - routine to create method context 126 127 Notes: 128 MatRegister() may be called multiple times to add several user-defined solvers. 129 130 Sample usage: 131 .vb 132 MatRegister("my_mat",MyMatCreate); 133 .ve 134 135 Then, your solver can be chosen with the procedural interface via 136 $ MatSetType(Mat,"my_mat") 137 or at runtime via the option 138 $ -mat_type my_mat 139 140 Level: advanced 141 142 .keywords: Mat, register 143 144 .seealso: MatRegisterAll(), MatRegisterDestroy() 145 146 147 Level: advanced 148 @*/ 149 PetscErrorCode MatRegister(const char sname[],PetscErrorCode (*function)(Mat)) 150 { 151 PetscErrorCode ierr; 152 153 PetscFunctionBegin; 154 ierr = PetscFunctionListAdd(&MatList,sname,function);CHKERRQ(ierr); 155 PetscFunctionReturn(0); 156 } 157 158 MatBaseName MatBaseNameList = 0; 159 160 #undef __FUNCT__ 161 #define __FUNCT__ "MatRegisterBaseName" 162 /*@C 163 MatRegisterBaseName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type. 164 165 Input Parameters: 166 + bname - the basename, for example, MATAIJ 167 . sname - the name of the sequential matrix type, for example, MATSEQAIJ 168 - mname - the name of the parallel matrix type, for example, MATMPIAIJ 169 170 171 Level: advanced 172 @*/ 173 PetscErrorCode MatRegisterBaseName(const char bname[],const char sname[],const char mname[]) 174 { 175 PetscErrorCode ierr; 176 MatBaseName names; 177 178 PetscFunctionBegin; 179 ierr = PetscNew(&names);CHKERRQ(ierr); 180 ierr = PetscStrallocpy(bname,&names->bname);CHKERRQ(ierr); 181 ierr = PetscStrallocpy(sname,&names->sname);CHKERRQ(ierr); 182 ierr = PetscStrallocpy(mname,&names->mname);CHKERRQ(ierr); 183 if (!MatBaseNameList) { 184 MatBaseNameList = names; 185 } else { 186 MatBaseName next = MatBaseNameList; 187 while (next->next) next = next->next; 188 next->next = names; 189 } 190 PetscFunctionReturn(0); 191 } 192 193 194 195 196 197 198 199