The purpose of this example is to show how to use Trilinos while adapting mesh. We’ll use the NOX solver, either using Newton’s method or JFNK, with or without preconditioning.
The underlying problem is benchmark “layer-interior”.
The dimension of the finite element space changes after each adaptivity step. Therefore also the initial coefficient vector for NOX has to change. Here, for simplicity, we always start from the zero vector:
// Initial coefficient vector for the Newton's method.
double* coeff_vec = new double[ndof_ref];
memset(coeff_vec, 0, ndof_ref * sizeof(double));
Indeed this is inefficient since lots of useful information from the previous reference solution is thrown away. Correctly one should project the last reference solution on the new reference mesh, herewith calculating a much better iniial vector. This is waiting for someone to implement.
In each adaptivity step we initialize a new NOX solver and preconditioner:
// Initialize NOX solver.
NewtonSolverNOX<double> solver(&dp, message_type, "GMRES", "Newton", ls_tolerance, "", flag_absresid, abs_resid,
flag_relresid, rel_resid, max_iters);
// Select preconditioner.
RCP<Precond> pc = rcp(new MlPrecond("sa"));
if (PRECOND)
{
if (JFNK) solver.set_precond(pc);
else solver.set_precond("ML");
}
The fine mesh problem is solved and the solution coefficient vector converted into a Solution. Skipping info outputs and visualization this reads:
info("Assembling by DiscreteProblem, solving by NOX.");
solver.set_init_sln(coeff_vec);
if (solver.solve()) {
Solution::vector_to_solution(solver.get_solution(), ref_space, &ref_sln);
info("Number of nonlin iterations: %d (norm of residual: %g)",
solver.get_num_iters(), solver.get_residual());
info("Total number of iterations in linsolver: %d (achieved tolerance in the last step: %g)",
solver.get_num_lin_iters(), solver.get_achieved_tol());
}
else
error("NOX failed.");
This step is common to all hp-adaptivity algorithms in Hermes:
info("Projecting reference solution on coarse mesh.");
OGProjection<double> ogProjection; ogProjection.project_global(&space, &ref_sln, &sln);
Now we have a pair of solutions to guide automatic hp-adaptivity, and we proceed as in benchmark “layer-internal”.