Commit 0444972f authored by GILLES Sebastien's avatar GILLES Sebastien

#1499 Fix a possible ABI issue: if an exception is thrown inside the functions...

#1499 Fix a possible ABI issue: if an exception is thrown inside the functions given to SNESSolve, we could have uncaught exceptions. So now the exceptions are caught inside the functions, the what() message is displayed an a non-zero return value is returned.
parent 8e421bd2
......@@ -40,7 +40,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
......
......@@ -110,9 +110,7 @@ namespace MoReFEM
else
{
// Create it nonetheless - but will trigger an exception if the value is called.
MoReFEM::Internal::MoReFEMDataNS::CheckInvertedElements
::CreateOrGetInstance(__FILE__, __LINE__);
MoReFEM::Internal::MoReFEMDataNS::CheckInvertedElements::CreateOrGetInstance(__FILE__, __LINE__);
}
}
catch(const ExceptionNS::GracefulExit& e)
......
......@@ -114,7 +114,7 @@ namespace MoReFEM
const auto& mpi = GetMpi();
const auto rank = mpi.GetRank<unsigned int>();
// Create the nodes for all finite element spaces.
CreateNodeList();
......
......@@ -62,8 +62,6 @@ namespace MoReFEM
}
} // namespace MoReFEM
......
......@@ -134,48 +134,56 @@ namespace MoReFEM
{
static_cast<void>(snes);
static_cast<void>(a_residual); // a_residual is not used as its content mirror the one of system_rhs_.
// \a context_as_void is in fact the VariationalFormulation object.
assert(context_as_void);
VariationalFormulation* variational_formulation_ptr = static_cast<VariationalFormulation*>(context_as_void);
assert(!(!variational_formulation_ptr));
auto& variational_formulation = *variational_formulation_ptr;
#ifndef NDEBUG
const auto& displacement_numbering_subset = variational_formulation.GetDisplacementNumberingSubset();
{
std::string desc;
namespace Petsc = Wrappers::Petsc;
const bool is_same = Petsc::AreEqual(Petsc::Vector(a_residual, false),
variational_formulation.GetSystemRhs(displacement_numbering_subset),
1.e-12,
desc,
__FILE__, __LINE__);
if (!is_same)
{
std::cerr << "Bug in SNES implementation: third argument of snes function implemention is expected "
"to be the residual, which is born in VariationalFormulationT by the attribute RHS(). It is not the case "
"here.\n" << desc << std::endl;
variational_formulation.GetSystemRhs(displacement_numbering_subset).View(variational_formulation.GetMpi(), __FILE__, __LINE__);
try
{
// \a context_as_void is in fact the VariationalFormulation object.
assert(context_as_void);
assert(false);
}
}
#endif // NDEBUG
variational_formulation.UpdateVectorsAndMatrices(petsc_vec_displacement_at_newton_iteration);
variational_formulation.ComputeResidual();
return 0;
VariationalFormulation* variational_formulation_ptr = static_cast<VariationalFormulation*>(context_as_void);
assert(!(!variational_formulation_ptr));
auto& variational_formulation = *variational_formulation_ptr;
#ifndef NDEBUG
const auto& displacement_numbering_subset = variational_formulation.GetDisplacementNumberingSubset();
{
std::string desc;
namespace Petsc = Wrappers::Petsc;
const bool is_same = Petsc::AreEqual(Petsc::Vector(a_residual, false),
variational_formulation.GetSystemRhs(displacement_numbering_subset),
1.e-12,
desc,
__FILE__, __LINE__);
if (!is_same)
{
std::cerr << "Bug in SNES implementation: third argument of snes function implemention is expected "
"to be the residual, which is born in VariationalFormulationT by the attribute RHS(). It is not the case "
"here.\n" << desc << std::endl;
variational_formulation.GetSystemRhs(displacement_numbering_subset).View(variational_formulation.GetMpi(), __FILE__, __LINE__);
assert(false);
}
}
#endif // NDEBUG
variational_formulation.UpdateVectorsAndMatrices(petsc_vec_displacement_at_newton_iteration);
variational_formulation.ComputeResidual();
return EXIT_SUCCESS;
}
catch(const std::exception& e)
{
std::cerr << "Exception caught: " << e.what() << std::endl;
return EXIT_FAILURE;
}
}
......@@ -419,20 +427,29 @@ namespace MoReFEM
static_cast<void>(jacobian);
static_cast<void>(preconditioner);
static_cast<void>(evaluation_state);
// \a context_as_void is in fact the VariationalFormulation object.
assert(context_as_void);
VariationalFormulation* variational_formulation_ptr = static_cast<VariationalFormulation*>(context_as_void);
assert(!(!variational_formulation_ptr));
auto& variational_formulation = *variational_formulation_ptr;
variational_formulation.ComputeTangent();
return 0;
try
{
// \a context_as_void is in fact the VariationalFormulation object.
assert(context_as_void);
VariationalFormulation* variational_formulation_ptr = static_cast<VariationalFormulation*>(context_as_void);
assert(!(!variational_formulation_ptr));
auto& variational_formulation = *variational_formulation_ptr;
variational_formulation.ComputeTangent();
return EXIT_SUCCESS;
}
catch(const std::exception& e)
{
std::cerr << "Exception caught: " << e.what() << std::endl;
return EXIT_FAILURE;
}
}
void VariationalFormulation::ComputeTangent()
{
......@@ -493,35 +510,43 @@ namespace MoReFEM
{
static_cast<void>(snes);
assert(context_as_void);
const VariationalFormulation* variational_formulation_ptr =
static_cast<const VariationalFormulation*>(context_as_void);
assert(!(!variational_formulation_ptr));
const auto& variational_formulation = *variational_formulation_ptr;
const auto& displacement = variational_formulation.GetVectorDisplacementAtNewtonIteration();
const auto& velocity = variational_formulation.GetVectorVelocityAtNewtonIteration();
const PetscReal displacement_min = displacement.Min(__FILE__, __LINE__).second;
const PetscReal displacement_max = displacement.Max(__FILE__, __LINE__).second;
const PetscReal velocity_min = velocity.Min(__FILE__, __LINE__).second;
const PetscReal velocity_max = velocity.Max(__FILE__, __LINE__).second;
Wrappers::Petsc::PrintMessageOnFirstProcessor("%3D Residual norm: %1.12e Ymin: %8.6e Ymax: %8.6e Ypmin: %8.6e Ypmax: %8.6e\n",
variational_formulation.GetMpi(),
__FILE__, __LINE__,
its + 1,
norm,
displacement_min,
displacement_max,
velocity_min,
velocity_max
);
return 0;
try
{
const VariationalFormulation* variational_formulation_ptr =
static_cast<const VariationalFormulation*>(context_as_void);
assert(!(!variational_formulation_ptr));
const auto& variational_formulation = *variational_formulation_ptr;
const auto& displacement = variational_formulation.GetVectorDisplacementAtNewtonIteration();
const auto& velocity = variational_formulation.GetVectorVelocityAtNewtonIteration();
const PetscReal displacement_min = displacement.Min(__FILE__, __LINE__).second;
const PetscReal displacement_max = displacement.Max(__FILE__, __LINE__).second;
const PetscReal velocity_min = velocity.Min(__FILE__, __LINE__).second;
const PetscReal velocity_max = velocity.Max(__FILE__, __LINE__).second;
Wrappers::Petsc::PrintMessageOnFirstProcessor("%3D Residual norm: %1.12e Ymin: %8.6e Ymax: %8.6e Ypmin: %8.6e Ypmax: %8.6e\n",
variational_formulation.GetMpi(),
__FILE__, __LINE__,
its + 1,
norm,
displacement_min,
displacement_max,
velocity_min,
velocity_max
);
return EXIT_SUCCESS;
}
catch(const std::exception& e)
{
std::cerr << "Exception caught: " << e.what() << std::endl;
return EXIT_FAILURE;
}
}
void VariationalFormulation::PrepareDynamicRuns()
......
......@@ -144,7 +144,6 @@ namespace MoReFEM
const auto& geom_elt = elementary_data.GetCurrentGeomElt();
for (const auto& infos_at_quad_pt : infos_at_quad_pt_list)
{
tangent_matrix.fill(0.);
......
......@@ -207,7 +207,8 @@ namespace MoReFEM
error_code = SNESMonitorSet(snes_, GetSnesViewer(), context, PETSC_NULL);
if (error_code)
throw ExceptionNS::Exception(error_code, "SNESMonitorSet", invoking_file, invoking_line);
error_code = SNESSolve(snes_, nullptr, solution.Internal());
if (error_code)
throw ExceptionNS::Exception(error_code, "SNESSolve", invoking_file, invoking_line);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment