Commit c77d4c7d authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

#995 Add new macro HAPPY_HEART_CHECK_NAN_AND_INF to decide whether there...

#995 Add new macro HAPPY_HEART_CHECK_NAN_AND_INF to decide whether there should be additional checks upon the validity of numerical values found (in any case Petsc check there are no nan or inf in the solution of a linear or non linear solve).
parent 88a4a06f
This diff is collapsed.
......@@ -28,7 +28,11 @@ def ReadConfigurationFile(configuration_file):
vars.Add(SCons.Variables.BoolVariable('HAPPY_HEART_EXTENDED_TIME_KEEP', \
"If true, TimeKeep gains the ability to track times between each call of PrintTimeElapsed(). If not, PrintTimeElapsed() is flatly ignored.", \
None))
None))
vars.Add(SCons.Variables.BoolVariable('HAPPY_HEART_CHECK_NAN_AND_INF', \
"If true, there are additional checks that no nan and inf appears in the code. Even if False, solver always check for the validity of its solution (if a nan or an inf is present the SolveLinear() or SolveNonLinear() operation throws with a dedicated Petsc error). Advised in debug mode and up to you in release mode.", \
None))
vars.Add(SCons.Variables.PathVariable("BUILD_DIR", "Path to the folder into which build will be installed.", None, SCons.Variables.PathVariable.PathIsDirCreate))
vars.Add(SCons.Variables.PathVariable("INTERMEDIATE_BUILD_DIR", "Path to the folder into which intermediate build will be installed.", None, SCons.Variables.PathVariable.PathIsDirCreate))
......
......@@ -257,7 +257,8 @@ def DefineEnvironment(vars):
specific_macro_list = \
( \
"HAPPY_HEART_CHECK_UPDATE_GHOSTS_CALL_RELEVANCE", \
"HAPPY_HEART_EXTENDED_TIME_KEEP" \
"HAPPY_HEART_EXTENDED_TIME_KEEP", \
"HAPPY_HEART_CHECK_NAN_AND_INF", \
)
for entry in specific_macro_list:
......
......@@ -1144,12 +1144,18 @@ namespace HappyHeart
const auto& value_list = dof_storage.GetDofValueList();
assert(std::none_of(value_list.cbegin(),
value_list.cend(),
[](const double value)
{
return std::isinf(value) || std::isnan(value);
}));
# ifdef HAPPY_HEART_CHECK_NAN_AND_INF
if (std::any_of(value_list.cbegin(),
value_list.cend(),
[](double val)
{
return std::isnan(val) || std::isinf(val);
}))
{
throw Exception("Nan or Inf value found in GodOfDof::ApplyPseudoElimination().", __FILE__, __LINE__);
}
# endif // HAPPY_HEART_CHECK_NAN_AND_INF
vector.SetValues(dof_index_list,
value_list.data(),
......
......@@ -99,9 +99,9 @@ namespace HappyHeart
{
assert(out.GetNumberingSubset() == rhs.GetNumberingSubset());
#ifndef NDEBUG
Wrappers::Petsc::AssertNumericValues(this->MpiHappyHeart(), "rhs", rhs, invoking_file, invoking_line);
#endif // NDEBUG
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::CheckNumericValues(this->MpiHappyHeart(), "rhs", rhs, invoking_file, invoking_line);
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
DoPrintMessage do_print_message =
(this->GetTimeManager().NtimeModified() % GetDisplayValue()) == 0
......@@ -136,9 +136,9 @@ namespace HappyHeart
out.UpdateGhosts(__FILE__, __LINE__);
#ifndef NDEBUG
Wrappers::Petsc::AssertNumericValues(this->MpiHappyHeart(), "out", out, invoking_file, invoking_line);
#endif // NDEBUG
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::CheckNumericValues(this->MpiHappyHeart(), "out", out, invoking_file, invoking_line);
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
}
......
......@@ -228,24 +228,24 @@ namespace HappyHeart
{
auto& mixed_residual = GetNonCstMixedResidual(); // with velocity and pressure
#ifndef NDEBUG
Wrappers::Petsc::AssertNumericValues(this->MpiHappyHeart(),
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::CheckNumericValues(this->MpiHappyHeart(),
"system_sol",
GetSystemSolution(GetNumberingSubset()), __FILE__, __LINE__);
#endif // NDEBUG
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::MatMult(GetResidualMatrix(),
GetSystemSolution(GetNumberingSubset()),
mixed_residual,
__FILE__, __LINE__);
#ifndef NDEBUG
Wrappers::Petsc::AssertNumericValues(this->MpiHappyHeart(),
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::CheckNumericValues(this->MpiHappyHeart(),
"residual_rhs",
GetResidualRhs(), __FILE__, __LINE__);
Wrappers::Petsc::AssertNumericValues(this->MpiHappyHeart(),
Wrappers::Petsc::CheckNumericValues(this->MpiHappyHeart(),
"mixed_residual",mixed_residual, __FILE__, __LINE__);
#endif // NDEBUG
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::AXPY(-1., GetResidualRhs(), mixed_residual,
__FILE__, __LINE__);
......@@ -263,7 +263,7 @@ namespace HappyHeart
__FILE__, __LINE__);
#ifndef NDEBUG
Wrappers::Petsc::AssertNumericValues(this->MpiHappyHeart(),
Wrappers::Petsc::CheckNumericValues(this->MpiHappyHeart(),
"residual",residual, __FILE__, __LINE__);
#endif // NDEBUG
......
......@@ -304,14 +304,14 @@ namespace HappyHeart
__FILE__, __LINE__);
// implicit_step_fluid_formulation.WriteSolution(time_manager, numbering_subset); #819 Do it carefully: files must not be overwritten (especially with the toggle is_differential).
#ifndef NDEBUG
Wrappers::Petsc::AssertNumericValues(this->MpiHappyHeart(),
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::CheckNumericValues(this->MpiHappyHeart(),
"system_rhs",
implicit_step_fluid_formulation.GetSystemRhs(numbering_subset), __FILE__, __LINE__);
Wrappers::Petsc::AssertNumericValues(this->MpiHappyHeart(),
Wrappers::Petsc::CheckNumericValues(this->MpiHappyHeart(),
"system_sol",
implicit_step_fluid_formulation.GetSystemSolution(numbering_subset), __FILE__, __LINE__);
#endif // NDEBUG
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
if (is_differential == differential::no)
{
......
......@@ -217,10 +217,10 @@ namespace HappyHeart
implicit_step_fluid_formulation.GetSystemSolution(numbering_subset).template Print<MpiScale::processor_wise>(mpi, aitken_output_dir + "implicit_step_fluid_solution.hhdata", __FILE__, __LINE__);
#ifndef NDEBUG
Wrappers::Petsc::AssertNumericValues(implicit_step_fluid_formulation.GetSystemRhs(numbering_subset), __FILE__, __LINE__);
Wrappers::Petsc::AssertNumericValues(implicit_step_fluid_formulation.GetSystemSolution(numbering_subset), __FILE__, __LINE__);
#endif // NDEBUG
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::CheckNumericValues(implicit_step_fluid_formulation.GetSystemRhs(numbering_subset), __FILE__, __LINE__);
Wrappers::Petsc::CheckNumericValues(implicit_step_fluid_formulation.GetSystemSolution(numbering_subset), __FILE__, __LINE__);
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
}
}
......
......@@ -239,19 +239,19 @@ namespace HappyHeart
{
auto& mixed_residual = GetNonCstMixedResidual(); // with velocity and pressure
#ifndef NDEBUG
Wrappers::Petsc::AssertNumericValues(GetSystemSolution(GetNumberingSubset()), __FILE__, __LINE__);
#endif // NDEBUG
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::CheckNumericValues(GetSystemSolution(GetNumberingSubset()), __FILE__, __LINE__);
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::MatMult(GetResidualMatrix(),
GetSystemSolution(GetNumberingSubset()),
mixed_residual,
__FILE__, __LINE__);
#ifndef NDEBUG
Wrappers::Petsc::AssertNumericValues(GetResidualRhs(), __FILE__, __LINE__);
Wrappers::Petsc::AssertNumericValues(mixed_residual, __FILE__, __LINE__);
#endif // NDEBUG
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::CheckNumericValues(GetResidualRhs(), __FILE__, __LINE__);
Wrappers::Petsc::CheckNumericValues(mixed_residual, __FILE__, __LINE__);
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::AXPY(-1., GetResidualRhs(), mixed_residual,
__FILE__, __LINE__);
......@@ -268,9 +268,9 @@ namespace HappyHeart
residual,
__FILE__, __LINE__);
#ifndef NDEBUG
Wrappers::Petsc::AssertNumericValues(residual, __FILE__, __LINE__);
#endif // NDEBUG
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::CheckNumericValues(residual, __FILE__, __LINE__);
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
residual.Scale(factor, __FILE__, __LINE__); // to comply with Freefem convention; probably not that good an idea.
......
......@@ -373,10 +373,10 @@ namespace HappyHeart
__FILE__, __LINE__);
// implicit_step_fluid_formulation.WriteSolution(time_manager, numbering_subset);
#ifndef NDEBUG
Wrappers::Petsc::AssertNumericValues(implicit_step_fluid_formulation.GetSystemRhs(numbering_subset), __FILE__, __LINE__);
Wrappers::Petsc::AssertNumericValues(implicit_step_fluid_formulation.GetSystemSolution(numbering_subset), __FILE__, __LINE__);
#endif // NDEBUG
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::CheckNumericValues(implicit_step_fluid_formulation.GetSystemRhs(numbering_subset), __FILE__, __LINE__);
Wrappers::Petsc::CheckNumericValues(implicit_step_fluid_formulation.GetSystemSolution(numbering_subset), __FILE__, __LINE__);
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
if (is_differential == differential::no)
{
......
......@@ -81,15 +81,15 @@ namespace HappyHeart
GetPorosity().Assemble(std::make_tuple(std::ref(vector)), GetSolidDisplacement());
#ifndef NDEBUG
Wrappers::Petsc::AssertNumericValues(this->MpiHappyHeart(),
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Petsc::CheckNumericValues(this->MpiHappyHeart(),
"solid_displacement",
GetSolidDisplacement(), __FILE__, __LINE__);
Wrappers::Petsc::AssertNumericValues(this->MpiHappyHeart(),
Wrappers::Petsc::CheckNumericValues(this->MpiHappyHeart(),
"rhs",
rhs, __FILE__, __LINE__);
#endif // NDEBUG
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
}
......
......@@ -477,11 +477,19 @@ namespace HappyHeart
transposed_De,
dW,
d2W);
<<<<<<< 88a4a06fc3f15387008b168a8e738a176baefa4d:Sources/OperatorInstances/VariationalOperator/NonlinearForm/Local/SecondPiolaKirchhoffStressTensor.hxx
# ifndef NDEBUG
Wrappers::Seldon::ThrowIfNanInside(d2W, __FILE__, __LINE__);
# endif // NDEBUG
=======
# ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Seldon::ThrowIfNanInside(d2W, __FILE__, __LINE__);
# endif // HAPPY_HEART_CHECK_NAN_AND_INF
>>>>>>> #995 Add new macro HAPPY_HEART_CHECK_NAN_AND_INF to decide whether there should be additional checks upon the validity of numerical values found (in any case Petsc check there are no nan or inf in the solution of a linear or non linear solve).:Sources/Operators/LocalVariationalOperatorInstances/NonlinearForm/SecondPiolaKirchhoffStressTensor.hxx
// ===================================================================================
// Finally build the terms that are actually required.
// ===================================================================================
......
......@@ -87,10 +87,10 @@ namespace HappyHeart
Seldon::Add(dWdI1, d2I1dC, d2W);
Seldon::Add(dWdI2, d2I2dC, d2W);
Seldon::Add(dWdI3, d2I3dC, d2W);
# ifndef NDEBUG
# ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Seldon::ThrowIfNanInside(d2W, __FILE__, __LINE__);
# endif // NDEBUG
# endif // HAPPY_HEART_CHECK_NAN_AND_INF
}
{
......
......@@ -69,9 +69,9 @@ namespace HappyHeart
Seldon::Mlt(1., transposed_De, d2W, linear_part_intermediate_matrix);
Seldon::Mlt(1., linear_part_intermediate_matrix, De, linear_part);
# ifndef NDEBUG
# ifdef HAPPY_HEART_CHECK_NAN_AND_INF
Wrappers::Seldon::ThrowIfNanInside(linear_part, __FILE__, __LINE__);
# endif // NDEBUG
# endif // HAPPY_HEART_CHECK_NAN_AND_INF
}
......
......@@ -68,13 +68,19 @@ namespace HappyHeart
assert((value_list_.size() == 3ul && mesh_dimension_ == 2ul)
|| (value_list_.size() == 6ul && mesh_dimension_ == 3ul));
assert(std::none_of(value_list_.cbegin(),
# ifdef HAPPY_HEART_CHECK_NAN_AND_INF
if (std::any_of(value_list_.cbegin(),
value_list_.cend(),
[](double val)
{
return std::isnan(val);
}));
return std::isnan(val) || std::isinf(val);
}))
{
throw Exception("Nan or Inf value found in CauchyGreenTensor.", __FILE__, __LINE__);
}
# endif // HAPPY_HEART_CHECK_NAN_AND_INF
return value_list_;
}
......
......@@ -682,8 +682,8 @@ namespace HappyHeart
}
#ifndef NDEBUG
void AssertNumericValues(const Mpi& mpi,
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
void CheckNumericValues(const Mpi& mpi,
const std::string& vector_name,
const Vector& vector,
const char* invoking_file, int invoking_line)
......@@ -715,7 +715,7 @@ namespace HappyHeart
}
}
#endif // NDEBUG
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
#ifdef HAPPY_HEART_CHECK_UPDATE_GHOSTS_CALL_RELEVANCE
......
......@@ -716,19 +716,22 @@ namespace HappyHeart
};
# ifndef NDEBUG
# ifdef HAPPY_HEART_CHECK_NAN_AND_INF
/*!
* \brief Assert none of the values is inf or nan.
* \brief Check none of the values is inf or nan.
*
* \copydetails doxygen_hide_mpi_param
* \param[in] vector_name Name of the vector under check; it is only used to provide information in the log.
* \param[in] vector Vector being scrutinized.
* \copydoc doxygen_hide_invoking_file_and_line
*/
void AssertNumericValues(const Mpi& mpi,
void CheckNumericValues(const Mpi& mpi,
const std::string& vector_name,
const Vector& vector,
const char* invoking_file, int invoking_line);
# endif // NDEBUG
# endif // HAPPY_HEART_CHECK_NAN_AND_INF
......
......@@ -97,8 +97,7 @@ namespace HappyHeart
}
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
void ThrowIfNanInside(const LocalMatrix& matrix, const char* invoking_file, int invoking_line)
{
const int Nrow = matrix.GetM();
......@@ -121,6 +120,7 @@ namespace HappyHeart
if (is_nan)
throw Exception("NaN value found in local matrix!", invoking_file, invoking_line);
}
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
bool IsZeroMatrix(const LocalMatrix& matrix)
......
......@@ -79,6 +79,8 @@ namespace HappyHeart
#endif // NDEBUG
#ifdef HAPPY_HEART_CHECK_NAN_AND_INF
/*!
* \brief Throw an exception if there is a nan values in a matrix.
*
......@@ -94,6 +96,9 @@ namespace HappyHeart
void ThrowIfNanInside(const LocalMatrix& matrix, const char* invoking_file, int invoking_line);
#endif // HAPPY_HEART_CHECK_NAN_AND_INF
/*!
* \brief Check whether a matrix is filled only with zero.
*/
......
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