diff --git a/src/Solvers/petsc_solver_ASM_AMG_to_do.hpp b/src/Solvers/petsc_solver_ASM_AMG_to_do.hpp new file mode 100644 index 0000000000000000000000000000000000000000..20d47f8894695d8f640bbdb4c3512b53a96ebc4b --- /dev/null +++ b/src/Solvers/petsc_solver_ASM_AMG_to_do.hpp @@ -0,0 +1,400 @@ +/* + * petsc_solver_ASM_AMG_to_do.hpp + * + * Created on: Jun 3, 2016 + * Author: i-bird + */ + +#ifndef OPENFPM_NUMERICS_SRC_SOLVERS_PETSC_SOLVER_ASM_AMG_TO_DO_HPP_ +#define OPENFPM_NUMERICS_SRC_SOLVERS_PETSC_SOLVER_ASM_AMG_TO_DO_HPP_ + + + /*! \brief try to solve the system with block jacobi pre-conditioner + * + * + * + */ + void try_solve_complex_bj(Mat & A_, const Vec & b_, Vec & x_) + { + PETSC_SAFE_CALL(KSPSetTolerances(ksp,rtol,abstol,dtol,5)); + PETSC_SAFE_CALL(KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL)); + + solve_complex(A_,b_,x_); + } + + + /*! \brief Try to solve the system using all the Krylov solver with simple preconditioners + * + * + * + */ + void try_solve_ASM(Mat & A_, const Vec & b_, Vec & x_) + { + PETSC_SAFE_CALL(KSPSetTolerances(ksp,rtol,abstol,dtol,5)); + for (size_t i = 0 ; i < solvs.size() ; i++) + { + setSolver(solvs.get(i).c_str()); + + // Disable convergence check + PETSC_SAFE_CALL(KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL)); + +// solve_simple(A_,b_,x_); + solve_ASM(A_,b_,x_); + } + } + + + /*! \brief solve complex use Krylov solver in combination with Block-Jacobi + Nested + * + * + * Solve the system using block-jacobi preconditioner + nested solver for each block + * + */ + void solve_complex(Mat & A_, const Vec & b_, Vec & x_) + { + // We get the size of the Matrix A + PetscInt row; + PetscInt col; + PetscInt row_loc; + PetscInt col_loc; + PetscInt * blks; + PetscInt nlocal; + PetscInt first; + KSP *subksp; + PC subpc; + + PETSC_SAFE_CALL(MatGetSize(A_,&row,&col)); + PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc)); + + // Set the preconditioner to Block-jacobi + PC pc; + KSPGetPC(ksp,&pc); + PCSetType(pc,PCBJACOBI); + PETSC_SAFE_CALL(KSPSetType(ksp,KSPGMRES)); + + PetscInt m = 1; + + PetscMalloc1(m,&blks); + for (size_t i = 0 ; i < m ; i++) blks[i] = row_loc; + + PCBJacobiSetLocalBlocks(pc,m,blks); + PetscFree(blks); + + KSPSetUp(ksp); + PCSetUp(pc); + + PCBJacobiGetSubKSP(pc,&nlocal,&first,&subksp); + + for (size_t i = 0; i < nlocal; i++) + { + KSPGetPC(subksp[i],&subpc); + + PCSetType(subpc,PCLU); + +// PCSetType(subpc,PCJACOBI); + KSPSetType(subksp[i],KSPPREONLY); +// PETSC_SAFE_CALL(KSPSetConvergenceTest(ksp,KSPConvergedDefault,NULL,NULL)); +// KSPSetTolerances(subksp[i],1.e-6,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); + +/* if (!rank) + { + if (i%2) + { + PCSetType(subpc,PCILU); + } + else + { + PCSetType(subpc,PCNONE); + KSPSetType(subksp[i],KSPBCGS); + KSPSetTolerances(subksp[i],1.e-6,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); + } + } + else + { + PCSetType(subpc,PCJACOBI); + KSPSetType(subksp[i],KSPGMRES); + KSPSetTolerances(subksp[i],1.e-6,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); + }*/ + } + + + KSPSolve(ksp,b_,x_); + + 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 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 solve_AMG(Mat & A_, const Vec & b_, Vec & x_) + { + // PETSC_SAFE_CALL(KSPSetType(ksp,s_type)); + PETSC_SAFE_CALL(KSPSetType(ksp,KSPRICHARDSON)); + + // -pc_hypre_boomeramg_tol <tol> + + // 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,PCJACOBI)); + + PETSC_SAFE_CALL(PCSetType(pc,PCHYPRE)); + // PCGAMGSetNSmooths(pc,0); + PCFactorSetShiftType(pc, MAT_SHIFT_NONZERO); + PCFactorSetShiftAmount(pc, PETSC_DECIDE); + PCHYPRESetType(pc, "boomeramg"); + MatSetBlockSize(A_,4); + PetscOptionsSetValue("-pc_hypre_boomeramg_print_statistics","2"); + PetscOptionsSetValue("-pc_hypre_boomeramg_max_iter","1000"); + PetscOptionsSetValue("-pc_hypre_boomeramg_nodal_coarsen","true"); + PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_all","SOR/Jacobi"); + PetscOptionsSetValue("-pc_hypre_boomeramg_coarsen_type","Falgout"); + PetscOptionsSetValue("-pc_hypre_boomeramg_cycle_type","W"); + PetscOptionsSetValue("-pc_hypre_boomeramg_max_levels","20"); + PetscOptionsSetValue("-pc_hypre_boomeramg_vec_interp_variant","0"); + KSPSetFromOptions(ksp); + + // 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)); + } + + // Solve the system + PETSC_SAFE_CALL(KSPSolve(ksp,b_,x_)); + + 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; + } + // } + } + + + /*! \brief solve simple use a Krylov solver + Simple selected Parallel Pre-conditioner + * + */ + void solve_Krylov_simple(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,PCJACOBI)); + + PETSC_SAFE_CALL(PCSetType(pc,PCHYPRE)); +// PCGAMGSetNSmooths(pc,0); + PCFactorSetShiftType(pc, MAT_SHIFT_NONZERO); + PCFactorSetShiftAmount(pc, PETSC_DECIDE); + PCHYPRESetType(pc, "boomeramg"); + MatSetBlockSize(A_,4); + PetscOptionsSetValue("-pc_hypre_boomeramg_print_statistics","2"); + PetscOptionsSetValue("-pc_hypre_boomeramg_max_iter","1000"); + PetscOptionsSetValue("-pc_hypre_boomeramg_nodal_coarsen","true"); + PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_all","SOR/Jacobi"); + PetscOptionsSetValue("-pc_hypre_boomeramg_coarsen_type","Falgout"); + PetscOptionsSetValue("-pc_hypre_boomeramg_cycle_type","W"); + PetscOptionsSetValue("-pc_hypre_boomeramg_max_levels","10"); + KSPSetFromOptions(ksp); + // 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)); + } + + // Solve the system + PETSC_SAFE_CALL(KSPSolve(ksp,b_,x_)); + + 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; + } +// } + } + + ///////////////////// + + IS *is,*is_local; + PetscInt Nsub; + + PCASMCreateSubdomains2D(128,128,4,4,1,1,&Nsub,&is,&is_local); + + + if (create_vcluster().getProcessUnitID() == 1) + ISView(is_local[1],PETSC_VIEWER_STDOUT_SELF); + + //////////////////// + +#endif /* OPENFPM_NUMERICS_SRC_SOLVERS_PETSC_SOLVER_ASM_AMG_TO_DO_HPP_ */