Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move post_stokes_solver signal invokation to the end of the solver. #5431

Open
bangerth opened this issue Oct 7, 2023 · 0 comments
Open

Comments

@bangerth
Copy link
Contributor

bangerth commented Oct 7, 2023

In both solver.cc and stokes_matrix_free.cc, we invoke the signals.post_stokes_solver signal *but then continue on doing things that clean up the solution variable. This looks as follows:

    //signal successful solver
    sim.signals.post_stokes_solver(sim,
                                   preconditioner_cheap.n_iterations_Schur_complement() + preconditioner_expensive.n_iterations_Schur_complement(),
                                   preconditioner_cheap.n_iterations_A_block() + preconditioner_expensive.n_iterations_A_block(),
                                   solver_control_cheap,
                                   solver_control_expensive);

    // distribute hanging node and other constraints
    solution_copy.update_ghost_values();
    internal::ChangeVectorTypes::copy(distributed_stokes_solution,solution_copy);

#if DEAL_II_VERSION_GTE(9,6,0)
    IndexSet stokes_dofs (sim.dof_handler.n_dofs());
    stokes_dofs.add_range (0, distributed_stokes_solution.size());
    const AffineConstraints<double> current_stokes_constraints
      = sim.current_constraints.get_view (stokes_dofs);
    current_stokes_constraints.distribute(distributed_stokes_solution);
#else
    sim.current_constraints.distribute(distributed_stokes_solution);
#endif

    // now rescale the pressure back to real physical units
    distributed_stokes_solution.block(block_p) *= sim.pressure_scaling;

    // then copy back the solution from the temporary (non-ghosted) vector
    // into the ghosted one with all solution components
    sim.solution.block(block_vel) = distributed_stokes_solution.block(block_vel);
    sim.solution.block(block_p) = distributed_stokes_solution.block(block_p);

    if (print_details)
      {
        sim.pcout << "    Schur complement preconditioner: " << preconditioner_cheap.n_iterations_Schur_complement()
                  << '+'
                  << preconditioner_expensive.n_iterations_Schur_complement()
                  << " iterations." << std::endl;
        sim.pcout << "    A block preconditioner: " << preconditioner_cheap.n_iterations_A_block()
                  << '+'
                  << preconditioner_expensive.n_iterations_A_block()
                  << " iterations." << std::endl;
      }

    // do some cleanup now that we have the solution
    sim.remove_nullspace(sim.solution, distributed_stokes_solution);
    if (sim.assemble_newton_stokes_system == false)
      sim.last_pressure_normalization_adjustment = sim.normalize_pressure(sim.solution);

I think that all of that stuff all the way down should be considered part of the "solve stokes" phase, and that the signal is probably best called after all of that.

The documentation only says this:

    /**
     * A signal that is triggered when the iterative Stokes solver is done.
     * Parameters are a reference to the SimulatorAccess, the number of
     * preconditioner inner solver iterations for the S and A block of the
     * system, and two information objects that contain information
     * about the success of the solve, the number of outer GMRES iterations
     * and the residual history for the cheap and expensive solver phase.
     */
    boost::signals2::signal<void (const SimulatorAccess<dim> &,
                                  const unsigned int number_S_iterations,
                                  const unsigned int number_A_iterations,
                                  const SolverControl &solver_control_cheap,
                                  const SolverControl &solver_control_expensive)> post_stokes_solver;

So presumably the intent is for that signal only to learn about the iterative solution process, but it is entirely conceivable that someone might actually want to inspect the solution in such a signal as well, so we better have that ready.

I will note that the signal isn't called after the direct solver. I will document that next.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant