diff --git a/docs/web/release-notes-5.0.md b/docs/web/release-notes-5.0.md index 11d90223d..e9e13f40a 100644 --- a/docs/web/release-notes-5.0.md +++ b/docs/web/release-notes-5.0.md @@ -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 diff --git a/mfront/include/MFront/DSLBase.hxx b/mfront/include/MFront/DSLBase.hxx index 1b6a28211..d5e71836f 100644 --- a/mfront/include/MFront/DSLBase.hxx +++ b/mfront/include/MFront/DSLBase.hxx @@ -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(); // diff --git a/mfront/include/MFront/MaterialKnowledgeDescription.hxx b/mfront/include/MFront/MaterialKnowledgeDescription.hxx index ad993af82..58a325f65 100644 --- a/mfront/include/MFront/MaterialKnowledgeDescription.hxx +++ b/mfront/include/MFront/MaterialKnowledgeDescription.hxx @@ -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 @@ -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 diff --git a/mfront/src/BehaviourCodeGeneratorBase.cxx b/mfront/src/BehaviourCodeGeneratorBase.cxx index 8f3e16ef8..6f6350e4b 100644 --- a/mfront/src/BehaviourCodeGeneratorBase.cxx +++ b/mfront/src/BehaviourCodeGeneratorBase.cxx @@ -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)) { diff --git a/mfront/src/CMaterialPropertyInterfaceBase.cxx b/mfront/src/CMaterialPropertyInterfaceBase.cxx index 352c8c03a..ec755b0f4 100644 --- a/mfront/src/CMaterialPropertyInterfaceBase.cxx +++ b/mfront/src/CMaterialPropertyInterfaceBase.cxx @@ -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" @@ -630,13 +631,15 @@ namespace mfront { for (const auto& i : mpd.inputs) { os << "static_cast(" << 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 diff --git a/mfront/src/CastemMaterialPropertyInterface.cxx b/mfront/src/CastemMaterialPropertyInterface.cxx index 1aed9c560..a1f1e1b85 100644 --- a/mfront/src/CastemMaterialPropertyInterface.cxx +++ b/mfront/src/CastemMaterialPropertyInterface.cxx @@ -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"); // @@ -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; @@ -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"; diff --git a/mfront/src/CastemModelInterface.cxx b/mfront/src/CastemModelInterface.cxx index 2894d5c86..d655ffd77 100644 --- a/mfront/src/CastemModelInterface.cxx +++ b/mfront/src/CastemModelInterface.cxx @@ -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) { diff --git a/mfront/src/CppMaterialPropertyInterface.cxx b/mfront/src/CppMaterialPropertyInterface.cxx index 68b85f26d..e2aa438de 100644 --- a/mfront/src/CppMaterialPropertyInterface.cxx +++ b/mfront/src/CppMaterialPropertyInterface.cxx @@ -453,43 +453,47 @@ namespace mfront { } else { src << "auto " << mpd.output.name << " = real{};\n"; } - if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { - src << "#ifndef MFRONT_NO_BOUNDS_CHECK\n"; - src << name << "::checkBounds("; - for (auto pi = mpd.inputs.begin(); pi != mpd.inputs.end();) { - src << pi->name; - if (useQuantities(mpd)) { - src << ".getValue()"; - } - if ((++pi) != mpd.inputs.end()) { - src << ","; + if (!areRuntimeChecksDisabled(mpd)) { + if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { + src << "#ifndef MFRONT_NO_BOUNDS_CHECK\n"; + src << name << "::checkBounds("; + for (auto pi = mpd.inputs.begin(); pi != mpd.inputs.end();) { + src << pi->name; + if (useQuantities(mpd)) { + src << ".getValue()"; + } + if ((++pi) != mpd.inputs.end()) { + src << ","; + } } + src << ");\n"; + src << "#endif /* MFRONT_NO_BOUNDS_CHECK */\n"; + } + if (!mpd.inputs.empty()) { + src << "#ifndef MFRONT_NOERRNO_HANDLING\n" + << "const auto mfront_errno_old = errno;\n" + << "errno=0;\n" + << "#endif /* MFRONT_NOERRNO_HANDLING */\n"; } - src << ");\n"; - src << "#endif /* MFRONT_NO_BOUNDS_CHECK */\n"; - } - if (!mpd.inputs.empty()) { - src << "#ifndef MFRONT_NOERRNO_HANDLING\n" - << "const auto mfront_errno_old = errno;\n" - << "errno=0;\n" - << "#endif /* MFRONT_NOERRNO_HANDLING */\n"; } src << mpd.f.body; - if (!mpd.inputs.empty()) { - src << "#ifndef MFRONT_NOERRNO_HANDLING\n" - // can't use std::swap here as errno might be a macro - << "const auto mfront_errno = errno;\n" - << "errno = mfront_errno_old;\n" - << "tfel::raise_if((mfront_errno!=0)||" - << "(!tfel::math::ieee754::isfinite(" << mpd.output.name << ")),\n" - << "\"" << name << ": errno has been set \"\n" - << "\"(\"+std::string(::strerror(errno))+\")\");\n" - << "#endif /* MFRONT_NOERRNO_HANDLING */\n"; + if (!areRuntimeChecksDisabled(mpd)) { + if (!mpd.inputs.empty()) { + src << "#ifndef MFRONT_NOERRNO_HANDLING\n" + // can't use std::swap here as errno might be a macro + << "const auto mfront_errno = errno;\n" + << "errno = mfront_errno_old;\n" + << "tfel::raise_if((mfront_errno!=0)||" + << "(!tfel::math::ieee754::isfinite(" << mpd.output.name << ")),\n" + << "\"" << name << ": errno has been set \"\n" + << "\"(\"+std::string(::strerror(errno))+\")\");\n" + << "#endif /* MFRONT_NOERRNO_HANDLING */\n"; + } + // + writePhysicalBoundsChecks(src, mpd.output, name); + writeBoundsChecks(src, mpd, mpd.output, name); } // - writePhysicalBoundsChecks(src, mpd.output, name); - writeBoundsChecks(src, mpd, mpd.output, name); - // if (useQuantities(mpd)) { src << "return " << mpd.output.name << ".getValue();\n"; } else { @@ -522,18 +526,20 @@ namespace mfront { << i.type << "(mfront_" << i.name << ");\n"; } } - if (hasPhysicalBounds(mpd.inputs)) { - src << "// treating physical bounds\n"; - for (const auto& i : mpd.inputs) { - writePhysicalBoundsChecks(src, i, name); - } - } - if (hasBounds(mpd.inputs)) { - src << "// treating standard bounds\n"; - if (!((!allowRuntimeModificationOfTheOutOfBoundsPolicy(mpd)) && - (getDefaultOutOfBoundsPolicy(mpd) == tfel::material::None))) { + if (!areRuntimeChecksDisabled(mpd)) { + if (hasPhysicalBounds(mpd.inputs)) { + src << "// treating physical bounds\n"; for (const auto& i : mpd.inputs) { - writeBoundsChecks(src, mpd, i, name); + writePhysicalBoundsChecks(src, i, name); + } + } + if (hasBounds(mpd.inputs)) { + src << "// treating standard bounds\n"; + if (!((!allowRuntimeModificationOfTheOutOfBoundsPolicy(mpd)) && + (getDefaultOutOfBoundsPolicy(mpd) == tfel::material::None))) { + for (const auto& i : mpd.inputs) { + writeBoundsChecks(src, mpd, i, name); + } } } } diff --git a/mfront/src/DSLBase.cxx b/mfront/src/DSLBase.cxx index 13f7e738b..e5cd23590 100644 --- a/mfront/src/DSLBase.cxx +++ b/mfront/src/DSLBase.cxx @@ -69,6 +69,8 @@ namespace mfront { const char* const DSLBase::overridingParameters = "overriding_parameters"; const char* const DSLBase::validatorOption = "validator"; const char* const DSLBase::buildIdentifierOption = "build_identifier"; + const char* const DSLBase::disableRuntimeChecksOption = + "disable_runtime_checks"; bool isValidMaterialName(std::string_view n) { return tfel::utilities::CxxTokenizer::isValidIdentifier(n, true); @@ -90,6 +92,7 @@ namespace mfront { DSLBase::runtimeModificationOfTheOutOfBoundsPolicyOption) .addDataTypeValidator(DSLBase::parametersAsStaticVariablesOption) .addDataTypeValidator(DSLBase::initializationFromFileOption) + .addDataTypeValidator(DSLBase::disableRuntimeChecksOption) .addDataTypeValidator(DSLBase::validatorOption) .addDataTypeValidator(DSLBase::buildIdentifierOption) .addDataTypeValidator( @@ -107,11 +110,14 @@ namespace mfront { void DSLBase::handleDSLOptions(MaterialKnowledgeDescription& d, const DSLOptions& opts) { + if (opts.count(DSLBase::disableRuntimeChecksOption) != 0) { + const auto opt = opts.at(DSLBase::disableRuntimeChecksOption).get(); + setDisableRuntimeChecks(d, opt); + } if (opts.count(DSLBase::defaultOutOfBoundsPolicyOption) != 0) { const auto opt = opts.at(DSLBase::defaultOutOfBoundsPolicyOption).get(); - d.setAttribute(MaterialKnowledgeDescription::defaultOutOfBoundsPolicy, - opt, false); + setDefaultOutOfBoundsPolicy(d, opt); } if (opts.count(DSLBase::runtimeModificationOfTheOutOfBoundsPolicyOption) != 0) { @@ -155,7 +161,8 @@ namespace mfront { MaterialKnowledgeDescription::buildIdentifier, ""); const auto validator = d.getAttribute( MaterialKnowledgeDescription::validator, ""); - return {{DSLBase::defaultOutOfBoundsPolicyOption, policy}, + return {{DSLBase::disableRuntimeChecksOption, areRuntimeChecksDisabled(d)}, + {DSLBase::defaultOutOfBoundsPolicyOption, policy}, {DSLBase::runtimeModificationOfTheOutOfBoundsPolicyOption, allowRuntimeModificationOfTheOutOfBoundsPolicy(d)}, {DSLBase::parametersAsStaticVariablesOption, @@ -174,7 +181,11 @@ namespace mfront { std::vector DSLBase::getDSLOptions() const { - return {{DSLBase::defaultOutOfBoundsPolicyOption, + return {{DSLBase::disableRuntimeChecksOption, + "boolean stating if interfaces shall remove as much runtime " + "checks as possible. Those checks include the treatment of " + "standard and physical bounds for instance."}, + {DSLBase::defaultOutOfBoundsPolicyOption, "string specifying the default out of bounds policy. Allowed " "values are `None`, `Warning`, `Strict`"}, {DSLBase::runtimeModificationOfTheOutOfBoundsPolicyOption, diff --git a/mfront/src/GenericMaterialPropertyInterfaceBase.cxx b/mfront/src/GenericMaterialPropertyInterfaceBase.cxx index 4ac78485b..5d1f8a6b5 100644 --- a/mfront/src/GenericMaterialPropertyInterfaceBase.cxx +++ b/mfront/src/GenericMaterialPropertyInterfaceBase.cxx @@ -429,33 +429,38 @@ namespace mfront { << "mfront_error_message.c_str(),511);\n" << "mfront_output_status->msg[511]='\\0';\n" << "};\n"; - os << "const int mfront_errno_old = errno;\n" - << "mfront_output_status->status = 0;\n" + if (!areRuntimeChecksDisabled(mpd)) { + os << "const int mfront_errno_old = errno;\n"; + } + os << "mfront_output_status->status = 0;\n" << "mfront_output_status->bounds_status = 0;\n" - << "mfront_output_status->c_error_number = 0;\n" - << "errno = 0;\n"; - // check number of arguments - os << "if(mfront_nargs!= " << mpd.inputs.size() << "){\n" - << "mfront_output_status->status = -5;\n" - << "mfront_report(\"invalid number of arguments " - << "(\"+std::to_string(mfront_nargs)+\" given, " << mpd.inputs.size() - << " expected)\");\n" - << "errno = mfront_errno_old;\n" - << "return std::nan(\"invalid number of arguments\");\n" - << "}\n"; - // parameters - if ((!areParametersTreatedAsStaticVariables(mpd)) && (!params.empty())) { - const auto hn = getMaterialPropertyParametersHandlerClassName(name); - os << "if(!" << iname << "::" << hn << "::get" << hn << "().ok){\n" - << "mfront_output_status->status = -6;\n" - << "mfront_report(" << iname << "::" << name - << "MaterialPropertyHandler::get" << name - << "MaterialPropertyHandler().msg);\n" + << "mfront_output_status->c_error_number = 0;\n"; + if (!areRuntimeChecksDisabled(mpd)) { + // C-error handling + os << "errno = 0;\n"; + // check number of arguments + os << "if(mfront_nargs!= " << mpd.inputs.size() << "){\n" + << "mfront_output_status->status = -5;\n" + << "mfront_report(\"invalid number of arguments " + << "(\"+std::to_string(mfront_nargs)+\" given, " << mpd.inputs.size() + << " expected)\");\n" << "errno = mfront_errno_old;\n" - << "return std::nan(" << iname << "::" << name - << "MaterialPropertyHandler::get" << name - << "MaterialPropertyHandler().msg.c_str());\n" + << "return std::nan(\"invalid number of arguments\");\n" << "}\n"; + // parameters + if ((!areParametersTreatedAsStaticVariables(mpd)) && (!params.empty())) { + const auto hn = getMaterialPropertyParametersHandlerClassName(name); + os << "if(!" << iname << "::" << hn << "::get" << hn << "().ok){\n" + << "mfront_output_status->status = -6;\n" + << "mfront_report(" << iname << "::" << name + << "MaterialPropertyHandler::get" << name + << "MaterialPropertyHandler().msg);\n" + << "errno = mfront_errno_old;\n" + << "return std::nan(" << iname << "::" << name + << "MaterialPropertyHandler::get" << name + << "MaterialPropertyHandler().msg.c_str());\n" + << "}\n"; + } } writeAssignMaterialPropertyParameters(os, mpd, name, "real", iname); // @@ -475,59 +480,69 @@ namespace mfront { } os << "auto " << mpd.output.name << " = " << mpd.output.type << "{};\n"; os << "try{\n"; - if ((hasPhysicalBounds(mpd.inputs)) || (hasBounds(mpd.inputs))) { - os << "#ifndef NO_" << iucname << "_BOUNDS_CHECK\n"; - } - if (hasPhysicalBounds(mpd.inputs)) { - os << "// treating physical bounds\n"; - for (decltype(mpd.inputs.size()) i = 0; i != mpd.inputs.size(); ++i) { - writePhysicalBounds(os, mpd.inputs[i], i + 1, useQuantities(mpd)); + if (!areRuntimeChecksDisabled(mpd)) { + if ((hasPhysicalBounds(mpd.inputs)) || (hasBounds(mpd.inputs))) { + os << "#ifndef NO_" << iucname << "_BOUNDS_CHECK\n"; } - } - if (hasBounds(mpd.inputs)) { - os << "// treating standard bounds\n"; - for (decltype(mpd.inputs.size()) i = 0; i != mpd.inputs.size(); ++i) { - writeBounds(os, prefix, mpd.inputs[i], i + 1, useQuantities(mpd)); + if (hasPhysicalBounds(mpd.inputs)) { + os << "// treating physical bounds\n"; + for (decltype(mpd.inputs.size()) i = 0; i != mpd.inputs.size(); ++i) { + writePhysicalBounds(os, mpd.inputs[i], i + 1, useQuantities(mpd)); + } + } + if (hasBounds(mpd.inputs)) { + os << "// treating standard bounds\n"; + for (decltype(mpd.inputs.size()) i = 0; i != mpd.inputs.size(); ++i) { + writeBounds(os, prefix, mpd.inputs[i], i + 1, useQuantities(mpd)); + } + } + if ((hasPhysicalBounds(mpd.inputs)) || (hasBounds(mpd.inputs))) { + os << "#endif /* NO_" << iucname << "_BOUNDS_CHECK */\n"; } - } - if ((hasPhysicalBounds(mpd.inputs)) || (hasBounds(mpd.inputs))) { - os << "#endif /* NO_" << iucname << "_BOUNDS_CHECK */\n"; } os << function.body; - if ((mpd.output.hasPhysicalBounds()) || (mpd.output.hasBounds())) { - os << "#ifndef NO_" << iucname << "_BOUNDS_CHECK\n"; - if (mpd.output.hasPhysicalBounds()) { - os << "// treating physical bounds\n"; - writePhysicalBounds(os, mpd.output, mpd.inputs.size() + 1, - useQuantities(mpd)); - } - if (mpd.output.hasBounds()) { - os << "// treating bounds\n"; - writeBounds(os, prefix, mpd.output, mpd.inputs.size() + 1, - useQuantities(mpd)); + if (!areRuntimeChecksDisabled(mpd)) { + if ((mpd.output.hasPhysicalBounds()) || (mpd.output.hasBounds())) { + os << "#ifndef NO_" << iucname << "_BOUNDS_CHECK\n"; + if (mpd.output.hasPhysicalBounds()) { + os << "// treating physical bounds\n"; + writePhysicalBounds(os, mpd.output, mpd.inputs.size() + 1, + useQuantities(mpd)); + } + if (mpd.output.hasBounds()) { + os << "// treating bounds\n"; + writeBounds(os, prefix, mpd.output, mpd.inputs.size() + 1, + useQuantities(mpd)); + } + os << "#endif /* NO_" << iucname << "_BOUNDS_CHECK */\n"; } - os << "#endif /* NO_" << iucname << "_BOUNDS_CHECK */\n"; } os << "} catch(std::exception& e){\n" << "mfront_output_status->status = -2;\n" - << "mfront_report(e.what());\n" - << "errno = mfront_errno_old;\n" - << "return std::nan(\"\");\n" + << "mfront_report(e.what());\n"; + if (!areRuntimeChecksDisabled(mpd)) { + os << "errno = mfront_errno_old;\n"; + } + os << "return std::nan(\"\");\n" << "} catch(...){\n" << "mfront_output_status->status = -2;\n" - << "mfront_report(\"unknown C++ exception\");\n" - << "errno = mfront_errno_old;\n" - << "return nan(\"\");\n" - << "}\n" - << "if (errno != 0) {\n" - << "mfront_output_status->status = -3;\n" - << "mfront_output_status->c_error_number = errno;\n" - << "mfront_report(strerror(errno));\n" - << "}\n" - << "errno = mfront_errno_old;\n" - << "if(!tfel::math::ieee754::isfinite(" << mpd.output.name << ")){\n" - << "mfront_output_status->status = -4;\n" + << "mfront_report(\"unknown C++ exception\");\n"; + if (!areRuntimeChecksDisabled(mpd)) { + os << "errno = mfront_errno_old;\n"; + } + os << "return nan(\"\");\n" << "}\n"; + if (!areRuntimeChecksDisabled(mpd)) { + os << "if (errno != 0) {\n" + << "mfront_output_status->status = -3;\n" + << "mfront_output_status->c_error_number = errno;\n" + << "mfront_report(strerror(errno));\n" + << "}\n" + << "errno = mfront_errno_old;\n" + << "if(!tfel::math::ieee754::isfinite(" << mpd.output.name << ")){\n" + << "mfront_output_status->status = -4;\n" + << "}\n"; + } if (useQuantities(mpd)) { os << "return " << mpd.output.name << ".getValue();\n"; } else { diff --git a/mfront/src/GenericModelInterface.cxx b/mfront/src/GenericModelInterface.cxx index 78fcf38f3..8df6141b2 100644 --- a/mfront/src/GenericModelInterface.cxx +++ b/mfront/src/GenericModelInterface.cxx @@ -368,20 +368,22 @@ namespace mfront { 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)) { + 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, @@ -398,20 +400,22 @@ namespace mfront { 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)) { + 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) { diff --git a/mfront/src/ImplicitCodeGeneratorBase.cxx b/mfront/src/ImplicitCodeGeneratorBase.cxx index 92bef284b..4f02a8f4e 100644 --- a/mfront/src/ImplicitCodeGeneratorBase.cxx +++ b/mfront/src/ImplicitCodeGeneratorBase.cxx @@ -1116,11 +1116,13 @@ namespace mfront { os << "this->computeFinalThermodynamicForces();\n"; } os << "this->updateAuxiliaryStateVariables();\n"; - for (const auto& v : d.getPersistentVariables()) { - this->writePhysicalBoundsChecks(os, v, false); - } - for (const auto& v : d.getPersistentVariables()) { - this->writeBoundsChecks(os, v, false); + if (!areRuntimeChecksDisabled(this->bd)) { + for (const auto& v : d.getPersistentVariables()) { + this->writePhysicalBoundsChecks(os, v, false); + } + for (const auto& v : d.getPersistentVariables()) { + this->writeBoundsChecks(os, v, false); + } } if (!this->bd.getTangentOperatorBlocks().empty()) { os << "if(smt!=NOSTIFFNESSREQUESTED){\n"; diff --git a/mfront/src/IsotropicMisesCreepCodeGenerator.cxx b/mfront/src/IsotropicMisesCreepCodeGenerator.cxx index 81c7ed41a..f55a68423 100644 --- a/mfront/src/IsotropicMisesCreepCodeGenerator.cxx +++ b/mfront/src/IsotropicMisesCreepCodeGenerator.cxx @@ -173,11 +173,13 @@ namespace mfront { "(this->lambda_tdt)*trace(this->eel)*StrainStensor::Id()+2*(this->mu_" "tdt)*(this->eel);\n" << "this->updateAuxiliaryStateVariables();\n"; - for (const auto& v : d.getPersistentVariables()) { - this->writePhysicalBoundsChecks(os, v, false); - } - for (const auto& v : d.getPersistentVariables()) { - this->writeBoundsChecks(os, v, false); + if (!areRuntimeChecksDisabled(this->bd)) { + for (const auto& v : d.getPersistentVariables()) { + this->writePhysicalBoundsChecks(os, v, false); + } + for (const auto& v : d.getPersistentVariables()) { + this->writeBoundsChecks(os, v, false); + } } if (this->bd.useQt()) { os << "return MechanicalBehaviour<" << btype diff --git a/mfront/src/IsotropicMisesPlasticFlowCodeGenerator.cxx b/mfront/src/IsotropicMisesPlasticFlowCodeGenerator.cxx index ff2b82f1a..375ea8e6e 100644 --- a/mfront/src/IsotropicMisesPlasticFlowCodeGenerator.cxx +++ b/mfront/src/IsotropicMisesPlasticFlowCodeGenerator.cxx @@ -196,11 +196,13 @@ namespace mfront { "(this->lambda_tdt)*trace(this->eel)*StrainStensor::Id()+2*(this->mu_" "tdt)*(this->eel);\n" << "this->updateAuxiliaryStateVariables();\n"; - for (const auto& v : d.getPersistentVariables()) { - this->writePhysicalBoundsChecks(os, v, false); - } - for (const auto& v : d.getPersistentVariables()) { - this->writeBoundsChecks(os, v, false); + if (!areRuntimeChecksDisabled(this->bd)) { + for (const auto& v : d.getPersistentVariables()) { + this->writePhysicalBoundsChecks(os, v, false); + } + for (const auto& v : d.getPersistentVariables()) { + this->writeBoundsChecks(os, v, false); + } } if (this->bd.useQt()) { os << "return MechanicalBehaviour<" << btype diff --git a/mfront/src/IsotropicStrainHardeningMisesCreepCodeGenerator.cxx b/mfront/src/IsotropicStrainHardeningMisesCreepCodeGenerator.cxx index b440bcea6..8fdd4cd74 100644 --- a/mfront/src/IsotropicStrainHardeningMisesCreepCodeGenerator.cxx +++ b/mfront/src/IsotropicStrainHardeningMisesCreepCodeGenerator.cxx @@ -186,11 +186,13 @@ namespace mfront { "(this->lambda_tdt)*trace(this->eel)*StrainStensor::Id()+2*(this->mu_" "tdt)*(this->eel);\n" << "this->updateAuxiliaryStateVariables();\n"; - for (const auto& v : d.getPersistentVariables()) { - this->writePhysicalBoundsChecks(os, v, false); - } - for (const auto& v : d.getPersistentVariables()) { - this->writeBoundsChecks(os, v, false); + if (!areRuntimeChecksDisabled(this->bd)) { + for (const auto& v : d.getPersistentVariables()) { + this->writePhysicalBoundsChecks(os, v, false); + } + for (const auto& v : d.getPersistentVariables()) { + this->writeBoundsChecks(os, v, false); + } } if (this->bd.useQt()) { os << "return MechanicalBehaviour<" << btype @@ -199,8 +201,8 @@ namespace mfront { os << "return MechanicalBehaviour<" << btype << ",hypothesis, NumericType,false>::SUCCESS;\n"; } - os << "}\n\n"; - } + os << "}\n\n"; + } void IsotropicStrainHardeningMisesCreepCodeGenerator:: writeBehaviourComputeTangentOperator(std::ostream& os, diff --git a/mfront/src/MFront.cxx b/mfront/src/MFront.cxx index 760f8a987..772ad49e0 100644 --- a/mfront/src/MFront.cxx +++ b/mfront/src/MFront.cxx @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "TFEL/Raise.hxx" diff --git a/mfront/src/MFrontLock.cxx b/mfront/src/MFrontLock.cxx index acac4bb6c..c0372ac5b 100644 --- a/mfront/src/MFrontLock.cxx +++ b/mfront/src/MFrontLock.cxx @@ -13,7 +13,6 @@ #include #include -#include #if !(defined _WIN32 || defined _WIN64 || defined __CYGWIN__) #include diff --git a/mfront/src/MaterialKnowledgeDescription.cxx b/mfront/src/MaterialKnowledgeDescription.cxx index 43127df50..c38a8481b 100644 --- a/mfront/src/MaterialKnowledgeDescription.cxx +++ b/mfront/src/MaterialKnowledgeDescription.cxx @@ -18,6 +18,8 @@ namespace mfront { + const char* const MaterialKnowledgeDescription::disableRuntimeChecks = + "disable_runtime_checks"; const char* const MaterialKnowledgeDescription::defaultOutOfBoundsPolicy = "default_out_of_bounds_policy"; const char* const @@ -153,6 +155,11 @@ namespace mfront { policy, false); } // end of setDefaultOutOfBoundsPolicy + void setDisableRuntimeChecks(MaterialKnowledgeDescription& d, const bool b) { + d.setAttribute(MaterialKnowledgeDescription::disableRuntimeChecks, b, + false); + } // end of setDisableRuntimeChecks + tfel::material::OutOfBoundsPolicy getDefaultOutOfBoundsPolicy( const MaterialKnowledgeDescription& d) { const auto policy = d.getAttribute( @@ -169,6 +176,11 @@ namespace mfront { return tfel::material::None; } // end of getDefaultOutOfBoundsPolicy + bool areRuntimeChecksDisabled(const MaterialKnowledgeDescription& d) { + return d.getAttribute( + MaterialKnowledgeDescription::disableRuntimeChecks, false); + } // end of getDisableRuntimeChecks + std::string getDefaultOutOfBoundsPolicyAsString( const MaterialKnowledgeDescription& d) { const auto& policy = d.getAttribute( diff --git a/mfront/src/MultipleIsotropicMisesFlowsCodeGenerator.cxx b/mfront/src/MultipleIsotropicMisesFlowsCodeGenerator.cxx index 29ea568f0..10f99a3b9 100644 --- a/mfront/src/MultipleIsotropicMisesFlowsCodeGenerator.cxx +++ b/mfront/src/MultipleIsotropicMisesFlowsCodeGenerator.cxx @@ -346,11 +346,13 @@ namespace mfront { "(this->lambda)*trace(this->eel)*StrainStensor::Id()+2*(this->mu)*(" "this->eel);\n" << "this->updateAuxiliaryStateVariables();\n"; - for (const auto& v : d.getPersistentVariables()) { - this->writePhysicalBoundsChecks(os, v, false); - } - for (const auto& v : d.getPersistentVariables()) { - this->writeBoundsChecks(os, v, false); + if (!areRuntimeChecksDisabled(this->bd)) { + for (const auto& v : d.getPersistentVariables()) { + this->writePhysicalBoundsChecks(os, v, false); + } + for (const auto& v : d.getPersistentVariables()) { + this->writeBoundsChecks(os, v, false); + } } if (this->bd.useQt()) { os << "return MechanicalBehaviour<" << btype diff --git a/mfront/src/OctaveMaterialPropertyInterface.cxx b/mfront/src/OctaveMaterialPropertyInterface.cxx index 1bc5224ce..97c87079c 100644 --- a/mfront/src/OctaveMaterialPropertyInterface.cxx +++ b/mfront/src/OctaveMaterialPropertyInterface.cxx @@ -325,8 +325,10 @@ namespace mfront { << "error(\"" << name << ": unsupported C++ exception\");\n" << "return 0;\n" << "}\n"; - writePhysicalBoundsChecks(out, mpd.output, name, 0); - writeBoundsChecks(out, mpd.output, name, 0); + if (!areRuntimeChecksDisabled(mpd)) { + writePhysicalBoundsChecks(out, mpd.output, name, 0); + writeBoundsChecks(out, mpd.output, name, 0); + } // if (useQuantities(mpd)) { out << "return " << mpd.output.name << ".getValue();\n"; @@ -334,36 +336,37 @@ namespace mfront { out << "return " << mpd.output.name << ";\n"; } out << "} // end of " << name << "_compute\n\n"; - if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { - out << "static double " << name << "_checkBounds("; - for (auto p3 = mpd.inputs.begin(); p3 != mpd.inputs.end();) { - out << "const double " << p3->name; - if ((++p3) != mpd.inputs.end()) { - out << ","; + if (!areRuntimeChecksDisabled(mpd)) { + if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { + out << "static double " << name << "_checkBounds("; + for (auto p3 = mpd.inputs.begin(); p3 != mpd.inputs.end();) { + out << "const double " << p3->name; + if ((++p3) != mpd.inputs.end()) { + out << ","; + } } - } - out << ")\n{\n"; - out << "using namespace std;\n"; - if (hasPhysicalBounds(mpd.inputs)) { - out << "// treating physical bounds\n"; - for (const auto& i : mpd.inputs) { - const auto nbr = - CMaterialPropertyInterfaceBase::getVariableNumber(mpd, i.name); - writePhysicalBoundsChecks(out, i, name, nbr); + out << ")\n{\n"; + out << "using namespace std;\n"; + if (hasPhysicalBounds(mpd.inputs)) { + out << "// treating physical bounds\n"; + for (const auto& i : mpd.inputs) { + const auto nbr = + CMaterialPropertyInterfaceBase::getVariableNumber(mpd, i.name); + writePhysicalBoundsChecks(out, i, name, nbr); + } } - } - if (hasBounds(mpd.inputs)) { - out << "// treating standard bounds\n"; - for (const auto& i : mpd.inputs) { - const auto nbr = - CMaterialPropertyInterfaceBase::getVariableNumber(mpd, i.name); - writeBoundsChecks(out, i, name, nbr); + if (hasBounds(mpd.inputs)) { + out << "// treating standard bounds\n"; + for (const auto& i : mpd.inputs) { + const auto nbr = + CMaterialPropertyInterfaceBase::getVariableNumber(mpd, i.name); + writeBoundsChecks(out, i, name, nbr); + } } + out << "return 0;\n" + << "} // end of " << name << "_checkBounds\n\n"; } - out << "return 0;\n" - << "} // end of " << name << "_checkBounds\n\n"; } - out << "DEFUN_DLD(" << name << ",args,nargout,\n" << "\"this function implements the " << name << " material law.\\n\"\n"; if (!fd.description.empty()) { @@ -418,11 +421,13 @@ namespace mfront { out << "retval = " << name << "_compute();\n"; } else if (mpd.inputs.size() == 1) { out << "if(args(0).is_real_scalar()){\n"; - if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { - out << "if(" << name << "_checkBounds("; - out << "args(0).scalar_value())<0){\n"; - out << "return retval;\n"; - out << "}\n"; + if (!areRuntimeChecksDisabled(mpd)) { + if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { + out << "if(" << name << "_checkBounds("; + out << "args(0).scalar_value())<0){\n"; + out << "return retval;\n"; + out << "}\n"; + } } out << "retval = " << name << "_compute("; out << "args(0).scalar_value());\n"; @@ -433,11 +438,13 @@ namespace mfront { out << "Matrix xout(xin0.rows(),xin0.cols());\n"; out << "for(i=0;i!=xin0.rows();++i){\n"; out << "for(j=0;j!=xin0.cols();++j){\n"; - if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { - out << "if(" << name << "_checkBounds("; - out << "xin0(i,j))<0){\n"; - out << "return retval;\n"; - out << "}\n"; + if (!areRuntimeChecksDisabled(mpd)) { + if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { + out << "if(" << name << "_checkBounds("; + out << "xin0(i,j))<0){\n"; + out << "return retval;\n"; + out << "}\n"; + } } out << "xout(i,j) = " << name << "_compute("; out << "xin0(i,j));\n"; @@ -495,14 +502,16 @@ namespace mfront { // all scalar case out << "if(areAllVariablesScalars){\n"; decltype(mpd.inputs.size()) i; - if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { - out << "if(" << name << "_checkBounds("; - for (i = 0; i != mpd.inputs.size() - 1; ++i) { - out << "args(" << i << ").scalar_value(),"; + if (!areRuntimeChecksDisabled(mpd)) { + if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { + out << "if(" << name << "_checkBounds("; + for (i = 0; i != mpd.inputs.size() - 1; ++i) { + out << "args(" << i << ").scalar_value(),"; + } + out << "args(" << i << ").scalar_value())<0){\n"; + out << "return retval;\n"; + out << "}\n"; } - out << "args(" << i << ").scalar_value())<0){\n"; - out << "return retval;\n"; - out << "}\n"; } out << "retval = " << name << "_compute("; for (i = 0; i != mpd.inputs.size() - 1; ++i) { @@ -517,14 +526,16 @@ namespace mfront { out << "Matrix xout(row,col);\n"; out << "for(i=0;i!=row;++i){\n"; out << "for(j=0;j!=col;++j){\n"; - if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { - out << "if(" << name << "_checkBounds("; - for (i = 0; i != mpd.inputs.size() - 1; ++i) { - out << "xin" << i << "(i,j),"; + if (!areRuntimeChecksDisabled(mpd)) { + if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { + out << "if(" << name << "_checkBounds("; + for (i = 0; i != mpd.inputs.size() - 1; ++i) { + out << "xin" << i << "(i,j),"; + } + out << "xin" << i << "(i,j))<0){\n"; + out << "return retval;\n"; + out << "}\n"; } - out << "xin" << i << "(i,j))<0){\n"; - out << "return retval;\n"; - out << "}\n"; } out << "xout(i,j) = " << name << "_compute("; for (i = 0; i != mpd.inputs.size() - 1; ++i) { @@ -539,14 +550,16 @@ namespace mfront { out << "Matrix xout(row,col);\n"; out << "for(i=0;i!=row;++i){\n"; out << "for(j=0;j!=col;++j){\n"; - if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { - out << "if(" << name << "_checkBounds("; - for (i = 0; i != mpd.inputs.size() - 1; ++i) { - out << "(*(getfunction[" << i << "]))(args(" << i << "),i,j),\n"; + if (!areRuntimeChecksDisabled(mpd)) { + if ((hasBounds(mpd.inputs)) || (hasPhysicalBounds(mpd.inputs))) { + out << "if(" << name << "_checkBounds("; + for (i = 0; i != mpd.inputs.size() - 1; ++i) { + out << "(*(getfunction[" << i << "]))(args(" << i << "),i,j),\n"; + } + out << "(*(getfunction[" << i << "]))(args(" << i << "),i,j))<0){\n"; + out << "return retval;\n"; + out << "}\n"; } - out << "(*(getfunction[" << i << "]))(args(" << i << "),i,j))<0){\n"; - out << "return retval;\n"; - out << "}\n"; } out << "xout(i,j) = " << name << "_compute("; for (i = 0; i != mpd.inputs.size() - 1; ++i) { diff --git a/mfront/src/PythonMaterialPropertyInterface.cxx b/mfront/src/PythonMaterialPropertyInterface.cxx index d733a19fa..7053ad672 100644 --- a/mfront/src/PythonMaterialPropertyInterface.cxx +++ b/mfront/src/PythonMaterialPropertyInterface.cxx @@ -377,7 +377,7 @@ namespace mfront { << "const double v" << "){\n"; for (const auto& p : mpd.parameters) { - srcFile << "if(strcmp(\"" << p.name << "\",p)==0){\n" + srcFile << "if(strcmp(\"" << p.name << "\",p) == 0){\n" << "python::" << hn << "::get" << hn << "()." << p.name << " = v;\n" << "return 1;\n" @@ -437,21 +437,23 @@ namespace mfront { } srcFile << ")){\nreturn NULL;\n}\n"; } - if ((hasPhysicalBounds(mpd.inputs)) || (hasBounds(mpd.inputs))) { - srcFile << "#ifndef PYTHON_NO_BOUNDS_CHECK\n"; - if (hasPhysicalBounds(mpd.inputs)) { - srcFile << "// treating physical bounds\n"; - for (const auto& i : mpd.inputs) { - writePhysicalBounds(srcFile, name, i); + if (!areRuntimeChecksDisabled(mpd)) { + if ((hasPhysicalBounds(mpd.inputs)) || (hasBounds(mpd.inputs))) { + srcFile << "#ifndef PYTHON_NO_BOUNDS_CHECK\n"; + if (hasPhysicalBounds(mpd.inputs)) { + srcFile << "// treating physical bounds\n"; + for (const auto& i : mpd.inputs) { + writePhysicalBounds(srcFile, name, i); + } } - } - if (hasBounds(mpd.inputs)) { - srcFile << "// treating standard bounds\n"; - for (const auto& i : mpd.inputs) { - writeBounds(srcFile, mpd, name, i); + if (hasBounds(mpd.inputs)) { + srcFile << "// treating standard bounds\n"; + for (const auto& i : mpd.inputs) { + writeBounds(srcFile, mpd, name, i); + } } + srcFile << "#endif /* PYTHON_NO_BOUNDS_CHECK */\n"; } - srcFile << "#endif /* PYTHON_NO_BOUNDS_CHECK */\n"; } if (useQuantities(mpd)) { srcFile << "auto " << output.name << " = " << output.type << "{};\n"; @@ -465,17 +467,19 @@ namespace mfront { << "} catch(...){\n" << " return throwPythonRuntimeException(\"unknown C++ exception\");\n" << "}\n"; - if ((hasPhysicalBounds(mpd.output)) || (hasBounds(mpd.output))) { - srcFile << "#ifndef PYTHON_NO_BOUNDS_CHECK\n"; - if (hasPhysicalBounds(mpd.output)) { - srcFile << "// treating physical bounds\n"; - writePhysicalBounds(srcFile, name, mpd.output); - } - if (hasBounds(mpd.output)) { - srcFile << "// treating standard bounds\n"; - writeBounds(srcFile, mpd, name, mpd.output); + if (!areRuntimeChecksDisabled(mpd)) { + if ((hasPhysicalBounds(mpd.output)) || (hasBounds(mpd.output))) { + srcFile << "#ifndef PYTHON_NO_BOUNDS_CHECK\n"; + if (hasPhysicalBounds(mpd.output)) { + srcFile << "// treating physical bounds\n"; + writePhysicalBounds(srcFile, name, mpd.output); + } + if (hasBounds(mpd.output)) { + srcFile << "// treating standard bounds\n"; + writeBounds(srcFile, mpd, name, mpd.output); + } + srcFile << "#endif /* PYTHON_NO_BOUNDS_CHECK */\n"; } - srcFile << "#endif /* PYTHON_NO_BOUNDS_CHECK */\n"; } srcFile << "return Py_BuildValue(\"d\"," << output.name << ");\n" << "} // end of " << name << "\n\n" diff --git a/mfront/src/RungeKuttaCodeGeneratorBase.cxx b/mfront/src/RungeKuttaCodeGeneratorBase.cxx index 7c12d7ed3..76ad86536 100644 --- a/mfront/src/RungeKuttaCodeGeneratorBase.cxx +++ b/mfront/src/RungeKuttaCodeGeneratorBase.cxx @@ -2247,11 +2247,13 @@ namespace mfront { "This shall not happen at this stage." " Please contact MFront developper to help them debug this."); } - for (const auto& v : d.getPersistentVariables()) { - this->writePhysicalBoundsChecks(os, v, false); - } - for (const auto& v : d.getPersistentVariables()) { - this->writeBoundsChecks(os, v, false); + if (!areRuntimeChecksDisabled(this->bd)) { + for (const auto& v : d.getPersistentVariables()) { + this->writePhysicalBoundsChecks(os, v, false); + } + for (const auto& v : d.getPersistentVariables()) { + this->writeBoundsChecks(os, v, false); + } } if (this->bd.getAttribute(BehaviourData::profiling, false)) { writeStandardPerformanceProfilingEnd(os);