Dear developers,
I was wondering if someone can comment on this:
I'm trying to set the KSP rtol and atl through command line and also coded
in for different systems. Before calling solve on a particular system I do:
PetscLinearSolver<Number>* elasticity_system_linear_solver =
libmesh_cast_ptr<PetscLinearSolver<Number >
*>(elasticity_system.linear_solver.get());
KSP elasticity_system_ksp = elasticity_system_linear_solver>ksp();
if (elasticity_system_ksp)
{
PC elasticity_system_pc;
ierr = KSPSetType(elasticity_system_ksp,KSPCG); CHKERRQ(ierr);
ierr = KSPSetTolerances(elasticity_system_ksp,1e8,1e12,1e3,1000);
CHKERRQ(ierr);
ierr = KSPGetPC(elasticity_system_ksp,&elasticity_system_pc); CHKERRQ(ierr);
ierr = PCSetType(elasticity_system_pc,PCBJACOBI);CHKERRQ(ierr);
CHKERRQ(ierr);
ierr = KSPSetOptionsPrefix(elasticity_system_ksp,"elasticity_system_");
CHKERRQ(ierr);
ierr = KSPSetFromOptions(elasticity_system_ksp); CHKERRQ(ierr);
}
However my command line rtol and my coded rtol both get overridden by
"linear solver tolerance" parameter but atol is set right by the command
line and/or hard code (which is very frustrating). The problem comes from
the fact that in PetscLinearSolver::Init the ksp is options supposed to be
set but then in PetscLinearSolver::Solve we have:
// Set the tolerances for the iterative solver. Use the usersupplied
// tolerance for the relative residual & leave the others at default
values.
// Convergence is detected at iteration k if
// r_k_2 < max(rtol*b_2 , abstol)
// where r_k is the residual vector and b is the righthand side. Note
that
// it is the *maximum* of the two values, the larger of which will almost
// always be rtol*b_2.
ierr = KSPSetTolerances (_ksp,
tol, // rtol = relative decrease in residual (1.e5)
PETSC_DEFAULT, // abstol = absolute convergence tolerance (1.e50)
PETSC_DEFAULT, // dtol = divergence tolerance (1.e+5)
max_its);
LIBMESH_CHKERRABORT(ierr);
which overrides the rtol ?!
Best,
Ata
