[cig-commits] [commit] master: make direct solver work with nonlinear schemes (ae7bf48)
cig_noreply at geodynamics.org
cig_noreply at geodynamics.org
Thu Jun 12 08:05:28 PDT 2014
Repository : https://github.com/geodynamics/aspect
On branch : master
Link : https://github.com/geodynamics/aspect/compare/75a1eead49c5165ff3ecee1573c3f4577ef534bb...62599834f9944b32d7d25d117a9a394c565642ea
>---------------------------------------------------------------
commit ae7bf48812b3b0222f87b1653125577ae6ad7a90
Author: Timo Heister <timo.heister at gmail.com>
Date: Wed Jun 11 11:16:09 2014 -0400
make direct solver work with nonlinear schemes
We need to compute and return the correct initial_residual in
solve_stokes() when using a direct solver for the nonlinear methods like
iterated IMPES to work. This is some extra work, sadly.
>---------------------------------------------------------------
ae7bf48812b3b0222f87b1653125577ae6ad7a90
source/simulator/solver.cc | 35 ++++++++++++++++++++++++++++++++---
1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/source/simulator/solver.cc b/source/simulator/solver.cc
index 133d099..d8a6579 100644
--- a/source/simulator/solver.cc
+++ b/source/simulator/solver.cc
@@ -458,14 +458,43 @@ namespace aspect
if (parameters.use_direct_stokes_solver)
{
- LinearAlgebra::BlockVector distributed_stokes_solution (introspection.index_sets.stokes_partitioning, mpi_communicator);
-
+ // We hardcode the blocks down below, so make sure block 0 is indeed
+ // the block containing velocity and pressure:
Assert(introspection.block_indices.velocities == 0, ExcNotImplemented());
Assert(introspection.block_indices.pressure == 0, ExcNotImplemented());
+ LinearAlgebra::BlockVector distributed_stokes_solution (introspection.index_sets.stokes_partitioning, mpi_communicator);
+
+ // While we don't need to set up the initial guess for the direct solver
+ // (it will be ignored by the solver anyway), we need this if we are
+ // using a nonlinear scheme, because we use this to compute the current
+ // nonlinear residual (see initial_residual below).
+ // TODO: if there was an easy way to know if the caller needs the
+ // initial residual we could skip all of this stuff.
+ distributed_stokes_solution.block(0) = current_linearization_point.block(0);
+ denormalize_pressure (distributed_stokes_solution);
+ current_constraints.set_zero (distributed_stokes_solution);
+
+ // Undo the pressure scaling:
+ for (unsigned int i=0; i< introspection.index_sets.locally_owned_pressure_dofs.n_elements(); ++i)
+ {
+ types::global_dof_index idx = introspection.index_sets.locally_owned_pressure_dofs.nth_index_in_set(i);
+
+ distributed_stokes_solution(idx) /= pressure_scaling;
+ }
+ distributed_stokes_solution.compress(VectorOperation::insert);
+
if (material_model->is_compressible ())
make_pressure_rhs_compatible(system_rhs);
+ // we need a temporary vector for the residual (even if we don't care about it)
+ LinearAlgebra::Vector residual (introspection.index_sets.stokes_partitioning[0], mpi_communicator);
+
+ const double initial_residual = system_matrix.block(0,0).residual(
+ residual,
+ distributed_stokes_solution.block(0),
+ system_rhs.block(0));
+
SolverControl cn;
// TODO: can we re-use the direct solver?
#ifdef ASPECT_USE_PETSC
@@ -518,7 +547,7 @@ namespace aspect
computing_timer.exit_section();
- return 0;
+ return initial_residual;
}
More information about the CIG-COMMITS
mailing list