void createOuterPC(OuterContext* ctx) { PCCreate(((ctx->data)->commAll), &(ctx->outerPC)); PCSetType(ctx->outerPC, PCSHELL); PCShellSetName(ctx->outerPC, "RSD"); PCShellSetContext(ctx->outerPC, ctx); PCShellSetApply(ctx->outerPC, &outerPCapply); }
int main(int argc,char **args) { PC pc; PetscErrorCode ierr; PetscInt n = 5; Mat mat; ierr = PetscInitialize(&argc,&args,(char*)0,help); if (ierr) return ierr; ierr = PCCreate(PETSC_COMM_WORLD,&pc); CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE); CHKERRQ(ierr); /* Vector and matrix must be set before calling PCSetUp */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,n,n,3,NULL,&mat); CHKERRQ(ierr); ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = PCSetOperators(pc,mat,mat); CHKERRQ(ierr); ierr = PCSetUp(pc); CHKERRQ(ierr); ierr = MatDestroy(&mat); CHKERRQ(ierr); ierr = PCDestroy(&pc); CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode DMCoarsen_AKKT_GAMG11(DM dm, Mat P0f0c, Mat *P1f1c_out) { PetscErrorCode ierr; DM_AKKT* kkt = (DM_AKKT*)(dm->data); Mat Aff = kkt->Aff; /* fine-level KKT matrix */ Mat A1f0f; /* fine-level dual (constraint) Jacobian */ Mat A1f0c; /* = A1f0f*P0f0c coarsen only primal indices */ Mat B1f1f; /* = A1f0c'*A1f0c */ PC gamg11;/* Use PCGAMG internally to get access to some of its methods to operate on B1f1f = A1f0c*A1f0c', where A1f0c = A1f0f*P0f0c. */ PC_GAMG* pc_gamg11; Mat G1f1f; /* = Graph(B1f1f) */ Mat P1f1c; /* = Prolongator(G1f1f); */ PetscCoarsenData *coarsening; PetscFunctionBegin; /* What is faster: - A0c1f = P0f0c'*A0f1f followed by B1f1f = A0c1f'*A0c1f, or - A1f0c = A1f0f*P0f0c followed by B1f1f = A1f0c*A1f0c'? My bet is on the latter: - fewer transpositions inside MatMatMult and row indices are always local. */ ierr = MatGetSubMatrix(Aff, kkt->isf[1], kkt->isf[0], MAT_INITIAL_MATRIX, &A1f0f); CHKERRQ(ierr); if(kkt->transposeP) { ierr = MatMatTransposeMult(A1f0f,P0f0c,MAT_INITIAL_MATRIX, PETSC_DEFAULT, &A1f0c); CHKERRQ(ierr); } ierr = MatMatMult(A1f0f,P0f0c,MAT_INITIAL_MATRIX, PETSC_DEFAULT, &A1f0c); CHKERRQ(ierr); ierr = MatMatTransposeMult(A1f0c, A1f0c, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &B1f1f); CHKERRQ(ierr); /* We create PCGAMG here since it is only needed for coarsening and we don't want to have to carry the attendant data structures, if we don't need them. */ ierr = PCCreate(((PetscObject)dm)->comm, &gamg11); CHKERRQ(ierr); /* This must be an aggregating GAMG. */ ierr = PCSetType(gamg11, PCGAMG); CHKERRQ(ierr); ierr = PCGAMGSetSquareGraph(gamg11, PETSC_FALSE); CHKERRQ(ierr); /* Observe that we want to "square" A1f0c before passing it (B1f1f) to GAMG. This is not because we are not sure how GAMG will deal with a (potentially) non-square matrix, but rather because if we asked GAMG to square it, it would also smooth the resulting prolongator. At least PC_GAMG_AGG would, and we need an unsmoothed prolongator. */ ierr = PCSetOperators(gamg11, B1f1f, B1f1f, DIFFERENT_NONZERO_PATTERN); CHKERRQ(ierr); /* FIX: Currently there is no way to tell GAMG to coarsen onto a give comm, but it shouldn't be hard to hack that stuff in. */ pc_gamg11 = (PC_GAMG*)(gamg11->data); ierr = pc_gamg11->graph(gamg11, B1f1f, &G1f1f); CHKERRQ(ierr); ierr = pc_gamg11->coarsen(gamg11, &G1f1f, &coarsening); CHKERRQ(ierr); ierr = pc_gamg11->prolongator(gamg11, B1f1f, G1f1f, coarsening, &P1f1c); CHKERRQ(ierr); ierr = MatDestroy(&A1f0f); CHKERRQ(ierr); ierr = MatDestroy(&A1f0c); CHKERRQ(ierr); ierr = MatDestroy(&B1f1f); CHKERRQ(ierr); ierr = MatDestroy(&G1f1f); CHKERRQ(ierr); ierr = PCDestroy(&gamg11); CHKERRQ(ierr); *P1f1c_out = P1f1c; PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat mat; Vec b,u; PC pc; PetscErrorCode ierr; PetscInt n = 5,i,col[3]; PetscScalar value[3]; PetscInitialize(&argc,&args,(char *)0,help); /* Create vectors */ ierr = VecCreateSeq(PETSC_COMM_SELF,n,&b);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,n,&u);CHKERRQ(ierr); /* Create and assemble matrix */ ierr = MatCreateSeqDense(PETSC_COMM_SELF,n,n,PETSC_NULL,&mat);CHKERRQ(ierr); value[0] = -1.0; value[1] = 2.0; value[2] = -1.0; for (i=1; i<n-1; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(mat,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = n - 1; col[0] = n - 2; col[1] = n - 1; ierr = MatSetValues(mat,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = 0; col[1] = 1; value[0] = 2.0; value[1] = -1.0; ierr = MatSetValues(mat,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Create PC context and set up data structures */ ierr = PCCreate(PETSC_COMM_WORLD,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCSOR);CHKERRQ(ierr); ierr = PCSetFromOptions(pc);CHKERRQ(ierr); ierr = PCSetOperators(pc,mat,mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = PCSetUp(pc);CHKERRQ(ierr); value[0] = 1.0; for (i=0; i<n; i++) { ierr = VecSet(u,0.0);CHKERRQ(ierr); ierr = VecSetValues(u,1,&i,value,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(u);CHKERRQ(ierr); ierr = VecAssemblyEnd(u);CHKERRQ(ierr); ierr = PCApply(pc,u,b);CHKERRQ(ierr); ierr = VecView(b,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } /* Free data structures */ ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = PCDestroy(&pc);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
MGSolver_PETScData* MultigridSolver_CreateCoarseSolver( MultigridSolver* self, Mat matrix ) { //MatrixSolver* coarseSolver; MGSolver_PETScData* courseSolver; unsigned nProcs; PC pc; MPI_Comm_size( self->mgData->comm, (int*)&nProcs ); /* coarseSolver = (MatrixSolver*)PETScMatrixSolver_New( "" ); PETScMatrixSolver_SetKSPType( coarseSolver, PETScMatrixSolver_KSPType_PreOnly ); if( nProcs == 1 ) { PETScMatrixSolver_SetPCType( coarseSolver, PETScMatrixSolver_PCType_LU ); } else { PETScMatrixSolver_SetPCType( coarseSolver, PETScMatrixSolver_PCType_RedundantLU ); } MatrixSolver_SetMatrix( coarseSolver, matrix ); */ if( nProcs == 1 ){ KSPCreate( MPI_COMM_WORLD, &courseSolver->ksp ); KSPSetType( courseSolver->ksp, KSPPREONLY ); KSPGetPC( courseSolver->ksp, &pc ); PCSetType( pc, PCLU ); } else { PCSetType( pc, PCREDUNDANT ); #if ((PETSC_VERSION_MAJOR>=3) && (PETSC_VERSION_MINOR>=2) ) PCCreate( MPI_COMM_WORLD, &pc); PCRedundantGetKSP( pc, &courseSolver->ksp ); #else KSPCreate( MPI_COMM_WORLD, &courseSolver->ksp ); KSPSetType( courseSolver->ksp, KSPPREONLY ); KSPGetPC( courseSolver->ksp, &pc ); PCRedundantGetPC( pc, &pc ); #endif PCSetType( pc, PCLU ); } if( courseSolver->matrix != PETSC_NULL ){ Stg_MatDestroy(&courseSolver->matrix );} courseSolver->matrix = matrix; Stg_KSPSetOperators( courseSolver->ksp, matrix, matrix, DIFFERENT_NONZERO_PATTERN ); return courseSolver; }
int main(int argc,char **args) { Mat C,A; PetscInt i,j; PetscErrorCode ierr; PetscScalar v; PC pc; Vec xtmp; PetscInitialize(&argc,&args,(char*)0,help); ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr); ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,3,3);CHKERRQ(ierr); ierr = MatSetFromOptions(C);CHKERRQ(ierr); ierr = MatSetUp(C);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_WORLD,3,&xtmp);CHKERRQ(ierr); i = 0; j = 0; v = 4; ierr = MatSetValues(C,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); i = 0; j = 2; v = 1; ierr = MatSetValues(C,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); i = 1; j = 0; v = 1; ierr = MatSetValues(C,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); i = 1; j = 1; v = 4; ierr = MatSetValues(C,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); i = 2; j = 1; v = 1; ierr = MatSetValues(C,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PCCreate(PETSC_COMM_WORLD,&pc);CHKERRQ(ierr); ierr = PCSetFromOptions(pc);CHKERRQ(ierr); ierr = PCSetOperators(pc,C,C,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = PCSetUp(pc);CHKERRQ(ierr); ierr = PCFactorGetMatrix(pc,&A);CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PCDestroy(&pc);CHKERRQ(ierr); ierr = VecDestroy(&xtmp);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { PC pc; PetscErrorCode ierr; PetscInt n = 5; Mat mat; PetscInitialize(&argc,&args,(char *)0,help); ierr = PCCreate(PETSC_COMM_WORLD,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); /* Vector and matrix must be set before calling PCSetUp */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,n,n,3,PETSC_NULL,&mat);CHKERRQ(ierr); ierr = PCSetOperators(pc,mat,mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = PCSetUp(pc);CHKERRQ(ierr); ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = PCDestroy(&pc); CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
void PetscPreconditioner<T>::init () { if(!this->_matrix) { libMesh::err << "ERROR: No matrix set for PetscPreconditioner, but init() called" << std::endl; libmesh_error(); } // Clear the preconditioner in case it has been created in the past if (!this->_is_initialized) { // Should probably use PCReset(), but it's not working at the moment so we'll destroy instead if (_pc) { int ierr = LibMeshPCDestroy(&_pc); LIBMESH_CHKERRABORT(ierr); } int ierr = PCCreate(this->comm().get(),&_pc); LIBMESH_CHKERRABORT(ierr); PetscMatrix<T> * pmatrix = libmesh_cast_ptr<PetscMatrix<T>*, SparseMatrix<T> >(this->_matrix); _mat = pmatrix->mat(); } int ierr = PCSetOperators(_pc,_mat,_mat,SAME_NONZERO_PATTERN); LIBMESH_CHKERRABORT(ierr); // Set the PCType. Note: this used to be done *before* the call to // PCSetOperators(), and only when !_is_initialized, but // 1.) Some preconditioners (those employing sub-preconditioners, // for example) have to call PCSetUp(), and can only do this after // the operators have been set. // 2.) It should be safe to call set_petsc_preconditioner_type() // multiple times. set_petsc_preconditioner_type(this->_preconditioner_type, _pc); this->_is_initialized = true; }
// ================================================= void PetscPreconditioner::init() { if(!this->_matrix) { std::cerr << "ERROR: No matrix set for PetscPreconditioner, but init() called" << std::endl; abort(); } //Clear the preconditioner in case it has been created in the past if(!this->_is_initialized) { //Create the preconditioning object PCCreate(MPI_COMM_WORLD, &_pc); //Set the PCType set_petsc_preconditioner_type(this->_preconditioner_type, _pc); // #ifdef LIBMESH_HAVE_PETSC_HYPRE // if(this->_preconditioner_type == AMG_PRECOND) // PCHYPRESetType(this->_pc, "boomerang"); // #endif PetscMatrix * pmatrix = libmeshM_cast_ptr<PetscMatrix*, SparseMatrix >(this->_matrix); _mat = pmatrix->mat(); } //PCSetOperators(_pc,_mat,_mat,SAME_NONZERO_PATTERN); PCSetOperators(_pc, _mat, _mat); //PETSC3p5 this->_is_initialized = true; }
static PetscErrorCode PCCompositeAddPC_Composite(PC pc,PCType type) { PC_Composite *jac; PC_CompositeLink next,ilink; PetscErrorCode ierr; PetscInt cnt = 0; const char *prefix; char newprefix[8]; PetscFunctionBegin; ierr = PetscNewLog(pc,&ilink);CHKERRQ(ierr); ilink->next = 0; ierr = PCCreate(PetscObjectComm((PetscObject)pc),&ilink->pc);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilink->pc);CHKERRQ(ierr); jac = (PC_Composite*)pc->data; next = jac->head; if (!next) { jac->head = ilink; ilink->previous = NULL; } else { cnt++; while (next->next) { next = next->next; cnt++; } next->next = ilink; ilink->previous = next; } ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); ierr = PCSetOptionsPrefix(ilink->pc,prefix);CHKERRQ(ierr); sprintf(newprefix,"sub_%d_",(int)cnt); ierr = PCAppendOptionsPrefix(ilink->pc,newprefix);CHKERRQ(ierr); /* type is set after prefix, because some methods may modify prefix, e.g. pcksp */ ierr = PCSetType(ilink->pc,type);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode PCBDDCNullSpaceAssembleCorrection(PC pc, PetscBool isdir, IS local_dofs) { PC_BDDC *pcbddc = (PC_BDDC*)pc->data; PC_IS *pcis = (PC_IS*)pc->data; Mat_IS* matis = (Mat_IS*)pc->pmat->data; KSP local_ksp; PC newpc; NullSpaceCorrection_ctx shell_ctx; Mat local_mat,local_pmat,small_mat,inv_small_mat; Vec work1,work2; const Vec *nullvecs; VecScatter scatter_ctx; IS is_aux; MatFactorInfo matinfo; PetscScalar *basis_mat,*Kbasis_mat,*array,*array_mat; PetscScalar one = 1.0,zero = 0.0, m_one = -1.0; PetscInt basis_dofs,basis_size,nnsp_size,i,k; PetscBool nnsp_has_cnst; PetscErrorCode ierr; PetscFunctionBegin; /* Infer the local solver */ ierr = ISGetSize(local_dofs,&basis_dofs);CHKERRQ(ierr); if (isdir) { /* Dirichlet solver */ local_ksp = pcbddc->ksp_D; } else { /* Neumann solver */ local_ksp = pcbddc->ksp_R; } ierr = KSPGetOperators(local_ksp,&local_mat,&local_pmat);CHKERRQ(ierr); /* Get null space vecs */ ierr = MatNullSpaceGetVecs(pcbddc->NullSpace,&nnsp_has_cnst,&nnsp_size,&nullvecs);CHKERRQ(ierr); basis_size = nnsp_size; if (nnsp_has_cnst) { basis_size++; } if (basis_dofs) { /* Create shell ctx */ ierr = PetscNew(&shell_ctx);CHKERRQ(ierr); /* Create work vectors in shell context */ ierr = VecCreate(PETSC_COMM_SELF,&shell_ctx->work_small_1);CHKERRQ(ierr); ierr = VecSetSizes(shell_ctx->work_small_1,basis_size,basis_size);CHKERRQ(ierr); ierr = VecSetType(shell_ctx->work_small_1,VECSEQ);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_small_1,&shell_ctx->work_small_2);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,&shell_ctx->work_full_1);CHKERRQ(ierr); ierr = VecSetSizes(shell_ctx->work_full_1,basis_dofs,basis_dofs);CHKERRQ(ierr); ierr = VecSetType(shell_ctx->work_full_1,VECSEQ);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&shell_ctx->work_full_2);CHKERRQ(ierr); /* Allocate workspace */ ierr = MatCreateSeqDense(PETSC_COMM_SELF,basis_dofs,basis_size,NULL,&shell_ctx->basis_mat );CHKERRQ(ierr); ierr = MatCreateSeqDense(PETSC_COMM_SELF,basis_dofs,basis_size,NULL,&shell_ctx->Kbasis_mat);CHKERRQ(ierr); ierr = MatDenseGetArray(shell_ctx->basis_mat,&basis_mat);CHKERRQ(ierr); ierr = MatDenseGetArray(shell_ctx->Kbasis_mat,&Kbasis_mat);CHKERRQ(ierr); /* Restrict local null space on selected dofs (Dirichlet or Neumann) and compute matrices N and K*N */ ierr = VecDuplicate(shell_ctx->work_full_1,&work1);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&work2);CHKERRQ(ierr); ierr = VecScatterCreate(pcis->vec1_N,local_dofs,work1,(IS)0,&scatter_ctx);CHKERRQ(ierr); } for (k=0;k<nnsp_size;k++) { ierr = VecScatterBegin(matis->rctx,nullvecs[k],pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(matis->rctx,nullvecs[k],pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); if (basis_dofs) { ierr = VecPlaceArray(work1,(const PetscScalar*)&basis_mat[k*basis_dofs]);CHKERRQ(ierr); ierr = VecScatterBegin(scatter_ctx,pcis->vec1_N,work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(scatter_ctx,pcis->vec1_N,work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecPlaceArray(work2,(const PetscScalar*)&Kbasis_mat[k*basis_dofs]);CHKERRQ(ierr); ierr = MatMult(local_mat,work1,work2);CHKERRQ(ierr); ierr = VecResetArray(work1);CHKERRQ(ierr); ierr = VecResetArray(work2);CHKERRQ(ierr); } } if (basis_dofs) { if (nnsp_has_cnst) { ierr = VecPlaceArray(work1,(const PetscScalar*)&basis_mat[k*basis_dofs]);CHKERRQ(ierr); ierr = VecSet(work1,one);CHKERRQ(ierr); ierr = VecPlaceArray(work2,(const PetscScalar*)&Kbasis_mat[k*basis_dofs]);CHKERRQ(ierr); ierr = MatMult(local_mat,work1,work2);CHKERRQ(ierr); ierr = VecResetArray(work1);CHKERRQ(ierr); ierr = VecResetArray(work2);CHKERRQ(ierr); } ierr = VecDestroy(&work1);CHKERRQ(ierr); ierr = VecDestroy(&work2);CHKERRQ(ierr); ierr = VecScatterDestroy(&scatter_ctx);CHKERRQ(ierr); ierr = MatDenseRestoreArray(shell_ctx->basis_mat,&basis_mat);CHKERRQ(ierr); ierr = MatDenseRestoreArray(shell_ctx->Kbasis_mat,&Kbasis_mat);CHKERRQ(ierr); /* Assemble another Mat object in shell context */ ierr = MatTransposeMatMult(shell_ctx->basis_mat,shell_ctx->Kbasis_mat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&small_mat);CHKERRQ(ierr); ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,basis_size,0,1,&is_aux);CHKERRQ(ierr); ierr = MatLUFactor(small_mat,is_aux,is_aux,&matinfo);CHKERRQ(ierr); ierr = ISDestroy(&is_aux);CHKERRQ(ierr); ierr = PetscMalloc1(basis_size*basis_size,&array_mat);CHKERRQ(ierr); for (k=0;k<basis_size;k++) { ierr = VecSet(shell_ctx->work_small_1,zero);CHKERRQ(ierr); ierr = VecSetValue(shell_ctx->work_small_1,k,one,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(shell_ctx->work_small_1);CHKERRQ(ierr); ierr = VecAssemblyEnd(shell_ctx->work_small_1);CHKERRQ(ierr); ierr = MatSolve(small_mat,shell_ctx->work_small_1,shell_ctx->work_small_2);CHKERRQ(ierr); ierr = VecGetArrayRead(shell_ctx->work_small_2,(const PetscScalar**)&array);CHKERRQ(ierr); for (i=0;i<basis_size;i++) { array_mat[i*basis_size+k]=array[i]; } ierr = VecRestoreArrayRead(shell_ctx->work_small_2,(const PetscScalar**)&array);CHKERRQ(ierr); } ierr = MatCreateSeqDense(PETSC_COMM_SELF,basis_size,basis_size,array_mat,&inv_small_mat);CHKERRQ(ierr); ierr = MatMatMult(shell_ctx->basis_mat,inv_small_mat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&shell_ctx->Lbasis_mat);CHKERRQ(ierr); ierr = PetscFree(array_mat);CHKERRQ(ierr); ierr = MatDestroy(&inv_small_mat);CHKERRQ(ierr); ierr = MatDestroy(&small_mat);CHKERRQ(ierr); ierr = MatScale(shell_ctx->Kbasis_mat,m_one);CHKERRQ(ierr); /* Rebuild local PC */ ierr = KSPGetPC(local_ksp,&shell_ctx->local_pc);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)shell_ctx->local_pc);CHKERRQ(ierr); ierr = PCCreate(PETSC_COMM_SELF,&newpc);CHKERRQ(ierr); ierr = PCSetOperators(newpc,local_mat,local_mat);CHKERRQ(ierr); ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); ierr = PCShellSetContext(newpc,shell_ctx);CHKERRQ(ierr); ierr = PCShellSetApply(newpc,PCBDDCApplyNullSpaceCorrectionPC);CHKERRQ(ierr); ierr = PCShellSetDestroy(newpc,PCBDDCDestroyNullSpaceCorrectionPC);CHKERRQ(ierr); ierr = PCSetUp(newpc);CHKERRQ(ierr); ierr = KSPSetPC(local_ksp,newpc);CHKERRQ(ierr); ierr = PCDestroy(&newpc);CHKERRQ(ierr); ierr = KSPSetUp(local_ksp);CHKERRQ(ierr); } /* test */ if (pcbddc->dbg_flag && basis_dofs) { KSP check_ksp; PC check_pc; Mat test_mat; Vec work3; PetscReal test_err,lambda_min,lambda_max; PetscBool setsym,issym=PETSC_FALSE; PetscInt tabs; ierr = PetscViewerASCIIGetTab(pcbddc->dbg_viewer,&tabs);CHKERRQ(ierr); ierr = KSPGetPC(local_ksp,&check_pc);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&work1);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&work2);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&work3);CHKERRQ(ierr); ierr = VecSetRandom(shell_ctx->work_small_1,NULL);CHKERRQ(ierr); ierr = MatMult(shell_ctx->basis_mat,shell_ctx->work_small_1,work1);CHKERRQ(ierr); ierr = VecCopy(work1,work2);CHKERRQ(ierr); ierr = MatMult(local_mat,work1,work3);CHKERRQ(ierr); ierr = PCApply(check_pc,work3,work1);CHKERRQ(ierr); ierr = VecAXPY(work1,m_one,work2);CHKERRQ(ierr); ierr = VecNorm(work1,NORM_INFINITY,&test_err);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d error for nullspace correction for ",PetscGlobalRank);CHKERRQ(ierr); ierr = PetscViewerASCIIUseTabs(pcbddc->dbg_viewer,PETSC_FALSE);CHKERRQ(ierr); if (isdir) { ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Dirichlet ");CHKERRQ(ierr); } else { ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Neumann ");CHKERRQ(ierr); } ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"solver is :%1.14e\n",test_err);CHKERRQ(ierr); ierr = PetscViewerASCIISetTab(pcbddc->dbg_viewer,tabs);CHKERRQ(ierr); ierr = PetscViewerASCIIUseTabs(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); ierr = MatTransposeMatMult(shell_ctx->Lbasis_mat,shell_ctx->Kbasis_mat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&test_mat);CHKERRQ(ierr); ierr = MatShift(test_mat,one);CHKERRQ(ierr); ierr = MatNorm(test_mat,NORM_INFINITY,&test_err);CHKERRQ(ierr); ierr = MatDestroy(&test_mat);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d error for nullspace matrices is :%1.14e\n",PetscGlobalRank,test_err);CHKERRQ(ierr); /* Create ksp object suitable for extreme eigenvalues' estimation */ ierr = KSPCreate(PETSC_COMM_SELF,&check_ksp);CHKERRQ(ierr); ierr = KSPSetErrorIfNotConverged(check_ksp,pc->erroriffailure);CHKERRQ(ierr); ierr = KSPSetOperators(check_ksp,local_mat,local_mat);CHKERRQ(ierr); ierr = KSPSetTolerances(check_ksp,1.e-8,1.e-8,PETSC_DEFAULT,basis_dofs);CHKERRQ(ierr); ierr = KSPSetComputeSingularValues(check_ksp,PETSC_TRUE);CHKERRQ(ierr); ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); if (issym) { ierr = KSPSetType(check_ksp,KSPCG);CHKERRQ(ierr); } ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); ierr = VecSetRandom(work1,NULL);CHKERRQ(ierr); ierr = MatMult(local_mat,work1,work2);CHKERRQ(ierr); ierr = KSPSolve(check_ksp,work2,work2);CHKERRQ(ierr); ierr = VecAXPY(work2,m_one,work1);CHKERRQ(ierr); ierr = VecNorm(work2,NORM_INFINITY,&test_err);CHKERRQ(ierr); ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); ierr = KSPGetIterationNumber(check_ksp,&k);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d error for adapted KSP %1.14e (it %d, eigs %1.6e %1.6e)\n",PetscGlobalRank,test_err,k,lambda_min,lambda_max);CHKERRQ(ierr); ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); ierr = VecDestroy(&work1);CHKERRQ(ierr); ierr = VecDestroy(&work2);CHKERRQ(ierr); ierr = VecDestroy(&work3);CHKERRQ(ierr); } /* all processes shoud call this, even the void ones */ if (pcbddc->dbg_flag) { ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*MC TSSUNDIALS - ODE solver using the LLNL CVODE/SUNDIALS package (now called SUNDIALS) Options Database: + -ts_sundials_type <bdf,adams> . -ts_sundials_gramschmidt_type <modified, classical> - type of orthogonalization inside GMRES . -ts_sundials_atol <tol> - Absolute tolerance for convergence . -ts_sundials_rtol <tol> - Relative tolerance for convergence . -ts_sundials_linear_tolerance <tol> . -ts_sundials_gmres_restart <restart> - Number of GMRES orthogonalization directions . -ts_sundials_exact_final_time - Interpolate output to stop exactly at the final time - -ts_sundials_monitor_steps - Monitor SUNDIALS internel steps Notes: This uses its own nonlinear solver and Krylov method so PETSc SNES and KSP options do not apply only PETSc PC options Level: beginner .seealso: TSCreate(), TS, TSSetType(), TSSundialsSetType(), TSSundialsSetGMRESRestart(), TSSundialsSetLinearTolerance(), TSSundialsSetGramSchmidtType(), TSSundialsSetTolerance(), TSSundialsGetPC(), TSSundialsGetIterations(), TSSundialsSetExactFinalTime() M*/ EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "TSCreate_Sundials" PetscErrorCode PETSCTS_DLLEXPORT TSCreate_Sundials(TS ts) { TS_Sundials *cvode; PetscErrorCode ierr; PetscFunctionBegin; if (ts->problem_type != TS_NONLINEAR) { SETERRQ(PETSC_ERR_SUP,"Only support for nonlinear problems"); } ts->ops->destroy = TSDestroy_Sundials; ts->ops->view = TSView_Sundials; ts->ops->setup = TSSetUp_Sundials_Nonlinear; ts->ops->step = TSStep_Sundials_Nonlinear; ts->ops->setfromoptions = TSSetFromOptions_Sundials_Nonlinear; ierr = PetscNewLog(ts,TS_Sundials,&cvode);CHKERRQ(ierr); ierr = PCCreate(((PetscObject)ts)->comm,&cvode->pc);CHKERRQ(ierr); ierr = PetscLogObjectParent(ts,cvode->pc);CHKERRQ(ierr); ts->data = (void*)cvode; cvode->cvode_type = SUNDIALS_BDF; cvode->gtype = SUNDIALS_CLASSICAL_GS; cvode->restart = 5; cvode->linear_tol = .05; cvode->exact_final_time = PETSC_TRUE; cvode->monitorstep = PETSC_FALSE; ierr = MPI_Comm_dup(((PetscObject)ts)->comm,&(cvode->comm_sundials));CHKERRQ(ierr); /* set tolerance for Sundials */ cvode->reltol = 1e-6; cvode->abstol = 1e-6; ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetType_C","TSSundialsSetType_Sundials", TSSundialsSetType_Sundials);CHKERRQ(ierr); ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetGMRESRestart_C", "TSSundialsSetGMRESRestart_Sundials", TSSundialsSetGMRESRestart_Sundials);CHKERRQ(ierr); ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetLinearTolerance_C", "TSSundialsSetLinearTolerance_Sundials", TSSundialsSetLinearTolerance_Sundials);CHKERRQ(ierr); ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetGramSchmidtType_C", "TSSundialsSetGramSchmidtType_Sundials", TSSundialsSetGramSchmidtType_Sundials);CHKERRQ(ierr); ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetTolerance_C", "TSSundialsSetTolerance_Sundials", TSSundialsSetTolerance_Sundials);CHKERRQ(ierr); ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsGetPC_C", "TSSundialsGetPC_Sundials", TSSundialsGetPC_Sundials);CHKERRQ(ierr); ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsGetIterations_C", "TSSundialsGetIterations_Sundials", TSSundialsGetIterations_Sundials);CHKERRQ(ierr); ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsSetExactFinalTime_C", "TSSundialsSetExactFinalTime_Sundials", TSSundialsSetExactFinalTime_Sundials);CHKERRQ(ierr); ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSSundialsMonitorInternalSteps_C", "TSSundialsMonitorInternalSteps_Sundials", TSSundialsMonitorInternalSteps_Sundials);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat mat; /* matrix */ Vec b,ustar,u; /* vectors (RHS, exact solution, approx solution) */ PC pc; /* PC context */ KSP ksp; /* KSP context */ PetscErrorCode ierr; PetscInt n = 10,i,its,col[3]; PetscScalar value[3]; PCType pcname; KSPType kspname; PetscReal norm,tol=1000.*PETSC_MACHINE_EPSILON; PetscInitialize(&argc,&args,(char*)0,help); /* Create and initialize vectors */ ierr = VecCreateSeq(PETSC_COMM_SELF,n,&b);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,n,&ustar);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,n,&u);CHKERRQ(ierr); ierr = VecSet(ustar,1.0);CHKERRQ(ierr); ierr = VecSet(u,0.0);CHKERRQ(ierr); /* Create and assemble matrix */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,n,n,3,NULL,&mat);CHKERRQ(ierr); value[0] = -1.0; value[1] = 2.0; value[2] = -1.0; for (i=1; i<n-1; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(mat,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = n - 1; col[0] = n - 2; col[1] = n - 1; ierr = MatSetValues(mat,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = 0; col[1] = 1; value[0] = 2.0; value[1] = -1.0; ierr = MatSetValues(mat,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Compute right-hand-side vector */ ierr = MatMult(mat,ustar,b);CHKERRQ(ierr); /* Create PC context and set up data structures */ ierr = PCCreate(PETSC_COMM_WORLD,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); ierr = PCSetFromOptions(pc);CHKERRQ(ierr); ierr = PCSetOperators(pc,mat,mat);CHKERRQ(ierr); ierr = PCSetUp(pc);CHKERRQ(ierr); /* Create KSP context and set up data structures */ ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetType(ksp,KSPRICHARDSON);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = PCSetOperators(pc,mat,mat);CHKERRQ(ierr); ierr = KSPSetPC(ksp,pc);CHKERRQ(ierr); ierr = KSPSetUp(ksp);CHKERRQ(ierr); /* Solve the problem */ ierr = KSPGetType(ksp,&kspname);CHKERRQ(ierr); ierr = PCGetType(pc,&pcname);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"Running %s with %s preconditioning\n",kspname,pcname);CHKERRQ(ierr); ierr = KSPSolve(ksp,b,u);CHKERRQ(ierr); ierr = VecAXPY(u,-1.0,ustar);CHKERRQ(ierr); ierr = VecNorm(u,NORM_2,&norm); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"2 norm of error %g Number of iterations %D\n",(double)norm,its);CHKERRQ(ierr); } /* Free data structures */ ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&ustar);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = PCDestroy(&pc);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PETSC_EXTERN void PETSC_STDCALL pccreate_(MPI_Fint * comm,PC *newpc, int *__ierr ){ *__ierr = PCCreate( MPI_Comm_f2c( *(comm) ),newpc); }