void solve_ASM(Mat & A_, const Vec & b_, Vec & x_) { PETSC_SAFE_CALL(KSPSetType(ksp,s_type)); // We set the size of x according to the Matrix A PetscInt row; PetscInt col; PetscInt row_loc; PetscInt col_loc; PETSC_SAFE_CALL(MatGetSize(A_,&row,&col)); PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc)); PC pc; // We set the Matrix operators PETSC_SAFE_CALL(KSPSetOperators(ksp,A_,A_)); // We set the pre-conditioner PETSC_SAFE_CALL(KSPGetPC(ksp,&pc)); PETSC_SAFE_CALL(PCSetType(pc,PCASM)); //////////////// ///////////////////// // PCASMSetLocalSubdomains(pc); PCASMSetOverlap(pc,5); KSP *subksp; /* array of KSP contexts for local subblocks */ PetscInt nlocal,first; /* number of local subblocks, first local subblock */ PC subpc; /* PC context for subblock */ PetscBool isasm; /* Set runtime options */ // KSPSetFromOptions(ksp); /* Flag an error if PCTYPE is changed from the runtime options */ // PetscObjectTypeCompare((PetscObject)pc,PCASM,&isasm); // if (!isasm) SETERRQ(PETSC_COMM_WORLD,1,"Cannot Change the PCTYPE when manually changing the subdomain solver settings"); /* Call KSPSetUp() to set the block Jacobi data structures (including creation of an internal KSP context for each block). Note: KSPSetUp() MUST be called before PCASMGetSubKSP(). */ KSPSetUp(ksp); /* Extract the array of KSP contexts for the local blocks */ PCASMGetSubKSP(pc,&nlocal,&first,&subksp); /* Loop over the local blocks, setting various KSP options for each block. */ for (size_t i = 0 ; i < nlocal ; i++) { KSPGetPC(subksp[i],&subpc); // PCFactorSetFill(subpc,30); PCFactorSetLevels(subpc,5); PCSetType(subpc,PCILU); KSPSetType(subksp[i],KSPRICHARDSON); KSPSetTolerances(subksp[i],1.e-3,0.1,PETSC_DEFAULT,PETSC_DEFAULT); } // if we are on on best solve set-up a monitor function if (try_solve == true) { // for bench-mark we are interested in non-preconditioned norm PETSC_SAFE_CALL(KSPMonitorSet(ksp,monitor,&vres,NULL)); // Disable convergence check PETSC_SAFE_CALL(KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL)); } // KSPGMRESSetRestart(ksp,100); // Solve the system PETSC_SAFE_CALL(KSPSolve(ksp,b_,x_)); KSPConvergedReason reason; KSPGetConvergedReason(ksp,&reason); std::cout << "Reason: " << reason << std::endl; auto & v_cl = create_vcluster(); // if (try_solve == true) // { // calculate error statistic about the solution solError err = statSolutionError(A_,b_,x_); if (v_cl.getProcessUnitID() == 0) { std::cout << "Method: " << s_type << " " << " pre-conditoner: " << PCJACOBI << " iterations: " << err.its << std::endl; std::cout << "Norm of error: " << err.err_norm << " Norm infinity: " << err.err_inf << std::endl; } // } }
void PETSC_STDCALL pcfactorsetlevels_(PC pc,PetscInt *levels, int *__ierr ){ *__ierr = PCFactorSetLevels( (PC)PetscToPointer((pc) ),*levels); }
void SolverLinearPetsc<T>::setPetscPreconditionerType() { int ierr = 0; #if (PETSC_VERSION_MAJOR == 3) && (PETSC_VERSION_MINOR >= 2) ierr = PCFactorSetMatSolverPackage( M_pc,MATSOLVERUMFPACK ); if ( ierr ) { ierr = PCFactorSetMatSolverPackage( M_pc,MATSOLVERSUPERLU ); if ( ierr ) { ierr = PCFactorSetMatSolverPackage( M_pc,MATSOLVERPETSC ); } } #elif (PETSC_VERSION_MAJOR >= 3) ierr = PCFactorSetMatSolverPackage( M_pc,MAT_SOLVER_UMFPACK ); if ( ierr ) { ierr = PCFactorSetMatSolverPackage( M_pc,MAT_SOLVER_SUPERLU ); if ( ierr ) { ierr = PCFactorSetMatSolverPackage( M_pc,MAT_SOLVER_PETSC ); } } #endif DVLOG(2) << "[SolverLinearPetsc] preconditioner type: " << this->preconditionerType() << "\n"; switch ( this->preconditionerType() ) { case IDENTITY_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCNONE ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; case CHOLESKY_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCCHOLESKY ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; case ICC_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCICC ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; case ILU_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCILU ); CHKERRABORT( this->worldComm().globalComm(),ierr ); if ( this->vm().count( "pc-factor-levels" ) ) { PCFactorSetLevels( M_pc,this->vm()["pc-factor-levels"].template as<int>() ); } else PCFactorSetLevels( M_pc,3 ); if ( this->vm().count( "pc-factor-fill" ) ) { PCFactorSetFill( M_pc,this->vm()["pc-factor-fill"].template as<double>() ); } else PCFactorSetFill( M_pc,40 ); return; case LU_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCLU ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; case ASM_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCASM ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; #if PETSC_VERSION_GREATER_OR_EQUAL_THAN( 3,2,0 ) case GASM_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCGASM ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; #endif case JACOBI_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCJACOBI ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; case BLOCK_JACOBI_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCBJACOBI ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; case SOR_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCSOR ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; case EISENSTAT_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCEISENSTAT ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; #if !((PETSC_VERSION_MAJOR == 2) && (PETSC_VERSION_MINOR <= 1) && (PETSC_VERSION_SUBMINOR <= 1)) case USER_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCMAT ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; #endif case SHELL_PRECOND: ierr = PCSetType ( M_pc, ( char* ) PCSHELL ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; case FIELDSPLIT_PRECOND: ierr = PCSetType( M_pc,( char* ) PCFIELDSPLIT ); CHKERRABORT( this->worldComm().globalComm(),ierr ); ierr = PCFieldSplitSetType( M_pc,PC_COMPOSITE_SCHUR ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; case ML_PRECOND: ierr = PCSetType( M_pc,( char* ) PCML ); CHKERRABORT( this->worldComm().globalComm(),ierr ); return; default: std::cerr << "ERROR: Unsupported PETSC Preconditioner: " << this->preconditionerType() << std::endl << "Continuing with PETSC defaults" << std::endl; } }