Trilinos - Adapt (04-trilinos-adapt)

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.

Model problem

The underlying problem is benchmark “layer-interior”.

Initial coefficient vector on fine mesh

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.

Initializing NOX on reference mesh

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");
}

Assembling and solving on reference mesh

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.");

Projecting fine mesh solution on coarse mesh

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);

The rest

Now we have a pair of solutions to guide automatic hp-adaptivity, and we proceed as in benchmark “layer-internal”.