void PetscMatTools::SetOption(Mat matrix, MatOption option) { #if (PETSC_VERSION_MAJOR == 3) //PETSc 3.x.x MatSetOption(matrix, option, PETSC_TRUE); #else MatSetOption(matrix, option); #endif }
EXTERN_C_END EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "MatConvert_SeqAIJ_SeqSBAIJ" PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_SeqSBAIJ(Mat A,const MatType newtype,MatReuse reuse,Mat *newmat) { Mat B; Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; Mat_SeqSBAIJ *b; PetscErrorCode ierr; PetscInt *ai=a->i,*aj,m=A->rmap->N,n=A->cmap->N,i,j,*bi,*bj,*rowlengths; MatScalar *av,*bv; PetscFunctionBegin; if (n != m) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square"); ierr = PetscMalloc(m*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); for (i=0; i<m; i++) { rowlengths[i] = ai[i+1] - a->diag[i]; } ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr); ierr = MatSetType(B,newtype);CHKERRQ(ierr); ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(B,1,0,rowlengths);CHKERRQ(ierr); ierr = MatSetOption(B,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); b = (Mat_SeqSBAIJ*)(B->data); bi = b->i; bj = b->j; bv = b->a; bi[0] = 0; for (i=0; i<m; i++) { aj = a->j + a->diag[i]; av = a->a + a->diag[i]; for (j=0; j<rowlengths[i]; j++){ *bj = *aj; bj++; aj++; *bv = *av; bv++; av++; } bi[i+1] = bi[i] + rowlengths[i]; b->ilen[i] = rowlengths[i]; } ierr = PetscFree(rowlengths);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (A->hermitian){ ierr = MatSetOption(B,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); } if (reuse == MAT_REUSE_MATRIX) { ierr = MatHeaderReplace(A,B);CHKERRQ(ierr); } else { *newmat = B; } PetscFunctionReturn(0); }
/* MatConvert_Basic - Converts from any input format to another format. For parallel formats, the new matrix distribution is determined by PETSc. Does not do preallocation so in general will be slow */ PETSC_INTERN PetscErrorCode MatConvert_Basic(Mat mat, MatType newtype,MatReuse reuse,Mat *newmat) { Mat M; const PetscScalar *vwork; PetscErrorCode ierr; PetscInt nz,i,m,n,rstart,rend,lm,ln; const PetscInt *cwork; PetscBool isSBAIJ; PetscFunctionBegin; ierr = PetscObjectTypeCompare((PetscObject)mat,MATSEQSBAIJ,&isSBAIJ);CHKERRQ(ierr); if (!isSBAIJ) { ierr = PetscObjectTypeCompare((PetscObject)mat,MATMPISBAIJ,&isSBAIJ);CHKERRQ(ierr); } if (isSBAIJ) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot convert from SBAIJ matrix since cannot obtain entire rows of matrix"); ierr = MatGetSize(mat,&m,&n);CHKERRQ(ierr); ierr = MatGetLocalSize(mat,&lm,&ln);CHKERRQ(ierr); if (ln == n) ln = PETSC_DECIDE; /* try to preserve column ownership */ ierr = MatCreate(PetscObjectComm((PetscObject)mat),&M);CHKERRQ(ierr); ierr = MatSetSizes(M,lm,ln,m,n);CHKERRQ(ierr); ierr = MatSetBlockSizesFromMats(M,mat,mat);CHKERRQ(ierr); ierr = MatSetType(M,newtype);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(M,NULL);CHKERRQ(ierr); ierr = MatMPIDenseSetPreallocation(M,NULL);CHKERRQ(ierr); ierr = MatSetUp(M);CHKERRQ(ierr); ierr = MatSetOption(M,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = MatSetOption(M,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)M,MATSEQSBAIJ,&isSBAIJ);CHKERRQ(ierr); if (!isSBAIJ) { ierr = PetscObjectTypeCompare((PetscObject)M,MATMPISBAIJ,&isSBAIJ);CHKERRQ(ierr); } if (isSBAIJ) { ierr = MatSetOption(M,MAT_IGNORE_LOWER_TRIANGULAR,PETSC_TRUE);CHKERRQ(ierr); } ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); for (i=rstart; i<rend; i++) { ierr = MatGetRow(mat,i,&nz,&cwork,&vwork);CHKERRQ(ierr); ierr = MatSetValues(M,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); ierr = MatRestoreRow(mat,i,&nz,&cwork,&vwork);CHKERRQ(ierr); } ierr = MatAssemblyBegin(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (reuse == MAT_INPLACE_MATRIX) { ierr = MatHeaderReplace(mat,&M);CHKERRQ(ierr); } else { *newmat = M; } PetscFunctionReturn(0); }
PetscErrorCode AssemblePressureMatrx( UserContext* uc ) { PetscErrorCode ierr; PetscScalar val[5]; PetscInt i, j; BCNode *bcn; Node *n; PetscFunctionBegin; ierr = MatCreate(PETSC_COMM_WORLD, &uc->A); CHKERRQ(ierr); ierr = MatSetSizes(uc->A, PETSC_DECIDE, PETSC_DECIDE, uc->numNodes, uc->numNodes); CHKERRQ(ierr); ierr = MatSetType(uc->A, MATUMFPACK); CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(uc->A, 5, PETSC_NULL); CHKERRQ(ierr); // ierr = MatCreateSeqSBAIJ(PETSC_COMM_WORLD,1,uc->numNodes, uc->numNodes,3, PETSC_NULL, &uc->A); CHKERRQ(ierr); // ierr = MatSetOption(uc->A, MAT_SYMMETRIC); CHKERRQ(ierr); // ierr = MatSetOption(uc->A, MAT_USE_INODES); CHKERRQ(ierr); // ierr = MatSetOption(uc->A, MAT_IGNORE_LOWER_TRIANGULAR); CHKERRQ(ierr); for (i = 0; i < uc->numNodes; ++i) { n = &uc->nodes[i]; for (j = 0; j < n->numNei; ++j) { val[j] = negone; } val[n->numNei] = n->numNei; ierr = MatSetValues(uc->A, 1, &i, n->numNei+1, n->nei, val, INSERT_VALUES); CHKERRQ(ierr); } PetscInt idx; for( i = 0; i < uc->numBC; ++i) { idx = uc->imageToNode[uc->bcToImage[i]]; n = &uc->nodes[idx]; for( j = 0; j < n->numNei; ++j) { ierr = MatSetValue(uc->A, idx, n->nei[j], zero, INSERT_VALUES); CHKERRQ(ierr); ierr = MatSetValue(uc->A, n->nei[j], idx, zero, INSERT_VALUES); CHKERRQ(ierr); } ierr = MatSetValue(uc->A, idx, idx, one, INSERT_VALUES); CHKERRQ(ierr); } ierr = MatSetOption(uc->A, MAT_NEW_NONZERO_LOCATION_ERR); CHKERRQ(ierr); ierr = MatSetOption(uc->A, MAT_NO_NEW_NONZERO_LOCATIONS); CHKERRQ(ierr); ierr = MatAssemblyBegin(uc->A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(uc->A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatStoreValues(uc->A); CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ MatSetFromOptions - Creates a matrix where the type is determined from the options database. Generates a parallel MPI matrix if the communicator has more than one processor. The default matrix type is AIJ, using the routines MatCreateSeqAIJ() and MatCreateAIJ() if you do not select a type in the options database. Collective on Mat Input Parameter: . A - the matrix Options Database Keys: + -mat_type seqaij - AIJ type, uses MatCreateSeqAIJ() . -mat_type mpiaij - AIJ type, uses MatCreateAIJ() . -mat_type seqdense - dense type, uses MatCreateSeqDense() . -mat_type mpidense - dense type, uses MatCreateDense() . -mat_type seqbaij - block AIJ type, uses MatCreateSeqBAIJ() - -mat_type mpibaij - block AIJ type, uses MatCreateBAIJ() Even More Options Database Keys: See the manpages for particular formats (e.g., MatCreateSeqAIJ()) for additional format-specific options. Level: beginner .keywords: matrix, create .seealso: MatCreateSeqAIJ((), MatCreateAIJ(), MatCreateSeqDense(), MatCreateDense(), MatCreateSeqBAIJ(), MatCreateBAIJ(), MatCreateSeqSBAIJ(), MatCreateSBAIJ(), MatConvert() @*/ PetscErrorCode MatSetFromOptions(Mat B) { PetscErrorCode ierr; const char *deft = MATAIJ; char type[256]; PetscBool flg,set; PetscFunctionBegin; PetscValidHeaderSpecific(B,MAT_CLASSID,1); ierr = PetscObjectOptionsBegin((PetscObject)B);CHKERRQ(ierr); if (B->rmap->bs < 0) { PetscInt newbs = -1; ierr = PetscOptionsInt("-mat_block_size","Set the blocksize used to store the matrix","MatSetBlockSize",newbs,&newbs,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscLayoutSetBlockSize(B->rmap,newbs);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(B->cmap,newbs);CHKERRQ(ierr); } } ierr = PetscOptionsFList("-mat_type","Matrix type","MatSetType",MatList,deft,type,256,&flg);CHKERRQ(ierr); if (flg) { ierr = MatSetType(B,type);CHKERRQ(ierr); } else if (!((PetscObject)B)->type_name) { ierr = MatSetType(B,deft);CHKERRQ(ierr); } ierr = PetscOptionsName("-mat_is_symmetric","Checks if mat is symmetric on MatAssemblyEnd()","MatIsSymmetric",&B->checksymmetryonassembly);CHKERRQ(ierr); ierr = PetscOptionsReal("-mat_is_symmetric","Checks if mat is symmetric on MatAssemblyEnd()","MatIsSymmetric",0.0,&B->checksymmetrytol,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-mat_null_space_test","Checks if provided null space is correct in MatAssemblyEnd()","MatSetNullSpaceTest",PETSC_FALSE,&B->checknullspaceonassembly,NULL);CHKERRQ(ierr); if (B->ops->setfromoptions) { ierr = (*B->ops->setfromoptions)(B);CHKERRQ(ierr); } flg = PETSC_FALSE; 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); if (set) {ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,flg);CHKERRQ(ierr);} flg = PETSC_FALSE; 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); if (set) {ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,flg);CHKERRQ(ierr);} /* process any options handlers added with PetscObjectAddOptionsHandler() */ ierr = PetscObjectProcessOptionsHandlers((PetscObject)B);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode Assemble(MPI_Comm comm,PetscInt n,MatType mtype) { Mat A; PetscInt first,last,i; PetscErrorCode ierr; PetscMPIInt rank,size; PetscFunctionBegin; ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A, PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetType(A,MATMPISBAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); if (rank < size-1) { ierr = MatMPISBAIJSetPreallocation(A,1,1,PETSC_NULL,1,PETSC_NULL);CHKERRQ(ierr); } else { ierr = MatMPISBAIJSetPreallocation(A,1,2,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); } ierr = MatGetOwnershipRange(A,&first,&last);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); last--; for (i=first; i<=last; i++){ ierr = MatSetValue(A,i,i,2.,INSERT_VALUES);CHKERRQ(ierr); if (i != n-1) {ierr = MatSetValue(A,i,n-1,-1.,INSERT_VALUES);CHKERRQ(ierr);} } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ KSPComputeExplicitOperator - Computes the explicit preconditioned operator. Collective on KSP Input Parameter: . ksp - the Krylov subspace context Output Parameter: . mat - the explict preconditioned operator Notes: This computation is done by applying the operators to columns of the identity matrix. Currently, this routine uses a dense matrix format when 1 processor is used and a sparse format otherwise. This routine is costly in general, and is recommended for use only with relatively small systems. Level: advanced .keywords: KSP, compute, explicit, operator .seealso: KSPComputeEigenvaluesExplicitly(), PCComputeExplicitOperator() @*/ PetscErrorCode KSPComputeExplicitOperator(KSP ksp,Mat *mat) { Vec in,out; PetscErrorCode ierr; PetscMPIInt size; PetscInt i,M,m,*rows,start,end; Mat A; MPI_Comm comm; PetscScalar *array,one = 1.0; PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); PetscValidPointer(mat,2); comm = ((PetscObject)ksp)->comm; ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = VecDuplicate(ksp->vec_sol,&in);CHKERRQ(ierr); ierr = VecDuplicate(ksp->vec_sol,&out);CHKERRQ(ierr); ierr = VecGetSize(in,&M);CHKERRQ(ierr); ierr = VecGetLocalSize(in,&m);CHKERRQ(ierr); ierr = VecGetOwnershipRange(in,&start,&end);CHKERRQ(ierr); ierr = PetscMalloc(m*sizeof(PetscInt),&rows);CHKERRQ(ierr); for (i=0; i<m; i++) {rows[i] = start + i;} ierr = MatCreate(comm,mat);CHKERRQ(ierr); ierr = MatSetSizes(*mat,m,m,M,M);CHKERRQ(ierr); if (size == 1) { ierr = MatSetType(*mat,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(*mat,PETSC_NULL);CHKERRQ(ierr); } else { ierr = MatSetType(*mat,MATMPIAIJ);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(*mat,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); } ierr = MatSetOption(*mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);} ierr = PCGetOperators(ksp->pc,&A,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); for (i=0; i<M; i++) { ierr = VecSet(in,0.0);CHKERRQ(ierr); ierr = VecSetValues(in,1,&i,&one,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(in);CHKERRQ(ierr); ierr = VecAssemblyEnd(in);CHKERRQ(ierr); ierr = KSP_MatMult(ksp,A,in,out);CHKERRQ(ierr); ierr = KSP_PCApply(ksp,out,in);CHKERRQ(ierr); ierr = VecGetArray(in,&array);CHKERRQ(ierr); ierr = MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); ierr = VecRestoreArray(in,&array);CHKERRQ(ierr); } ierr = PetscFree(rows);CHKERRQ(ierr); ierr = VecDestroy(&in);CHKERRQ(ierr); ierr = VecDestroy(&out);CHKERRQ(ierr); ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatBlockMatSetPreallocation_BlockMat(Mat A,PetscInt bs,PetscInt nz,PetscInt *nnz) { Mat_BlockMat *bmat = (Mat_BlockMat*)A->data; PetscErrorCode ierr; PetscInt i; PetscFunctionBegin; ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); ierr = PetscLayoutGetBlockSize(A->rmap,&bs);CHKERRQ(ierr); if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); if (nnz) { for (i=0; i<A->rmap->n/bs; i++) { if (nnz[i] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); if (nnz[i] > A->cmap->n/bs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],A->cmap->n/bs); } } bmat->mbs = A->rmap->n/bs; ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,bs,NULL,&bmat->right);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,bs,NULL,&bmat->middle);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,bs,&bmat->left);CHKERRQ(ierr); if (!bmat->imax) { ierr = PetscMalloc2(A->rmap->n,&bmat->imax,A->rmap->n,&bmat->ilen);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)A,2*A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); } if (nnz) { nz = 0; for (i=0; i<A->rmap->n/A->rmap->bs; i++) { bmat->imax[i] = nnz[i]; nz += nnz[i]; } } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Currently requires block row by row preallocation"); /* bmat->ilen will count nonzeros in each row so far. */ for (i=0; i<bmat->mbs; i++) bmat->ilen[i] = 0; /* allocate the matrix space */ ierr = MatSeqXAIJFreeAIJ(A,(PetscScalar**)&bmat->a,&bmat->j,&bmat->i);CHKERRQ(ierr); ierr = PetscMalloc3(nz,&bmat->a,nz,&bmat->j,A->rmap->n+1,&bmat->i);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); bmat->i[0] = 0; for (i=1; i<bmat->mbs+1; i++) { bmat->i[i] = bmat->i[i-1] + bmat->imax[i-1]; } bmat->singlemalloc = PETSC_TRUE; bmat->free_a = PETSC_TRUE; bmat->free_ij = PETSC_TRUE; bmat->nz = 0; bmat->maxnz = nz; A->info.nz_unneeded = (double)bmat->maxnz; ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode Assemble(MPI_Comm comm,PetscInt bs,const MatType mtype) { const PetscInt rc[] = {0,1,2,3}; const PetscScalar vals[] = {1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16, 17,18,19,20,21,22,23,24, 25,26,27,28,29,30,31,32, 33,34,35,36,37,38,39,40, 41,42,43,44,45,46,47,48, 49,50,51,52,53,54,55,56, 57,58,49,60,61,62,63,64}; Mat A; PetscViewer viewer; PetscErrorCode ierr; PetscFunctionBegin; ierr = MatCreate(comm,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,4*bs,4*bs);CHKERRQ(ierr); ierr = MatSetType(A,mtype);CHKERRQ(ierr); ierr = MatMPIBAIJSetPreallocation(A,bs,2,NULL,2,NULL);CHKERRQ(ierr); ierr = MatMPISBAIJSetPreallocation(A,bs,2,NULL,2,NULL);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); /* All processes contribute a global matrix */ ierr = MatSetValuesBlocked(A,4,rc,4,rc,vals,ADD_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = PetscPrintf(comm,"Matrix %s(%D)\n",mtype,bs);CHKERRQ(ierr); ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr); ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr); ierr = MatView(A,viewer);CHKERRQ(ierr); ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); ierr = MatView(A,viewer);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* RHSMatrixHeat - User-provided routine to compute the right-hand-side matrix for the heat equation. Input Parameters: ts - the TS context t - current time global_in - global input vector dummy - optional user-defined context, as set by TSetRHSJacobian() Output Parameters: AA - Jacobian matrix BB - optionally different preconditioning matrix str - flag indicating matrix structure Notes: RHSMatrixHeat computes entries for the locally owned part of the system. - Currently, all PETSc parallel matrix formats are partitioned by contiguous chunks of rows across the processors. - Each processor needs to insert only elements that it owns locally (but any non-local elements will be sent to the appropriate processor during matrix assembly). - Always specify global row and columns of matrix entries when using MatSetValues(); we could alternatively use MatSetValuesLocal(). - Here, we set all entries for a particular row at once. - Note that MatSetValues() uses 0-based row and column numbers in Fortran as well as in C. */ PetscErrorCode RHSMatrixHeat(TS ts,PetscReal t,Vec X,Mat AA,Mat BB,void *ctx) { Mat A = AA; /* Jacobian matrix */ AppCtx *appctx = (AppCtx*)ctx; /* user-defined application context */ PetscErrorCode ierr; PetscInt i,mstart,mend,idx[3]; PetscScalar v[3],stwo = -2./(appctx->h*appctx->h),sone = -.5*stwo; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute entries for the locally owned part of the matrix - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatGetOwnershipRange(A,&mstart,&mend);CHKERRQ(ierr); /* Set matrix rows corresponding to boundary data */ if (mstart == 0) { /* first processor only */ v[0] = 1.0; ierr = MatSetValues(A,1,&mstart,1,&mstart,v,INSERT_VALUES);CHKERRQ(ierr); mstart++; } if (mend == appctx->m) { /* last processor only */ mend--; v[0] = 1.0; ierr = MatSetValues(A,1,&mend,1,&mend,v,INSERT_VALUES);CHKERRQ(ierr); } /* Set matrix rows corresponding to interior data. We construct the matrix one row at a time. */ v[0] = sone; v[1] = stwo; v[2] = sone; for (i=mstart; i<mend; i++) { idx[0] = i-1; idx[1] = i; idx[2] = i+1; ierr = MatSetValues(A,1,&i,3,idx,v,INSERT_VALUES);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Complete the matrix assembly process and set some options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Assemble matrix, using the 2-step process: MatAssemblyBegin(), MatAssemblyEnd() Computations can be done while messages are in transition by placing code between these two statements. */ ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Set and option to indicate that we will never add a new nonzero location to the matrix. If we do, it will generate an error. */ ierr = MatSetOption(A,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); return 0; }
PetscErrorCode StokesSetupMatBlock01(Stokes *s) { PetscInt row, start, end, size, i, j; PetscInt cols[5]; PetscScalar vals[5]; PetscErrorCode ierr; PetscFunctionBeginUser; /* A[1] is 2N-by-N */ ierr = MatCreate(PETSC_COMM_WORLD, &s->subA[1]);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(s->subA[1],"a01_"); ierr = MatSetSizes(s->subA[1],PETSC_DECIDE,PETSC_DECIDE,2*s->nx*s->ny,s->nx*s->ny);CHKERRQ(ierr); ierr = MatSetType(s->subA[1],MATMPIAIJ);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(s->subA[1],5,NULL,5,NULL);CHKERRQ(ierr); ierr = MatGetOwnershipRange(s->subA[1],&start,&end);CHKERRQ(ierr); ierr = MatSetOption(s->subA[1],MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); for (row = start; row < end; row++) { ierr = StokesGetPosition(s, row, &i, &j);CHKERRQ(ierr); /* first part: rows 0 to (nx*ny-1) */ if (row < s->nx*s->ny) { ierr = StokesStencilGradientX(s, i, j, &size, cols, vals);CHKERRQ(ierr); } /* second part: rows (nx*ny) to (2*nx*ny-1) */ else { ierr = StokesStencilGradientY(s, i, j, &size, cols, vals);CHKERRQ(ierr); } ierr = MatSetValues(s->subA[1], 1, &row, size, cols, vals, INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(s->subA[1], MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(s->subA[1], MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }
PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqBAIJ(Mat A,MatType newtype,MatReuse reuse,Mat *newmat) { Mat B; Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; Mat_SeqBAIJ *b; PetscErrorCode ierr; PetscInt *ai=a->i,m=A->rmap->N,n=A->cmap->N,i,*rowlengths; PetscFunctionBegin; if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Matrix must be square"); if (A->rmap->bs > 1) { ierr = MatConvert_Basic(A,newtype,reuse,newmat); CHKERRQ(ierr); PetscFunctionReturn(0); } ierr = PetscMalloc1(m,&rowlengths); CHKERRQ(ierr); for (i=0; i<m; i++) { rowlengths[i] = ai[i+1] - ai[i]; } ierr = MatCreate(PetscObjectComm((PetscObject)A),&B); CHKERRQ(ierr); ierr = MatSetSizes(B,m,n,m,n); CHKERRQ(ierr); ierr = MatSetType(B,MATSEQBAIJ); CHKERRQ(ierr); ierr = MatSeqBAIJSetPreallocation_SeqBAIJ(B,1,0,rowlengths); CHKERRQ(ierr); ierr = PetscFree(rowlengths); CHKERRQ(ierr); ierr = MatSetOption(B,MAT_ROW_ORIENTED,PETSC_TRUE); CHKERRQ(ierr); b = (Mat_SeqBAIJ*)(B->data); ierr = PetscMemcpy(b->i,a->i,(m+1)*sizeof(PetscInt)); CHKERRQ(ierr); ierr = PetscMemcpy(b->ilen,a->ilen,m*sizeof(PetscInt)); CHKERRQ(ierr); ierr = PetscMemcpy(b->j,a->j,a->nz*sizeof(PetscInt)); CHKERRQ(ierr); ierr = PetscMemcpy(b->a,a->a,a->nz*sizeof(MatScalar)); CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); if (reuse == MAT_REUSE_MATRIX) { ierr = MatHeaderReplace(A,B); CHKERRQ(ierr); } else { *newmat = B; } PetscFunctionReturn(0); }
int main(int argc,char **argv) { Mat A,B; PetscInt m = 7,n,i,rstart,rend,cols[3]; PetscErrorCode ierr; PetscScalar v[3]; PetscBool equal; const char *eq[2]; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_COMMON);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-m",&m,NULL);CHKERRQ(ierr); n = m; /* ------- Assemble matrix, --------- */ ierr = MatCreateAIJ(PETSC_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,m,n,0,0,0,0,&A);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); if (!rstart) { cols[0] = 0; cols[1] = 1; v[0] = 2.0; v[1] = -1.0; ierr = MatSetValues(A,1,&rstart,2,cols,v,INSERT_VALUES);CHKERRQ(ierr); rstart++; } if (rend == m) { rend--; cols[0] = rend-1; cols[1] = rend; v[0] = -1.0; v[1] = 2.0; ierr = MatSetValues(A,1,&rend,2,cols,v,INSERT_VALUES);CHKERRQ(ierr); } v[0] = -1.0; v[1] = 2.0; v[2] = -1.0; for (i=rstart; i<rend; i++) { cols[0] = i-1; cols[1] = i; cols[2] = i+1; ierr = MatSetValues(A,1,&i,3,cols,v,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); ierr = MatEqual(A,B,&equal); eq[0] = "not equal"; eq[1] = "equal"; ierr = PetscPrintf(PETSC_COMM_WORLD,"Matrices are %s\n",eq[equal]);CHKERRQ(ierr); /* Free data structures */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
/* RHSMatrixLaplacian - User-provided routine to compute the right-hand-side matrix for the Laplacian operator Input Parameters: ts - the TS context t - current time (ignored) X - current solution (ignored) dummy - optional user-defined context, as set by TSetRHSJacobian() Output Parameters: AA - Jacobian matrix BB - optionally different matrix from which the preconditioner is built str - flag indicating matrix structure */ PetscErrorCode RHSMatrixLaplaciangllDM(TS ts,PetscReal t,Vec X,Mat A,Mat BB,void *ctx) { PetscReal **temp; PetscReal vv; AppCtx *appctx = (AppCtx*)ctx; /* user-defined application context */ PetscErrorCode ierr; PetscInt i,xs,xn,l,j; PetscInt *rowsDM; PetscBool flg = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL,"-gll_mf",&flg,NULL);CHKERRQ(ierr); if (!flg) { /* Creates the element stiffness matrix for the given gll */ ierr = PetscGLLElementLaplacianCreate(&appctx->SEMop.gll,&temp);CHKERRQ(ierr); /* workarround for clang analyzer warning: Division by zero */ if (appctx->param.N <= 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_WRONG,"Spectral element order should be > 1"); /* scale by the size of the element */ for (i=0; i<appctx->param.N; i++) { vv=-appctx->param.mu*2.0/appctx->param.Le; for (j=0; j<appctx->param.N; j++) temp[i][j]=temp[i][j]*vv; } ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = DMDAGetCorners(appctx->da,&xs,NULL,NULL,&xn,NULL,NULL);CHKERRQ(ierr); xs = xs/(appctx->param.N-1); xn = xn/(appctx->param.N-1); ierr = PetscMalloc1(appctx->param.N,&rowsDM);CHKERRQ(ierr); /* loop over local elements */ for (j=xs; j<xs+xn; j++) { for (l=0; l<appctx->param.N; l++) { rowsDM[l] = 1+(j-xs)*(appctx->param.N-1)+l; } ierr = MatSetValuesLocal(A,appctx->param.N,rowsDM,appctx->param.N,rowsDM,&temp[0][0],ADD_VALUES);CHKERRQ(ierr); } ierr = PetscFree(rowsDM);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecReciprocal(appctx->SEMop.mass);CHKERRQ(ierr); ierr = MatDiagonalScale(A,appctx->SEMop.mass,0);CHKERRQ(ierr); ierr = VecReciprocal(appctx->SEMop.mass);CHKERRQ(ierr); ierr = PetscGLLElementLaplacianDestroy(&appctx->SEMop.gll,&temp);CHKERRQ(ierr); } else { ierr = MatSetType(A,MATSHELL);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatShellSetContext(A,appctx);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_MULT,(void (*)(void))MatMult_Laplacian);CHKERRQ(ierr); } return 0; }
PetscErrorCode MatSetOption_IS(Mat A,MatOption op,PetscBool flg) { Mat_IS *a = (Mat_IS*)A->data; PetscErrorCode ierr; PetscFunctionBegin; ierr = MatSetOption(a->A,op,flg);CHKERRQ(ierr); PetscFunctionReturn(0); }
EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "MatConvert_SeqBAIJ_SeqAIJ" PetscErrorCode MatConvert_SeqBAIJ_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) { Mat B; Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data; PetscErrorCode ierr; PetscInt bs = A->rmap->bs,*ai = a->i,*aj = a->j,n = A->rmap->N/bs,i,j,k; PetscInt *rowlengths,*rows,*cols,maxlen = 0,ncols; MatScalar *aa = a->a; PetscFunctionBegin; ierr = PetscMalloc(n*bs*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); for (i=0; i<n; i++) { maxlen = PetscMax(maxlen,(ai[i+1] - ai[i])); for (j=0; j<bs; j++) { rowlengths[i*bs+j] = bs*(ai[i+1] - ai[i]); } } ierr = MatCreate(((PetscObject)A)->comm,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(B,0,rowlengths);CHKERRQ(ierr); ierr = MatSetOption(B,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); ierr = PetscFree(rowlengths);CHKERRQ(ierr); ierr = PetscMalloc(bs*sizeof(PetscInt),&rows);CHKERRQ(ierr); ierr = PetscMalloc(bs*maxlen*sizeof(PetscInt),&cols);CHKERRQ(ierr); for (i=0; i<n; i++) { for (j=0; j<bs; j++) { rows[j] = i*bs+j; } ncols = ai[i+1] - ai[i]; for (k=0; k<ncols; k++) { for (j=0; j<bs; j++) { cols[k*bs+j] = bs*(*aj) + j; } aj++; } ierr = MatSetValues(B,bs,rows,bs*ncols,cols,aa,INSERT_VALUES);CHKERRQ(ierr); aa += ncols*bs*bs; } ierr = PetscFree(cols);CHKERRQ(ierr); ierr = PetscFree(rows);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); B->rmap->bs = A->rmap->bs; if (reuse == MAT_REUSE_MATRIX) { ierr = MatHeaderReplace(A,B);CHKERRQ(ierr); } else { *newmat = B; } PetscFunctionReturn(0); }
PetscErrorCode MatShift_Basic(Mat Y,PetscScalar a) { PetscErrorCode ierr; PetscInt i,start,end; PetscScalar alpha = a; PetscBool prevoption; PetscFunctionBegin; ierr = MatGetOption(Y,MAT_NO_OFF_PROC_ENTRIES,&prevoption);CHKERRQ(ierr); ierr = MatSetOption(Y,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); for (i=start; i<end; i++) { ierr = MatSetValues(Y,1,&i,1,&i,&alpha,ADD_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatSetOption(Y,MAT_NO_OFF_PROC_ENTRIES,prevoption);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode FormRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat,Mat Pmat,void *ptr) { User user = (User)ptr; PetscErrorCode ierr; const PetscScalar **x; PetscInt M = user->Nspec+1,i,j,xs,xm;; DM dm; PetscFunctionBeginUser; if (user->reactions) { ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); ierr = MatZeroEntries(Pmat);CHKERRQ(ierr); ierr = MatSetOption(Pmat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); ierr = MatSetOption(Pmat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOFRead(dm,X,&x);CHKERRQ(ierr); ierr = DMDAGetCorners(dm,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); for (i=xs; i<xs+xm; i++) { ierr = PetscMemcpy(user->tchemwork,x[i],(user->Nspec+1)*sizeof(x[xs][0]));CHKERRQ(ierr); user->tchemwork[0] *= user->Tini; /* Dimensionalize temperature (first row) because that is what Tchem wants */ ierr = TC_getJacTYN(user->tchemwork,user->Nspec,user->Jdense,1);CHKERRQ(ierr); for (j=0; j<M; j++) user->Jdense[j + 0*M] /= user->Tini; /* Non-dimensionalize first column */ for (j=0; j<M; j++) user->Jdense[0 + j*M] /= user->Tini; /* Non-dimensionalize first row */ for (j=0; j<M; j++) user->rows[j] = i*M+j; ierr = MatSetValues(Pmat,M,user->rows,M,user->rows,user->Jdense,INSERT_VALUES);CHKERRQ(ierr); } ierr = DMDAVecRestoreArrayDOFRead(dm,X,&x);CHKERRQ(ierr); ierr = MatAssemblyBegin(Pmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Pmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } else { ierr = MatZeroEntries(Pmat);CHKERRQ(ierr); } if (user->diffusion) { ierr = FormDiffusionJacobian(ts,t,X,Amat,Pmat,ptr);CHKERRQ(ierr); } if (Amat != Pmat) { ierr = MatAssemblyBegin(Amat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Amat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode AlgJacobian(SNES snes,Vec X,Mat A,Mat B,void *ctx) { PetscErrorCode ierr; Userctx *user=(Userctx*)ctx; PetscFunctionBegin; ierr = ResidualJacobian(snes,X,A,B,ctx);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); ierr = MatZeroRowsIS(A,user->is_diff,1.0,NULL,NULL);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode PadMatrix(Mat A,Vec v,PetscScalar c,Mat *B) { PetscErrorCode ierr; PetscInt n = A->rmap->n,i,*cnt,*indices; Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; PetscScalar *vv; PetscFunctionBegin; ierr = VecGetArray(v,&vv); CHKERRQ(ierr); ierr = PetscMalloc(n*sizeof(PetscInt),&indices); CHKERRQ(ierr); for (i=0; i<n; i++) indices[i] = i; /* determine number of nonzeros per row in the new matrix */ ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cnt); CHKERRQ(ierr); for (i=0; i<n; i++) { cnt[i] = aij->i[i+1] - aij->i[i] + (vv[i] != 0.0); } cnt[n] = 1; for (i=0; i<n; i++) { cnt[n] += (vv[i] != 0.0); } ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,n+1,n+1,0,cnt,B); CHKERRQ(ierr); ierr = MatSetOption(*B,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE); CHKERRQ(ierr); /* copy over the matrix entries from the matrix and then the vector */ for (i=0; i<n; i++) { ierr = MatSetValues(*B,1,&i,aij->i[i+1] - aij->i[i],aij->j + aij->i[i],aij->a + aij->i[i],INSERT_VALUES); CHKERRQ(ierr); } ierr = MatSetValues(*B,1,&n,n,indices,vv,INSERT_VALUES); CHKERRQ(ierr); ierr = MatSetValues(*B,n,indices,1,&n,vv,INSERT_VALUES); CHKERRQ(ierr); ierr = MatSetValues(*B,1,&n,1,&n,&c,INSERT_VALUES); CHKERRQ(ierr); ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = VecRestoreArray(v,&vv); CHKERRQ(ierr); ierr = PetscFree(cnt); CHKERRQ(ierr); ierr = PetscFree(indices); CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatPreallocatorPreallocate_Preallocator(Mat mat, PetscBool fill, Mat A) { Mat_Preallocator *p = (Mat_Preallocator *) mat->data; PetscInt *udnz = NULL, *uonz = NULL; PetscInt bs; PetscErrorCode ierr; PetscFunctionBegin; ierr = MatGetBlockSize(mat, &bs);CHKERRQ(ierr); ierr = MatXAIJSetPreallocation(A, bs, p->dnz, p->onz, udnz, uonz);CHKERRQ(ierr); ierr = MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr); PetscFunctionReturn(0); }
PETSC_EXTERN PetscErrorCode MatConvert_MPIBAIJ_MPISBAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) { PetscErrorCode ierr; Mat M; Mat_MPIBAIJ *mpimat = (Mat_MPIBAIJ*)A->data; Mat_SeqBAIJ *Aa = (Mat_SeqBAIJ*)mpimat->A->data,*Ba = (Mat_SeqBAIJ*)mpimat->B->data; PetscInt *d_nnz,*o_nnz; PetscInt i,j,nz; PetscInt m,n,lm,ln; PetscInt rstart,rend; const PetscScalar *vwork; const PetscInt *cwork; PetscInt bs = A->rmap->bs; PetscFunctionBegin; ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); ierr = MatGetLocalSize(A,&lm,&ln);CHKERRQ(ierr); ierr = PetscMalloc2(lm/bs,&d_nnz,lm/bs,&o_nnz);CHKERRQ(ierr); ierr = MatMarkDiagonal_SeqBAIJ(mpimat->A);CHKERRQ(ierr); for (i=0; i<lm/bs; i++) { d_nnz[i] = Aa->i[i+1] - Aa->diag[i]; o_nnz[i] = Ba->i[i+1] - Ba->i[i]; } ierr = MatCreate(PetscObjectComm((PetscObject)A),&M);CHKERRQ(ierr); ierr = MatSetSizes(M,lm,ln,m,n);CHKERRQ(ierr); ierr = MatSetType(M,MATMPISBAIJ);CHKERRQ(ierr); ierr = MatSeqSBAIJSetPreallocation(M,bs,0,d_nnz);CHKERRQ(ierr); ierr = MatMPISBAIJSetPreallocation(M,bs,0,d_nnz,0,o_nnz);CHKERRQ(ierr); ierr = PetscFree2(d_nnz,o_nnz);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); ierr = MatSetOption(M,MAT_IGNORE_LOWER_TRIANGULAR,PETSC_TRUE);CHKERRQ(ierr); for (i=rstart; i<rend; i++) { ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); j = 0; ierr = MatSetValues(M,1,&i,nz,cwork+j,vwork+j,INSERT_VALUES);CHKERRQ(ierr); ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); } ierr = MatAssemblyBegin(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (reuse == MAT_REUSE_MATRIX) { ierr = MatHeaderReplace(A,&M);CHKERRQ(ierr); } else { *newmat = M; } PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat C=0; PetscScalar v; PetscInt Ii,J,Istart,Iend; PetscErrorCode ierr; PetscInt i,j,m = 3,n = 2; PetscMPIInt size,rank; PetscInt solve_count; const MatType type; PetscInitialize(&argc,&args,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-m",&m,PETSC_NULL);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); n = 2*size; ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr); ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);CHKERRQ(ierr); ierr = MatSetFromOptions(C);CHKERRQ(ierr); for (solve_count=0; solve_count<3; solve_count++){ if (solve_count == 1){ ierr = MatSetType(C,MATSBAIJ);CHKERRQ(ierr); ierr = MatSetOption(C,MAT_IGNORE_LOWER_TRIANGULAR,PETSC_TRUE);CHKERRQ(ierr); } else { ierr = MatSetType(C,MATMPIDENSE);CHKERRQ(ierr); } ierr = MatGetOwnershipRange(C,&Istart,&Iend);CHKERRQ(ierr); for (Ii=Istart; Ii<Iend; Ii++) { v = -1.0; i = Ii/n; j = Ii - i*n; if (i>0) {J = Ii - n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);} if (i<m-1) {J = Ii + n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);} if (j>0) {J = Ii - 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);} if (j<n-1) {J = Ii + 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);} v = 4.0; ierr = MatSetValues(C,1,&Ii,1,&Ii,&v,ADD_VALUES); } ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatGetType(C,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," case %D, matrix type: %s\n",solve_count,type); } /* Free work space. */ ierr = MatDestroy(C);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
PetscErrorCode TestMatZeroRows_with_no_allocation(Mat A,IS is,PetscScalar diag) { Mat B; PetscErrorCode ierr; /* Now copy A into B, and test it with MatZeroRows() */ ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); /* Set this flag after assembly. This way, it affects only MatZeroRows() */ ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); ierr = MatZeroRowsIS(B,is,diag,0,0);CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); return 0; }
/* RHSMatrixAdvection - User-provided routine to compute the right-hand-side matrix for the Advection (gradient) operator. Input Parameters: ts - the TS context t - current time global_in - global input vector dummy - optional user-defined context, as set by TSetRHSJacobian() Output Parameters: AA - Jacobian matrix BB - optionally different preconditioning matrix str - flag indicating matrix structure */ PetscErrorCode RHSMatrixAdvectiongllDM(TS ts,PetscReal t,Vec X,Mat A,Mat BB,void *ctx) { PetscReal **temp; AppCtx *appctx = (AppCtx*)ctx; /* user-defined application context */ PetscErrorCode ierr; PetscInt xs,xn,l,j; PetscInt *rowsDM; PetscBool flg = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL,"-gll_mf",&flg,NULL);CHKERRQ(ierr); if (!flg) { /* Creates the advection matrix for the given gll */ ierr = PetscGLLElementAdvectionCreate(&appctx->SEMop.gll,&temp);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = DMDAGetCorners(appctx->da,&xs,NULL,NULL,&xn,NULL,NULL);CHKERRQ(ierr); xs = xs/(appctx->param.N-1); xn = xn/(appctx->param.N-1); ierr = PetscMalloc1(appctx->param.N,&rowsDM);CHKERRQ(ierr); for (j=xs; j<xs+xn; j++) { for (l=0; l<appctx->param.N; l++) { rowsDM[l] = 1+(j-xs)*(appctx->param.N-1)+l; } ierr = MatSetValuesLocal(A,appctx->param.N,rowsDM,appctx->param.N,rowsDM,&temp[0][0],ADD_VALUES);CHKERRQ(ierr); } ierr = PetscFree(rowsDM);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecReciprocal(appctx->SEMop.mass);CHKERRQ(ierr); ierr = MatDiagonalScale(A,appctx->SEMop.mass,0);CHKERRQ(ierr); ierr = VecReciprocal(appctx->SEMop.mass);CHKERRQ(ierr); ierr = PetscGLLElementAdvectionDestroy(&appctx->SEMop.gll,&temp);CHKERRQ(ierr); } else { ierr = MatSetType(A,MATSHELL);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatShellSetContext(A,appctx);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_MULT,(void (*)(void))MatMult_Advection);CHKERRQ(ierr); } return 0; }
void linearSystemPETSc<scalar>::preAllocateEntries() { if (_entriesPreAllocated) return; if (!_isAllocated) Msg::Fatal("system must be allocated first"); int blockSize = _getBlockSizeFromParameters(); std::vector<int> nByRowDiag (_localSize), nByRowOffDiag (_localSize); if (_sparsity.getNbRows() == 0) { PetscInt prealloc = 500; PetscBool set; PetscOptionsGetInt(PETSC_NULL, "-petsc_prealloc", &prealloc, &set); prealloc = std::min(prealloc, _localSize); nByRowDiag.resize(0); nByRowDiag.resize(_localSize, prealloc); } else { for (int i = 0; i < _localSize; i++) { int n; const int *r = _sparsity.getRow(i, n); for (int j = 0; j < n; j++) { if (r[j] >= _localRowStart && r[j] < _localRowEnd) nByRowDiag[i] ++; else nByRowOffDiag[i] ++; } } _sparsity.clear(); } //MatXAIJSetPreallocation is not available in petsc < 3.3 int commSize = 1; MPI_Comm_size(_comm, &commSize); if (commSize == 1){ if (blockSize == 1) _try(MatSeqAIJSetPreallocation(_a, 0, &nByRowDiag[0])); else _try(MatSeqBAIJSetPreallocation(_a, blockSize, 0, &nByRowDiag[0])); } else { if (blockSize == 1) _try(MatMPIAIJSetPreallocation(_a, 0, &nByRowDiag[0], 0, &nByRowOffDiag[0])); else _try(MatMPIBAIJSetPreallocation(_a, blockSize, 0, &nByRowDiag[0], 0, &nByRowOffDiag[0])); } if (blockSize > 1) _try(MatSetOption(_a, MAT_ROW_ORIENTED, PETSC_FALSE)); _entriesPreAllocated = true; }
/* FormJacobianLocal - Evaluates Jacobian matrix on local process patch */ PetscErrorCode FormJacobianLocal(DMDALocalInfo *info,PetscScalar **x,Mat A,Mat jac, MatStructure *str,ObsCtx *user) { PetscErrorCode ierr; PetscInt i,j; MatStencil col[5],row; PetscReal v[5],dx,dy,oxx,oyy; PetscFunctionBeginUser; dx = 4.0 / (PetscReal)(info->mx-1); dy = 4.0 / (PetscReal)(info->my-1); oxx = 1.0 / (dx * dx); oyy = 1.0 / (dy * dy); for (j=info->ys; j<info->ys+info->ym; j++) { for (i=info->xs; i<info->xs+info->xm; i++) { row.j = j; row.i = i; if (i == 0 || j == 0 || i == info->mx-1 || j == info->my-1) { /* boundary */ v[0] = 1.0; ierr = MatSetValuesStencil(jac,1,&row,1,&row,v,INSERT_VALUES);CHKERRQ(ierr); } else { /* interior grid points */ v[0] = -oyy; col[0].j = j - 1; col[0].i = i; v[1] = -oxx; col[1].j = j; col[1].i = i - 1; v[2] = 2.0 * (oxx + oyy); col[2].j = j; col[2].i = i; v[3] = -oxx; col[3].j = j; col[3].i = i + 1; v[4] = -oyy; col[4].j = j + 1; col[4].i = i; ierr = MatSetValuesStencil(jac,1,&row,5,col,v,INSERT_VALUES);CHKERRQ(ierr); } } } /* Assemble matrix, using the 2-step process: */ ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (A != jac) { ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } *str = SAME_NONZERO_PATTERN; /* Tell the matrix we will never add a new nonzero location to the matrix. If we do, it will generate an error. */ ierr = MatSetOption(jac,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscLogFlops(2.0*info->ym*info->xm);CHKERRQ(ierr); PetscFunctionReturn(0); }
void PETScLinearSolver::MatrixCreate( PetscInt m, PetscInt n) { MatCreate(PETSC_COMM_WORLD, &A); // TEST MatSetSizes(A, m_size_loc, PETSC_DECIDE, m, n); MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, m, n); //MatSetSizes(A, m_size_loc, PETSC_DECIDE, m, n); MatSetType(A, MATMPIAIJ); MatSetFromOptions(A); MatSeqAIJSetPreallocation(A, d_nz, PETSC_NULL); MatMPIAIJSetPreallocation(A, d_nz, PETSC_NULL, o_nz, PETSC_NULL); MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE); MatSetUp(A); // KG44 this seems to work with petsc 3.3 ..the commands below result in problems when assembling the matrix with version 3.3 MatGetOwnershipRange(A, &i_start, &i_end); }
int main(int argc,char **args) { Mat C; PetscInt i,j,m = 5,n = 5,Ii,J; PetscErrorCode ierr; PetscScalar v,five = 5.0; IS isrow; PetscBool keepnonzeropattern; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; /* create the matrix for the five point stencil, YET AGAIN*/ ierr = MatCreate(PETSC_COMM_SELF,&C);CHKERRQ(ierr); ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);CHKERRQ(ierr); ierr = MatSetFromOptions(C);CHKERRQ(ierr); ierr = MatSetUp(C);CHKERRQ(ierr); for (i=0; i<m; i++) { for (j=0; j<n; j++) { v = -1.0; Ii = j + n*i; if (i>0) {J = Ii - n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (i<m-1) {J = Ii + n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j>0) {J = Ii - 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j<n-1) {J = Ii + 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} v = 4.0; ierr = MatSetValues(C,1,&Ii,1,&Ii,&v,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,(m*n)/2,0,2,&isrow);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL,"-keep_nonzero_pattern",&keepnonzeropattern);CHKERRQ(ierr); if (keepnonzeropattern) { ierr = MatSetOption(C,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); } ierr = MatZeroRowsIS(C,isrow,five,0,0);CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = ISDestroy(&isrow);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode TestMatZeroRows_Basic(Mat A,IS is,PetscScalar diag) { Mat B; PetscErrorCode ierr; PetscBool keepnonzeropattern; /* Now copy A into B, and test it with MatZeroRows() */ ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL,"-keep_nonzero_pattern",&keepnonzeropattern);CHKERRQ(ierr); if (keepnonzeropattern) { ierr = MatSetOption(B,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); } ierr = MatZeroRowsIS(B,is,diag,0,0);CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); return 0; }