8 #ifndef OPENFPM_NUMERICS_SRC_SOLVERS_PETSC_SOLVER_HPP_
9 #define OPENFPM_NUMERICS_SRC_SOLVERS_PETSC_SOLVER_HPP_
15 #include "Vector/Vector.hpp"
17 #include <petsctime.h>
18 #include "Plot/GoogleChart.hpp"
19 #include "Matrix/SparseMatrix.hpp"
20 #include "Vector/Vector.hpp"
27 std::ostringstream out;
28 out << std::setprecision(n) << a_value;
32 #define UMFPACK_NONE 0
37 #define PCHYPRE_BOOMERAMG "petsc_boomeramg"
75 #define SOLVER_NOOPTION 0
76 #define SOLVER_PRINT_RESIDUAL_NORM_INFINITY 1
77 #define SOLVER_PRINT_DETERMINANT 2
170 T s_int = slv.
time / slv.
res.size();
173 size_t pt = std::floor(t / s_int);
175 if (pt < slv.
res.size())
176 return slv.
res.get(pt).err_norm;
178 return slv.
res.last().err_norm;
187 if (create_vcluster().getProcessUnitID() != 0)
195 for (
size_t i = 0 ; i <
bench.size() ; i++)
196 x.add(
bench.get(i).smethod);
200 yn.add(
"Norm infinity");
201 yn.add(
"Norm average");
202 yn.add(
"Number of iterations");
206 for (
size_t i = 0 ; i <
bench.size() ; i++)
207 y.add({bench.get(i).err.err_inf,bench.get(i).err.err_norm,(T)bench.get(i).err.its});
212 options.
title = std::string(
"Residual error");
213 options.
yAxis = std::string(
"Error");
214 options.
xAxis = std::string(
"Method");
215 options.
stype = std::string(
"bars");
216 options.
more = std::string(
"vAxis: {scaleType: 'log'}");
220 std::stringstream ss;
222 cg.
addHTML(
"<h2>Robustness</h2>");
229 yn.add(
"Time in millseconds");
230 options.
title = std::string(
"Time");
232 for (
size_t i = 0 ; i <
bench.size() ; i++)
233 y.add({bench.get(i).time});
248 for (
size_t i = 0 ; i <
bench.size() ; i++)
250 if (
bench.get(i).time > max_time) {max_time =
bench.get(i).time;}
251 yn.add(
bench.get(i).smethod);
258 T dt = max_time / n_int;
264 for (T t = dt ; t <= max_time + 0.05 * max_time ; t += dt)
268 for (
size_t j = 0 ; j <
bench.size() ; j++)
272 std::stringstream ss2;
273 ss2 <<
"<h2>Convergence with time</h2><br>" << std::endl;
275 options.
title = std::string(
"Residual norm infinity");
276 options.
yAxis = std::string(
"residual");
277 options.
xAxis = std::string(
"Time in milliseconds");
279 options.
more = std::string(
"vAxis: {scaleType: 'log'},hAxis: {scaleType: 'log'}");
284 ss <<
"<h2>Solvers Tested</h2><br><br>" << std::endl;
285 for (
size_t i = 0 ; i <
bench.size() ; i++)
286 ss <<
bench.get(i).smethod <<
" = " <<
bench.get(i).method <<
"<br>" << std::endl;
290 cg.
write(
"gc_solver.html");
302 PETSC_SAFE_CALL(KSPSetNormType(
ksp,KSP_NORM_UNPRECONDITIONED));
304 if (
atype == HYPRE_AMG)
309 PETSC_SAFE_CALL(KSPGetPC(
ksp,&pc));
311 PCFactorSetShiftType(pc, MAT_SHIFT_NONZERO);
312 PCFactorSetShiftAmount(pc, PETSC_DECIDE);
322 auto & v_cl = create_vcluster();
324 if (v_cl.getProcessUnitID() == 0)
325 std::cout <<
"-----------------------25-----------------------50-----------------------75----------------------100" << std::endl;
351 PETSC_SAFE_CALL(KSPGetOperators(
ksp,&A,NULL));
352 PETSC_SAFE_CALL(MatCreateVecs(A,&w,&v));
353 PETSC_SAFE_CALL(KSPBuildResidual(
ksp,v,w,&Br));
354 PETSC_SAFE_CALL(KSPBuildResidual(
ksp,v,w,&Br));
355 PETSC_SAFE_CALL(VecNorm(Br,NORM_INFINITY,&erri.
err_norm));
358 size_t old_size = pts->
bench.last().res.size();
359 pts->
bench.last().res.resize(it+1);
362 err_fill = pts->
bench.last().res.get(old_size-1);
366 for (
long int i = old_size ; i < (
long int)it ; i++)
367 pts->
bench.last().res.get(i) = err_fill;
370 pts->
bench.last().res.get(it) = erri;
384 PETSC_SAFE_CALL(KSPGetTolerances(
ksp,NULL,NULL,NULL,&n_max_it));
386 auto & v_cl = create_vcluster();
388 if (std::floor(it * 100.0 / n_max_it) >
tmp)
390 size_t diff = it * 100.0 / n_max_it -
tmp;
391 tmp = it * 100.0 / n_max_it;
392 if (v_cl.getProcessUnitID() == 0)
394 for (
size_t k = 0 ; k < diff ; k++) {std::cout <<
"*";}
395 std::cout << std::flush;
407 auto & v_cl = create_vcluster();
409 if (v_cl.getProcessUnitID() == 0)
412 KSPGetType(
ksp,&typ);
414 std::cout <<
"Method: " << typ <<
" " <<
" pre-conditoner: " << PCJACOBI <<
" iterations: " << err.
its << std::endl;
415 std::cout <<
"Norm of error: " << err.
err_norm <<
" Norm infinity: " << err.
err_inf << std::endl;
429 if (solv == std::string(KSPBCGS))
431 return std::string(
"BiCGStab (Stabilized version of BiConjugate Gradient Squared)");
433 else if (solv == std::string(KSPIBCGS))
435 return std::string(
"IBiCGStab (Improved Stabilized version of BiConjugate Gradient Squared)");
437 else if (solv == std::string(KSPFBCGS))
439 return std::string(
"FBiCGStab (Flexible Stabilized version of BiConjugate Gradient Squared)");
441 else if (solv == std::string(KSPFBCGSR))
443 return std::string(
"FBiCGStab-R (Modified Flexible Stabilized version of BiConjugate Gradient Squared)");
445 else if (solv == std::string(KSPBCGSL))
447 return std::string(
"BiCGStab(L) (Stabilized version of BiConjugate Gradient Squared with L search directions)");
449 else if (solv == std::string(KSPGMRES))
451 return std::string(
"GMRES(M) (Generalized Minimal Residual method with restart)");
453 else if (solv == std::string(KSPFGMRES))
455 return std::string(
"FGMRES(M) (Flexible Generalized Minimal Residual with restart)");
457 else if (solv == std::string(KSPLGMRES))
459 return std::string(
"LGMRES(M) (Augment Generalized Minimal Residual method with restart)");
461 else if (solv == std::string(KSPPGMRES))
463 return std::string(
"PGMRES(M) (Pipelined Generalized Minimal Residual method)");
465 else if (solv == std::string(KSPGCR))
467 return std::string(
"GCR (Generalized Conjugate Residual)");
470 return std::string(
"UNKNOWN");
483 bench.last().smethod = std::string(str);
498 VecCopy(sol,best_sol);
516 PETSC_SAFE_CALL(VecDuplicate(x_,&best_sol));
519 T best_res = std::numeric_limits<T>::max();
522 auto & v_cl = create_vcluster();
527 for (
size_t i = 0 ; i <
solvs.
size() ; i++)
535 PETSC_SAFE_CALL(KSPGetPC(
ksp,&pc));
536 PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_type",PCNONE));
541 if (
solvs.get(i) == std::string(KSPBCGSL))
544 for (
size_t j = 2 ; j < 6 ; j++)
548 if (v_cl.getProcessUnitID() == 0)
549 std::cout <<
"L = " << j << std::endl;
550 bench.last().smethod += std::string(
"(") + std::to_string(j) + std::string(
")");
557 else if (
solvs.get(i) == std::string(KSPGMRES) ||
558 solvs.get(i) == std::string(std::string(KSPFGMRES)) ||
559 solvs.get(i) == std::string(std::string(KSPLGMRES)) )
562 for (
size_t j = 50 ; j < 300 ; j += 50)
567 if (v_cl.getProcessUnitID() == 0)
568 std::cout <<
"Restart = " << j << std::endl;
569 bench.last().smethod += std::string(
"(") + std::to_string(j) + std::string(
")");
592 PETSC_SAFE_CALL(VecCopy(best_sol,x_));
593 PETSC_SAFE_CALL(VecDestroy(&best_sol));
612 PETSC_SAFE_CALL(KSPMonitorCancel(
ksp));
618 if (create_vcluster().getProcessUnitID() == 0)
619 std::cout << std::endl;
622 bench.time = t.getwct() * 1000.0;
631 if (create_vcluster().getProcessUnitID() == 0)
632 std::cout << std::endl;
652 PETSC_SAFE_CALL(MatGetSize(A_,&row,&col));
653 PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc));
656 PETSC_SAFE_CALL(KSPSetOperators(
ksp,A_,A_));
660 PETSC_SAFE_CALL(KSPSetFromOptions(
ksp));
664 PETSC_SAFE_CALL(KSPSolve(
ksp,b_,x_));
676 PETSC_SAFE_CALL(KSPSolve(
ksp,b_,x_));
696 PETSC_SAFE_CALL(KSPGetIterationNumber(
ksp,&its));
709 PETSC_SAFE_CALL(KSPCreate(PETSC_COMM_WORLD,&
ksp));
718 PETSC_SAFE_CALL(KSPCreate(PETSC_COMM_WORLD,&
ksp));
745 KSPGetOperators(
ksp,&A_,&P_);
761 PetscScalar neg_one = -1.0;
769 PETSC_SAFE_CALL(MatGetSize(A_,&row,&col));
770 PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc));
780 Vec & r_ = r.getVec();
782 PETSC_SAFE_CALL(MatMult(A_,x_,r_));
783 PETSC_SAFE_CALL(VecAXPY(r_,neg_one,b_));
785 PETSC_SAFE_CALL(VecNorm(r_,NORM_1,&norm));
786 PETSC_SAFE_CALL(VecNorm(r_,NORM_INFINITY,&norm_inf));
803 PETSC_SAFE_CALL(KSPDestroy(&
ksp));
813 solvs.add(std::string(KSPBCGS));
817 solvs.add(std::string(KSPBCGSL));
818 solvs.add(std::string(KSPGMRES));
819 solvs.add(std::string(KSPFGMRES));
820 solvs.add(std::string(KSPLGMRES));
833 auto & v_cl = create_vcluster();
835 if (v_cl.getProcessUnitID() == 0)
841 PETSC_SAFE_CALL(KSPGetPC(
ksp,&pc));
842 PETSC_SAFE_CALL(PCGetType(pc,&type_pc));
844 std::cout <<
"The precoditioner is: " << type_pc << std::endl;
854 auto & v_cl = create_vcluster();
856 if (v_cl.getProcessUnitID() == 0)
861 PETSC_SAFE_CALL(KSPGetType(
ksp,&type_ksp));
863 std::cout <<
"The ksp_type is: " << type_ksp << std::endl;
892 for (
size_t i = 0 ; i <
solvs.
size() ; i++)
894 if (
solvs.get(i) == solver)
907 PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-ksp_monitor",0));
908 PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_print_statistics",
"2"));
920 PetscOptionsSetValue(NULL,
"-ksp_type",type);
937 PETSC_SAFE_CALL(KSPGetTolerances(
ksp,&rtol,&abstol,&dtol,&
maxits));
938 PETSC_SAFE_CALL(KSPSetTolerances(
ksp,rtol_,abstol,dtol,
maxits));
955 PETSC_SAFE_CALL(KSPGetTolerances(
ksp,&rtol,&abstol,&dtol,&
maxits));
956 PETSC_SAFE_CALL(KSPSetTolerances(
ksp,rtol,abstol_,dtol,
maxits));
973 PETSC_SAFE_CALL(KSPGetTolerances(
ksp,&rtol,&abstol,&dtol,&
maxits));
974 PETSC_SAFE_CALL(KSPSetTolerances(
ksp,rtol,abstol,dtol_,
maxits));
989 PETSC_SAFE_CALL(KSPGetTolerances(
ksp,&rtol,&abstol,&dtol,&
maxits));
990 PETSC_SAFE_CALL(KSPSetTolerances(
ksp,rtol,abstol,dtol,n));
1006 PetscOptionsSetValue(NULL,
"-ksp_bcgsl_ell",std::to_string(l).c_str());
1016 PetscOptionsSetValue(NULL,
"-ksp_gmres_restart",std::to_string(n).c_str());
1050 if (std::string(type) == PCHYPRE_BOOMERAMG)
1055 PETSC_SAFE_CALL(KSPGetPC(
ksp,&pc));
1057 PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_type",PCHYPRE));
1059 PETSC_SAFE_CALL(PCFactorSetShiftType(pc, MAT_SHIFT_NONZERO));
1060 PETSC_SAFE_CALL(PCFactorSetShiftAmount(pc, PETSC_DECIDE));
1061 #ifdef PETSC_HAVE_HYPRE
1062 PETSC_SAFE_CALL(PCHYPRESetType(pc,
"boomeramg"));
1068 PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_type",type));
1082 if (
atype == HYPRE_AMG)
1084 PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_max_levels",std::to_string(nl).c_str()));
1088 std::cout << __FILE__ <<
":" << __LINE__ <<
"Warning: the selected preconditioner does not support this option" << std::endl;
1099 if (
atype == HYPRE_AMG)
1101 PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_max_iter",std::to_string(nit).c_str()));
1105 std::cout << __FILE__ <<
":" << __LINE__ <<
"Warning: the selected preconditioner does not support this option" << std::endl;
1131 if (
atype == HYPRE_AMG)
1134 {PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_relax_type_all",type.c_str()));}
1135 else if (k == REL_UP)
1136 {PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_relax_type_up",type.c_str()));}
1137 else if (k == REL_DOWN)
1138 {PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_relax_type_down",type.c_str()));}
1142 std::cout << __FILE__ <<
":" << __LINE__ <<
"Warning: the selected preconditioner does not support this option" << std::endl;
1164 if (
atype == HYPRE_AMG)
1166 PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_cycle_type",cycle_type.c_str()));
1169 {PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_grid_sweeps_down",std::to_string(sweep_up).c_str()));}
1172 {PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_grid_sweeps_up",std::to_string(sweep_dw).c_str()));}
1174 if (sweep_crs != -1)
1175 {PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_grid_sweeps_coarse",std::to_string(sweep_crs).c_str()));}
1179 std::cout << __FILE__ <<
":" << __LINE__ <<
"Warning: the selected preconditioner does not support this option" << std::endl;
1195 if (
atype == HYPRE_AMG)
1197 PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_coarsen_type",type.c_str()));
1201 std::cout << __FILE__ <<
":" << __LINE__ <<
"Warning: the selected preconditioner does not support this option" << std::endl;
1217 if (
atype == HYPRE_AMG)
1219 PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_interp_type",type.c_str()));
1223 std::cout << __FILE__ <<
":" << __LINE__ <<
"Warning: the selected preconditioner does not support this option" << std::endl;
1246 if (
atype == HYPRE_AMG)
1248 PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_nodal_coarsen",std::to_string(norm).c_str()));
1252 std::cout << __FILE__ <<
":" << __LINE__ <<
"Warning: the selected preconditioner does not support this option" << std::endl;
1263 if (
atype == HYPRE_AMG)
1265 PETSC_SAFE_CALL(PetscOptionsSetValue(NULL,
"-pc_hypre_boomeramg_eu_level",std::to_string(k).c_str()));
1269 std::cout << __FILE__ <<
":" << __LINE__ <<
"Warning: the selected preconditioner does not support this option" << std::endl;
1307 initial_guess =
false)
1309 Mat & A_ = A.getMat();
1310 const Vec & b_ = b.getVec();
1318 PETSC_SAFE_CALL(KSPSetInitialGuessNonzero(
ksp,PETSC_FALSE));
1319 PETSC_SAFE_CALL(MatGetSize(A_,&row,&col));
1320 PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc));
1323 Vec & x_ = x.getVec();
1345 Mat & A_ = A.getMat();
1346 const Vec & b_ = b.getVec();
1347 Vec & x_ = x.getVec();
1355 PETSC_SAFE_CALL(KSPSetInitialGuessNonzero(
ksp,PETSC_TRUE));
1385 const Vec & b_ = b.getVec();
1390 PETSC_SAFE_CALL(KSPSetInitialGuessNonzero(
ksp,PETSC_FALSE));
1392 PETSC_SAFE_CALL(VecGetSize(b_,&row));
1393 PETSC_SAFE_CALL(VecGetLocalSize(b_,&row_loc));
1395 Vec & x_ = x.getVec();
1396 PETSC_SAFE_CALL(KSPSetNormType(
ksp,KSP_NORM_UNPRECONDITIONED));
1421 const Vec & b_ = b.getVec();
1422 Vec & x_ = x.getVec();
1430 PETSC_SAFE_CALL(KSPSetInitialGuessNonzero(
ksp,PETSC_TRUE));
1435 PETSC_SAFE_CALL(KSPSetNormType(
ksp,KSP_NORM_UNPRECONDITIONED));
1466 PETSC_BASE> & b,
bool initial_guess =
false,
bool symmetric =
false)
1469 Mat & A_ = A.getMat();
1470 const Vec & b_ = b.getVec();
1477 PETSC_SAFE_CALL(KSPSetInitialGuessNonzero(
ksp,PETSC_FALSE));
1478 PETSC_SAFE_CALL(MatGetSize(A_,&row,&col));
1479 PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc));
1483 Vec & x_ = x.getVec();
1485 PETSC_SAFE_CALL(KSPSetFromOptions(
ksp));
1486 PETSC_SAFE_CALL(KSPSetOperators(
ksp,A_,A_));
1487 PETSC_SAFE_CALL(KSPSolve(
ksp,b_,x_));
1507 PETSC_SAFE_CALL(MatCreateDense(PETSC_COMM_WORLD, rows, N, PETSC_DETERMINE, PETSC_DETERMINE, NULL, &V));
1508 PETSC_SAFE_CALL(MatDuplicate(V, MAT_DO_NOT_COPY_VALUES, &work));
1509 PETSC_SAFE_CALL(MatMatSolve(
F, work, V));
1511 std::cout<<
"Dimension:" << N;
1513 for(
int i=0;i<N;i++)
1515 PETSC_SAFE_CALL(MatGetColumnVector(V,nvec[i],i));
1517 MatNullSpace nullspace;
1519 PETSC_SAFE_CALL(MatNullSpaceCreate(PETSC_COMM_WORLD,PETSC_TRUE,N,nvec,&nullspace));
1520 PETSC_SAFE_CALL(MatSetTransposeNullSpace(A_,nullspace));
1521 PETSC_SAFE_CALL(MatSetNullSpace(A_,nullspace));
1522 PETSC_SAFE_CALL(MatNullSpaceDestroy(&nullspace));
1524 PETSC_SAFE_CALL(KSPSetOperators(
ksp,A_,A_));
1525 PETSC_SAFE_CALL(KSPSetFromOptions(
ksp));
1526 PETSC_SAFE_CALL(KSPSolve(
ksp,b_,x_));
1584 const Vec & b_ = b.getVec();
1590 PETSC_SAFE_CALL(KSPSetInitialGuessNonzero(
ksp,PETSC_FALSE));
1591 PETSC_SAFE_CALL(VecGetSize(b_,&row));
1592 PETSC_SAFE_CALL(VecGetLocalSize(b_,&row_loc));
1595 Vec & x_ = x.getVec();
1619 const Vec & b_ = b.getVec();
1620 Vec & x_ = x.getVec();
1638 PetscOptionsSetValue(NULL,name,value);
1654 Mat & A_ = A.getMat();
1655 const Vec & b_ = b.getVec();
1663 PETSC_SAFE_CALL(KSPSetInitialGuessNonzero(
ksp,PETSC_FALSE));
1664 PETSC_SAFE_CALL(MatGetSize(A_,&row,&col));
1665 PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc));
1668 Vec & x_ = x.getVec();
std::string to_string_with_precision(const T myValue, const size_t n=6)
Converts value into string maintaining a desired precision.
Small class to produce graph with Google chart in HTML.
void write(std::string file)
It write the graphs on file in html format using Google charts.
void AddLinesGraph(openfpm::vector< X > &x, openfpm::vector< Y > &y, const GCoptions &opt)
Add a simple lines graph.
void AddHistGraph(openfpm::vector< Y > &y)
Add an histogram graph.
void addHTML(const std::string &html)
Add HTML text.
Sparse Matrix implementation.
PETSC vector for linear algebra.
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support.
Implementation of 1-D std::vector like structure.
This class is able to do Matrix inversion in parallel with PETSC solvers.
Vector< T, PETSC_BASE > return_type
Type of the solution object.
size_t tmp
Temporal variable used for calculation of static members.
void setRelTol(PetscReal rtol_)
Set the relative tolerance as stop criteria.
KSP ksp
Main parallel solver.
PetscInt maxits
KSP Maximum number of iterations.
openfpm::vector< solv_bench_info > bench
It contain the solver benchmark results.
Vector< T, PETSC_BASE > solve(SparseMatrix< T, int, PETSC_BASE > &A, const Vector< T, PETSC_BASE > &b, bool initial_guess=false)
Here we invert the matrix and solve the system.
void bench_solve_simple(const Mat &A_, const Vec &b_, Vec &x_, solv_bench_info &bench)
Benchmark solve simple solving x=inv(A)*b.
void progress(PetscInt it)
This function print an "*" showing the progress of the solvers.
void print_stat(solError &err)
Print statistic about the solution error and method used.
static solError statSolutionError(const Mat &A_, const Vec &b_, Vec &x_, KSP ksp)
Calculate statistic on the error solution.
static T calculate_it(T t, solv_bench_info &slv)
Calculate the residual error at time t for one method.
void setDivTol(PetscReal dtol_)
Set the divergence tolerance.
void pre_solve_impl(const Mat &A_, const Vec &b_, Vec &x_)
It set up the solver based on the provided options.
void setPreconditionerAMG_cycleType(const std::string &cycle_type, int sweep_up=-1, int sweep_dw=-1, int sweep_crs=-1)
It set the type of cycle and optionally the number of sweep.
void try_solve_simple(const Mat &A_, const Vec &b_, Vec &x_)
Try to solve the system x=inv(A)*b using all the Krylov solvers with simple Jacobi pre-conditioner.
void write_bench_report()
Here we write the benchmark report.
void new_bench(const std::string &str)
Allocate a new benchmark slot for a method.
solError get_residual_error(SparseMatrix< T, int, PETSC_BASE > &A, const Vector< T, PETSC_BASE > &x, const Vector< T, PETSC_BASE > &b)
It return the resiual error.
void setBlockSize(int block_sz)
Set how many degree of freedom each node has.
Vector< T, PETSC_BASE > with_nullspace_solve(SparseMatrix< T, int, PETSC_BASE > &A, const Vector< T, PETSC_BASE > &b, bool initial_guess=false, bool symmetric=false)
Here we invert the matrix and solve the system using a Nullspace for Neumann BC.
solError get_residual_error(const Vector< T, PETSC_BASE > &x, const Vector< T, PETSC_BASE > &b)
It return the resiual error.
static solError getSolNormError(const Mat &A_, const Vec &b_, const Vec &x_)
Return the norm error of the solution.
void print_preconditioner()
Print the preconditioner used by the solver.
void solve_simple(const Vec &b_, Vec &x_)
solve simple use a Krylov solver + Simple selected Parallel Pre-conditioner
void removeTestSolver(const std::string &solver)
Remove a test solver.
bool is_preconditioner_set
indicate if the preconditioner is set
void copy_if_better(T res, Vec &sol, T &best_res, Vec &best_sol)
Copy the solution if better.
void initKSP()
initialize the KSP object
Vector< T, PETSC_BASE > solve_successive(Vector< T, PETSC_BASE > &x, const Vector< T, PETSC_BASE > &b)
Here we invert the matrix and solve the system with previous operator and initial guess.
void searchDirections(PetscInt l)
Vector< T, PETSC_BASE > solve_successive(const Vector< T, PETSC_BASE > &b, bool initial_guess=false)
Here we invert the matrix and solve the system with previous operator.
std::string to_string_method(const std::string &solv)
It convert the KSP type into a human read-able string.
KSP getKSP()
Return the KSP solver.
void solve_simple(const Mat &A_, const Vec &b_, Vec &x_)
solve simple use a Krylov solver + Simple selected Parallel Pre-conditioner
void setPreconditionerAMG_nl(int nl)
Set the number of levels for the algebraic-multigrid preconditioner.
Vector< T, PETSC_BASE > solve(const Vector< T, PETSC_BASE > &b)
Here we invert the matrix and solve the system.
void log_monitor()
Set the Petsc solver.
void setPreconditionerAMG_coarsenNodalType(int norm)
Set the block coarsening norm type.
void setPreconditionerAMG_interp(const std::string &type)
Set the interpolation method for the algebraic-multi-grid preconditioner.
void setPreconditioner(PCType type)
Set the preconditioner of the linear solver.
void setPreconditionerAMG_coarsen(const std::string &type)
Set the coarsening method for the algebraic-multi-grid preconditioner.
static PetscErrorCode monitor_progress_residual(KSP ksp, PetscInt it, PetscReal res, void *data)
procedure print the progress of the solver in benchmark mode
void addTestSolver(std::string &solver)
Add a test solver.
void initKSPForTest()
initialize the KSP object for solver testing
void setPreconditionerAMG_interp_eu_level(int k)
Indicate the number of levels in the ILU(k) for the Euclid smoother.
void setSolver(KSPType type)
Set the Petsc solver.
void destroyKSP()
Destroy the KSP object.
AMG_type atype
Type of the algebraic multi-grid preconditioner.
openfpm::vector< std::string > solvs
The full set of solvers.
void setPreconditionerAMG_relax(const std::string &type, int k=REL_ALL)
Set the relaxation method for the algebraic-multi-grid preconditioner.
void setMaxIter(PetscInt n)
Set the maximum number of iteration for Krylov solvers.
void setAbsTol(PetscReal abstol_)
Set the absolute tolerance as stop criteria.
Vector< T, PETSC_BASE > try_solve(SparseMatrix< T, int, PETSC_BASE > &A, const Vector< T, PETSC_BASE > &b)
Try to solve the system using all the solvers and generate a report.
void print_ksptype()
Print the ksp_type used by the solver.
void setPreconditionerAMG_maxit(int nit)
Set the maximum number of V or W cycle for algebraic-multi-grid.
bool solve(Vector< T, PETSC_BASE > &x, const Vector< T, PETSC_BASE > &b)
Here we invert the matrix and solve the system.
Vector< T, PETSC_BASE > solve(SparseMatrix< T, int, PETSC_BASE > &A, Vector< T, PETSC_BASE > &x, const Vector< T, PETSC_BASE > &b)
Here we invert the matrix and solve the system.
static solError getSolNormError(const Vec &b_, const Vec &x_, KSP ksp)
Return the norm error of the solution.
void setRestart(PetscInt n)
For GMRES based method, the number of Krylov directions to orthogonalize against.
void print_progress_bar()
Print a progress bar on standard out.
void setPetscOption(const char *name, const char *value)
this function give you the possibility to set PETSC options
Class for cpu time benchmarking.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
[v_transform metafunction]
std::string xAxis
X axis name.
size_t lineWidth
Width of the line.
std::string title
Title of the chart.
std::string yAxis
Y axis name.
contain the infinity norm of the residual at each iteration
PetscReal err_norm
error norm at iteration it
It contain the benchmark information for each solver.
T time
time to converge in milliseconds
std::string method
Solver Krylov name.
std::string smethod
Method name (short form)
solError err
Solution error.
openfpm::vector< itError > res
Convergence per iteration.
It contain statistic of the error of the calculated solution.
PetscReal err_inf
infinity norm of the error
PetscInt its
Number of iterations.
PetscReal err_norm
L1 norm of the error.