@@ -683,61 +683,69 @@ namespace aspect
683683 // why that happened:
684684
685685 // todo_solver
686-
687- // If the exception we got is not one of the two documented by
688- // throw_linear_solver_failure_exception(), then we have a genuine
689- // problem here, and will need to get outta here right away:
690- if ((dynamic_cast <const ExcMessage *>(&exc)==nullptr ) &&
691- (dynamic_cast <const QuietException *>(&exc)==nullptr ))
692- throw ;
693-
694- // Otherwise, the solver presumably failed because the Newton matrix
695- // is not symmetric or not definite. If we do not actually want to
696- // handle this case, then again leave:
697- if (newton_handler->parameters .use_Newton_failsafe == false )
698- throw ;
699-
700- // Otherwise, start the solve over again and try with a stabilized version:
701- pcout << " failed, trying again with stabilization" << std::endl;
702- newton_handler->parameters .preconditioner_stabilization = Newton::Parameters::Stabilization::SPD;
703- newton_handler->parameters .velocity_block_stabilization = Newton::Parameters::Stabilization::SPD;
704-
705- // If the Stokes matrix depends on the solution, or we have active
706- // velocity boundary conditions, we need to re-assemble the system matrix
707- // (and preconditioner) every time. If we have active boundary conditions,
708- // they could a) depend on the solution, or b) be inhomogeneous. In both
709- // cases, just assembling the RHS will be incorrect. If no active
710- // boundaries exist, we only have no-slip or free slip conditions, so we
711- // don't need to force assembly of the matrix.
712- if (stokes_matrix_depends_on_solution ()
713- ||
714- (nonlinear_iteration == 0 && boundary_velocity_manager.get_prescribed_boundary_velocity_indicators ().size () > 0 ))
715- rebuild_stokes_matrix = rebuild_stokes_preconditioner = assemble_newton_stokes_matrix = true ;
716- else if (parameters.enable_prescribed_dilation )
717- // The dilation requires the Stokes matrix (which is on the rhs
718- // in the Newton solver) to be updated.
719- rebuild_stokes_matrix = true ;
720-
721- assemble_stokes_system ();
722-
723- /* *
724- * Eisenstat Walker method for determining the tolerance
725- */
726- if (nonlinear_iteration > 1 )
686+ // question, how the dcr.stokes_residuals got handled if solve_stokes throws some exception
687+ if (parameters.continue_nonlinear_solver_loop_after_linear_solver_failure )
688+ {
689+ pcout << " linear solver failed, but this is allowed and nonlinear solver loop continues" << std::endl;
690+ }
691+ else
727692 {
728- update_residuals ();
729693
730- // Eisenstat Walker method for determining the linear solver tolerance
731- if (!use_picard)
694+ // If the exception we got is not one of the two documented by
695+ // throw_linear_solver_failure_exception(), then we have a genuine
696+ // problem here, and will need to get outta here right away:
697+ if ((dynamic_cast <const ExcMessage *>(&exc)==nullptr ) &&
698+ (dynamic_cast <const QuietException *>(&exc)==nullptr ))
699+ throw ;
700+
701+ // Otherwise, the solver presumably failed because the Newton matrix
702+ // is not symmetric or not definite. If we do not actually want to
703+ // handle this case, then again leave:
704+ if (newton_handler->parameters .use_Newton_failsafe == false )
705+ throw ;
706+
707+ // Otherwise, start the solve over again and try with a stabilized version:
708+ pcout << " failed, trying again with stabilization" << std::endl;
709+ newton_handler->parameters .preconditioner_stabilization = Newton::Parameters::Stabilization::SPD;
710+ newton_handler->parameters .velocity_block_stabilization = Newton::Parameters::Stabilization::SPD;
711+
712+ // If the Stokes matrix depends on the solution, or we have active
713+ // velocity boundary conditions, we need to re-assemble the system matrix
714+ // (and preconditioner) every time. If we have active boundary conditions,
715+ // they could a) depend on the solution, or b) be inhomogeneous. In both
716+ // cases, just assembling the RHS will be incorrect. If no active
717+ // boundaries exist, we only have no-slip or free slip conditions, so we
718+ // don't need to force assembly of the matrix.
719+ if (stokes_matrix_depends_on_solution ()
720+ ||
721+ (nonlinear_iteration == 0 && boundary_velocity_manager.get_prescribed_boundary_velocity_indicators ().size () > 0 ))
722+ rebuild_stokes_matrix = rebuild_stokes_preconditioner = assemble_newton_stokes_matrix = true ;
723+ else if (parameters.enable_prescribed_dilation )
724+ // The dilation requires the Stokes matrix (which is on the rhs
725+ // in the Newton solver) to be updated.
726+ rebuild_stokes_matrix = true ;
727+
728+ assemble_stokes_system ();
729+
730+ /* *
731+ * Eisenstat Walker method for determining the tolerance
732+ */
733+ if (nonlinear_iteration > 1 )
732734 {
733- update_Eisenstat_Walker_tolerance ();
735+ update_residuals ();
736+
737+ // Eisenstat Walker method for determining the linear solver tolerance
738+ if (!use_picard)
739+ {
740+ update_Eisenstat_Walker_tolerance ();
741+ }
734742 }
735- }
736743
737- build_preconditioner ();
744+ build_preconditioner ();
738745
739- // Give this another try:
740- dcr.stokes_residuals = solve_stokes (search_direction);
746+ // Give this another try:
747+ dcr.stokes_residuals = solve_stokes (search_direction);
748+ }
741749 }
742750
743751 // Apply the solution or the update of the solution
0 commit comments