PetscErrorCode StokesSetupMatBlock00(Stokes *s) { PetscInt row, start, end, size, i, j; PetscInt cols[5]; PetscScalar vals[5]; PetscErrorCode ierr; PetscFunctionBeginUser; /* A[0] is 2N-by-2N */ ierr = MatCreate(PETSC_COMM_WORLD,&s->subA[0]);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(s->subA[0],"a00_");CHKERRQ(ierr); ierr = MatSetSizes(s->subA[0],PETSC_DECIDE,PETSC_DECIDE,2*s->nx*s->ny,2*s->nx*s->ny);CHKERRQ(ierr); ierr = MatSetType(s->subA[0],MATMPIAIJ);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(s->subA[0],5,NULL,5,NULL);CHKERRQ(ierr); ierr = MatGetOwnershipRange(s->subA[0], &start, &end);CHKERRQ(ierr); for (row = start; row < end; row++) { ierr = StokesGetPosition(s, row, &i, &j);CHKERRQ(ierr); /* first part: rows 0 to (nx*ny-1) */ ierr = StokesStencilLaplacian(s, i, j, &size, cols, vals);CHKERRQ(ierr); /* second part: rows (nx*ny) to (2*nx*ny-1) */ if (row >= s->nx*s->ny) { for (i = 0; i < 5; i++) cols[i] = cols[i] + s->nx*s->ny; } for (i = 0; i < 5; i++) vals[i] = -1.0*vals[i]; /* dynamic viscosity coef mu=-1 */ ierr = MatSetValues(s->subA[0], 1, &row, size, cols, vals, INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(s->subA[0], MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(s->subA[0], MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(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); }
PetscErrorCode StokesSetupMatFp(Stokes *s) { PetscInt row, start, end, size, i, j; PetscInt cols[5]; PetscScalar vals[5]; PetscErrorCode ierr; PetscFunctionBeginUser; // Fp is N-by-N ierr = MatCreate(PETSC_COMM_WORLD,&s->Fp);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(s->Fp,"Fp_");CHKERRQ(ierr); ierr = MatSetSizes(s->Fp,PETSC_DECIDE,PETSC_DECIDE,s->nx*s->ny,s->nx*s->ny);CHKERRQ(ierr); ierr = MatSetType(s->Fp,MATMPIAIJ);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(s->Fp,5,NULL,5,NULL);CHKERRQ(ierr); ierr = MatGetOwnershipRange(s->Fp, &start, &end);CHKERRQ(ierr); for (row = start; row < end; row++) { ierr = StokesGetPosition(s, row, &i, &j);CHKERRQ(ierr); ierr = StokesStencilLaplacian(s, i, j, &size, cols, vals);CHKERRQ(ierr); for (i = 0; i < 5; i++) vals[i] = -1.0*vals[i]; //* dynamic viscosity coef mu=-1 ierr = MatSetValues(s->Fp, 1, &row, size, cols, vals, INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(s->Fp, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(s->Fp, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) { PetscErrorCode ierr; PetscInt n,bs; Mat_IS *is = (Mat_IS*)A->data; IS from,to; Vec global; PetscFunctionBegin; PetscCheckSameComm(A,1,rmapping,2); if (rmapping != cmapping) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MATIS requires the row and column mappings to be identical"); if (is->mapping) { /* Currenly destroys the objects that will be created by this routine. Is there anything else that should be checked? */ ierr = ISLocalToGlobalMappingDestroy(&is->mapping);CHKERRQ(ierr); ierr = VecDestroy(&is->x);CHKERRQ(ierr); ierr = VecDestroy(&is->y);CHKERRQ(ierr); ierr = VecScatterDestroy(&is->ctx);CHKERRQ(ierr); ierr = MatDestroy(&is->A);CHKERRQ(ierr); } ierr = PetscObjectReference((PetscObject)rmapping);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingDestroy(&is->mapping);CHKERRQ(ierr); is->mapping = rmapping; /* ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); */ /* Create the local matrix A */ ierr = ISLocalToGlobalMappingGetSize(rmapping,&n);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&bs);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); if (bs > 1) { ierr = MatSetType(is->A,MATSEQBAIJ);CHKERRQ(ierr); } else { ierr = MatSetType(is->A,MATSEQAIJ);CHKERRQ(ierr); } ierr = MatSetSizes(is->A,n,n,n,n);CHKERRQ(ierr); ierr = MatSetBlockSize(is->A,bs);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); /* Create the local work vectors */ ierr = VecCreate(PETSC_COMM_SELF,&is->x);CHKERRQ(ierr); ierr = VecSetBlockSize(is->x,bs);CHKERRQ(ierr); ierr = VecSetSizes(is->x,n,n);CHKERRQ(ierr); ierr = VecSetOptionsPrefix(is->x,((PetscObject)A)->prefix);CHKERRQ(ierr); ierr = VecAppendOptionsPrefix(is->x,"is_");CHKERRQ(ierr); ierr = VecSetFromOptions(is->x);CHKERRQ(ierr); ierr = VecDuplicate(is->x,&is->y);CHKERRQ(ierr); /* setup the global to local scatter */ ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&to);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); ierr = MatCreateVecs(A,&global,NULL);CHKERRQ(ierr); ierr = VecScatterCreate(global,from,is->x,to,&is->ctx);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = ISDestroy(&to);CHKERRQ(ierr); ierr = ISDestroy(&from);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc, char **argv) { Mat mat; MatNullSpace nsp; PetscBool prefix = PETSC_FALSE, flg; PetscErrorCode ierr; PetscInt zero = 0; PetscScalar value = 0; ierr = PetscInitialize(&argc, &argv, NULL, help); if (ierr) return ierr; ierr = PetscOptionsGetBool(NULL, NULL, "-with_prefix",&prefix,NULL);CHKERRQ(ierr); ierr = MatCreateDense(PETSC_COMM_WORLD, 1, 1, 1, 1, NULL, &mat);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(mat, prefix ? "prefix_" : NULL);CHKERRQ(ierr); ierr = MatSetUp(mat);CHKERRQ(ierr); ierr = MatSetValues(mat, 1, &zero, 1, &zero, &value, INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatNullSpaceCreate(PETSC_COMM_WORLD, PETSC_TRUE, 0, NULL, &nsp);CHKERRQ(ierr); ierr = MatNullSpaceTest(nsp, mat, &flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Null space test failed!"); ierr = MatNullSpaceDestroy(&nsp);CHKERRQ(ierr); ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode StokesSetupMatBlock10(Stokes *s) { PetscErrorCode ierr; PetscFunctionBeginUser; /* A[2] is minus transpose of A[1] */ ierr = MatTranspose(s->subA[1], MAT_INITIAL_MATRIX, &s->subA[2]);CHKERRQ(ierr); ierr = MatScale(s->subA[2], -1.0);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(s->subA[2], "a10_");CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode StokesSetupMatBlock11(Stokes *s) { PetscErrorCode ierr; PetscFunctionBeginUser; /* A[3] is N-by-N null matrix */ ierr = MatCreate(PETSC_COMM_WORLD, &s->subA[3]);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(s->subA[3], "a11_");CHKERRQ(ierr); ierr = MatSetSizes(s->subA[3], PETSC_DECIDE, PETSC_DECIDE, s->nx*s->ny, s->nx*s->ny);CHKERRQ(ierr); ierr = MatSetType(s->subA[3], MATMPIAIJ);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(s->subA[3], 0, NULL, 0, NULL);CHKERRQ(ierr); ierr = MatAssemblyBegin(s->subA[3], MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(s->subA[3], MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **args) { PetscErrorCode ierr; DM da; KSP ksp; Mat A; Vec b,u,uexact; PetscReal errnorm; DMDALocalInfo info; PetscInitialize(&argc,&args,(char*)0,help); ierr = DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, 9,1,1,NULL, &da); CHKERRQ(ierr); ierr = DMSetFromOptions(da); CHKERRQ(ierr); ierr = DMSetUp(da); CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,0.0,1.0,-1.0,-1.0,-1.0,-1.0); CHKERRQ(ierr); ierr = DMCreateMatrix(da,&A);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(A,"a_"); CHKERRQ(ierr); ierr = MatSetFromOptions(A); CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&b);CHKERRQ(ierr); ierr = VecDuplicate(b,&u); CHKERRQ(ierr); ierr = VecDuplicate(b,&uexact); CHKERRQ(ierr); ierr = formExactAndRHS(da,uexact,b); CHKERRQ(ierr); ierr = formdirichletlaplacian(da,A); CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp); CHKERRQ(ierr); ierr = KSPSetOperators(ksp,A,A); CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp); CHKERRQ(ierr); ierr = KSPSolve(ksp,b,u); CHKERRQ(ierr); ierr = VecAXPY(u,-1.0,uexact); CHKERRQ(ierr); // u <- u + (-1.0) uxact ierr = VecNorm(u,NORM_INFINITY,&errnorm); CHKERRQ(ierr); ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "on %d point grid: error |u-uexact|_inf = %g\n", info.mx,errnorm); CHKERRQ(ierr); VecDestroy(&u); VecDestroy(&uexact); VecDestroy(&b); MatDestroy(&A); KSPDestroy(&ksp); DMDestroy(&da); PetscFinalize(); return 0; }
PETSC_EXTERN PetscErrorCode TaoCreate_BQNLS(Tao tao) { TAO_BNK *bnk; TAO_BQNK *bqnk; PetscErrorCode ierr; PetscFunctionBegin; ierr = TaoCreate_BQNK(tao);CHKERRQ(ierr); ierr = KSPSetOptionsPrefix(tao->ksp, "unused");CHKERRQ(ierr); tao->ops->solve = TaoSolve_BNLS; tao->ops->setfromoptions = TaoSetFromOptions_BQNLS; bnk = (TAO_BNK*)tao->data; bnk->update_type = BNK_UPDATE_STEP; bnk->computehessian = TaoBQNLSComputeHessian; bnk->computestep = TaoBQNLSComputeStep; bqnk = (TAO_BQNK*)bnk->ctx; ierr = MatSetOptionsPrefix(bqnk->B, "tao_bqnls_");CHKERRQ(ierr); ierr = MatSetType(bqnk->B, MATLMVMBFGS);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInitialize(&argc,&argv,(char*)0,help); const int d = 2; // d = DOF Mat A, Aminus; // these are dense d x d sequential matrices, unrelated to the grid // (each processor owns whole matrix) ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,d,d,d,NULL,&A); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(A,"A_"); CHKERRQ(ierr); ierr = MatSetFromOptions(A); CHKERRQ(ierr); // fill A double val[d][d], c = 3.0; val[0][0] = 0.0; val[0][1] = c; val[1][0] = c; val[1][1] = 0.0; ierr = fillsmallmat(2,val,A); CHKERRQ(ierr); // fill Aminus; see getAminus.m for computation of Aminus from A ierr = MatDuplicate(A,MAT_SHARE_NONZERO_PATTERN,&Aminus); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(Aminus,"Aminus_"); CHKERRQ(ierr); val[0][0] = -1.5; val[0][1] = 1.5; val[1][0] = 1.5; val[1][1] = -1.5; ierr = fillsmallmat(2,val,Aminus); CHKERRQ(ierr); // set up the grid DM da; ierr = DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, -50, // override with -da_grid_x or -da_refine d, 1, NULL, // dof = 1 and stencil width = 1 &da); CHKERRQ(ierr); // determine grid locations (cell-centered grid) DMDALocalInfo info; double L = 10.0, dx; ierr = DMDAGetLocalInfo(da,&info); CHKERRQ(ierr); dx = L / (double)(info.mx); ierr = DMDASetUniformCoordinates(da,dx/2,L-dx/2,-1.0,-1.0,-1.0,-1.0);CHKERRQ(ierr); // u = u(t_n), unew = u(t_n+1) Vec u, unew, F; ierr = DMCreateLocalVector(da,&u);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)u,"solution u"); CHKERRQ(ierr); ierr = VecDuplicate(u,&F);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)F,"flux F"); CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&unew);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)unew,"updated solution unew"); CHKERRQ(ierr); ierr = VecSet(unew,0.0); CHKERRQ(ierr); // at each cell we will need to compute Fcell = A qleft + Aminus dq Vec dq, qleft, tmp, Fcell; ierr = VecCreateSeq(PETSC_COMM_WORLD,d,&dq); CHKERRQ(ierr); ierr = VecDuplicate(dq,&qleft); CHKERRQ(ierr); ierr = VecDuplicate(dq,&tmp); CHKERRQ(ierr); ierr = VecDuplicate(dq,&Fcell); CHKERRQ(ierr); // view the solution graphically; control with -draw_pause PetscViewer viewer; ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,NULL,"solution u", PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,&viewer); CHKERRQ(ierr); /* time-stepping loop */ double t = 0.0, tf = 10.0, dt, nu; int n, NN = 10; dt = tf / NN; nu = dt / dx; for (n = 0; n < NN; ++n) { ierr = PetscPrintf(PETSC_COMM_WORLD, " time[%3d]=%6g: \n", n, t); CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,unew,INSERT_VALUES,u); CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,unew,INSERT_VALUES,u); CHKERRQ(ierr); ierr = VecView(u,viewer); CHKERRQ(ierr); double **au, **aunew, **aF; int j, p; ierr = DMDAVecGetArrayDOF(da, u, &au);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da, F, &aF);CHKERRQ(ierr); for (j=info.xs; j<info.xs+info.xm; j++) { double *adq, *aqleft, *aFcell; ierr = VecGetArray(dq,&adq); CHKERRQ(ierr); ierr = VecGetArray(qleft,&aqleft); CHKERRQ(ierr); for (p = 0; p < d; p++) { adq[p] = au[j+1][p] - au[j][p]; aqleft[p] = au[j][p]; } ierr = VecRestoreArray(dq,&adq); CHKERRQ(ierr); ierr = VecRestoreArray(qleft,&aqleft); CHKERRQ(ierr); // tmp = A qleft // Fcell = tmp + Aminus dq ierr = MatMult(A,qleft,tmp); CHKERRQ(ierr); ierr = MatMultAdd(Aminus,dq,tmp,Fcell); CHKERRQ(ierr); ierr = VecGetArray(Fcell,&aFcell); CHKERRQ(ierr); for (p = 0; p < d; p++) aF[j][p] = aFcell[p]; ierr = VecRestoreArray(Fcell,&aFcell); CHKERRQ(ierr); } ierr = DMDAVecRestoreArrayDOF(da, F, &aF);CHKERRQ(ierr); ierr = DMLocalToLocalBegin(da,F,INSERT_VALUES,F); CHKERRQ(ierr); ierr = DMLocalToLocalEnd(da,F,INSERT_VALUES,F); CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da, F, &aF);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da, unew, &aunew);CHKERRQ(ierr); for (j=info.xs; j<info.xs+info.xm; j++) { for (p = 0; p < d; p++) aunew[j][p] = au[j][p] - nu * (aF[j+1][p] - aF[j][p]); } ierr = DMDAVecRestoreArrayDOF(da, u, &au);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da, F, &aF);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da, unew, &aunew);CHKERRQ(ierr); t += dt; } // clean up ierr = VecDestroy(&u); CHKERRQ(ierr); ierr = VecDestroy(&unew); CHKERRQ(ierr); ierr = VecDestroy(&F); CHKERRQ(ierr); ierr = VecDestroy(&dq); CHKERRQ(ierr); ierr = VecDestroy(&qleft); CHKERRQ(ierr); ierr = VecDestroy(&tmp); CHKERRQ(ierr); ierr = VecDestroy(&Fcell); CHKERRQ(ierr); ierr = MatDestroy(&A); CHKERRQ(ierr); ierr = MatDestroy(&Aminus); CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr); ierr = DMDestroy(&da); CHKERRQ(ierr); ierr = PetscFinalize(); CHKERRQ(ierr); return 0; }
void PetscMatrix<T>::init (const numeric_index_type m_in, const numeric_index_type n_in, const numeric_index_type m_l, const numeric_index_type n_l, const numeric_index_type nnz, const numeric_index_type noz, const numeric_index_type blocksize_in) { // So compilers don't warn when !LIBMESH_ENABLE_BLOCKED_STORAGE libmesh_ignore(blocksize_in); // Clear initialized matrices if (this->initialized()) this->clear(); this->_is_initialized = true; PetscErrorCode ierr = 0; PetscInt m_global = static_cast<PetscInt>(m_in); PetscInt n_global = static_cast<PetscInt>(n_in); PetscInt m_local = static_cast<PetscInt>(m_l); PetscInt n_local = static_cast<PetscInt>(n_l); PetscInt n_nz = static_cast<PetscInt>(nnz); PetscInt n_oz = static_cast<PetscInt>(noz); ierr = MatCreate(this->comm().get(), &_mat); LIBMESH_CHKERRABORT(ierr); ierr = MatSetSizes(_mat, m_local, n_local, m_global, n_global); LIBMESH_CHKERRABORT(ierr); #ifdef LIBMESH_ENABLE_BLOCKED_STORAGE PetscInt blocksize = static_cast<PetscInt>(blocksize_in); if (blocksize > 1) { // specified blocksize, bs>1. // double check sizes. libmesh_assert_equal_to (m_local % blocksize, 0); libmesh_assert_equal_to (n_local % blocksize, 0); libmesh_assert_equal_to (m_global % blocksize, 0); libmesh_assert_equal_to (n_global % blocksize, 0); libmesh_assert_equal_to (n_nz % blocksize, 0); libmesh_assert_equal_to (n_oz % blocksize, 0); ierr = MatSetType(_mat, MATBAIJ); // Automatically chooses seqbaij or mpibaij LIBMESH_CHKERRABORT(ierr); ierr = MatSetBlockSize(_mat, blocksize); LIBMESH_CHKERRABORT(ierr); ierr = MatSeqBAIJSetPreallocation(_mat, blocksize, n_nz/blocksize, PETSC_NULL); LIBMESH_CHKERRABORT(ierr); ierr = MatMPIBAIJSetPreallocation(_mat, blocksize, n_nz/blocksize, PETSC_NULL, n_oz/blocksize, PETSC_NULL); LIBMESH_CHKERRABORT(ierr); } else #endif { ierr = MatSetType(_mat, MATAIJ); // Automatically chooses seqaij or mpiaij LIBMESH_CHKERRABORT(ierr); ierr = MatSeqAIJSetPreallocation(_mat, n_nz, PETSC_NULL); LIBMESH_CHKERRABORT(ierr); ierr = MatMPIAIJSetPreallocation(_mat, n_nz, PETSC_NULL, n_oz, PETSC_NULL); LIBMESH_CHKERRABORT(ierr); } // Make it an error for PETSc to allocate new nonzero entries during assembly #if PETSC_VERSION_LESS_THAN(3,0,0) ierr = MatSetOption(_mat, MAT_NEW_NONZERO_ALLOCATION_ERR); #else ierr = MatSetOption(_mat, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE); #endif LIBMESH_CHKERRABORT(ierr); // Is prefix information available somewhere? Perhaps pass in the system name? ierr = MatSetOptionsPrefix(_mat, ""); LIBMESH_CHKERRABORT(ierr); ierr = MatSetFromOptions(_mat); LIBMESH_CHKERRABORT(ierr); this->zero (); }
void PetscMatrix<T>::init () { libmesh_assert(this->_dof_map); // Clear initialized matrices if (this->initialized()) this->clear(); this->_is_initialized = true; const numeric_index_type my_m = this->_dof_map->n_dofs(); const numeric_index_type my_n = my_m; const numeric_index_type n_l = this->_dof_map->n_dofs_on_processor(this->processor_id()); const numeric_index_type m_l = n_l; const std::vector<numeric_index_type>& n_nz = this->_dof_map->get_n_nz(); const std::vector<numeric_index_type>& n_oz = this->_dof_map->get_n_oz(); // Make sure the sparsity pattern isn't empty unless the matrix is 0x0 libmesh_assert_equal_to (n_nz.size(), m_l); libmesh_assert_equal_to (n_oz.size(), m_l); PetscErrorCode ierr = 0; PetscInt m_global = static_cast<PetscInt>(my_m); PetscInt n_global = static_cast<PetscInt>(my_n); PetscInt m_local = static_cast<PetscInt>(m_l); PetscInt n_local = static_cast<PetscInt>(n_l); ierr = MatCreate(this->comm().get(), &_mat); LIBMESH_CHKERRABORT(ierr); ierr = MatSetSizes(_mat, m_local, n_local, m_global, n_global); LIBMESH_CHKERRABORT(ierr); #ifdef LIBMESH_ENABLE_BLOCKED_STORAGE PetscInt blocksize = static_cast<PetscInt>(this->_dof_map->block_size()); if (blocksize > 1) { // specified blocksize, bs>1. // double check sizes. libmesh_assert_equal_to (m_local % blocksize, 0); libmesh_assert_equal_to (n_local % blocksize, 0); libmesh_assert_equal_to (m_global % blocksize, 0); libmesh_assert_equal_to (n_global % blocksize, 0); ierr = MatSetType(_mat, MATBAIJ); // Automatically chooses seqbaij or mpibaij LIBMESH_CHKERRABORT(ierr); ierr = MatSetBlockSize(_mat, blocksize); LIBMESH_CHKERRABORT(ierr); // transform the per-entry n_nz and n_oz arrays into their block counterparts. std::vector<numeric_index_type> b_n_nz, b_n_oz; transform_preallocation_arrays (blocksize, n_nz, n_oz, b_n_nz, b_n_oz); ierr = MatSeqBAIJSetPreallocation(_mat, blocksize, 0, (PetscInt*)(b_n_nz.empty()?NULL:&b_n_nz[0])); LIBMESH_CHKERRABORT(ierr); ierr = MatMPIBAIJSetPreallocation(_mat, blocksize, 0, (PetscInt*)(b_n_nz.empty()?NULL:&b_n_nz[0]), 0, (PetscInt*)(b_n_oz.empty()?NULL:&b_n_oz[0])); LIBMESH_CHKERRABORT(ierr); } else #endif { // no block storage case ierr = MatSetType(_mat, MATAIJ); // Automatically chooses seqaij or mpiaij LIBMESH_CHKERRABORT(ierr); ierr = MatSeqAIJSetPreallocation(_mat, 0, (PetscInt*)(n_nz.empty()?NULL:&n_nz[0])); LIBMESH_CHKERRABORT(ierr); ierr = MatMPIAIJSetPreallocation(_mat, 0, (PetscInt*)(n_nz.empty()?NULL:&n_nz[0]), 0, (PetscInt*)(n_oz.empty()?NULL:&n_oz[0])); LIBMESH_CHKERRABORT(ierr); } // Is prefix information available somewhere? Perhaps pass in the system name? ierr = MatSetOptionsPrefix(_mat, ""); LIBMESH_CHKERRABORT(ierr); ierr = MatSetFromOptions(_mat); LIBMESH_CHKERRABORT(ierr); this->zero(); }
int main(int argc,char **argv) { Mat A,R,C,C_dense,C_sparse,Rt_dense,P,PtAP; PetscInt row,col,m,n; PetscErrorCode ierr; MatScalar one =1.0,val; MatColoring mc; MatTransposeColoring matcoloring = 0; ISColoring iscoloring; PetscBool equal; PetscMPIInt size; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"This is a uniprocessor example only!"); /* Create seqaij A */ ierr = MatCreate(PETSC_COMM_SELF,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,4,4,4,4);CHKERRQ(ierr); ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); row = 0; col=0; val=1.0; ierr = MatSetValues(A,1,&row,1,&col,&val,ADD_VALUES);CHKERRQ(ierr); row = 1; col=3; val=2.0; ierr = MatSetValues(A,1,&row,1,&col,&val,ADD_VALUES);CHKERRQ(ierr); row = 2; col=2; val=3.0; ierr = MatSetValues(A,1,&row,1,&col,&val,ADD_VALUES);CHKERRQ(ierr); row = 3; col=0; val=4.0; ierr = MatSetValues(A,1,&row,1,&col,&val,ADD_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(A,"A_");CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n");CHKERRQ(ierr); /* Create seqaij R */ ierr = MatCreate(PETSC_COMM_SELF,&R);CHKERRQ(ierr); ierr = MatSetSizes(R,2,4,2,4);CHKERRQ(ierr); ierr = MatSetType(R,MATSEQAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(R);CHKERRQ(ierr); ierr = MatSetUp(R);CHKERRQ(ierr); row = 0; col=0; ierr = MatSetValues(R,1,&row,1,&col,&one,ADD_VALUES);CHKERRQ(ierr); row = 0; col=1; ierr = MatSetValues(R,1,&row,1,&col,&one,ADD_VALUES);CHKERRQ(ierr); row = 1; col=1; ierr = MatSetValues(R,1,&row,1,&col,&one,ADD_VALUES);CHKERRQ(ierr); row = 1; col=2; ierr = MatSetValues(R,1,&row,1,&col,&one,ADD_VALUES);CHKERRQ(ierr); row = 1; col=3; ierr = MatSetValues(R,1,&row,1,&col,&one,ADD_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(R,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(R,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(R,"R_");CHKERRQ(ierr); ierr = MatView(R,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n");CHKERRQ(ierr); /* C = A*R^T */ ierr = MatMatTransposeMult(A,R,MAT_INITIAL_MATRIX,2.0,&C);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(C,"ARt_");CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n");CHKERRQ(ierr); /* Create MatTransposeColoring from symbolic C=A*R^T */ ierr = MatColoringCreate(C,&mc);CHKERRQ(ierr); ierr = MatColoringSetDistance(mc,2);CHKERRQ(ierr); /* ierr = MatColoringSetType(mc,MATCOLORINGSL);CHKERRQ(ierr); */ ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); ierr = MatColoringApply(mc,&iscoloring);CHKERRQ(ierr); ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); ierr = MatTransposeColoringCreate(C,iscoloring,&matcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); /* Create Rt_dense */ ierr = MatCreate(PETSC_COMM_WORLD,&Rt_dense);CHKERRQ(ierr); ierr = MatSetSizes(Rt_dense,4,matcoloring->ncolors,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(Rt_dense,MATDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(Rt_dense,NULL);CHKERRQ(ierr); ierr = MatAssemblyBegin(Rt_dense,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Rt_dense,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatGetLocalSize(Rt_dense,&m,&n);CHKERRQ(ierr); printf("Rt_dense: %d,%d\n",(int)m,(int)n); /* Get Rt_dense by Apply MatTransposeColoring to R */ ierr = MatTransColoringApplySpToDen(matcoloring,R,Rt_dense);CHKERRQ(ierr); /* C_dense = A*Rt_dense */ ierr = MatMatMult(A,Rt_dense,MAT_INITIAL_MATRIX,2.0,&C_dense);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(C_dense,"ARt_dense_");CHKERRQ(ierr); /*ierr = MatView(C_dense,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */ /*ierr = PetscPrintf(PETSC_COMM_SELF,"\n");CHKERRQ(ierr); */ /* Recover C from C_dense */ ierr = MatDuplicate(C,MAT_DO_NOT_COPY_VALUES,&C_sparse);CHKERRQ(ierr); ierr = MatTransColoringApplyDenToSp(matcoloring,C_dense,C_sparse);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(C_sparse,"ARt_color_");CHKERRQ(ierr); ierr = MatView(C_sparse,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n");CHKERRQ(ierr); ierr = MatDestroy(&C_dense);CHKERRQ(ierr); ierr = MatDestroy(&C_sparse);CHKERRQ(ierr); ierr = MatDestroy(&Rt_dense);CHKERRQ(ierr); ierr = MatTransposeColoringDestroy(&matcoloring);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); /* Test PtAP = P^T*A*P, P = R^T */ ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&P);CHKERRQ(ierr); ierr = MatPtAP(A,P,MAT_INITIAL_MATRIX,2.0,&PtAP);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(PtAP,"PtAP_");CHKERRQ(ierr); ierr = MatView(PtAP,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&P);CHKERRQ(ierr); /* Test C = RARt */ ierr = MatRARt(A,R,MAT_INITIAL_MATRIX,2.0,&C);CHKERRQ(ierr); ierr = MatRARt(A,R,MAT_REUSE_MATRIX,2.0,&C);CHKERRQ(ierr); ierr = MatEqual(C,PtAP,&equal);CHKERRQ(ierr); if (!equal) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: PtAP != RARt");CHKERRQ(ierr); } /* Free spaces */ ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&R);CHKERRQ(ierr); ierr = MatDestroy(&PtAP);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
/* Developer Notes: This should be implemented with a MatCreate_SchurComplement() as that is the standard design for new Mat classes. */ PetscErrorCode MatGetSchurComplement_Basic(Mat mat,IS isrow0,IS iscol0,IS isrow1,IS iscol1,MatReuse mreuse,Mat *newmat,MatReuse preuse,Mat *newpmat) { PetscErrorCode ierr; Mat A=0,Ap=0,B=0,C=0,D=0; PetscFunctionBegin; PetscValidHeaderSpecific(mat,MAT_CLASSID,1); PetscValidHeaderSpecific(isrow0,IS_CLASSID,2); PetscValidHeaderSpecific(iscol0,IS_CLASSID,3); PetscValidHeaderSpecific(isrow1,IS_CLASSID,4); PetscValidHeaderSpecific(iscol1,IS_CLASSID,5); if (mreuse == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,7); if (preuse == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newpmat,MAT_CLASSID,9); PetscValidType(mat,1); if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); if (mreuse != MAT_IGNORE_MATRIX) { /* Use MatSchurComplement */ if (mreuse == MAT_REUSE_MATRIX) { ierr = MatSchurComplementGetSubmatrices(*newmat,&A,&Ap,&B,&C,&D);CHKERRQ(ierr); if (!A || !Ap || !B || !C) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Attempting to reuse matrix but Schur complement matrices unset"); if (A != Ap) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Preconditioning matrix does not match operator"); ierr = MatDestroy(&Ap);CHKERRQ(ierr); /* get rid of extra reference */ } ierr = MatGetSubMatrix(mat,isrow0,iscol0,mreuse,&A);CHKERRQ(ierr); ierr = MatGetSubMatrix(mat,isrow0,iscol1,mreuse,&B);CHKERRQ(ierr); ierr = MatGetSubMatrix(mat,isrow1,iscol0,mreuse,&C);CHKERRQ(ierr); ierr = MatGetSubMatrix(mat,isrow1,iscol1,mreuse,&D);CHKERRQ(ierr); switch (mreuse) { case MAT_INITIAL_MATRIX: ierr = MatCreateSchurComplement(A,A,B,C,D,newmat);CHKERRQ(ierr); break; case MAT_REUSE_MATRIX: ierr = MatSchurComplementUpdate(*newmat,A,A,B,C,D,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); break; default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Unrecognized value of mreuse"); } } if (preuse != MAT_IGNORE_MATRIX) { /* Use the diagonal part of A to form D - C inv(diag(A)) B */ Mat Ad,AdB,S; Vec diag; PetscInt i,m,n,mstart,mend; PetscScalar *x; /* We could compose these with newpmat so that the matrices can be reused. */ if (!A) {ierr = MatGetSubMatrix(mat,isrow0,iscol0,MAT_INITIAL_MATRIX,&A);CHKERRQ(ierr);} if (!B) {ierr = MatGetSubMatrix(mat,isrow0,iscol1,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr);} if (!C) {ierr = MatGetSubMatrix(mat,isrow1,iscol0,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr);} if (!D) {ierr = MatGetSubMatrix(mat,isrow1,iscol1,MAT_INITIAL_MATRIX,&D);CHKERRQ(ierr);} ierr = MatGetVecs(A,&diag,PETSC_NULL);CHKERRQ(ierr); ierr = MatGetDiagonal(A,diag);CHKERRQ(ierr); ierr = VecReciprocal(diag);CHKERRQ(ierr); ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); /* We need to compute S = D - C inv(diag(A)) B. For row-oriented formats, it is easy to scale the rows of B and * for column-oriented formats the columns of C can be scaled. Would skip creating a silly diagonal matrix. */ ierr = MatCreate(((PetscObject)A)->comm,&Ad);CHKERRQ(ierr); ierr = MatSetSizes(Ad,m,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(Ad,((PetscObject)mat)->prefix);CHKERRQ(ierr); ierr = MatAppendOptionsPrefix(Ad,"diag_");CHKERRQ(ierr); ierr = MatSetFromOptions(Ad);CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(Ad,1,PETSC_NULL);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(Ad,1,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr); ierr = MatGetOwnershipRange(Ad,&mstart,&mend);CHKERRQ(ierr); ierr = VecGetArray(diag,&x);CHKERRQ(ierr); for (i=mstart; i<mend; i++) { ierr = MatSetValue(Ad,i,i,x[i-mstart],INSERT_VALUES);CHKERRQ(ierr); } ierr = VecRestoreArray(diag,&x);CHKERRQ(ierr); ierr = MatAssemblyBegin(Ad,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Ad,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecDestroy(&diag);CHKERRQ(ierr); ierr = MatMatMult(Ad,B,MAT_INITIAL_MATRIX,1,&AdB);CHKERRQ(ierr); S = (preuse == MAT_REUSE_MATRIX) ? *newpmat : (Mat)0; ierr = MatMatMult(C,AdB,preuse,PETSC_DEFAULT,&S);CHKERRQ(ierr); ierr = MatAYPX(S,-1,D,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); *newpmat = S; ierr = MatDestroy(&Ad);CHKERRQ(ierr); ierr = MatDestroy(&AdB);CHKERRQ(ierr); } ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&D);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat A,Asp; PetscViewer fd; /* viewer */ char file[PETSC_MAX_PATH_LEN]; /* input file name */ PetscErrorCode ierr; PetscInt m,n,rstart,rend; PetscBool flg; PetscInt row,ncols,j,nrows,nnzA=0,nnzAsp=0; const PetscInt *cols; const PetscScalar *vals; PetscReal norm,percent,val,dtol=1.e-16; PetscMPIInt rank; MatInfo matinfo; PetscInt Dnnz,Onnz; PetscInitialize(&argc,&args,(char *)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); /* Determine files from which we read the linear systems. */ ierr = PetscOptionsGetString(PETSC_NULL,"-f",file,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate binary file with the -f option"); /* Open binary file. Note that we use FILE_MODE_READ to indicate reading from this file. */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); /* Load the matrix; then destroy the viewer. */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(A,"a_");CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatLoad(A,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); ierr = MatGetInfo(A,MAT_LOCAL,&matinfo);CHKERRQ(ierr); //printf("matinfo.nz_used %g\n",matinfo.nz_used); /* Get a sparse matrix Asp by dumping zero entries of A */ ierr = MatCreate(PETSC_COMM_WORLD,&Asp);CHKERRQ(ierr); ierr = MatSetSizes(Asp,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(Asp,"asp_");CHKERRQ(ierr); ierr = MatSetFromOptions(Asp);CHKERRQ(ierr); Dnnz = (PetscInt)matinfo.nz_used/m + 1; Onnz = Dnnz/2; printf("Dnnz %d %d\n",Dnnz,Onnz); ierr = MatSeqAIJSetPreallocation(Asp,Dnnz,PETSC_NULL);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(Asp,Dnnz,PETSC_NULL,Onnz,PETSC_NULL);CHKERRQ(ierr); /* Check zero rows */ ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); nrows = 0; for (row=rstart; row<rend; row++){ ierr = MatGetRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); nnzA += ncols; norm = 0.0; for (j=0; j<ncols; j++){ val = PetscAbsScalar(vals[j]); if (norm < val) norm = norm; if (val > dtol){ ierr = MatSetValues(Asp,1,&row,1,&cols[j],&vals[j],INSERT_VALUES);CHKERRQ(ierr); nnzAsp++; } } if (!norm) nrows++; ierr = MatRestoreRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); } ierr = MatAssemblyBegin(Asp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Asp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); percent=(PetscReal)nnzA*100/(m*n); ierr = PetscPrintf(PETSC_COMM_SELF," [%d] Matrix A local size %d,%d; nnzA %d, %g percent; No. of zero rows: %d\n",rank,m,n,nnzA,percent,nrows); percent=(PetscReal)nnzAsp*100/(m*n); ierr = PetscPrintf(PETSC_COMM_SELF," [%d] Matrix Asp nnzAsp %d, %g percent\n",rank,nnzAsp,percent); /* investigate matcoloring for Asp */ PetscBool Asp_coloring = PETSC_FALSE; ierr = PetscOptionsHasName(PETSC_NULL,"-Asp_color",&Asp_coloring);CHKERRQ(ierr); if (Asp_coloring){ ISColoring iscoloring; MatFDColoring matfdcoloring; ierr = PetscPrintf(PETSC_COMM_WORLD," Create coloring of Asp...\n"); ierr = MatGetColoring(Asp,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(Asp,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); //ierr = MatFDColoringView(matfdcoloring,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); } /* Write Asp in binary for study - see ~petsc/src/mat/examples/tests/ex124.c */ PetscBool Asp_write = PETSC_FALSE; ierr = PetscOptionsHasName(PETSC_NULL,"-Asp_write",&Asp_write);CHKERRQ(ierr); if (Asp_write){ PetscViewer viewer; ierr = PetscPrintf(PETSC_COMM_SELF,"Write Asp into file Asp.dat ...\n"); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"Asp.dat",FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = MatView(Asp,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&Asp);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) { PetscErrorCode ierr; PetscInt nr,rbs,nc,cbs; Mat_IS *is = (Mat_IS*)A->data; IS from,to; Vec cglobal,rglobal; PetscFunctionBegin; PetscCheckSameComm(A,1,rmapping,2); PetscCheckSameComm(A,1,cmapping,3); /* Destroy any previous data */ ierr = VecDestroy(&is->x);CHKERRQ(ierr); ierr = VecDestroy(&is->y);CHKERRQ(ierr); ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); ierr = MatDestroy(&is->A);CHKERRQ(ierr); ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); /* Setup Layout and set local to global maps */ ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); /* Create the local matrix A */ ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); /* Create the local work vectors */ ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); /* setup the global to local scatters */ ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); if (rmapping != cmapping) { ierr = ISDestroy(&to);CHKERRQ(ierr); ierr = ISDestroy(&from);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); } else { ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); is->cctx = is->rctx; } ierr = VecDestroy(&rglobal);CHKERRQ(ierr); ierr = VecDestroy(&cglobal);CHKERRQ(ierr); ierr = ISDestroy(&to);CHKERRQ(ierr); ierr = ISDestroy(&from);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { Mat A,B,C,D; PetscScalar a[]= {1.,1.,0.,0.,1.,1.,0.,0.,1.}; PetscInt ij[]= {0,1,2}; PetscScalar none=-1.; PetscErrorCode ierr; PetscReal fill=4; PetscReal norm; PetscInitialize(&argc,&argv,(char *)0,help); ierr = MatCreate(PETSC_COMM_SELF,&A); CHKERRQ(ierr); ierr = MatSetSizes(A,3,3,3,3); CHKERRQ(ierr); ierr = MatSetType(A,MATSEQAIJ); CHKERRQ(ierr); ierr = MatSetUp(A); CHKERRQ(ierr); ierr = MatSetOption(A,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE); CHKERRQ(ierr); ierr = MatSetValues(A,3,ij,3,ij,a,ADD_VALUES); CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(A,"A_"); CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); /* Test MatMatMult() */ ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B); CHKERRQ(ierr); /* B = A^T */ ierr = MatMatMult(B,A,MAT_INITIAL_MATRIX,fill,&C); CHKERRQ(ierr); /* C = B*A */ ierr = MatSetOptionsPrefix(C,"C=B*A=A^T*A_"); CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); ierr = MatMatMultSymbolic(C,A,fill,&D); CHKERRQ(ierr); ierr = MatMatMultNumeric(C,A,D); CHKERRQ(ierr); /* D = C*A = (A^T*A)*A */ ierr = MatSetOptionsPrefix(D,"D=C*A=(A^T*A)*A_"); CHKERRQ(ierr); ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); /* Repeat the numeric product to test reuse of the previous symbolic product */ ierr = MatMatMultNumeric(C,A,D); CHKERRQ(ierr); ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); ierr = MatDestroy(&B); CHKERRQ(ierr); ierr = MatDestroy(&C); CHKERRQ(ierr); /* Test PtAP routine. */ ierr = MatDuplicate(A,MAT_COPY_VALUES,&B); CHKERRQ(ierr); /* B = A */ ierr = MatPtAP(A,B,MAT_INITIAL_MATRIX,fill,&C); CHKERRQ(ierr); /* C = B^T*A*B */ ierr = MatAXPY(D,none,C,DIFFERENT_NONZERO_PATTERN); CHKERRQ(ierr); ierr = MatNorm(D,NORM_FROBENIUS,&norm); if (norm > 1.e-15) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error in MatPtAP: %g\n",norm); } ierr = MatDestroy(&C); CHKERRQ(ierr); ierr = MatDestroy(&D); CHKERRQ(ierr); /* Repeat PtAP to test symbolic/numeric separation for reuse of the symbolic product */ ierr = MatPtAP(A,B,MAT_INITIAL_MATRIX,fill,&C); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(C,"C=BtAB_"); CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); ierr = MatPtAPSymbolic(A,B,fill,&D); CHKERRQ(ierr); ierr = MatPtAPNumeric(A,B,D); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(D,"D=BtAB_"); CHKERRQ(ierr); ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); /* Repeat numeric product to test reuse of the previous symbolic product */ ierr = MatPtAPNumeric(A,B,D); CHKERRQ(ierr); ierr = MatAXPY(D,none,C,DIFFERENT_NONZERO_PATTERN); CHKERRQ(ierr); ierr = MatNorm(D,NORM_FROBENIUS,&norm); if (norm > 1.e-15) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error in symbolic/numeric MatPtAP: %g\n",norm); } ierr = MatDestroy(&B); ierr = MatDestroy(&C); ierr = MatDestroy(&D); /* A test contributed by Tobias Neckel <*****@*****.**> */ ierr = testPTAPRectangular(); CHKERRQ(ierr); /* test MatMatTransposeMult(): A*B^T */ ierr = MatMatTransposeMult(A,A,MAT_INITIAL_MATRIX,fill,&D); CHKERRQ(ierr); /* D = A*A^T */ ierr = MatSetOptionsPrefix(D,"D=A*A^T_"); CHKERRQ(ierr); ierr = MatView(D,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B); CHKERRQ(ierr); /* B = A^T */ ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,fill,&C); CHKERRQ(ierr); /* C=A*B */ ierr = MatSetOptionsPrefix(C,"D=A*B=A*A^T_"); CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"\n"); CHKERRQ(ierr); ierr = MatDestroy(&A); ierr = MatDestroy(&B); ierr = MatDestroy(&C); ierr = MatDestroy(&D); PetscFinalize(); return(0); }
static PetscErrorCode ComputeSubdomainMatrix(DomainData dd, GLLData glldata, Mat *local_mat) { PetscErrorCode ierr; PetscInt localsize,zloc,yloc,xloc,auxnex,auxney,auxnez; PetscInt ie,je,ke,i,j,k,ig,jg,kg,ii,ming; PetscInt *indexg,*cols,*colsg; PetscScalar *vals; Mat temp_local_mat,elem_mat_DBC=0,*usedmat; IS submatIS; PetscFunctionBeginUser; ierr = MatGetSize(glldata.elem_mat,&i,&j);CHKERRQ(ierr); ierr = PetscMalloc1(i,&indexg);CHKERRQ(ierr); ierr = PetscMalloc1(i,&colsg);CHKERRQ(ierr); /* get submatrix of elem_mat without dirichlet nodes */ if (!dd.pure_neumann && !dd.DBC_zerorows && !dd.ipx) { xloc = dd.p+1; yloc = 1; zloc = 1; if (dd.dim>1) yloc = dd.p+1; if (dd.dim>2) zloc = dd.p+1; ii = 0; for (k=0;k<zloc;k++) { for (j=0;j<yloc;j++) { for (i=1;i<xloc;i++) { indexg[ii]=k*xloc*yloc+j*xloc+i; ii++; } } } ierr = ISCreateGeneral(PETSC_COMM_SELF,ii,indexg,PETSC_COPY_VALUES,&submatIS);CHKERRQ(ierr); ierr = MatGetSubMatrix(glldata.elem_mat,submatIS,submatIS,MAT_INITIAL_MATRIX,&elem_mat_DBC);CHKERRQ(ierr); ierr = ISDestroy(&submatIS);CHKERRQ(ierr); } /* Assemble subdomain matrix */ localsize = dd.xm_l*dd.ym_l*dd.zm_l; ierr = MatCreate(PETSC_COMM_SELF,&temp_local_mat);CHKERRQ(ierr); ierr = MatSetSizes(temp_local_mat,localsize,localsize,localsize,localsize);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(temp_local_mat,"subdomain_");CHKERRQ(ierr); /* set local matrices type: here we use SEQSBAIJ primarily for testing purpose */ /* in order to avoid conversions inside the BDDC code, use SeqAIJ if possible */ if (dd.DBC_zerorows && !dd.ipx) { /* in this case, we need to zero out some of the rows, so use seqaij */ ierr = MatSetType(temp_local_mat,MATSEQAIJ);CHKERRQ(ierr); } else { ierr = MatSetType(temp_local_mat,MATSEQSBAIJ);CHKERRQ(ierr); } ierr = MatSetFromOptions(temp_local_mat);CHKERRQ(ierr); i = PetscPowRealInt(3.0*(dd.p+1.0),dd.dim); ierr = MatSeqAIJSetPreallocation(temp_local_mat,i,NULL);CHKERRQ(ierr); /* very overestimated */ ierr = MatSeqSBAIJSetPreallocation(temp_local_mat,1,i,NULL);CHKERRQ(ierr); /* very overestimated */ ierr = MatSetOption(temp_local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); yloc = dd.p+1; zloc = dd.p+1; if (dd.dim < 3) zloc = 1; if (dd.dim < 2) yloc = 1; auxnez = dd.nez_l; auxney = dd.ney_l; auxnex = dd.nex_l; if (dd.dim < 3) auxnez = 1; if (dd.dim < 2) auxney = 1; for (ke=0; ke<auxnez; ke++) { for (je=0; je<auxney; je++) { for (ie=0; ie<auxnex; ie++) { /* customize element accounting for BC */ xloc = dd.p+1; ming = 0; usedmat = &glldata.elem_mat; if (!dd.pure_neumann && !dd.DBC_zerorows && !dd.ipx) { if (ie == 0) { xloc = dd.p; usedmat = &elem_mat_DBC; } else { ming = -1; usedmat = &glldata.elem_mat; } } /* local to the element/global to the subdomain indexing */ for (k=0; k<zloc; k++) { kg = ke*dd.p+k; for (j=0; j<yloc; j++) { jg = je*dd.p+j; for (i=0; i<xloc; i++) { ig = ie*dd.p+i+ming; ii = k*xloc*yloc+j*xloc+i; indexg[ii] = kg*dd.xm_l*dd.ym_l+jg*dd.xm_l+ig; } } } /* Set values */ for (i=0; i<xloc*yloc*zloc; i++) { ierr = MatGetRow(*usedmat,i,&j,(const PetscInt**)&cols,(const PetscScalar**)&vals);CHKERRQ(ierr); for (k=0; k<j; k++) colsg[k] = indexg[cols[k]]; ierr = MatSetValues(temp_local_mat,1,&indexg[i],j,colsg,vals,ADD_VALUES);CHKERRQ(ierr); ierr = MatRestoreRow(*usedmat,i,&j,(const PetscInt**)&cols,(const PetscScalar**)&vals);CHKERRQ(ierr); } } } } ierr = PetscFree(indexg);CHKERRQ(ierr); ierr = PetscFree(colsg);CHKERRQ(ierr); ierr = MatAssemblyBegin(temp_local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd (temp_local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); #if DEBUG { Vec lvec,rvec; PetscReal norm; ierr = MatCreateVecs(temp_local_mat,&lvec,&rvec);CHKERRQ(ierr); ierr = VecSet(lvec,1.0);CHKERRQ(ierr); ierr = MatMult(temp_local_mat,lvec,rvec);CHKERRQ(ierr); ierr = VecNorm(rvec,NORM_INFINITY,&norm);CHKERRQ(ierr); printf("Test null space of local mat % 1.14e\n",norm); ierr = VecDestroy(&lvec);CHKERRQ(ierr); ierr = VecDestroy(&rvec);CHKERRQ(ierr); } #endif *local_mat = temp_local_mat; ierr = MatDestroy(&elem_mat_DBC);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **args) { PetscErrorCode ierr; Vec x, b, xexact; Mat A; KSP ksp; int m = 4, i, Istart, Iend, j[3]; double v[3], xval, errnorm; PetscInitialize(&argc,&args,NULL,help); ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"tri_","options for tri",""); CHKERRQ(ierr); ierr = PetscOptionsInt("-m","dimension of linear system","tri.c",m,&m,NULL); CHKERRQ(ierr); ierr = PetscOptionsEnd(); CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&x); CHKERRQ(ierr); ierr = VecSetSizes(x,PETSC_DECIDE,m); CHKERRQ(ierr); ierr = VecSetFromOptions(x); CHKERRQ(ierr); ierr = VecDuplicate(x,&b); CHKERRQ(ierr); ierr = VecDuplicate(x,&xexact); CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A); CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,m,m); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(A,"a_"); CHKERRQ(ierr); ierr = MatSetFromOptions(A); CHKERRQ(ierr); ierr = MatSetUp(A); CHKERRQ(ierr); //ENDSETUP ierr = MatGetOwnershipRange(A,&Istart,&Iend); CHKERRQ(ierr); for (i=Istart; i<Iend; i++) { if (i == 0) { v[0] = 3.0; v[1] = -1.0; j[0] = 0; j[1] = 1; ierr = MatSetValues(A,1,&i,2,j,v,INSERT_VALUES); CHKERRQ(ierr); } else { v[0] = -1.0; v[1] = 3.0; v[2] = -1.0; j[0] = i-1; j[1] = i; j[2] = i+1; if (i == m-1) { ierr = MatSetValues(A,1,&i,2,j,v,INSERT_VALUES); CHKERRQ(ierr); } else { ierr = MatSetValues(A,1,&i,3,j,v,INSERT_VALUES); CHKERRQ(ierr); } } xval = exp(cos(i)); ierr = VecSetValues(xexact,1,&i,&xval,INSERT_VALUES); CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = VecAssemblyBegin(xexact); CHKERRQ(ierr); ierr = VecAssemblyEnd(xexact); CHKERRQ(ierr); ierr = MatMult(A,xexact,b); CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp); CHKERRQ(ierr); ierr = KSPSetOperators(ksp,A,A); CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp); CHKERRQ(ierr); ierr = KSPSolve(ksp,b,x); CHKERRQ(ierr); ierr = VecAXPY(x,-1.0,xexact); CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&errnorm); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "error for m = %d system is |x-xexact|_2 = %.1e\n",m,errnorm); CHKERRQ(ierr); KSPDestroy(&ksp); MatDestroy(&A); VecDestroy(&x); VecDestroy(&b); VecDestroy(&xexact); PetscFinalize(); return 0; }