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