"I think that's what you had in mind, right?"

Yes :)

"Do you want to take a look whether the PETSC SNES and the Trilinos NOX
solvers behave in the same way and perhaps also need to be fixed?"

I do not have Trilinos configured with NOX on my system.
For PETSC SNES, I attached a test that allows only a single nonlinear 
iteration.
But the error message (release mode) is very descriptive: 

***************************************************************
Computing residual for the 1th time, at u=10
Setting up Jacobian system at u=10
Computing residual for the 2th time, at u=10
Computing residual for the 3th time, at u=-88.0839
Reporting recoverable failure.
Computing residual for the 3th time, at u=-39.0419
Reporting recoverable failure.
Computing residual for the 3th time, at u=-14.521
Reporting recoverable failure.
Computing residual for the 3th time, at u=-2.26049
Computing residual for the 4th time, at u=8.77395
Nonlinear Solver threw an exception with the following message:

--------------------------------------------------------
An error occurred in line <649> of file 
</calculate/temp/ltmadmin/spack-stage-dealii-9.6.0-zazikg5icx5chodqsv5hc7v77ksctgrj/spack-src/include/deal.II/lac/petsc_snes.templates.h>
 
in function
    unsigned int dealii::PETScWrappers::NonlinearSolver<VectorType, 
PMatrixType, AMatrixType>::solve(VectorType&) [with VectorType = 
dealii::PETScWrappers::MPI::Vector; PMatrixType = 
dealii::PETScWrappers::MatrixBase; AMatrixType = 
dealii::PETScWrappers::MatrixBase]
The violated condition was: 
    reason > 0
Additional information: 
    SNES solver did not converge after 1 iterations with reason
    DIVERGED_MAX_IT

***************************************************************

Additionally, if the user callbacks fail repeatedly (e.g., comment in the 
count variable), the resulting error message remains informative.

Therefore, I have no suggestions regarding PETSC SNES. 

Best,
Simon

On Tuesday, May 6, 2025 at 10:43:32 PM UTC+2 Wolfgang Bangerth wrote:


Simon: 

> That said, if there is no pending exception from the callbacks, the 
> status returned by KINSOL 
> is ignored in release mode. 
> One solution would be to define the AssertKINSOL macro as 
> "AssertThrow(...)", rather than "Assert(...)". 

Yes, thanks for showing me a situation where this can happen! I made 
this into a test, and changed the Assert into AssertThrow here: 
https://github.com/dealii/dealii/pull/18428 
I think that's what you had in mind, right? 

Do you want to take a look whether the PETSC SNES and the Trilinos NOX 
solvers behave in the same way and perhaps also need to be fixed? 

Best & thanks for the collaboration! 
W. 

-- 
The deal.II project is located at http://www.dealii.org/
For mailing list/forum options, see 
https://groups.google.com/d/forum/dealii?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"deal.II User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/dealii/3b1b1b70-35c3-4576-aee7-86c503871752n%40googlegroups.com.
// ------------------------------------------------------------------------
//
// SPDX-License-Identifier: LGPL-2.1-or-later
// Copyright (C) 2017 - 2023 by the deal.II authors
//
// This file is part of the deal.II library.
//
// Part of the source code is dual licensed under Apache-2.0 WITH
// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
// governing the source code and code contributions can be found in
// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
//
// ------------------------------------------------------------------------

#include <deal.II/base/utilities.h>

#include <deal.II/lac/petsc_vector.h>

#include <deal.II/numerics/nonlinear.h>

#include <fstream>


// Test description goes here


int
main(int argc, char *argv[])
{

  using namespace dealii;

  using VectorType = PETScWrappers::MPI::Vector;

  Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);

  // Size of the problem
  const unsigned int N = 1;

  NonlinearSolverSelector<VectorType>::AdditionalData additional_data;
  additional_data.solver_type =
  NonlinearSolverSelector<VectorType>::AdditionalData::SolverType::petsc_snes;
  additional_data.maximum_non_linear_iterations = 1;

  NonlinearSolverSelector<VectorType> nonlinear_solver(additional_data);

  nonlinear_solver.reinit_vector = [N](VectorType &v) { v.reinit(MPI_COMM_WORLD, N, N); };

  nonlinear_solver.residual = [&](const VectorType &u, VectorType &F) {
    // Count how many times this function has been called. 
    static int count = 0;
    std::cout << "Computing residual for the " << count + 1
            << "th time, at u=" << u[0] << std::endl;
    if ((u[0] < -10) || (u[0] > 20) /* || (count > 0) */)
      {
        std::cout << "Reporting recoverable failure." << std::endl;
        throw RecoverableUserCallbackError();
      }
    count++;


    F.reinit(u);
    F[0] = std::atan(u[0]) - 0.5;
    F.compress(VectorOperation::values::insert);
  };

  double J_inverse;

  nonlinear_solver.setup_jacobian = [&J_inverse](const VectorType &u) {
    std::cout << "Setting up Jacobian system at u=" << u[0] << std::endl;

    const double J = 1. / (1 + u[0] * u[0]);
    J_inverse      = 1. / J;
  };


  nonlinear_solver.solve_with_jacobian = [&](const VectorType &rhs,
                                   VectorType       &dst,
                                   double) { 
    dst[0] = J_inverse * rhs[0]; 
    dst.compress(VectorOperation::values::insert); 
  };


  VectorType v(MPI_COMM_WORLD, N, N);
  v[0] = 10;
  v.compress(VectorOperation::values::insert);

  try
    {
      nonlinear_solver.solve(v);
    }
  catch (const std::exception &e)
    {
      std::cout << "Nonlinear Solver threw an exception with the following message:"
              << std::endl
              << e.what() << std::endl;
    }
}

Reply via email to