1 2 #include <petsc-private/matimpl.h> /*I "petscmat.h" I*/ 3 4 #if 0 5 #undef __FUNCT__ 6 #define __FUNCT__ "MatPublish_Base" 7 static PetscErrorCode MatPublish_Base(PetscObject obj) 8 { 9 PetscFunctionBegin; 10 PetscFunctionReturn(0); 11 } 12 #endif 13 14 #undef __FUNCT__ 15 #define __FUNCT__ "MatCreate" 16 /*@ 17 MatCreate - Creates a matrix where the type is determined 18 from either a call to MatSetType() or from the options database 19 with a call to MatSetFromOptions(). The default matrix type is 20 AIJ, using the routines MatCreateSeqAIJ() or MatCreateAIJ() 21 if you do not set a type in the options database. If you never 22 call MatSetType() or MatSetFromOptions() it will generate an 23 error when you try to use the matrix. 24 25 Collective on MPI_Comm 26 27 Input Parameter: 28 . comm - MPI communicator 29 30 Output Parameter: 31 . A - the matrix 32 33 Options Database Keys: 34 + -mat_type seqaij - AIJ type, uses MatCreateSeqAIJ() 35 . -mat_type mpiaij - AIJ type, uses MatCreateAIJ() 36 . -mat_type seqdense - dense type, uses MatCreateSeqDense() 37 . -mat_type mpidense - dense type, uses MatCreateDense() 38 . -mat_type seqbaij - block AIJ type, uses MatCreateSeqBAIJ() 39 - -mat_type mpibaij - block AIJ type, uses MatCreateBAIJ() 40 41 Even More Options Database Keys: 42 See the manpages for particular formats (e.g., MatCreateSeqAIJ()) 43 for additional format-specific options. 44 45 Notes: 46 47 Level: beginner 48 49 User manual sections: 50 + sec_matcreate 51 - chapter_matrices 52 53 .keywords: matrix, create 54 55 .seealso: MatCreateSeqAIJ(), MatCreateAIJ(), 56 MatCreateSeqDense(), MatCreateDense(), 57 MatCreateSeqBAIJ(), MatCreateBAIJ(), 58 MatCreateSeqSBAIJ(), MatCreateSBAIJ(), 59 MatConvert() 60 @*/ 61 PetscErrorCode MatCreate(MPI_Comm comm,Mat *A) 62 { 63 Mat B; 64 PetscErrorCode ierr; 65 66 PetscFunctionBegin; 67 PetscValidPointer(A,2); 68 69 *A = PETSC_NULL; 70 #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 71 ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr); 72 #endif 73 74 ierr = PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_CLASSID,0,"Mat","Matrix","Mat",comm,MatDestroy,MatView);CHKERRQ(ierr); 75 ierr = PetscLayoutCreate(comm,&B->rmap);CHKERRQ(ierr); 76 ierr = PetscLayoutCreate(comm,&B->cmap);CHKERRQ(ierr); 77 B->preallocated = PETSC_FALSE; 78 *A = B; 79 PetscFunctionReturn(0); 80 } 81 82 #undef __FUNCT__ 83 #define __FUNCT__ "MatSetSizes" 84 /*@ 85 MatSetSizes - Sets the local and global sizes, and checks to determine compatibility 86 87 Collective on Mat 88 89 Input Parameters: 90 + A - the matrix 91 . m - number of local rows (or PETSC_DECIDE) 92 . n - number of local columns (or PETSC_DECIDE) 93 . M - number of global rows (or PETSC_DETERMINE) 94 - N - number of global columns (or PETSC_DETERMINE) 95 96 Notes: 97 m (n) and M (N) cannot be both PETSC_DECIDE 98 If one processor calls this with M (N) of PETSC_DECIDE then all processors must, otherwise the program will hang. 99 100 If PETSC_DECIDE is not used for the arguments 'm' and 'n', then the 101 user must ensure that they are chosen to be compatible with the 102 vectors. To do this, one first considers the matrix-vector product 103 'y = A x'. The 'm' that is used in the above routine must match the 104 local size used in the vector creation routine VecCreateMPI() for 'y'. 105 Likewise, the 'n' used must match that used as the local size in 106 VecCreateMPI() for 'x'. 107 108 You cannot change the sizes once they have been set. 109 110 The sizes must be set before MatSetUp() or MatXXXSetPreallocation() is called. 111 112 Level: beginner 113 114 .seealso: MatGetSize(), PetscSplitOwnership() 115 @*/ 116 PetscErrorCode MatSetSizes(Mat A, PetscInt m, PetscInt n, PetscInt M, PetscInt N) 117 { 118 PetscFunctionBegin; 119 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 120 if (M > 0 && m > M) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local column size %D cannot be larger than global column size %D",m,M); 121 if (N > 0 && n > N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local row size %D cannot be larger than global row size %D",n,N); 122 if ((A->rmap->n >= 0 || A->rmap->N >= 0) && (A->rmap->n != m || A->rmap->N != M)) SETERRQ4(PETSC_COMM_SELF,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); 123 if ((A->cmap->n >= 0 || A->cmap->N >= 0) && (A->cmap->n != n || A->cmap->N != N)) SETERRQ4(PETSC_COMM_SELF,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); 124 A->rmap->n = m; 125 A->cmap->n = n; 126 A->rmap->N = M; 127 A->cmap->N = N; 128 PetscFunctionReturn(0); 129 } 130 131 #undef __FUNCT__ 132 #define __FUNCT__ "MatSetFromOptions" 133 /*@ 134 MatSetFromOptions - Creates a matrix where the type is determined 135 from the options database. Generates a parallel MPI matrix if the 136 communicator has more than one processor. The default matrix type is 137 AIJ, using the routines MatCreateSeqAIJ() and MatCreateAIJ() if 138 you do not select a type in the options database. 139 140 Collective on Mat 141 142 Input Parameter: 143 . A - the matrix 144 145 Options Database Keys: 146 + -mat_type seqaij - AIJ type, uses MatCreateSeqAIJ() 147 . -mat_type mpiaij - AIJ type, uses MatCreateAIJ() 148 . -mat_type seqdense - dense type, uses MatCreateSeqDense() 149 . -mat_type mpidense - dense type, uses MatCreateDense() 150 . -mat_type seqbaij - block AIJ type, uses MatCreateSeqBAIJ() 151 - -mat_type mpibaij - block AIJ type, uses MatCreateBAIJ() 152 153 Even More Options Database Keys: 154 See the manpages for particular formats (e.g., MatCreateSeqAIJ()) 155 for additional format-specific options. 156 157 Level: beginner 158 159 .keywords: matrix, create 160 161 .seealso: MatCreateSeqAIJ((), MatCreateAIJ(), 162 MatCreateSeqDense(), MatCreateDense(), 163 MatCreateSeqBAIJ(), MatCreateBAIJ(), 164 MatCreateSeqSBAIJ(), MatCreateSBAIJ(), 165 MatConvert() 166 @*/ 167 PetscErrorCode MatSetFromOptions(Mat B) 168 { 169 PetscErrorCode ierr; 170 const char *deft = MATAIJ; 171 char type[256]; 172 PetscBool flg,set; 173 174 PetscFunctionBegin; 175 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 176 177 ierr = PetscObjectOptionsBegin((PetscObject)B);CHKERRQ(ierr); 178 179 if (B->rmap->bs < 0) { 180 PetscInt newbs = -1; 181 ierr = PetscOptionsInt("-mat_block_size","Set the blocksize used to store the matrix","MatSetBlockSize",newbs,&newbs,&flg);CHKERRQ(ierr); 182 if (flg) { 183 ierr = PetscLayoutSetBlockSize(B->rmap,newbs);CHKERRQ(ierr); 184 ierr = PetscLayoutSetBlockSize(B->cmap,newbs);CHKERRQ(ierr); 185 } 186 } 187 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 ierr = PetscViewerDestroy(&B->viewonassembly);CHKERRQ(ierr); 196 ierr = PetscOptionsViewer("-mat_view","Display mat with the viewer on MatAssemblyEnd()","MatViewe",&B->viewonassembly,&B->viewformatonassembly,PETSC_NULL);CHKERRQ(ierr); 197 ierr = PetscOptionsName("-mat_is_symmetric","Checks if mat is symmetric on MatAssemblyEnd()","MatIsSymmetric",&B->checksymmetryonassembly);CHKERRQ(ierr); 198 ierr = PetscOptionsReal("-mat_is_symmetric","Checks if mat is symmetric on MatAssemblyEnd()","MatIsSymmetric",0.0,&B->checksymmetrytol,PETSC_NULL);CHKERRQ(ierr); 199 ierr = PetscOptionsBool("-mat_null_space_test","Checks if provided null space is correct in MatAssemblyEnd()","MatSetNullSpaceTest",PETSC_FALSE,&B->checknullspaceonassembly,PETSC_NULL);CHKERRQ(ierr); 200 201 if (B->ops->setfromoptions) { 202 ierr = (*B->ops->setfromoptions)(B);CHKERRQ(ierr); 203 } 204 205 flg = PETSC_FALSE; 206 ierr = PetscOptionsBool("-mat_new_nonzero_location_err","Generate an error if new nonzeros are created in the matrix structure (useful to test preallocation)","MatSetOption",flg,&flg,&set);CHKERRQ(ierr); 207 if (set) {ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,flg);CHKERRQ(ierr);} 208 flg = PETSC_FALSE; 209 ierr = PetscOptionsBool("-mat_new_nonzero_allocation_err","Generate an error if new nonzeros are allocated in the matrix structure (useful to test preallocation)","MatSetOption",flg,&flg,&set);CHKERRQ(ierr); 210 if (set) {ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,flg);CHKERRQ(ierr);} 211 212 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 213 ierr = PetscObjectProcessOptionsHandlers((PetscObject)B);CHKERRQ(ierr); 214 ierr = PetscOptionsEnd();CHKERRQ(ierr); 215 PetscFunctionReturn(0); 216 } 217 218 #undef __FUNCT__ 219 #define __FUNCT__ "MatXAIJSetPreallocation" 220 /*@ 221 MatXAIJSetPreallocation - set preallocation for serial and parallel AIJ, BAIJ, and SBAIJ matrices 222 223 Collective on Mat 224 225 Input Arguments: 226 + A - matrix being preallocated 227 . bs - block size 228 . dnnz - number of nonzero blocks per block row of diagonal part of parallel matrix 229 . onnz - number of nonzero blocks per block row of off-diagonal part of parallel matrix 230 . dnnzu - number of nonzero blocks per block row of upper-triangular part of diagonal part of parallel matrix 231 - onnzu - number of nonzero blocks per block row of upper-triangular part of off-diagonal part of parallel matrix 232 233 Level: beginner 234 235 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatSeqBAIJSetPreallocation(), MatMPIBAIJSetPreallocation(), MatSeqSBAIJSetPreallocation(), MatMPISBAIJSetPreallocation(), 236 PetscSplitOwnership() 237 @*/ 238 PetscErrorCode MatXAIJSetPreallocation(Mat A,PetscInt bs,const PetscInt *dnnz,const PetscInt *onnz,const PetscInt *dnnzu,const PetscInt *onnzu) 239 { 240 PetscErrorCode ierr; 241 void (*aij)(void); 242 243 PetscFunctionBegin; 244 ierr = MatSetBlockSize(A,bs);CHKERRQ(ierr); 245 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 246 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 247 ierr = MatSeqBAIJSetPreallocation(A,bs,0,dnnz);CHKERRQ(ierr); 248 ierr = MatMPIBAIJSetPreallocation(A,bs,0,dnnz,0,onnz);CHKERRQ(ierr); 249 ierr = MatSeqSBAIJSetPreallocation(A,bs,0,dnnzu);CHKERRQ(ierr); 250 ierr = MatMPISBAIJSetPreallocation(A,bs,0,dnnzu,0,onnzu);CHKERRQ(ierr); 251 /* 252 In general, we have to do extra work to preallocate for scalar (AIJ) matrices so we check whether it will do any 253 good before going on with it. 254 */ 255 ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPIAIJSetPreallocation_C",&aij);CHKERRQ(ierr); 256 if (!aij) { 257 ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",&aij);CHKERRQ(ierr); 258 } 259 if (aij) { 260 if (bs == 1) { 261 ierr = MatSeqAIJSetPreallocation(A,0,dnnz);CHKERRQ(ierr); 262 ierr = MatMPIAIJSetPreallocation(A,0,dnnz,0,onnz);CHKERRQ(ierr); 263 } else { /* Convert block-row precallocation to scalar-row */ 264 PetscInt i,m,*sdnnz,*sonnz; 265 ierr = MatGetLocalSize(A,&m,PETSC_NULL);CHKERRQ(ierr); 266 ierr = PetscMalloc2((!!dnnz)*m,PetscInt,&sdnnz,(!!onnz)*m,PetscInt,&sonnz);CHKERRQ(ierr); 267 for (i=0; i<m; i++) { 268 if (dnnz) sdnnz[i] = dnnz[i/bs] * bs; 269 if (onnz) sonnz[i] = onnz[i/bs] * bs; 270 } 271 ierr = MatSeqAIJSetPreallocation(A,0,dnnz?sdnnz:PETSC_NULL);CHKERRQ(ierr); 272 ierr = MatMPIAIJSetPreallocation(A,0,dnnz?sdnnz:PETSC_NULL,0,onnz?sonnz:PETSC_NULL);CHKERRQ(ierr); 273 ierr = PetscFree2(sdnnz,sonnz);CHKERRQ(ierr); 274 } 275 } 276 PetscFunctionReturn(0); 277 } 278 279 /* 280 Merges some information from Cs header to A; the C object is then destroyed 281 282 This is somewhat different from MatHeaderReplace() it would be nice to merge the code 283 */ 284 #undef __FUNCT__ 285 #define __FUNCT__ "MatHeaderMerge" 286 PetscErrorCode MatHeaderMerge(Mat A,Mat C) 287 { 288 PetscErrorCode ierr; 289 PetscInt refct; 290 PetscOps *Abops; 291 MatOps Aops; 292 char *mtype,*mname; 293 void *spptr; 294 295 PetscFunctionBegin; 296 /* save the parts of A we need */ 297 Abops = ((PetscObject)A)->bops; 298 Aops = A->ops; 299 refct = ((PetscObject)A)->refct; 300 mtype = ((PetscObject)A)->type_name; 301 mname = ((PetscObject)A)->name; 302 spptr = A->spptr; 303 304 /* zero these so the destroy below does not free them */ 305 ((PetscObject)A)->type_name = 0; 306 ((PetscObject)A)->name = 0; 307 308 /* free all the interior data structures from mat */ 309 ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 310 311 ierr = PetscFree(C->spptr);CHKERRQ(ierr); 312 313 ierr = PetscLayoutDestroy(&A->rmap);CHKERRQ(ierr); 314 ierr = PetscLayoutDestroy(&A->cmap);CHKERRQ(ierr); 315 ierr = PetscFunctionListDestroy(&((PetscObject)A)->qlist);CHKERRQ(ierr); 316 ierr = PetscObjectListDestroy(&((PetscObject)A)->olist);CHKERRQ(ierr); 317 318 /* copy C over to A */ 319 ierr = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr); 320 321 /* return the parts of A we saved */ 322 ((PetscObject)A)->bops = Abops; 323 A->ops = Aops; 324 ((PetscObject)A)->refct = refct; 325 ((PetscObject)A)->type_name = mtype; 326 ((PetscObject)A)->name = mname; 327 A->spptr = spptr; 328 329 /* since these two are copied into A we do not want them destroyed in C */ 330 ((PetscObject)C)->qlist = 0; 331 ((PetscObject)C)->olist = 0; 332 ierr = PetscHeaderDestroy(&C);CHKERRQ(ierr); 333 PetscFunctionReturn(0); 334 } 335 /* 336 Replace A's header with that of C; the C object is then destroyed 337 338 This is essentially code moved from MatDestroy() 339 340 This is somewhat different from MatHeaderMerge() it would be nice to merge the code 341 */ 342 #undef __FUNCT__ 343 #define __FUNCT__ "MatHeaderReplace" 344 PetscErrorCode MatHeaderReplace(Mat A,Mat C) 345 { 346 PetscErrorCode ierr; 347 PetscInt refct; 348 349 PetscFunctionBegin; 350 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 351 PetscValidHeaderSpecific(C,MAT_CLASSID,2); 352 if (A == C) PetscFunctionReturn(0); 353 PetscCheckSameComm(A,1,C,2); 354 if (((PetscObject)C)->refct != 1) SETERRQ1(((PetscObject)C)->comm,PETSC_ERR_ARG_WRONGSTATE,"Object C has refct %D > 1, would leave hanging reference",((PetscObject)C)->refct); 355 356 /* free all the interior data structures from mat */ 357 ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 358 ierr = PetscHeaderDestroy_Private((PetscObject)A);CHKERRQ(ierr); 359 ierr = PetscFree(A->ops);CHKERRQ(ierr); 360 ierr = PetscLayoutDestroy(&A->rmap);CHKERRQ(ierr); 361 ierr = PetscLayoutDestroy(&A->cmap);CHKERRQ(ierr); 362 ierr = PetscFree(A->spptr);CHKERRQ(ierr); 363 364 /* copy C over to A */ 365 refct = ((PetscObject)A)->refct; 366 ierr = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr); 367 ((PetscObject)A)->refct = refct; 368 ierr = PetscLogObjectDestroy((PetscObject)C);CHKERRQ(ierr); 369 ierr = PetscFree(C);CHKERRQ(ierr); 370 PetscFunctionReturn(0); 371 } 372