From 39b92169c9935acc682d4c9abf9812e75aadff39 Mon Sep 17 00:00:00 2001 From: SteveMaas1978 Date: Wed, 21 Aug 2024 14:31:27 -0600 Subject: [PATCH] Users can now set the max nr. of negative jacobians reported using the output_negative_jacobians flag. --- FEBio/FEBioApp.cpp | 9 +++------ FEBio/FEBioCommand.cpp | 4 ++-- FEBioLib/config.cpp | 2 +- FECore/FEException.cpp | 17 +++++++++++++++-- FECore/FEException.h | 15 +++++++++++++-- 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/FEBio/FEBioApp.cpp b/FEBio/FEBioApp.cpp index f3d3da506..b6564f6d8 100644 --- a/FEBio/FEBioApp.cpp +++ b/FEBio/FEBioApp.cpp @@ -351,7 +351,6 @@ bool FEBioApp::ParseCmdLine(int nargs, char* argv[]) else if ((strcmp(sz, "-g") == 0) || (strcmp(sz, "-g1") == 0)) { ops.ndebug = 1; - NegativeJacobian::m_boutput = true; } else if (strcmp(sz, "-g2") == 0) { @@ -436,15 +435,13 @@ bool FEBioApp::ParseCmdLine(int nargs, char* argv[]) } else if (strncmp(sz, "-output_negative_jacobians", 26) == 0) { - bool output = true; + int n = -1; if (sz[26] == '=') { const char* szval = sz + 27; - if (strcmp(szval, "0") == 0) output = false; - else if (strcmp(szval, "1") == 0) output = true; - else { fprintf(stderr, "Invalid value for output_negative_jacobian option\n"); return false; } + n = atoi(szval); } - NegativeJacobian::m_boutput = output; + NegativeJacobian::m_maxout = n; } else if (sz[0] == '-') { diff --git a/FEBio/FEBioCommand.cpp b/FEBio/FEBioCommand.cpp index 071596ff7..99291ebf4 100644 --- a/FEBio/FEBioCommand.cpp +++ b/FEBio/FEBioCommand.cpp @@ -741,7 +741,7 @@ int FEBioCmd_set::run(int nargs, char** argv) FEBioModel* fem = GetFEM(); if (nargs == 1) { - printf("output_negative_jacobians = %d\n", (NegativeJacobian::m_boutput ? 1 : 0)); + printf("output_negative_jacobians = %d\n", NegativeJacobian::m_maxout); if (fem) { printf("print_model_params = %d\n", (fem->GetPrintParametersFlag() ? 1 : 0)); @@ -760,7 +760,7 @@ int FEBioCmd_set::run(int nargs, char** argv) if (strcmp(argv[1], "output_negative_jacobians") == 0) { - NegativeJacobian::m_boutput = (n != 0); + NegativeJacobian::m_maxout = n; printf("output_negative_jacobians = %d", n); } else if (fem && strcmp(argv[1], "print_model_params") == 0) diff --git a/FEBioLib/config.cpp b/FEBioLib/config.cpp index 924ea91c7..54f71a4d3 100644 --- a/FEBioLib/config.cpp +++ b/FEBioLib/config.cpp @@ -207,7 +207,7 @@ namespace febio { { int n; tag.value(n); - NegativeJacobian::m_boutput = (n != 0); + NegativeJacobian::m_maxout = n; return true; } diff --git a/FECore/FEException.cpp b/FECore/FEException.cpp index 4bdba6a26..1e74061e1 100644 --- a/FECore/FEException.cpp +++ b/FECore/FEException.cpp @@ -145,8 +145,9 @@ ZeroDiagonal::ZeroDiagonal(vector& l, FEM& fem) } */ //============================================================================= -bool NegativeJacobian::m_boutput = false; bool NegativeJacobian::m_bthrown = false; +int NegativeJacobian::m_maxout = 0; // output off by default +int NegativeJacobian::m_count = 0; //----------------------------------------------------------------------------- NegativeJacobian::NegativeJacobian(int iel, int ng, double vol, FEElement* pe) @@ -162,7 +163,9 @@ NegativeJacobian::NegativeJacobian(int iel, int ng, double vol, FEElement* pe) //----------------------------------------------------------------------------- bool NegativeJacobian::DoOutput() { - return m_boutput; + m_count++; // we do this here because this function is called from critical sections. + bool b = (m_maxout < 0) || (m_count <= m_maxout); + return b; } //----------------------------------------------------------------------------- @@ -177,6 +180,16 @@ bool NegativeJacobian::IsThrown() return m_bthrown; } +int NegativeJacobian::Count() +{ + return m_count; +} + +void NegativeJacobian::ResetCount() +{ + m_count = 0; +} + //----------------------------------------------------------------------------- NANInResidualDetected::NANInResidualDetected(const FENodalDofInfo& ndi) { diff --git a/FECore/FEException.h b/FECore/FEException.h index b4daf03d1..19f30d62f 100644 --- a/FECore/FEException.h +++ b/FECore/FEException.h @@ -72,9 +72,13 @@ class FECORE_API NegativeJacobian : public FEException static void clearFlag(); static bool IsThrown(); + static int Count(); + static void ResetCount(); + public: - static bool m_boutput; //!< set to false to suppress output of negative jacobians static bool m_bthrown; + static int m_maxout; // max nr of negative jacobians reported (< 0 for unlimited, 0 = off, > 0 sets limit) + static int m_count; }; class FECORE_API ZeroDiagonal : public FEException @@ -151,7 +155,14 @@ public: FactorizationError() : FEException("Fatal error in factorization of stif }; class FECORE_API NegativeJacobianDetected : public FEException { -public: NegativeJacobianDetected() : FEException("Negative jacobian was detected.") {} +public: NegativeJacobianDetected() { + int n = NegativeJacobian::Count(); + if (n > 1) + what("%d negative jacobians detected.", n); + else + what("Negative jacobian detected."); + NegativeJacobian::ResetCount(); + } }; class FECORE_API ConcentrationChangeDetected : public FEException {