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