Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Issue #594 #595

Merged
merged 1 commit into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading