Skip to content

Commit

Permalink
Merge pull request #595 from thelfer/594-mfront-add-the-disable_runti…
Browse files Browse the repository at this point in the history
…me_checks-option

Fix Issue #594
  • Loading branch information
thelfer authored Jun 26, 2024
2 parents a69c7c8 + ac0511f commit 64c2da4
Show file tree
Hide file tree
Showing 22 changed files with 492 additions and 373 deletions.
8 changes: 8 additions & 0 deletions docs/web/release-notes-5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ T.setGlossaryName("Temperature");
}
~~~~

## New DSL options

### The `disable_runtime_checks` option

If this option is set to `true`, interfaces may disable as much runtime
checks as possible. Those runtime checks include checking standard
bounds and physical bounds for instance.

## `generic` interface improvements

### The `@SelectedModellingHypothesis` and `@SelectedModellingHypotheses` keywords
Expand Down
2 changes: 2 additions & 0 deletions mfront/include/MFront/DSLBase.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ namespace mfront {
static const char* const buildIdentifierOption;
//! \brief standard option
static const char* const overridingParameters;
//! \brief standard option name
static const char* const disableRuntimeChecksOption;
//! \return a validator for the options passed to the DSL
static tfel::utilities::DataMapValidator getDSLOptionsValidator();
//
Expand Down
17 changes: 17 additions & 0 deletions mfront/include/MFront/MaterialKnowledgeDescription.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ namespace mfront {
struct MFRONT_VISIBILITY_EXPORT MaterialKnowledgeDescription {
//! \brief standard option and attribute name
static const char* const defaultOutOfBoundsPolicy;
//! \brief standard option and attribute name
static const char* const disableRuntimeChecks;
//! \brief standard option name
static const char* const runtimeModificationOfTheOutOfBoundsPolicy;
//! \brief attribute name
Expand Down Expand Up @@ -157,6 +159,21 @@ namespace mfront {
externalMFrontFiles;
}; // end of struct MaterialKnowledgeDescription

/*!
* \brief set if runtime checks shall be disabled
* \param[out] d: material knowledge description
* \param[in] b: boolean
*/
MFRONT_VISIBILITY_EXPORT void setDisableRuntimeChecks(
MaterialKnowledgeDescription&, const bool);
/*!
* \brief this function returns the value of the
* `MaterialKnowledgeDescription::disableRuntimeChecks`
* attribute if it is defined, `false` otherwise.
* \param[in] d: material knowledge description
*/
MFRONT_VISIBILITY_EXPORT bool areRuntimeChecksDisabled(
const MaterialKnowledgeDescription&);
/*!
* \brief set the default out of bounds policy
* \param[out] d: material knowledge description
Expand Down
16 changes: 9 additions & 7 deletions mfront/src/BehaviourCodeGeneratorBase.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2082,13 +2082,15 @@ namespace mfront {
os << "this->updateIntegrationVariables();\n"
<< "this->updateStateVariables();\n"
<< "this->updateAuxiliaryStateVariables();\n";
for (const auto& v :
this->bd.getBehaviourData(h).getPersistentVariables()) {
this->writePhysicalBoundsChecks(os, v, false);
}
for (const auto& v :
this->bd.getBehaviourData(h).getPersistentVariables()) {
this->writeBoundsChecks(os, v, false);
if (!areRuntimeChecksDisabled(this->bd)) {
for (const auto& v :
this->bd.getBehaviourData(h).getPersistentVariables()) {
this->writePhysicalBoundsChecks(os, v, false);
}
for (const auto& v :
this->bd.getBehaviourData(h).getPersistentVariables()) {
this->writeBoundsChecks(os, v, false);
}
}
if (!this->bd.getTangentOperatorBlocks().empty()) {
if (hasUserDefinedTangentOperatorCode(this->bd, h)) {
Expand Down
69 changes: 36 additions & 33 deletions mfront/src/CMaterialPropertyInterfaceBase.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -560,44 +560,45 @@ namespace mfront {
}
}
this->writeInterfaceSpecificVariables(os, mpd);
if (!mpd.inputs.empty()) {
if ((!areRuntimeChecksDisabled(mpd)) && (!mpd.inputs.empty())) {
os << "#ifndef MFRONT_NOERRNO_HANDLING\n"
<< "const auto mfront_errno_old = errno;\n"
<< "errno=0;\n"
<< "#endif /* MFRONT_NOERRNO_HANDLING */\n";
}

os << "auto " << mpd.output.name << " = " << mpd.output.type << "{};\n";
this->writeCxxTryBlock(os);
os << mpd.f.body << "\n";
// checking the bounds and physical bounds of the output
if ((mpd.output.hasBounds()) || (mpd.output.hasPhysicalBounds())) {
const auto cast_start = useQuantities(mpd) ? mpd.output.type + "(" : "";
const auto cast_end = useQuantities(mpd) ? ")" : "";
if (mpd.output.hasPhysicalBounds()) {
const auto b = mpd.output.getPhysicalBounds();
if (b.boundsType == VariableBoundsDescription::LOWER) {
os << "if(" << mpd.output.name << " < " << cast_start << b.lowerBound
<< cast_end << "){\n"
<< "return std::nan(\"\");\n"
<< "}\n";
} else if (b.boundsType == VariableBoundsDescription::UPPER) {
os << "if(" << mpd.output.name << " > " << cast_start << b.upperBound
<< cast_end << "){\n"
<< "return std::nan(\"\");\n"
<< "}\n";
} else {
os << "if((" << mpd.output.name << " < " << cast_start << b.lowerBound
<< cast_end << ")||"
<< "(" << mpd.output.name << " > " << cast_start << b.upperBound
<< cast_end << ")){\n"
<< "return std::nan(\"\");\n"
<< "}\n";
if (!areRuntimeChecksDisabled(mpd)) {
// checking the bounds and physical bounds of the output
if ((mpd.output.hasBounds()) || (mpd.output.hasPhysicalBounds())) {
const auto cast_start = useQuantities(mpd) ? mpd.output.type + "(" : "";
const auto cast_end = useQuantities(mpd) ? ")" : "";
if (mpd.output.hasPhysicalBounds()) {
const auto b = mpd.output.getPhysicalBounds();
if (b.boundsType == VariableBoundsDescription::LOWER) {
os << "if(" << mpd.output.name << " < " << cast_start
<< b.lowerBound << cast_end << "){\n"
<< "return std::nan(\"\");\n"
<< "}\n";
} else if (b.boundsType == VariableBoundsDescription::UPPER) {
os << "if(" << mpd.output.name << " > " << cast_start
<< b.upperBound << cast_end << "){\n"
<< "return std::nan(\"\");\n"
<< "}\n";
} else {
os << "if((" << mpd.output.name << " < " << cast_start
<< b.lowerBound << cast_end << ")||"
<< "(" << mpd.output.name << " > " << cast_start << b.upperBound
<< cast_end << ")){\n"
<< "return std::nan(\"\");\n"
<< "}\n";
}
}
}
}
this->writeCxxCatchBlock(os, mpd, floating_point_type, use_qt);
if (!mpd.inputs.empty()) {
if ((!areRuntimeChecksDisabled(mpd)) && (!mpd.inputs.empty())) {
os << "#ifndef MFRONT_NOERRNO_HANDLING\n";
// can't use std::swap here as errno might be a macro
os << "const auto mfront_errno = errno;\n"
Expand Down Expand Up @@ -630,13 +631,15 @@ namespace mfront {
for (const auto& i : mpd.inputs) {
os << "static_cast<void>(" << i.name << ");\n";
}
if (hasPhysicalBounds(mpd.inputs)) {
os << "/* treating mpd.physical bounds */\n";
writePhysicalBounds(os, mpd);
}
if (hasBounds(mpd.inputs)) {
os << "/* treating standard bounds */\n";
writeBounds(os, mpd);
if (!areRuntimeChecksDisabled(mpd)) {
if (hasPhysicalBounds(mpd.inputs)) {
os << "/* treating mpd.physical bounds */\n";
writePhysicalBounds(os, mpd);
}
if (hasBounds(mpd.inputs)) {
os << "/* treating standard bounds */\n";
writeBounds(os, mpd);
}
}
os << "return 0;\n";
} // end of writeMaterialPropertyCheckBoundsBody
Expand Down
70 changes: 38 additions & 32 deletions mfront/src/CastemMaterialPropertyInterface.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -404,13 +404,15 @@ namespace mfront {
out << ")\n{\n";
writeBeginningOfMaterialPropertyBody(out, mpd, fd, "double", true);
// parameters
if ((!areParametersTreatedAsStaticVariables(mpd)) && (!params.empty())) {
const auto hn = getMaterialPropertyParametersHandlerClassName(name);
out << "if(!castem::" << hn << "::get" << hn << "().ok){\n"
<< "std::cerr << castem::" << hn << "::get" << hn
<< "().msg.c_str() << '\\n';\n"
<< "return std::nan(\"\");\n"
<< "}\n";
if (!areRuntimeChecksDisabled(mpd)) {
if ((!areParametersTreatedAsStaticVariables(mpd)) && (!params.empty())) {
const auto hn = getMaterialPropertyParametersHandlerClassName(name);
out << "if(!castem::" << hn << "::get" << hn << "().ok){\n"
<< "std::cerr << castem::" << hn << "::get" << hn
<< "().msg.c_str() << '\\n';\n"
<< "return std::nan(\"\");\n"
<< "}\n";
}
}
writeAssignMaterialPropertyParameters(out, mpd, name, "real", "castem");
//
Expand All @@ -430,23 +432,25 @@ namespace mfront {
}
}
out << "auto " << mpd.output.name << " = " << mpd.output.type << "{};\n";
if ((hasPhysicalBounds(mpd.inputs)) || (hasBounds(mpd.inputs))) {
out << "#ifndef NO_CASTEM_BOUNDS_CHECK\n";
}
if (hasPhysicalBounds(mpd.inputs)) {
out << "// treating physical bounds\n";
for (const auto& i : mpd.inputs) {
writePhysicalBounds(out, name, i);
if (!areRuntimeChecksDisabled(mpd)) {
if ((hasPhysicalBounds(mpd.inputs)) || (hasBounds(mpd.inputs))) {
out << "#ifndef NO_CASTEM_BOUNDS_CHECK\n";
}
}
if (hasBounds(mpd.inputs)) {
out << "// treating standard bounds\n";
for (const auto& i : mpd.inputs) {
writeBounds(out, mpd, name, i);
if (hasPhysicalBounds(mpd.inputs)) {
out << "// treating physical bounds\n";
for (const auto& i : mpd.inputs) {
writePhysicalBounds(out, name, i);
}
}
if (hasBounds(mpd.inputs)) {
out << "// treating standard bounds\n";
for (const auto& i : mpd.inputs) {
writeBounds(out, mpd, name, i);
}
}
if ((hasPhysicalBounds(mpd.inputs)) || (hasBounds(mpd.inputs))) {
out << "#endif /* NO_CASTEM_BOUNDS_CHECK */\n";
}
}
if ((hasPhysicalBounds(mpd.inputs)) || (hasBounds(mpd.inputs))) {
out << "#endif /* NO_CASTEM_BOUNDS_CHECK */\n";
}
out << "try{\n";
out << function.body;
Expand All @@ -462,17 +466,19 @@ namespace mfront {
<< "#endif /* NO_CASTEM_ERROR_OUTPUT */\n"
<< "return std::nan(\"\");\n"
<< "}\n";
if ((mpd.output.hasPhysicalBounds()) || (mpd.output.hasBounds())) {
out << "#ifndef NO_CASTEM_BOUNDS_CHECK\n";
if (mpd.output.hasPhysicalBounds()) {
out << "// treating physical bounds\n";
writePhysicalBounds(out, name, mpd.output);
}
if (mpd.output.hasBounds()) {
out << "// treating bounds\n";
writeBounds(out, mpd, name, mpd.output);
if (!areRuntimeChecksDisabled(mpd)) {
if ((mpd.output.hasPhysicalBounds()) || (mpd.output.hasBounds())) {
out << "#ifndef NO_CASTEM_BOUNDS_CHECK\n";
if (mpd.output.hasPhysicalBounds()) {
out << "// treating physical bounds\n";
writePhysicalBounds(out, name, mpd.output);
}
if (mpd.output.hasBounds()) {
out << "// treating bounds\n";
writeBounds(out, mpd, name, mpd.output);
}
out << "#endif /* NO_CASTEM_BOUNDS_CHECK */\n";
}
out << "#endif /* NO_CASTEM_BOUNDS_CHECK */\n";
}
if (useQuantities(mpd)) {
out << "return " << mpd.output.name << ".getValue();\n";
Expand Down
110 changes: 58 additions & 52 deletions mfront/src/CastemModelInterface.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -467,65 +467,71 @@ namespace mfront {
<< "{mfront_STATEV[" << pos << "]};\n";
}
}
auto write_physical_bounds = [&os, &raise](const VariableDescription& v,
const std::string& n,
const unsigned short vdepth) {
if (!v.hasPhysicalBounds()) {
return;
}
if (!v.isScalar()) {
raise("error while treating physical bounds of variable '" + v.name +
"' (only scalar variable are supported)");
}
writePhysicalBoundsChecks(os, v, n, "1u", false, false);
if (vdepth == 1u) {
writePhysicalBoundsChecks(os, v, v.name + "_1", "1u", false, false);
}
};
for (const auto& mv : f.usedVariables) {
const auto [n, vdepth] = md.decomposeVariableName(mv);
if (md.outputs.contains(n)) {
const auto& v = md.outputs.getVariable(n);
write_physical_bounds(v, v.name, vdepth);
if (!areRuntimeChecksDisabled(md)) {
auto write_physical_bounds = [&os, &raise](
const VariableDescription& v,
const std::string& n,
const unsigned short vdepth) {
if (!v.hasPhysicalBounds()) {
return;
}
if (!v.isScalar()) {
raise("error while treating physical bounds of variable '" +
v.name + "' (only scalar variable are supported)");
}
writePhysicalBoundsChecks(os, v, n, "1u", false, false);
if (vdepth == 1u) {
writePhysicalBoundsChecks(os, v, v.name + "_1", "1u", false, false);
}
};
for (const auto& mv : f.usedVariables) {
const auto [n, vdepth] = md.decomposeVariableName(mv);
if (md.outputs.contains(n)) {
const auto& v = md.outputs.getVariable(n);
write_physical_bounds(v, v.name, vdepth);
}
if (md.inputs.contains(n)) {
const auto& v = md.inputs.getVariable(n);
write_physical_bounds(v, v.name, vdepth);
}
}
if (md.inputs.contains(n)) {
const auto& v = md.inputs.getVariable(n);
write_physical_bounds(v, v.name, vdepth);
for (const auto& p : md.parameters) {
write_physical_bounds(p, p.name, 0u);
}
}
for (const auto& p : md.parameters) {
write_physical_bounds(p, p.name, 0u);
}
//
auto write_bounds = [&os, &raise](const VariableDescription& v,
const std::string& n,
const unsigned short vdepth) {
if (!v.hasBounds()) {
return;
}
if (!v.isScalar()) {
raise("error while treating bounds of variable '" + v.name +
"' (only scalar variable are supported)");
}
writeBoundsChecks(os, v, n, "1u", "policy", false, false);
if (vdepth == 1u) {
writeBoundsChecks(os, v, v.name + "_1", "1u", "policy", false, false);
}
};
for (const auto& mv : f.usedVariables) {
const auto [n, vdepth] = md.decomposeVariableName(mv);
if (md.outputs.contains(n)) {
const auto& v = md.outputs.getVariable(n);
write_bounds(v, v.name, vdepth);
if (!areRuntimeChecksDisabled(md)) {
auto write_bounds = [&os, &raise](const VariableDescription& v,
const std::string& n,
const unsigned short vdepth) {
if (!v.hasBounds()) {
return;
}
if (!v.isScalar()) {
raise("error while treating bounds of variable '" + v.name +
"' (only scalar variable are supported)");
}
writeBoundsChecks(os, v, n, "1u", "policy", false, false);
if (vdepth == 1u) {
writeBoundsChecks(os, v, v.name + "_1", "1u", "policy", false,
false);
}
};
for (const auto& mv : f.usedVariables) {
const auto [n, vdepth] = md.decomposeVariableName(mv);
if (md.outputs.contains(n)) {
const auto& v = md.outputs.getVariable(n);
write_bounds(v, v.name, vdepth);
}
if (md.inputs.contains(n)) {
const auto& v = md.inputs.getVariable(n);
write_bounds(v, v.name, vdepth);
}
}
if (md.inputs.contains(n)) {
const auto& v = md.inputs.getVariable(n);
write_bounds(v, v.name, vdepth);
for (const auto& p : md.parameters) {
write_bounds(p, p.name, 0u);
}
}
for (const auto& p : md.parameters) {
write_bounds(p, p.name, 0u);
}
//
os << f.body << '\n';
for (const auto& mv : f.modifiedVariables) {
Expand Down
Loading

0 comments on commit 64c2da4

Please sign in to comment.