1 #define PETSCMAT_DLL 2 3 #include "src/mat/matimpl.h" /*I "petscmat.h" I*/ 4 #include "petscsys.h" 5 6 #undef __FUNCT__ 7 #define __FUNCT__ "MatPublish_Base" 8 static PetscErrorCode MatPublish_Base(PetscObject obj) 9 { 10 PetscFunctionBegin; 11 PetscFunctionReturn(0); 12 } 13 14 15 #undef __FUNCT__ 16 #define __FUNCT__ "MatCreate" 17 /*@ 18 MatCreate - Creates a matrix where the type is determined 19 from either a call to MatSetType() or from the options database 20 with a call to MatSetFromOptions(). The default matrix type is 21 AIJ, using the routines MatCreateSeqAIJ() or MatCreateMPIAIJ() 22 if you do not set a type in the options database. If you never 23 call MatSetType() or MatSetFromOptions() it will generate an 24 error when you try to use the matrix. 25 26 Collective on MPI_Comm 27 28 Input Parameter: 29 . comm - MPI communicator 30 31 Output Parameter: 32 . A - the matrix 33 34 Options Database Keys: 35 + -mat_type seqaij - AIJ type, uses MatCreateSeqAIJ() 36 . -mat_type mpiaij - AIJ type, uses MatCreateMPIAIJ() 37 . -mat_type seqbdiag - block diagonal type, uses MatCreateSeqBDiag() 38 . -mat_type mpibdiag - block diagonal type, uses MatCreateMPIBDiag() 39 . -mat_type mpirowbs - rowbs type, uses MatCreateMPIRowbs() 40 . -mat_type seqdense - dense type, uses MatCreateSeqDense() 41 . -mat_type mpidense - dense type, uses MatCreateMPIDense() 42 . -mat_type seqbaij - block AIJ type, uses MatCreateSeqBAIJ() 43 - -mat_type mpibaij - block AIJ type, uses MatCreateMPIBAIJ() 44 45 Even More Options Database Keys: 46 See the manpages for particular formats (e.g., MatCreateSeqAIJ()) 47 for additional format-specific options. 48 49 Notes: 50 51 Level: beginner 52 53 User manual sections: 54 + sec_matcreate 55 - chapter_matrices 56 57 .keywords: matrix, create 58 59 .seealso: MatCreateSeqAIJ((), MatCreateMPIAIJ(), 60 MatCreateSeqBDiag(),MatCreateMPIBDiag(), 61 MatCreateSeqDense(), MatCreateMPIDense(), 62 MatCreateMPIRowbs(), MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), 63 MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(), 64 MatConvert() 65 @*/ 66 PetscErrorCode PETSCMAT_DLLEXPORT MatCreate(MPI_Comm comm,Mat *A) 67 { 68 Mat B; 69 PetscErrorCode ierr; 70 71 PetscFunctionBegin; 72 PetscValidPointer(A,2); 73 74 *A = PETSC_NULL; 75 #ifndef PETSC_USE_DYNAMIC_LIBRARIES 76 ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr); 77 #endif 78 79 ierr = PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,0,"Mat",comm,MatDestroy,MatView);CHKERRQ(ierr); 80 B->rmap.n = -1; 81 B->rmap.N = -1; 82 B->cmap.n = -1; 83 B->cmap.N = -1; 84 B->rmap.bs = 1; 85 B->cmap.bs = 1; 86 B->preallocated = PETSC_FALSE; 87 B->bops->publish = MatPublish_Base; 88 *A = B; 89 PetscFunctionReturn(0); 90 } 91 92 #undef __FUNCT__ 93 #define __FUNCT__ "MatSetSizes" 94 /*@ 95 MatSetSizes - Sets the local and global sizes, and checks to determine compatibility 96 97 Collective on Mat 98 99 Input Parameters: 100 + A - the matrix 101 . m - number of local rows (or PETSC_DECIDE) 102 . n - number of local columns (or PETSC_DECIDE) 103 . M - number of global rows (or PETSC_DETERMINE) 104 - N - number of global columns (or PETSC_DETERMINE) 105 106 Notes: 107 m (n) and M (N) cannot be both PETSC_DECIDE 108 If one processor calls this with M (N) of PETSC_DECIDE then all processors must, otherwise the program will hang. 109 110 If PETSC_DECIDE is not used for the arguments 'm' and 'n', then the 111 user must ensure that they are chosen to be compatible with the 112 vectors. To do this, one first considers the matrix-vector product 113 'y = A x'. The 'm' that is used in the above routine must match the 114 local size used in the vector creation routine VecCreateMPI() for 'y'. 115 Likewise, the 'n' used must match that used as the local size in 116 VecCreateMPI() for 'x'. 117 118 Level: beginner 119 120 .seealso: MatGetSize(), PetscSplitOwnership() 121 @*/ 122 PetscErrorCode PETSCMAT_DLLEXPORT MatSetSizes(Mat A, PetscInt m, PetscInt n, PetscInt M, PetscInt N) 123 { 124 PetscErrorCode ierr; 125 126 PetscFunctionBegin; 127 PetscValidHeaderSpecific(A,MAT_COOKIE,1); 128 if (M > 0 && m > M) SETERRQ2(PETSC_ERR_ARG_INCOMP,"Local column size %D cannot be larger than global column size %D",m,M); 129 if (N > 0 && n > N) SETERRQ2(PETSC_ERR_ARG_INCOMP,"Local row size %D cannot be larger than global row size %D",n,N); 130 if (A->ops->setsizes) { 131 /* Since this will not be set until the type has been set, this will NOT be called on the initial 132 call of MatSetSizes() (which must be called BEFORE MatSetType() */ 133 ierr = (*A->ops->setsizes)(A,m,n,M,N);CHKERRQ(ierr); 134 } else { 135 if ((A->rmap.n >= 0 || A->rmap.N >= 0) && (A->rmap.n != m || A->rmap.N != M)) SETERRQ4(PETSC_ERR_SUP,"Cannot change/reset row sizes to %D local %D global after previously setting them to %D local %D global",m,M,A->rmap.n,A->rmap.N); 136 if ((A->cmap.n >= 0 || A->cmap.N >= 0) && (A->cmap.n != n || A->cmap.N != N)) SETERRQ4(PETSC_ERR_SUP,"Cannot change/reset column sizes to %D local %D global after previously setting them to %D local %D global",n,N,A->cmap.n,A->cmap.N); 137 } 138 A->rmap.n = m; 139 A->cmap.n = n; 140 A->rmap.N = M; 141 A->cmap.N = N; 142 /* also set rmap/cmap.bs here? */ 143 ierr = PetscMapInitialize(A->comm,&A->rmap);CHKERRQ(ierr); 144 ierr = PetscMapInitialize(A->comm,&A->cmap);CHKERRQ(ierr); 145 PetscFunctionReturn(0); 146 } 147 148 #undef __FUNCT__ 149 #define __FUNCT__ "MatSetFromOptions" 150 /*@ 151 MatSetFromOptions - Creates a matrix where the type is determined 152 from the options database. Generates a parallel MPI matrix if the 153 communicator has more than one processor. The default matrix type is 154 AIJ, using the routines MatCreateSeqAIJ() and MatCreateMPIAIJ() if 155 you do not select a type in the options database. 156 157 Collective on Mat 158 159 Input Parameter: 160 . A - the matrix 161 162 Options Database Keys: 163 + -mat_type seqaij - AIJ type, uses MatCreateSeqAIJ() 164 . -mat_type mpiaij - AIJ type, uses MatCreateMPIAIJ() 165 . -mat_type seqbdiag - block diagonal type, uses MatCreateSeqBDiag() 166 . -mat_type mpibdiag - block diagonal type, uses MatCreateMPIBDiag() 167 . -mat_type mpirowbs - rowbs type, uses MatCreateMPIRowbs() 168 . -mat_type seqdense - dense type, uses MatCreateSeqDense() 169 . -mat_type mpidense - dense type, uses MatCreateMPIDense() 170 . -mat_type seqbaij - block AIJ type, uses MatCreateSeqBAIJ() 171 - -mat_type mpibaij - block AIJ type, uses MatCreateMPIBAIJ() 172 173 Even More Options Database Keys: 174 See the manpages for particular formats (e.g., MatCreateSeqAIJ()) 175 for additional format-specific options. 176 177 Level: beginner 178 179 .keywords: matrix, create 180 181 .seealso: MatCreateSeqAIJ((), MatCreateMPIAIJ(), 182 MatCreateSeqBDiag(),MatCreateMPIBDiag(), 183 MatCreateSeqDense(), MatCreateMPIDense(), 184 MatCreateMPIRowbs(), MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), 185 MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(), 186 MatConvert() 187 @*/ 188 PetscErrorCode PETSCMAT_DLLEXPORT MatSetFromOptions(Mat B) 189 { 190 PetscErrorCode ierr; 191 char mtype[256]; 192 PetscTruth flg; 193 194 PetscFunctionBegin; 195 ierr = PetscOptionsGetString(B->prefix,"-mat_type",mtype,256,&flg);CHKERRQ(ierr); 196 if (flg) { 197 ierr = MatSetType(B,mtype);CHKERRQ(ierr); 198 } 199 if (!B->type_name) { 200 ierr = MatSetType(B,MATAIJ);CHKERRQ(ierr); 201 } 202 PetscFunctionReturn(0); 203 } 204 205 #undef __FUNCT__ 206 #define __FUNCT__ "MatSetUpPreallocation" 207 /*@C 208 MatSetUpPreallocation 209 210 Collective on Mat 211 212 Input Parameter: 213 . A - the matrix 214 215 Level: beginner 216 217 .keywords: matrix, create 218 219 .seealso: MatCreateSeqAIJ((), MatCreateMPIAIJ(), 220 MatCreateSeqBDiag(),MatCreateMPIBDiag(), 221 MatCreateSeqDense(), MatCreateMPIDense(), 222 MatCreateMPIRowbs(), MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), 223 MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(), 224 MatConvert() 225 @*/ 226 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUpPreallocation(Mat B) 227 { 228 PetscErrorCode ierr; 229 230 PetscFunctionBegin; 231 if (B->ops->setuppreallocation) { 232 ierr = PetscInfo(B,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 233 ierr = (*B->ops->setuppreallocation)(B);CHKERRQ(ierr); 234 B->ops->setuppreallocation = 0; 235 } 236 B->preallocated = PETSC_TRUE; 237 PetscFunctionReturn(0); 238 } 239 240 /* 241 Copies from Cs header to A 242 */ 243 #undef __FUNCT__ 244 #define __FUNCT__ "MatHeaderCopy" 245 PetscErrorCode MatHeaderCopy(Mat A,Mat C) 246 { 247 PetscErrorCode ierr; 248 PetscInt refct; 249 PetscOps *Abops; 250 MatOps Aops; 251 char *mtype,*mname; 252 void *spptr; 253 254 PetscFunctionBegin; 255 /* free all the interior data structures from mat */ 256 ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 257 258 /* save the parts of A we need */ 259 Abops = A->bops; 260 Aops = A->ops; 261 refct = A->refct; 262 mtype = A->type_name; 263 mname = A->name; 264 spptr = A->spptr; 265 266 ierr = PetscFree(C->spptr);CHKERRQ(ierr); 267 C->spptr = PETSC_NULL; 268 269 ierr = PetscFree(A->rmap.range);CHKERRQ(ierr); 270 ierr = PetscFree(A->cmap.range);CHKERRQ(ierr); 271 272 /* copy C over to A */ 273 ierr = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr); 274 275 /* return the parts of A we saved */ 276 A->bops = Abops; 277 A->ops = Aops; 278 A->qlist = 0; 279 A->refct = refct; 280 A->type_name = mtype; 281 A->name = mname; 282 A->spptr = spptr; 283 284 ierr = PetscHeaderDestroy(C);CHKERRQ(ierr); 285 PetscFunctionReturn(0); 286 } 287 /* 288 Replace A's header with that of C 289 This is essentially code moved from MatDestroy 290 */ 291 #undef __FUNCT__ 292 #define __FUNCT__ "MatHeaderReplace" 293 PetscErrorCode MatHeaderReplace(Mat A,Mat C) 294 { 295 PetscErrorCode ierr; 296 297 PetscFunctionBegin; 298 /* free all the interior data structures from mat */ 299 ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 300 ierr = PetscHeaderDestroy_Private((PetscObject)A);CHKERRQ(ierr); 301 ierr = PetscFree(A->rmap.range);CHKERRQ(ierr); 302 ierr = PetscFree(A->cmap.range);CHKERRQ(ierr); 303 304 /* copy C over to A */ 305 if (C) { 306 ierr = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr); 307 ierr = PetscLogObjectDestroy((PetscObject)C);CHKERRQ(ierr); 308 ierr = PetscFree(C);CHKERRQ(ierr); 309 } 310 PetscFunctionReturn(0); 311 } 312