1 /*! 2 * \file SingleStructureSchemeParser.cxx 3 * \brief 4 * \author Thomas Helfer 5 * \date 21 déc. 2015 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 <sstream> 15 #include "TFEL/Raise.hxx" 16 #include "TFEL/Math/Parser/ConstantExternalFunction.hxx" 17 #include "TFEL/Material/OutOfBoundsPolicy.hxx" 18 #include "MFront/MFrontLogStream.hxx" 19 #include "MTest/MTest.hxx" 20 #include "MTest/Behaviour.hxx" 21 #include "MTest/Evolution.hxx" 22 #include "MTest/CastemEvolution.hxx" 23 #include "MTest/CyranoEvolution.hxx" 24 #include "MTest/FunctionEvolution.hxx" 25 #include "MTest/SingleStructureSchemeParser.hxx" 26 27 namespace mtest { 28 selectVariables(std::vector<std::string> & r,const std::vector<std::string> & names,const std::string & n)29 static void selectVariables(std::vector<std::string>& r, 30 const std::vector<std::string>& names, 31 const std::string& n) { 32 r.clear(); 33 if (find(names.begin(), names.end(), n) != names.end()) { 34 r.push_back(n); 35 } else { 36 // checking for an array of internal state variables 37 for (const auto& vn : names) { 38 if (vn.compare(0, n.length(), n) == 0) { 39 if (!(vn.size() >= n.length() + 3u)) { 40 continue; 41 } 42 auto pn = vn.crbegin(); 43 const auto pne = vn.crbegin() + (vn.size() - n.size() - 1); 44 if ((vn[n.size()] != '[') || (*pn != ']')) { 45 continue; 46 } 47 ++pn; 48 bool ok = true; 49 while ((pn != pne) && (ok)) { 50 ok = ::isdigit(*pn) != 0; 51 ++pn; 52 } 53 if (ok) { 54 r.push_back(vn); 55 } 56 } 57 } 58 } 59 } // end of selectVariables 60 getSTensorSize(const unsigned short d)61 static unsigned short getSTensorSize(const unsigned short d) { 62 if (d == 1) { 63 return 3; 64 } else if (d == 2) { 65 return 4; 66 } else if (d == 3) { 67 return 6; 68 } 69 tfel::raise("mfront::getSTensorSize: invalid dimension"); 70 } 71 getTensorSize(const unsigned short d)72 static unsigned short getTensorSize(const unsigned short d) { 73 if (d == 1) { 74 return 3; 75 } else if (d == 2) { 76 return 5; 77 } else if (d == 3) { 78 return 9; 79 } 80 tfel::raise("mfront::getTensorSize: invalid dimension"); 81 } 82 handleHandleThermalExpansion(SingleStructureScheme & t,tokens_iterator & p)83 void SingleStructureSchemeParser::handleHandleThermalExpansion(SingleStructureScheme& t, 84 tokens_iterator& p) { 85 bool b; 86 this->checkNotEndOfLine("SingleStructureSchemeParser::handleHandleThermalExpansion", p, 87 this->tokens.end()); 88 if (p->value == "true") { 89 b = true; 90 } else if (p->value == "false") { 91 b = false; 92 } else { 93 tfel::raise( 94 "SingleStructureSchemeParser::handleHandleThermalExpansion : " 95 "unexpected token '" + 96 p->value + "'"); 97 } 98 ++p; 99 this->readSpecifiedToken("SingleStructureSchemeParser::handleHandleThermalExpansion", ";", p, 100 this->tokens.end()); 101 t.setHandleThermalExpansion(b); 102 } 103 handleBehaviour(SingleStructureScheme & t,tokens_iterator & p)104 void SingleStructureSchemeParser::handleBehaviour(SingleStructureScheme& t, tokens_iterator& p) { 105 auto i = std::string{}; // interface 106 auto w = std::string{}; // wrapper 107 this->checkNotEndOfLine("SingleStructureSchemeParser::handleBehaviour", p, this->tokens.end()); 108 if (p->value == "<") { 109 this->readSpecifiedToken("SingleStructureSchemeParser::handleBehaviour", "<", p, 110 this->tokens.end()); 111 this->checkNotEndOfLine("SingleStructureSchemeParser::handleBehaviour", p, 112 this->tokens.end()); 113 if((p->value == "generic") || (p->value == "Generic")){ 114 i = "Generic"; 115 } 116 #ifdef HAVE_CASTEM 117 if ((p->value == "umat") || (p->value == "castem") || (p->value == "Castem") || 118 (p->value == "Cast3M")) { 119 i = "castem"; 120 } 121 if (p->value == "mistral") { 122 i = "mistral"; 123 } 124 if ((p->value == "mistral") || (p->value == "castem_umat_small_strain") || 125 (p->value == "castem_umat_finite_strain")) { 126 i = p->value; 127 } 128 #endif /* HAVE_CASTEM */ 129 #ifdef HAVE_ASTER 130 if ((p->value == "aster") || (p->value == "Aster")) { 131 i = p->value; 132 } 133 #endif /* HAVE_ASTER */ 134 #ifdef HAVE_EUROPLEXUS 135 if((p->value=="europlexus")||(p->value=="epx")){ 136 i = p->value; 137 } 138 #endif /* HAVE_EUROPLEXUS */ 139 #ifdef HAVE_ABAQUS 140 if ((p->value == "Abaqus") || (p->value == "abaqus") || 141 (p->value == "abaqus_standard") || (p->value == "abaqus_umat")) { 142 i = "abaqus"; 143 } 144 if ((p->value == "AbaqusExplicit") || (p->value == "abaqus_explicit") || 145 (p->value == "abaqus_vumat")) { 146 i = "abaqus_explicit"; 147 } 148 #endif /* HAVE_ABAQUS */ 149 #ifdef HAVE_ANSYS 150 if ((p->value == "Ansys") || (p->value == "ansys") || 151 (p->value == "ansys_usermat")) { 152 i = "ansys"; 153 } 154 #endif /* HAVE_ANSYS */ 155 #ifdef HAVE_CYRANO 156 if(p->value=="cyrano"){ 157 i = p->value; 158 } 159 #endif /* HAVE_CYRANO */ 160 #ifdef HAVE_CALCULIX 161 if((p->value=="calculix")||(p->value=="CalculiX")){ 162 i = "CalculiX"; 163 } 164 #endif /* HAVE_CALCULIX */ 165 #ifdef HAVE_DIANAFEA 166 if((p->value=="dianafea")||(p->value=="DianaFEA")){ 167 i = "DianaFEA"; 168 } 169 #endif /* HAVE_DIANAFEA */ 170 tfel::raise_if(i.empty(), 171 "SingleStructureSchemeParser::handleBehaviour: " 172 "unknown interface '"+p->value+"'"); 173 ++p; 174 this->checkNotEndOfLine("SingleStructureSchemeParser::handleBehaviour",p, 175 this->tokens.end()); 176 if(p->value==","){ 177 this->readSpecifiedToken("SingleStructureSchemeParser::handleBehaviour", ",", p, 178 this->tokens.end()); 179 w = p->value; 180 ++p; 181 } 182 this->readSpecifiedToken("SingleStructureSchemeParser::handleBehaviour",">",p, 183 this->tokens.end()); 184 } 185 const auto& l = this->readString(p, this->tokens.end()); 186 const auto& f = this->readString(p, this->tokens.end()); 187 this->checkNotEndOfLine("SingleStructureSchemeParser::handleBehaviour", p, this->tokens.end()); 188 tfel::utilities::Data d; 189 if (p->value == "{") { 190 d = tfel::utilities::Data::read(p, this->tokens.end()); 191 } 192 this->readSpecifiedToken("SingleStructureSchemeParser::handleBehaviour", ";", p, 193 this->tokens.end()); 194 mfront::getLogStream() << l << " " << f << std::endl; 195 if (w.empty()) { 196 t.setBehaviour(i, l, f, d); 197 } else { 198 t.setBehaviour(w, i, l, f, d); 199 } 200 const auto& b = *(t.getBehaviour()); 201 // adding parameters 202 const auto& n = b.getBehaviourName(); 203 for (const auto& p : b.getParametersNames()) { 204 const auto cste = 205 std::make_shared<tfel::math::parser::ConstantExternalFunction>( 206 b.getRealParameterDefaultValue(p)); 207 this->externalFunctions->insert({n + "::" + p, cste}); 208 } 209 } // end of SingleStructureSchemeParser::handleBehaviour 210 handleMaterialProperty(SingleStructureScheme & t,tokens_iterator & p)211 void SingleStructureSchemeParser::handleMaterialProperty(SingleStructureScheme& t, 212 tokens_iterator& p) { 213 using namespace std; 214 using namespace tfel::utilities; 215 string i; 216 this->readSpecifiedToken("SingleStructureSchemeParser::handleMaterialProperty", "<", p, 217 this->tokens.end()); 218 this->checkNotEndOfLine("SingleStructureSchemeParser::handleMaterialProperty", p, 219 this->tokens.end()); 220 if ((p->value == "constant") || (p->value == "castem") || 221 (p->value == "cyrano") || (p->value == "function")) { 222 i = p->value; 223 } else { 224 tfel::raise( 225 "SingleStructureSchemeParser::handleMaterialProperty: " 226 "unknown interface '" + 227 p->value + "'"); 228 } 229 ++p; 230 this->readSpecifiedToken("SingleStructureSchemeParser::handleMaterialProperty", ">", p, 231 this->tokens.end()); 232 const auto& n = this->readString(p, this->tokens.end()); 233 if (i == "constant") { 234 shared_ptr<Evolution> mpev; 235 this->checkNotEndOfLine("SingleStructureSchemeParser::handleMaterialProperty", p, 236 this->tokens.end()); 237 const real v = this->readDouble(t, p); 238 mpev = shared_ptr<Evolution>(new ConstantEvolution(v)); 239 t.setMaterialProperty(n, mpev, true); 240 } else if (i == "function") { 241 shared_ptr<Evolution> mpev; 242 const string f = this->readString(p, this->tokens.end()); 243 mpev = shared_ptr<Evolution>(new FunctionEvolution(f, t.getEvolutions())); 244 t.setMaterialProperty(n, mpev, true); 245 } else if (i == "castem") { 246 shared_ptr<Evolution> mpev; 247 const string l = this->readString(p, this->tokens.end()); 248 const string f = this->readString(p, this->tokens.end()); 249 mpev = shared_ptr<Evolution>(new CastemEvolution(l, f, t.getEvolutions())); 250 t.setMaterialProperty(n, mpev, true); 251 } else if (i == "cyrano") { 252 shared_ptr<Evolution> mpev; 253 const string l = this->readString(p, this->tokens.end()); 254 const string f = this->readString(p, this->tokens.end()); 255 mpev = 256 shared_ptr<Evolution>(new CyranoEvolution(l, f, t.getEvolutions())); 257 t.setMaterialProperty(n, mpev, true); 258 } else { 259 tfel::raise( 260 "SingleStructureSchemeParser::handleMaterialProperty: " 261 "unknown interface '" + 262 i + "'"); 263 } 264 this->readSpecifiedToken("SingleStructureSchemeParser::handleMaterialProperty", ";", p, 265 this->tokens.end()); 266 } 267 handleOutOfBoundsPolicy(SingleStructureScheme & t,tokens_iterator & p)268 void SingleStructureSchemeParser::handleOutOfBoundsPolicy(SingleStructureScheme& t, 269 tokens_iterator& p) { 270 const std::string& s = this->readString(p, this->tokens.end()); 271 this->readSpecifiedToken("SingleStructureSchemeParser::handlePredictionPolicy", ";", p, 272 this->tokens.end()); 273 if (s == "None") { 274 t.setOutOfBoundsPolicy(tfel::material::None); 275 } else if (s == "Warning") { 276 t.setOutOfBoundsPolicy(tfel::material::Warning); 277 } else if (s == "Strict") { 278 t.setOutOfBoundsPolicy(tfel::material::Strict); 279 } else { 280 tfel::raise( 281 "SingleStructureSchemeParser::handleOutOfBoundsPolicy: " 282 "unsupported policy '" + 283 s + "'"); 284 } 285 } // end of SingleStructureSchemeParser::handleOutOfBoundsPolicy 286 handleParameter(SingleStructureScheme & t,tokens_iterator & p)287 void SingleStructureSchemeParser::handleParameter(SingleStructureScheme& t, tokens_iterator& p) { 288 const auto n = this->readString(p, this->tokens.end()); 289 const real v = this->readDouble(t, p); 290 t.setParameter(n, v); 291 this->readSpecifiedToken("SingleStructureSchemeParser::handleParameter", ";", p, 292 this->tokens.end()); 293 } // end of SingleStructureSchemeParser::handleParameter 294 handleIntegerParameter(SingleStructureScheme & t,tokens_iterator & p)295 void SingleStructureSchemeParser::handleIntegerParameter(SingleStructureScheme& t, 296 tokens_iterator& p) { 297 const auto n = this->readString(p, this->tokens.end()); 298 const int v = this->readInt(p, this->tokens.end()); 299 t.setIntegerParameter(n, v); 300 this->readSpecifiedToken("SingleStructureSchemeParser::handleIntegerParameter", ";", p, 301 this->tokens.end()); 302 } // end of SingleStructureSchemeParser::handleIntegerParameter 303 handleUnsignedIntegerParameter(SingleStructureScheme & t,tokens_iterator & p)304 void SingleStructureSchemeParser::handleUnsignedIntegerParameter(SingleStructureScheme& t, 305 tokens_iterator& p) { 306 const auto n = this->readString(p, this->tokens.end()); 307 const auto v = this->readUnsignedInt(p, this->tokens.end()); 308 t.setUnsignedIntegerParameter(n, v); 309 this->readSpecifiedToken("SingleStructureSchemeParser::handleUnsignedIntegerParameter", ";", p, 310 this->tokens.end()); 311 } // end of SingleStructureSchemeParser::handleUnsignedIntegerParameteru 312 handleInternalStateVariable(SingleStructureScheme & t,tokens_iterator & p)313 void SingleStructureSchemeParser::handleInternalStateVariable(SingleStructureScheme& t, 314 tokens_iterator& p) { 315 using namespace std; 316 shared_ptr<Behaviour> b(t.getBehaviour()); 317 const string& n = this->readString(p, this->tokens.end()); 318 const vector<string>& ivsnames = b->getInternalStateVariablesNames(); 319 vector<string> ivs; 320 selectVariables(ivs, ivsnames, n); 321 tfel::raise_if(ivs.empty(), 322 "SingleStructureSchemeParser::handleInternalStateVariable: " 323 "the behaviour does not declare an internal state " 324 "variable named '" + 325 n + "'"); 326 if (ivs.size() == 1) { 327 this->setInternalStateVariableValue(t, p, ivs[0]); 328 } else { 329 const int type = b->getInternalStateVariableType(ivs[0]); 330 bool uniform = false; 331 if (type == 0) { 332 uniform = p->value != "{"; 333 } else { 334 tfel::raise_if(p->value != "{", 335 "SingleStructureSchemeParser::handleInternalStateVariable: " 336 "unexpected token '" + 337 n + "'"); 338 ++p; 339 this->checkNotEndOfLine("SingleStructureSchemeParser::handleInternalStateVariable", p, 340 this->tokens.end()); 341 uniform = p->value != "{"; 342 --p; 343 } 344 if (uniform) { 345 vector<string>::const_iterator pn; 346 const tokens_iterator p2 = p; 347 for (pn = ivs.begin(); pn != ivs.end(); ++pn) { 348 p = p2; 349 this->setInternalStateVariableValue(t, p, *pn); 350 } 351 } else { 352 this->readSpecifiedToken("SingleStructureSchemeParser::handleInternalStateVariable", "{", p, 353 this->tokens.end()); 354 vector<string>::const_iterator pn; 355 for (pn = ivs.begin(); pn != ivs.end();) { 356 this->setInternalStateVariableValue(t, p, *pn); 357 if (++pn != ivs.end()) { 358 this->readSpecifiedToken("SingleStructureSchemeParser::handleInternalStateVariable", 359 ",", p, this->tokens.end()); 360 } 361 } 362 this->readSpecifiedToken("SingleStructureSchemeParser::handleInternalStateVariable", "}", p, 363 this->tokens.end()); 364 } 365 } 366 this->readSpecifiedToken("SingleStructureSchemeParser::handleInternalStateVariable", ";", p, 367 this->tokens.end()); 368 } 369 handleExternalStateVariable(SingleStructureScheme & t,tokens_iterator & p)370 void SingleStructureSchemeParser::handleExternalStateVariable(SingleStructureScheme& t, 371 tokens_iterator& p) { 372 const auto& evt = this->readEvolutionType(p); 373 const auto& n = this->readString(p, this->tokens.end()); 374 t.setExternalStateVariable(n, this->parseEvolution(t, evt, p), true); 375 this->readSpecifiedToken("SingleStructureSchemeParser::handleExternalStateVariable", ";", p, 376 this->tokens.end()); 377 } 378 setInternalStateVariableValue(SingleStructureScheme & t,tokens_iterator & p,const std::string & n)379 void SingleStructureSchemeParser::setInternalStateVariableValue(SingleStructureScheme& t, 380 tokens_iterator& p, 381 const std::string& n) { 382 using namespace std; 383 const int type = t.getBehaviour()->getInternalStateVariableType(n); 384 if (type == 0) { 385 t.setScalarInternalStateVariableInitialValue(n, this->readDouble(t, p)); 386 } else if (type == 1) { 387 const unsigned short N = getSTensorSize(t.getDimension()); 388 vector<real> v(N); 389 this->readArrayOfSpecifiedSize(v, t, p); 390 t.setStensorInternalStateVariableInitialValues(n, v); 391 } else if (type == 3) { 392 const unsigned short N = getTensorSize(t.getDimension()); 393 vector<real> v(N); 394 this->readArrayOfSpecifiedSize(v, t, p); 395 t.setTensorInternalStateVariableInitialValues(n, v); 396 } else { 397 tfel::raise( 398 "SingleStructureSchemeParser::setInternalStateVariableValue : " 399 "unsupported state variable type for " 400 "internal state variable '" + 401 n + "'"); 402 } 403 } 404 registerCallBack(const std::string & k,const SingleStructureSchemeParser::CallBack & p)405 void SingleStructureSchemeParser::registerCallBack( 406 const std::string& k, const SingleStructureSchemeParser::CallBack& p) { 407 this->callbacks.insert({k, p}); 408 } // end of SingleStructureSchemeParser::registerCallBack 409 registerCallBacks()410 void SingleStructureSchemeParser::registerCallBacks() { 411 this->registerCallBack("@Behaviour", &SingleStructureSchemeParser::handleBehaviour); 412 this->registerCallBack("@MaterialProperty", 413 &SingleStructureSchemeParser::handleMaterialProperty); 414 this->registerCallBack("@InternalStateVariable", 415 &SingleStructureSchemeParser::handleInternalStateVariable); 416 this->registerCallBack("@ExternalStateVariable", 417 &SingleStructureSchemeParser::handleExternalStateVariable); 418 this->registerCallBack("@OutOfBoundsPolicy", 419 &SingleStructureSchemeParser::handleOutOfBoundsPolicy); 420 this->registerCallBack("@Parameter", &SingleStructureSchemeParser::handleParameter); 421 this->registerCallBack("@IntegerParameter", 422 &SingleStructureSchemeParser::handleIntegerParameter); 423 this->registerCallBack("@UnsignedIntegerParameter", 424 &SingleStructureSchemeParser::handleUnsignedIntegerParameter); 425 this->registerCallBack("@HandleThermalExpansion", 426 &SingleStructureSchemeParser::handleHandleThermalExpansion); 427 } // end of SingleStructureSchemeParser::registerCallBacks 428 treatKeyword(SingleStructureScheme & t,tokens_iterator & p)429 bool SingleStructureSchemeParser::treatKeyword(SingleStructureScheme& t, tokens_iterator& p) { 430 auto pc = this->callbacks.find(p->value); 431 if (pc == this->callbacks.end()) { 432 return false; 433 } 434 if (mfront::getVerboseMode() >= mfront::VERBOSE_DEBUG) { 435 auto& log = mfront::getLogStream(); 436 log << "SingleStructureSchemeParser::execute : treating keyword '" << p->value 437 << "' at line '" << p->line << "'\n"; 438 } 439 ++p; 440 auto line = p->line; 441 try { 442 (this->*(pc->second))(t, p); 443 } catch (std::exception& e) { 444 std::ostringstream msg; 445 msg << "SingleStructureSchemeParser::SingleStructureScheme : error while " 446 << "parsing file '" << this->file << "' at line '" << line << "'.\n" 447 << e.what(); 448 tfel::raise(msg.str()); 449 } 450 return true; 451 } // end of SingleStructureSchemeParser::treatKeyword 452 getKeyWordsList() const453 std::vector<std::string> SingleStructureSchemeParser::getKeyWordsList() const { 454 auto keys = std::vector<std::string>{}; 455 for (const auto& k : this->callbacks) { 456 keys.push_back(k.first); 457 } 458 return keys; 459 } // end of SingleStructureSchemeParser::getKeyWordsList 460 461 SingleStructureSchemeParser::~SingleStructureSchemeParser() = default; 462 463 } // end of namespace mtest 464