208class AlephMatrixSloop :
public IAlephMatrix
218 : IAlephMatrix(tm, kernel, index)
219 , m_sloop_matrix(NULL)
221 debug() <<
"\t\t[AlephMatrixSloop::AlephMatrixSloop] NEW AlephMatrixSloop";
229 debug() <<
"\33[1;5;32m\t\t\t[~AlephMatrixSloop]\33[0m";
230 delete m_sloop_matrix;
236 void AlephMatrixCreate(
void)
238 ItacFunction(AlephMatrixSloop);
239 debug() <<
"\t\t[AlephMatrixSloop::AlephMatrixCreate] create new SLOOP::SLOOPDistMatrix";
242 m_sloop_matrix =
new SLOOP::SLOOPDistMatrix(*aleph_topology_sloop->m_sloop_topology,
243 *aleph_topology_sloop->m_sloop_msg,
248 throw Exception(
"AlephSolverMatrix::create",
"new SLOOPDistMatrix() failed");
251 if (aleph_topology_sloop->m_sloop_topology->get_type() == SLOOP::contiguous)
252 m_sloop_matrix->set_renumbering_opt(SLOOP::SLOOPDistMatrix::interface,
false);
253 m_sloop_matrix->set_renumbering_opt(SLOOP::SLOOPDistMatrix::processor,
false);
254 m_sloop_matrix->set_renumbering_opt(SLOOP::SLOOPDistMatrix::interior,
false);
255 m_sloop_matrix->init_length(m_kernel->topology()->gathered_nb_row_elements().unguardedBasePointer());
256 debug() <<
"\t\t[AlephMatrixSloop::AlephMatrixCreate] done";
262 void AlephMatrixSetFilled(
bool toggle)
264 ItacFunction(AlephMatrixSloop);
265 debug() <<
"\t\t[AlephMatrixSloop::AlephMatrixSetFilled]";
266 m_sloop_matrix->setfilled(toggle);
272 int AlephMatrixAssemble(
void)
274 ItacFunction(AlephMatrixSloop);
275 debug() <<
"\t\t[AlephMatrixSloop::AlephMatrixAssemble]";
276 m_sloop_matrix->configure();
283 void AlephMatrixFill(
int size,
int* rows,
int* cols,
double* values)
285 ItacFunction(AlephMatrixSloop);
286 debug() <<
"\t\t[AlephMatrixSloop::AlephMatrixFill] size=" << size;
287 m_sloop_matrix->locfill(values, rows, cols, size);
288 debug() <<
"\t\t[AlephMatrixSloop::AlephMatrixFill] done";
294 bool isAlreadySolved(SLOOP::SLOOPDistVector* x,
295 SLOOP::SLOOPDistVector* b,
296 SLOOP::SLOOPDistVector* tmp,
300 const Real res0 = b->norm_max();
301 const Real considered_as_null = params->minRHSNorm();
302 const bool convergence_analyse = params->convergenceAnalyse();
304 if (convergence_analyse)
305 debug() <<
"convergence analysis: max norm of the right-hand side res0: " << res0;
307 if (res0 < considered_as_null) {
309 residual_norm[0] = res0;
310 if (convergence_analyse)
311 debug() <<
"convergence analysis: the right-hand side of the linear system is less than "
312 << considered_as_null;
316 if (params->xoUser()) {
318 m_sloop_matrix->vector_multiply(*tmp, *x);
319 tmp->substract(*tmp, *b);
320 const Real residu = tmp->norm_max();
321 debug() <<
"[IAlephSloop::isAlreadySolved] residu=" << residu;
323 if (residu < considered_as_null) {
324 if (convergence_analyse) {
325 debug() <<
"convergence analysis: |Ax0-b| is less than " << considered_as_null;
326 debug() <<
"convergence analysis: x0 is already a solution to the system.";
328 residual_norm[0] = residu;
331 const Real relative_error = residu / res0;
332 if (convergence_analyse)
333 debug() <<
"convergence analysis: initial residual: " << residu
334 <<
" --- initial relative residual (residu/res0): " << residu / res0;
336 if (relative_error < (params->epsilon())) {
337 if (convergence_analyse)
338 debug() <<
"convergence analysis: X is already a solution to the system";
339 residual_norm[0] = residu;
355 ItacFunction(AlephMatrixSloop);
357 debug() <<
"\t\t[AlephMatrixSloop::SloopSolve] getTopologyImplementation #" << m_index;
368 SLOOP::SLOOPDistVector* solution = x_sloop->m_sloop_vector;
369 SLOOP::SLOOPDistVector* RHS = b_sloop->m_sloop_vector;
370 SLOOP::SLOOPDistVector* temp = tmp_sloop->m_sloop_vector;
372 if (isAlreadySolved(solution, RHS, temp, residual_norm, solver_param)) {
373 debug() <<
"\t[AlephMatrixSloop::AlephMatrixSolve] isAlreadySolved !";
379 sc = createSloopStopCriteria(solver_param, *sloopParallelInfo->m_sloop_msg);
382 global_solver = createSloopSolver(solver_param, *sloopParallelInfo->m_sloop_msg);
385 precond = createSloopPreconditionner(solver_param, *sloopParallelInfo->m_sloop_msg);
387 this->setSloopSolverParameters(solver_param, global_solver.
get());
388 this->setSloopPreconditionnerParameters(solver_param, precond.
get());
391 const bool normalize = normalizeSolverMatrix(solver_param);
393 debug() <<
"\t\t[AlephMatrixSloop::SloopSolve] Normalize";
394 diag =
new SLOOP::SLOOPDistVector(*sloopParallelInfo->m_sloop_topology, *sloopParallelInfo->m_sloop_msg);
395 global_solver->normalize(*m_sloop_matrix, *diag, *solution, *RHS);
398 const bool xo = solver_param->xoUser();
399 switch (solver_param->precond()) {
400 case TypesSolver::NONE:
403 debug() <<
"\t\t[AlephMatrixSloop::SloopSolve] xo à true (without preconditioning)";
404 status = global_solver->solve(*m_sloop_matrix, *solution, *RHS, *sc);
407 debug() <<
"\t\t[AlephMatrixSloop::SloopSolve] xo à false (without preconditioning)";
408 status = global_solver->solve_b(*m_sloop_matrix, *solution, *RHS, *sc);
414 debug() <<
"\t\t[AlephMatrixSloop::SloopSolve] xo à true (with preconditioning)";
415 status = global_solver->solve(*m_sloop_matrix, *solution, *RHS, *precond, *sc);
418 debug() <<
"\t\t[AlephMatrixSloop::SloopSolve] xo à false (avec preconditionnement)";
419 status = global_solver->solve_b(*m_sloop_matrix, *solution, *RHS, *precond, *sc);
425 debug() <<
"\t\t[AlephMatrixSloop::SloopSolve] INV-normalize";
426 global_solver->inv_normalize(*m_sloop_matrix, *diag, *solution, *RHS);
429 nb_iteration = global_solver->get_iteration();
430 residual_norm[0] = sc->get_criteria();
431 Integer max_iteration = global_solver->get_max_iteration();
432 residual_norm[3] = global_solver->get_stagnation();
434 if ((solver_param->getCriteriaStop() == TypesSolver::STAG) || (solver_param->getCriteriaStop() == TypesSolver::NIter)) {
439 if (nb_iteration == max_iteration && solver_param->stopErrorStrategy()) {
440 info() <<
"\n============================================================";
441 info() <<
"\nCette erreur est retournée après " << nb_iteration <<
"\n";
442 info() <<
"\nOn a atteind le nombre max d'itérations du solveur ";
443 info() <<
"\nIl est possible de demander au code de ne pas tenir compte de cette erreur.";
444 info() <<
"\nVoir la documentation du jeu de données concernant le service solveur.";
445 info() <<
"\n============================================================";
446 throw Exception(
"AlephMatrixSloop::SloopSolve",
"On a atteind le nombre max d'itérations du solveur");
449 debug() <<
"\t\t[AlephMatrixSloop::SloopSolve] nbIteration=" << global_solver->get_iteration()
450 <<
", criteria=" << residual_norm[0] <<
", stagnation=" << residual_norm[3];
457 void writeToFile(
const String file_name)
459 ItacFunction(AlephMatrixSloop);
460 m_sloop_matrix->write_to_file(file_name.
localstr());
466 SLOOP::SLOOPSolver* createSloopSolver(
AlephParams* solver_param, SLOOP::SLOOPMsg& info_sloop_msg)
468 const Integer output_level = solver_param->getOutputLevel();
469 ItacFunction(AlephMatrixSloop);
470 switch (solver_param->method()) {
471 case TypesSolver::PCG:
472 return new SLOOP::SLOOPCGSolver(info_sloop_msg, output_level);
473 case TypesSolver::BiCGStab:
474 return new SLOOP::SLOOPBiCGStabSolver(info_sloop_msg, output_level);
475 case TypesSolver::BiCGStab2:
476 return new SLOOP::SLOOPBiCGStabSolver(info_sloop_msg, output_level);
477 case TypesSolver::GMRES:
478 return new SLOOP::SLOOPGMRESSolver(info_sloop_msg, output_level);
479 case TypesSolver::SAMG:
480 return new SLOOP::SLOOPAMGSolver(info_sloop_msg, output_level);
481 case TypesSolver::QMR:
482 return new SLOOP::SLOOPQMRSolver(info_sloop_msg, output_level);
483 case TypesSolver::SuperLU: {
484 SLOOP::SLOOPSolver* solver =
new SLOOP::SLOOPSuperLUSolver(info_sloop_msg, output_level);
485 solver->set_parameter(SLOOP::sv_residual_calculation, 1);
489 throw Exception(
"AlephMatrixSloop::createSloopSolver",
"Type de solver non accessible pour la bibliothèque SLOOP");
497 SLOOP::SLOOPPreconditioner* createSloopPreconditionner(
AlephParams* solver_param,
498 SLOOP::SLOOPMsg& info_sloop_msg)
500 const Integer output_level = solver_param->getOutputLevel();
501 ItacFunction(AlephMatrixSloop);
502 switch (solver_param->precond()) {
503 case TypesSolver::AINV:
506 if (TypesSolver::PCG == solver_param->method())
507 return new SLOOP::SLOOPAINVPC(info_sloop_msg, output_level);
509 return new SLOOP::SLOOPMAINVPC(info_sloop_msg, output_level);
510 case TypesSolver::DIAGONAL:
511 return new SLOOP::SLOOPDiagPC(info_sloop_msg, output_level);
512 case TypesSolver::AMG:
513 return new SLOOP::SLOOPAMGPC(info_sloop_msg, output_level);
514 case TypesSolver::IC:
515 return new SLOOP::SLOOPCholPC(info_sloop_msg, output_level);
516 case TypesSolver::POLY:
517 return new SLOOP::SLOOPPolyPC(info_sloop_msg, output_level);
518 case TypesSolver::ILU:
519 return new SLOOP::SLOOPILUPC(info_sloop_msg, output_level);
520 case TypesSolver::ILUp:
521 return new SLOOP::SLOOPILUPC(info_sloop_msg, output_level);
522 case TypesSolver::SPAIstat:
523 return new SLOOP::SLOOPSPAIPC(info_sloop_msg, output_level);
524 case TypesSolver::SPAIdyn:
525 return new SLOOP::SLOOPSPAIPC(info_sloop_msg, output_level);
526 case TypesSolver::NONE:
529 throw Exception(
"AlephMatrixSloop::createSloopPreconditionner",
530 "préconditionneur non accessible pour la bibliothèque SLOOP");
538 SLOOP::SLOOPStopCriteria* createSloopStopCriteria(
AlephParams* solver_param,
539 SLOOP::SLOOPMsg& info_sloop_msg)
541 ItacFunction(AlephMatrixSloop);
542 switch (solver_param->getCriteriaStop()) {
543 case TypesSolver::RR0:
544 return new SLOOP::SLOOPStopCriteriaRR0();
546 return new SLOOP::SLOOPStopCriteriaR();
547 case TypesSolver::RCB:
548 return new SLOOP::SLOOPStopCriteriaRCB();
549 case TypesSolver::RBinf:
550 return new SLOOP::SLOOPStopCriteriaRBinf();
551 case TypesSolver::EpsA:
552 return new SLOOP::SLOOPStopCriteriaEpsA();
553 case TypesSolver::NIter:
554 return new SLOOP::SLOOPStopCriteriaNIter();
555 case TypesSolver::RR0inf:
556 return new SLOOP::SLOOPStopCriteriaRR0inf();
557 case TypesSolver::STAG:
558 return new SLOOP::SLOOPStopCriteriaSTAG();
559 case TypesSolver::RB:
561 return new SLOOP::SLOOPStopCriteriaRB();
568 void setSloopSolverParameters(
AlephParams* solver_param,
569 SLOOP::SLOOPSolver* sloop_solver)
572 Integer gamma = solver_param->gamma();
573 double alpha = solver_param->alpha();
574 ItacFunction(AlephMatrixSloop);
575 error += sloop_solver->set_parameter(SLOOP::sv_epsilon, solver_param->epsilon());
576 error += sloop_solver->set_parameter(SLOOP::sv_max_iter, solver_param->maxIter());
577 switch (solver_param->method()) {
578 case TypesSolver::PCG:
580 case TypesSolver::QMR:
582 case TypesSolver::SuperLU:
584 case TypesSolver::BiCGStab:
585 error += sloop_solver->set_parameter(SLOOP::bicg_dimension, 1);
587 case TypesSolver::BiCGStab2:
588 error += sloop_solver->set_parameter(SLOOP::bicg_dimension, 2);
590 case TypesSolver::GMRES:
591 error += sloop_solver->set_parameter(SLOOP::gmres_order, 20);
592 error += sloop_solver->set_parameter(SLOOP::gmres_type, SLOOP::ICGS);
594 case TypesSolver::SAMG: {
595 error += sloop_solver->set_parameter(SLOOP::amg_buffer_size, 200);
599 error += sloop_solver->set_parameter(SLOOP::amg_level, gamma);
604 error += sloop_solver->set_parameter(SLOOP::amg_alpha, alpha);
607 error += sloop_solver->set_parameter(SLOOP::amg_smoother_iter, solver_param->getAmgSmootherIter());
609 error += sloop_solver->set_parameter(SLOOP::amg_iter, solver_param->getAmgCycle());
611 SLOOP::SLOOPAMGCoarseningOption coarsening_option =
612 static_cast<SLOOP::SLOOPAMGCoarseningOption
>(solver_param->getAmgCoarseningOption());
613 error += sloop_solver->set_parameter(SLOOP::amg_coarsening_option, coarsening_option);
616 SLOOP::SLOOPAMGCoarseSolverOption coarse_solver_option =
617 static_cast<SLOOP::SLOOPAMGCoarseSolverOption
>(solver_param->getAmgCoarseSolverOption());
618 error += sloop_solver->set_parameter(SLOOP::amg_coarse_solver_option, coarse_solver_option);
621 SLOOP::SLOOPAMGSmootherOption smoother_option =
622 static_cast<SLOOP::SLOOPAMGSmootherOption
>(solver_param->getAmgSmootherOption());
623 error += sloop_solver->set_parameter(SLOOP::amg_smoother_option, smoother_option);
627 throw Exception(
"AlephMatrixSloop::setSloopSolverParameters",
628 "Type de solver SLOOP non prévu dans la gestion des paramètres");
631 throw Exception(
"AlephMatrixSloop::setSloopSolverParameters",
"set_parameter() failed");
636 void setSloopPreconditionnerParameters(
AlephParams* solver_param,
637 SLOOP::SLOOPPreconditioner* preconditionner)
639 const TypesSolver::ePreconditionerMethod precond_method = solver_param->precond();
640 double alpha = solver_param->alpha();
641 int gamma = solver_param->gamma();
642 const String function_id =
"SolverMatrixSloop::setSloopPreconditionnerParameters";
643 ItacFunction(AlephMatrixSloop);
647 switch (precond_method) {
648 case TypesSolver::NONE:
650 case TypesSolver::DIAGONAL:
652 case TypesSolver::AMG: {
655 preconditionner->set_parameter(SLOOP::amg_level, gamma);
656 preconditionner->set_parameter(SLOOP::amg_buffer_size, 200);
657 preconditionner->set_parameter(SLOOP::amg_solver_iter, solver_param->getAmgSolverIter());
658 preconditionner->set_parameter(SLOOP::amg_iter, solver_param->getAmgCycle());
659 preconditionner->set_parameter(SLOOP::amg_smoother_iter, solver_param->getAmgSmootherIter());
661 SLOOP::SLOOPAMGSmootherOption smoother_option =
662 static_cast<SLOOP::SLOOPAMGSmootherOption
>(solver_param->getAmgSmootherOption());
664 SLOOP::SLOOPAMGCoarseningOption coarsening_option =
665 static_cast<SLOOP::SLOOPAMGCoarseningOption
>(solver_param->getAmgCoarseningOption());
667 SLOOP::SLOOPAMGCoarseSolverOption coarse_solver_option =
668 static_cast<SLOOP::SLOOPAMGCoarseSolverOption
>(solver_param->getAmgCoarseSolverOption());
670 if (TypesSolver::PCG == solver_param->method()) {
672 switch (solver_param->getAmgSmootherOption()) {
673 case TypesSolver::CG_smoother:
674 case TypesSolver::Rich_IC_smoother:
675 case TypesSolver::Rich_AINV_smoother:
676 case TypesSolver::SymHybGSJ_smoother:
677 case TypesSolver::Rich_IC_block_smoother:
678 case TypesSolver::SymHybGSJ_block_smoother:
681 throw Exception(
"AlephMatrixSloop::setSloopPreconditionnerParameters",
682 "incorrect smoother choice for a symmetric matrix");
687 switch (solver_param->getAmgSmootherOption()) {
688 case TypesSolver::CG_smoother:
689 case TypesSolver::Rich_IC_smoother:
690 case TypesSolver::Rich_AINV_smoother:
691 case TypesSolver::Rich_IC_block_smoother:
692 case TypesSolver::SymHybGSJ_block_smoother:
693 throw Exception(
"AlephMatrixSloop::setSloopPreconditionnerParameters",
694 "incorrect smoother choice with a non-symmetric matrix ");
695 case TypesSolver::SymHybGSJ_smoother:
697 solver_param->setAmgSmootherOption(TypesSolver::HybGSJ_smoother);
703 switch (solver_param->getAmgCoarseSolverOption()) {
704 case TypesSolver::CG_coarse_solver:
705 case TypesSolver::Cholesky_coarse_solver:
706 solver_param->setAmgCoarseSolverOption(TypesSolver::LU_coarse_solver);
709 solver_param->setAmgCoarseSolverOption(TypesSolver::BiCGStab_coarse_solver);
714 preconditionner->set_parameter(SLOOP::amg_smoother_option, smoother_option);
716 preconditionner->set_parameter(SLOOP::amg_coarsening_option, coarsening_option);
718 preconditionner->set_parameter(SLOOP::amg_coarse_solver_option, coarse_solver_option);
721 case TypesSolver::POLY:
725 case TypesSolver::AINV:
730 case TypesSolver::IC:
731 case TypesSolver::ILU:
735 case TypesSolver::ILUp:
739 case TypesSolver::SPAIstat:
740 preconditionner->set_parameter(SLOOP::spai_sparsity, SLOOP::StatSparsity);
741 preconditionner->set_parameter(SLOOP::spai_init_sparsity, SLOOP::PowerSparsity);
742 preconditionner->set_parameter(SLOOP::spai_power_level, 1);
743 preconditionner->set_parameter(SLOOP::spai_Amax_row_size, 30);
744 preconditionner->set_parameter(SLOOP::spai_A_drop_eps, 0.001);
746 case TypesSolver::SPAIdyn:
747 preconditionner->set_parameter(SLOOP::spai_sparsity, SLOOP::DynSparsity);
748 preconditionner->set_parameter(SLOOP::spai_init_sparsity, SLOOP::DiagSparsity);
749 preconditionner->set_parameter(SLOOP::spai_Amax_row_size, 10);
750 preconditionner->set_parameter(SLOOP::spai_A_drop_eps, 0.001);
753 throw Exception(
"AlephMatrixSloop::setSloopPreconditionnerParameters",
"Préconditionneur inconnu.");
757 switch (precond_method) {
758 case TypesSolver::NONE:
759 case TypesSolver::SPAIstat:
760 case TypesSolver::SPAIdyn:
763 case TypesSolver::AMG:
764 preconditionner->set_parameter(SLOOP::amg_alpha, alpha);
765 preconditionner->set_parameter(SLOOP::amg_level, gamma);
766 preconditionner->set_parameter(SLOOP::amg_parallel_opt, 0);
768 preconditionner->set_parameter(SLOOP::amg_coarse_solver_sc_option, SLOOP::RB);
772 preconditionner->set_parameter(SLOOP::pc_alpha, alpha);
773 preconditionner->set_parameter(SLOOP::pc_nbelem, gamma);
774 preconditionner->set_parameter(SLOOP::pc_parallel_opt, 1);
775 preconditionner->set_parameter(SLOOP::pc_order, gamma);
782 bool normalizeSolverMatrix(
AlephParams* solver_param)
784 ItacFunction(AlephMatrixSloop);
785 switch (solver_param->precond()) {
786 case TypesSolver::AINV:
788 case TypesSolver::SPAIstat:
789 case TypesSolver::SPAIdyn:
791 case TypesSolver::AMG:
792 case TypesSolver::NONE:
793 case TypesSolver::DIAGONAL:
794 case TypesSolver::IC:
795 case TypesSolver::POLY:
796 case TypesSolver::ILU:
797 case TypesSolver::ILUp:
800 throw Exception(
"AlephMatrixSloop::normalizeSolverMatrix",
"Préconditionneur inconnu.");
807 SLOOP::SLOOPMatrix* m_sloop_matrix;