35class AlephVectorTrilinos :
public IAlephVector
40 : IAlephVector(tm, kernel, index)
42 debug() <<
"\t\t[AlephVectorTrilinos::AlephVectorTrilinos] new SolverVectorTrilinos";
44 m_trilinos_Comm =
new Epetra_MpiComm(*(MPI_Comm*)(m_kernel->subParallelMng(m_index)->getMPICommunicator()));
46 m_trilinos_Comm =
new Epetra_SerialComm();
50 ~AlephVectorTrilinos()
52 delete m_trilinos_vector;
53 delete m_trilinos_Comm;
61 void AlephVectorCreate(
void)
63 debug() <<
"\t\t[AlephVectorTrilinos::AlephVectorCreate] TRILINOS VectorCreate";
66 for (
int iCpu = 0; iCpu < m_kernel->size(); ++iCpu) {
67 if (m_kernel->rank() != m_kernel->solverRanks(m_index)[iCpu])
70 jlower = m_kernel->topology()->gathered_nb_row(iCpu);
71 jupper = m_kernel->topology()->gathered_nb_row(iCpu + 1) - 1;
73 Integer size = jupper - jlower + 1;
74 debug() <<
"\t\t[AlephVectorTrilinos::AlephVectorCreate] jlower=" << jlower <<
", jupper=" << jupper;
75 Epetra_Map trilinos_Map = Epetra_Map(m_kernel->topology()->nb_row_size(),
79 m_trilinos_vector =
new Epetra_Vector(trilinos_Map);
80 debug() <<
"\t\t[AlephVectorTrilinos::AlephVectorCreate] done";
86 void AlephVectorSet(
const double* bfr_val,
const int* bfr_idx,
Integer size)
88 debug() <<
"\t\t[AlephVectorTrilinos::AlephVectorSet]";
89 m_trilinos_vector->ReplaceGlobalValues(size, bfr_val, bfr_idx);
96 int AlephVectorAssemble(
void)
105 void AlephVectorGet(
double* bfr_val,
const int* bfr_idx,
Integer size)
107 ARCANE_UNUSED(bfr_idx);
108 debug() <<
"\t\t[AlephVectorTrilinos::AlephVectorGet]";
109 for (
int i = 0; i < size; ++i) {
111 bfr_val[i] = (*m_trilinos_vector)[i];
121 void writeToFile(
const String filename)
123 ARCANE_UNUSED(filename);
124 debug() <<
"\t\t[AlephVectorTrilinos::writeToFile]";
131 Real LinftyNorm(
void)
134 if (m_trilinos_vector->NormInf(&Result) != 0)
135 throw Exception(
"LinftyNorm",
"NormInf error");
142 void fill(
Real value)
144 m_trilinos_vector->PutScalar(value);
149 Epetra_Vector* m_trilinos_vector =
nullptr;
150 Epetra_Comm* m_trilinos_Comm =
nullptr;
159class AlephMatrixTrilinos
168 : IAlephMatrix(tm, kernel, index)
170 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixTrilinos] new AlephMatrixTrilinos";
172 m_trilinos_Comm =
new Epetra_MpiComm(*(MPI_Comm*)(m_kernel->subParallelMng(m_index)->getMPICommunicator()));
174 m_trilinos_Comm =
new Epetra_SerialComm();
178 ~AlephMatrixTrilinos()
180 delete m_trilinos_matrix;
181 delete m_trilinos_Comm;
187 void AlephMatrixCreate(
void)
189 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixCreate] TRILINOS MatrixCreate idx:" << m_index;
192 for (
int iCpu = 0; iCpu < m_kernel->size(); ++iCpu) {
193 if (m_kernel->rank() != m_kernel->solverRanks(m_index)[iCpu])
196 ilower = m_kernel->topology()->gathered_nb_row(iCpu);
197 iupper = m_kernel->topology()->gathered_nb_row(iCpu + 1) - 1;
199 Integer size = iupper - ilower + 1;
201 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixCreate] ilower=" << ilower <<
", iupper=" << iupper;
205 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixCreate] jlower=" << jlower <<
", jupper=" << jupper;
206 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixCreate] global=" << m_kernel->topology()->nb_row_size();
207 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixCreate] size=" << size;
209 Epetra_Map trilinos_Map = Epetra_Map(m_kernel->topology()->nb_row_size(),
213 m_trilinos_matrix =
new Epetra_CrsMatrix(Copy,
215 m_kernel->topology()->gathered_nb_row_elements().subView(ilower, size).unguardedBasePointer(),
222 void AlephMatrixSetFilled(
bool) {}
227 int AlephMatrixAssemble(
void)
229 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixAssemble] AlephMatrixAssemble";
230 m_trilinos_matrix->FillComplete();
237 void AlephMatrixFill(
int size,
int* rows,
int* cols,
double* values)
239 [[maybe_unused]]
int rtn = 0;
240 for (
int i = 0; i < size; i++) {
245 rtn += m_trilinos_matrix->InsertGlobalValues(rows[i], 1, &values[i], &cols[i]);
248 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixFill] done";
271 const bool convergence_analyse =
true;
274 const Real res0 = b->LinftyNorm();
276 if (convergence_analyse)
277 debug() <<
"convergence analysis: max norm of the right-hand side res0: " << res0;
279 const Real considered_as_null = params->minRHSNorm();
280 if (res0 < considered_as_null) {
282 residual_norm[0] = res0;
283 if (convergence_analyse)
284 debug() <<
"convergence analysis: the right-hand side of the linear system is less than: " << considered_as_null;
288 if (params->xoUser()) {
291 m_trilinos_matrix->Multiply(
false,
292 *x->m_trilinos_vector,
293 *tmp->m_trilinos_vector);
294 tmp->m_trilinos_vector->Update(-1.0,
295 *b->m_trilinos_vector,
297 const Real residu = tmp->LinftyNorm();
300 if (residu < considered_as_null) {
301 if (convergence_analyse) {
302 debug() <<
"convergence analysis: |Ax0-b| is less than " << considered_as_null;
303 debug() <<
"convergence analysis: x0 is already a solution to the system.";
305 residual_norm[0] = residu;
309 const Real relative_error = residu / res0;
310 if (convergence_analyse)
311 debug() <<
"convergence analysis: initial residual : " << residu
312 <<
" --- initial relative residual (residu/res0) : " << residu / res0;
314 if (relative_error < (params->epsilon())) {
315 if (convergence_analyse)
316 debug() <<
"convergence analysis: X is already a solution to the system";
317 residual_norm[0] = residu;
321 if (convergence_analyse)
322 debug() <<
"convergence analysis: return false";
336 Ifpack_IC* ICPrecond =
nullptr;
337 Teuchos::ParameterList* MLList =
nullptr;
338 ML_Epetra::MultiLevelPreconditioner* MLPrecond =
nullptr;
339 const String func_name(
"SolverMatrixTrilinos::solve");
349 if (isAlreadySolved(x_tri, b_tri, t_tri, residual_norm, solver_param)) {
351 debug() <<
"\t[AlephMatrixSloop::AlephMatrixSolve] isAlreadySolved !";
356 Epetra_Vector* X = x_tri->m_trilinos_vector;
357 Epetra_Vector* B = b_tri->m_trilinos_vector;
359 if (!solver_param->xoUser())
363 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixSolve] Create Linear Problem";
364 Epetra_LinearProblem problem(m_trilinos_matrix, X, B);
367 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixSolve] Create AztecOO instance";
368 AztecOO solver(problem);
370 solver.SetAztecOption(AZ_output, solver_param->getOutputLevel());
372 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixSolve] Setting options";
373 switch (solver_param->method()) {
374 case TypesSolver::PCG:
375 solver.SetAztecOption(AZ_solver, AZ_cg);
377 case TypesSolver::BiCGStab:
378 solver.SetAztecOption(AZ_solver, AZ_bicgstab);
380 case TypesSolver::BiCGStab2:
381 solver.SetAztecOption(AZ_solver, AZ_bicgstab);
383 case TypesSolver::GMRES:
384 solver.SetAztecOption(AZ_solver, AZ_gmres);
386 case TypesSolver::SuperLU:
387 solver.SetAztecOption(AZ_solver, AZ_slu);
393 switch (solver_param->precond()) {
394 case TypesSolver::NONE:
395 solver.SetAztecOption(AZ_precond, AZ_none);
397 case TypesSolver::DIAGONAL:
398 solver.SetAztecOption(AZ_precond, AZ_Jacobi);
400 case TypesSolver::ILU: {
401 solver.SetAztecOption(AZ_precond, AZ_dom_decomp);
402 solver.SetAztecOption(AZ_subdomain_solve, AZ_ilu);
405 case TypesSolver::ILUp:
406 solver.SetAztecOption(AZ_precond, AZ_bilu);
408 case TypesSolver::POLY:
409 solver.SetAztecOption(AZ_precond, AZ_Neumann);
411 case TypesSolver::AMG: {
412 MLList =
new Teuchos::ParameterList();
422 ML_Epetra::SetDefaults(
"SA", *MLList);
426 MLList->set(
"cycle applications", solver_param->getAmgSolverIter());
427 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixSolve] Setting cycle application=" << solver_param->getAmgSolverIter();
430 MLList->set(
"smoother: sweeps", solver_param->getAmgSmootherIter());
431 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixSolve] Setting smoother: sweeps=" << solver_param->getAmgSmootherIter();
435 MLList->set(
"ML debug mode",
false);
437 MLPrecond =
new ML_Epetra::MultiLevelPreconditioner(*m_trilinos_matrix, *MLList);
447 solver.SetPrecOperator(MLPrecond);
450 case TypesSolver::IC: {
451 ICPrecond =
new Ifpack_IC(m_trilinos_matrix);
452 IFPACK_CHK_ERR(ICPrecond->Compute());
453 solver.SetPrecOperator(ICPrecond);
456 case TypesSolver::SPAIstat:
457 throw ArgumentException(func_name,
"AztecOO::SPAIstat preconditioner unavailable");
458 case TypesSolver::AINV:
460 case TypesSolver::SPAIdyn:
461 throw ArgumentException(func_name,
"AztecOO::SPAIdyn preconditioner unavailable");
468 solver.Iterate(solver_param->maxIter(), solver_param->epsilon());
471 solver.GetLHS()->Norm2(norm);
472 double real_residual;
473 X->Norm2(&real_residual);
475 debug() <<
"[AlephMatrixTrilinos::AlephMatrixSolve]"
477 <<
"\n\t\tNumIters=" << solver.NumIters()
479 <<
"\n\t\tTrueResidual=" << solver.TrueResidual()
481 <<
"\n\t\tScaledResidual=" << solver.ScaledResidual()
483 <<
"\n\t\tRecursiveResidual=" << solver.RecursiveResidual()
484 <<
"\n\t\tnorm=" << norm[0]
485 <<
"\n\t\tRealResidual=" << real_residual;
487 nb_iteration =
static_cast<Integer>(solver.NumIters());
488 residual_norm[0] =
static_cast<Real>(solver.TrueResidual());
490 if (solver_param->maxIter() <= nb_iteration)
491 throw Exception(
"Maximum number of solver iterations reached!",
492 "AlephMatrixTrilinos::AlephMatrixSolve");
499 if (MLPrecond != NULL)
501 if (ICPrecond != NULL)
504 debug() <<
"\t\t[AlephMatrixTrilinos::AlephMatrixSolve] done";
511 void writeToFile(
const String filename)
513 ARCANE_UNUSED(filename);
518 Epetra_CrsMatrix* m_trilinos_matrix =
nullptr;
519 Epetra_Comm* m_trilinos_Comm =
nullptr;