1 /*! 2 * \file mfront/src/StandardBehaviourInterface.cxx 3 * \brief 4 * \author Thomas Helfer 5 * \brief 21 juil. 2018 6 * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights 7 * reserved. 8 * This project is publicly released under either the GNU GPL Licence 9 * or the CECILL-A licence. A copy of thoses licences are delivered 10 * with the sources of TFEL. CEA or EDF may also distribute this 11 * project under specific licensing conditions. 12 */ 13 14 #include<ostream> 15 #include"TFEL/Raise.hxx" 16 #include"TFEL/Glossary/Glossary.hxx" 17 #include"TFEL/Glossary/GlossaryEntry.hxx" 18 #include"MFront/DSLUtilities.hxx" 19 #include"MFront/BehaviourDescription.hxx" 20 #include"MFront/StandardBehaviourInterface.hxx" 21 22 namespace mfront { 23 24 /*! 25 * \param[out] rp: if true, a least one floatting-point parameter 26 * has been found. 27 * \param[out] ip: if true, a least one integer parameter has been 28 * found. 29 * \param[out] up: if true, a least one parameter of type 30 * `unsigned short` has been found. 31 * \param[in] pc: list of parameters. 32 */ checkParametersType(bool & rp,bool & ip,bool & up,const VariableDescriptionContainer & pc)33 static void checkParametersType( 34 bool& rp,bool& ip,bool& up, 35 const VariableDescriptionContainer& pc) { 36 rp = false; 37 ip = false; 38 up = false; 39 for (const auto& v : pc) { 40 if (v.type == "int") { 41 ip = true; 42 } else if (v.type == "ushort") { 43 up = true; 44 } else { 45 const auto f = SupportedTypes::getTypeFlag(v.type); 46 tfel::raise_if(f != SupportedTypes::SCALAR, 47 "checkParametersType: " 48 "unsupport parameter type '" + 49 v.type + "'."); 50 rp = true; 51 } 52 } 53 } // end of checkParametersType 54 55 StandardBehaviourInterface::StandardBehaviourInterface() = default; 56 57 const char* const StandardBehaviourInterface::generateMTestFileAttribute = 58 "GenerateMTestFileOnFailure"; 59 isBehaviourConstructorRequired(const Hypothesis h,const BehaviourDescription & mb) const60 bool StandardBehaviourInterface::isBehaviourConstructorRequired( 61 const Hypothesis h, const BehaviourDescription& mb) const { 62 const auto mhs = this->getModellingHypothesesToBeTreated(mb); 63 if (h == ModellingHypothesis::UNDEFINEDHYPOTHESIS) { 64 return !mb.areAllMechanicalDataSpecialised(mhs); 65 } 66 return mhs.find(h) != mhs.end(); 67 } // end of StandardBehaviourInterface::isBehaviourConstructorRequired 68 getHeaderGuard(const BehaviourDescription & mb) const69 std::string StandardBehaviourInterface::getHeaderGuard( 70 const BehaviourDescription& mb) const { 71 const auto& m = mb.getMaterialName(); 72 auto header = "LIB_" + makeUpperCase(this->getInterfaceName()); 73 if (!mb.getLibrary().empty()) { 74 header += "_"; 75 header += makeUpperCase(mb.getLibrary()); 76 } 77 if (!m.empty()) { 78 header += "_"; 79 header += makeUpperCase(m); 80 } 81 header += "_"; 82 header += makeUpperCase(mb.getClassName()); 83 header += "_HXX"; 84 return header; 85 } // end of StandardBehaviourInterface::getHeaderGuard 86 writeVisibilityDefines(std::ostream & out) const87 void StandardBehaviourInterface::writeVisibilityDefines(std::ostream& out) const { 88 out << "#ifdef _WIN32\n" 89 << "#ifndef NOMINMAX\n" 90 << "#define NOMINMAX\n" 91 << "#endif /* NOMINMAX */\n" 92 << "#include <windows.h>\n" 93 << "#ifdef small\n" 94 << "#undef small\n" 95 << "#endif /* small */\n" 96 << "#endif /* _WIN32 */\n\n" 97 << "#ifndef MFRONT_SHAREDOBJ\n" 98 << "#define MFRONT_SHAREDOBJ TFEL_VISIBILITY_EXPORT\n" 99 << "#endif /* MFRONT_SHAREDOBJ */\n\n"; 100 } // end of StandardBehaviourInterface::writeVisibilityDefines 101 102 std::pair<std::vector<BehaviourMaterialProperty>, SupportedTypes::TypeSize> buildMaterialPropertiesList(const BehaviourDescription & bd,const Hypothesis h) const103 StandardBehaviourInterface::buildMaterialPropertiesList(const BehaviourDescription& bd, 104 const Hypothesis h) const { 105 if (h == ModellingHypothesis::UNDEFINEDHYPOTHESIS) { 106 return mfront::buildMaterialPropertiesList( 107 bd, this->getModellingHypothesesToBeTreated(bd)); 108 } 109 return mfront::buildMaterialPropertiesList(bd, h); 110 } // end of StandardBehaviourInterface::buildMaterialPropertiesList 111 writeSetOutOfBoundsPolicyFunctionDeclaration(std::ostream & out,const std::string & name) const112 void StandardBehaviourInterface::writeSetOutOfBoundsPolicyFunctionDeclaration( 113 std::ostream& out, const std::string& name) const { 114 out << "MFRONT_SHAREDOBJ void\n" 115 << this->getFunctionNameBasis(name) 116 << "_setOutOfBoundsPolicy(const int);\n\n"; 117 } 118 writeGetOutOfBoundsPolicyFunctionImplementation(std::ostream & out,const std::string & name) const119 void StandardBehaviourInterface::writeGetOutOfBoundsPolicyFunctionImplementation( 120 std::ostream& out, const std::string& name) const { 121 out << "static tfel::material::OutOfBoundsPolicy&\n" 122 << this->getFunctionNameBasis(name) << "_getOutOfBoundsPolicy(){\n" 123 << "using namespace tfel::material;\n" 124 << "static OutOfBoundsPolicy policy = None;\n" 125 << "return policy;\n" 126 << "}\n\n"; 127 } // end of 128 // StandardBehaviourInterface::writeGetOutOfBoundsPolicyFunctionImplementation 129 writeSetOutOfBoundsPolicyFunctionImplementation(std::ostream & out,const std::string & name) const130 void StandardBehaviourInterface::writeSetOutOfBoundsPolicyFunctionImplementation( 131 std::ostream& out, const std::string& name) const { 132 out << "MFRONT_SHAREDOBJ void\n" 133 << this->getFunctionNameBasis(name) 134 << "_setOutOfBoundsPolicy(const int p){\n" 135 << "if(p==0){\n" 136 << this->getFunctionNameBasis(name) 137 << "_getOutOfBoundsPolicy() = tfel::material::None;\n" 138 << "} else if(p==1){\n" 139 << this->getFunctionNameBasis(name) 140 << "_getOutOfBoundsPolicy() = tfel::material::Warning;\n" 141 << "} else if(p==2){\n" 142 << this->getFunctionNameBasis(name) 143 << "_getOutOfBoundsPolicy() = tfel::material::Strict;\n" 144 << "} else {\n" 145 << "std::cerr << \"" << this->getFunctionNameBasis(name) 146 << "_setOutOfBoundsPolicy: invalid argument\\n\";\n" 147 << "}\n" 148 << "}\n\n"; 149 } 150 writeSetParametersFunctionsDeclarations(std::ostream & out,const BehaviourDescription & mb,const std::string & name) const151 void StandardBehaviourInterface::writeSetParametersFunctionsDeclarations( 152 std::ostream& out, 153 const BehaviourDescription& mb, 154 const std::string& name) const { 155 const auto mh = mb.getDistinctModellingHypotheses(); 156 const auto mh2 = this->getModellingHypothesesToBeTreated(mb); 157 for (const auto h : mh) { 158 if ((h == ModellingHypothesis::UNDEFINEDHYPOTHESIS) || 159 (mh2.find(h) != mh2.end())) { 160 bool rp, ip, up; 161 const auto& d = mb.getBehaviourData(h); 162 const auto& pc = d.getParameters(); 163 checkParametersType(rp, ip, up, pc); 164 auto fctName = this->getFunctionNameBasis(name); 165 auto suffix = std::string{}; 166 if (h != ModellingHypothesis::UNDEFINEDHYPOTHESIS) { 167 suffix += ModellingHypothesis::toString(h); 168 fctName += "_" + suffix; 169 } 170 if (rp) { 171 out << "MFRONT_SHAREDOBJ int\n" 172 << fctName 173 << "_setParameter(const char *const,const double);\n\n"; 174 } 175 if (ip) { 176 out << "MFRONT_SHAREDOBJ int\n" 177 << fctName 178 << "_setIntegerParameter(const char *const,const int);\n\n"; 179 } 180 if (up) { 181 out << "MFRONT_SHAREDOBJ int\n" 182 << fctName << "_setUnsignedShortParameter(const char " 183 "*const,const unsigned short);\n\n"; 184 } 185 } 186 } 187 } // end of StandardBehaviourInterface::writeSetParametersFunctionsDeclarations 188 writeSetParametersFunctionsImplementations(std::ostream & out,const BehaviourDescription & mb,const std::string & name) const189 void StandardBehaviourInterface::writeSetParametersFunctionsImplementations( 190 std::ostream& out, 191 const BehaviourDescription& mb, 192 const std::string& name) const { 193 const auto mh = mb.getDistinctModellingHypotheses(); 194 const auto mh2 = this->getModellingHypothesesToBeTreated(mb); 195 for (const auto& h : mh) { 196 if ((h == ModellingHypothesis::UNDEFINEDHYPOTHESIS) || 197 (mh2.find(h) != mh2.end())) { 198 const auto& d = mb.getBehaviourData(h); 199 const auto& pc = d.getParameters(); 200 bool rp, ip, up; 201 checkParametersType(rp, ip, up, pc); 202 auto fctName = this->getFunctionNameBasis(name); 203 std::string suffix; 204 if (h != ModellingHypothesis::UNDEFINEDHYPOTHESIS) { 205 suffix += ModellingHypothesis::toString(h); 206 fctName += "_" + suffix; 207 } 208 const auto cname = mb.getClassName() + suffix + "ParametersInitializer"; 209 if (rp) { 210 out << "MFRONT_SHAREDOBJ int\n" 211 << fctName 212 << "_setParameter(const char *const key,const double value){\n" 213 << "using tfel::material::" << cname << ";\n" 214 << "auto& i = " << cname << "::get();\n" 215 << "try{\n" 216 << "i.set(key,value);\n" 217 << "} catch(std::runtime_error& e){\n" 218 << "std::cerr << e.what() << std::endl;\n" 219 << "return 0;\n" 220 << "}\n" 221 << "return 1;\n" 222 << "}\n\n"; 223 } 224 if (ip) { 225 out << "MFRONT_SHAREDOBJ int\n" 226 << fctName << "_setIntegerParameter(const char *const key,const " 227 "int value){\n" 228 << "using tfel::material::" << cname << ";\n" 229 << "auto& i = " << cname << "::get();\n" 230 << "try{\n" 231 << "i.set(key,value);\n" 232 << "} catch(std::runtime_error& e){\n" 233 << "std::cerr << e.what() << std::endl;\n" 234 << "return 0;\n" 235 << "}\n" 236 << "return 1;\n" 237 << "}\n\n"; 238 } 239 if (up) { 240 out << "MFRONT_SHAREDOBJ int\n" 241 << fctName << "_setUnsignedShortParameter(const char *const " 242 "key,const unsigned short value){\n" 243 << "using tfel::material::" << cname << ";\n" 244 << "auto& i = " << cname << "::get();\n" 245 << "try{\n" 246 << "i.set(key,value);\n" 247 << "} catch(std::runtime_error& e){\n" 248 << "std::cerr << e.what() << std::endl;\n" 249 << "return 0;\n" 250 << "}\n" 251 << "return 1;\n" 252 << "}\n\n"; 253 } 254 } 255 } 256 } 257 setGenerateMTestFileOnFailureAttribute(BehaviourDescription & bd,const bool b) const258 void StandardBehaviourInterface::setGenerateMTestFileOnFailureAttribute( 259 BehaviourDescription& bd, const bool b) const { 260 const auto a = this->getInterfaceName() + "::" + 261 StandardBehaviourInterface::generateMTestFileAttribute; 262 bd.setAttribute(a, b, false); 263 } // end of StandardBehaviourInterface::setGenerateMTestFileOnFailureAttribute 264 shallGenerateMTestFileOnFailure(const BehaviourDescription & bd) const265 bool StandardBehaviourInterface::shallGenerateMTestFileOnFailure( 266 const BehaviourDescription& bd) const { 267 const auto a = this->getInterfaceName() + "::" + 268 StandardBehaviourInterface::generateMTestFileAttribute; 269 return bd.getAttribute<bool>(a, false); 270 } // end of StandardBehaviourInterface::shallGenerateMTestFileOnFailure 271 272 std::pair<bool, SupportedTypes::TypeSize> checkIfAxialStrainIsDefinedAndGetItsOffset(const BehaviourDescription & mb,const Hypothesis h) const273 StandardBehaviourInterface::checkIfAxialStrainIsDefinedAndGetItsOffset( 274 const BehaviourDescription& mb, const Hypothesis h) const { 275 using tfel::glossary::Glossary; 276 const auto& d = mb.getBehaviourData(h); 277 const auto& sv = d.getPersistentVariables(); 278 SupportedTypes::TypeSize o; 279 for (const auto& elem : sv) { 280 if (d.getExternalName(elem.name) == Glossary::AxialStrain) { 281 return {true, o}; 282 } 283 o += SupportedTypes::getTypeSize(elem.type, elem.arraySize); 284 } 285 return {false, o}; 286 } 287 288 std::pair<bool, SupportedTypes::TypeSize> StandardBehaviourInterface:: checkIfAxialDeformationGradientIsDefinedAndGetItsOffset(const BehaviourDescription & mb,const Hypothesis h) const289 checkIfAxialDeformationGradientIsDefinedAndGetItsOffset( 290 const BehaviourDescription& mb, const Hypothesis h) const { 291 using tfel::glossary::Glossary; 292 const auto& d = mb.getBehaviourData(h); 293 const auto& sv = d.getPersistentVariables(); 294 SupportedTypes::TypeSize o; 295 for (const auto& elem : sv) { 296 if (d.getExternalName(elem.name) == Glossary::AxialDeformationGradient) { 297 return {true, o}; 298 } 299 o += SupportedTypes::getTypeSize(elem.type, elem.arraySize); 300 } 301 return {false, o}; 302 } 303 readBooleanValue(const std::string & key,tokens_iterator & current,const tokens_iterator end) const304 bool StandardBehaviourInterface::readBooleanValue( 305 const std::string& key, 306 tokens_iterator& current, 307 const tokens_iterator end) const { 308 auto throw_if = [&key](const bool b, const std::string& m) { 309 tfel::raise_if(b, "UMATInterfaceBase::readBooleanValue: " + m + 310 ".\nError while treating key (" + key + ")\n"); 311 }; 312 throw_if(current == end, "unexpected end of file"); 313 const auto b = [¤t, &throw_if]() -> bool { 314 if (current->value == "true") { 315 return true; 316 } else if (current->value == "false") { 317 return false; 318 } else { 319 throw_if(true, "expected 'true' or 'false'"); 320 } 321 }(); 322 ++(current); 323 throw_if(current == end, "unexpected end of file"); 324 throw_if(current->value != ";", 325 "expected ';', read '" + current->value + "'"); 326 ++(current); 327 return b; 328 } // end of StandardBehaviourInterface::readBooleanValue 329 330 StandardBehaviourInterface::~StandardBehaviourInterface() = default; 331 332 } // end of namespace mfront 333