1 /*! 2 * \file AbaqusInterfaceBase.cxx 3 * \brief 4 * \author Thomas Helfer 5 * \date 17 mars 2016 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<fstream> 15 #include"TFEL/Raise.hxx" 16 #include"MFront/DSLUtilities.hxx" 17 #include"MFront/FileDescription.hxx" 18 #include"MFront/AbaqusInterfaceBase.hxx" 19 20 #ifndef _MSC_VER 21 static const char * const constexpr_c = "constexpr"; 22 #else 23 static const char * const constexpr_c = "const"; 24 #endif 25 26 namespace mfront{ 27 28 const char* const 29 AbaqusInterfaceBase::finiteStrainStrategy = "abaqus::finiteStrainStrategy"; 30 31 const char* const 32 AbaqusInterfaceBase::orthotropyManagementPolicy = "abaqus::orthotropyManagementPolicy"; 33 checkFiniteStrainStrategy(const std::string & fs)34 static void checkFiniteStrainStrategy(const std::string& fs){ 35 tfel::raise_if((fs!="Native")&& 36 (fs!="FiniteRotationSmallStrain")&& 37 (fs!="MieheApelLambrechtLogarithmicStrain"), 38 "checkFiniteStrainStrategy: " 39 "unsupported strategy '"+fs+"'\n" 40 "The only supported strategies are " 41 "'Native', 'FiniteRotationSmallStrain', " 42 "'MieheApelLambrechtLogarithmicStrain'"); 43 } // end of checkFiniteStrainStrategy 44 45 void checkFiniteStrainStrategyDefinitionConsistency(const BehaviourDescription & bd,const std::string & fs)46 AbaqusInterfaceBase::checkFiniteStrainStrategyDefinitionConsistency(const BehaviourDescription& bd, 47 const std::string& fs) 48 { 49 auto throw_if = [](const bool c,const std::string& msg){ 50 tfel::raise_if(c,"AbaqusInterfaceBase::checkFiniteStrainStrategyDefinitionConsistency: "+msg); 51 }; 52 checkFiniteStrainStrategy(fs); 53 if(bd.isStrainMeasureDefined()){ 54 const auto ms = bd.getStrainMeasure(); 55 if(ms==BehaviourDescription::LINEARISED){ 56 throw_if(fs!="Native","incompatible finite strain strategy " 57 "'"+fs+"' (only `Native` accepted)"); 58 } else if(ms==BehaviourDescription::GREENLAGRANGE){ 59 throw_if(fs!="FiniteRotationSmallStrain", 60 "incompatible finite strain strategy " 61 "'"+fs+"' (only `FiniteRotationSmallStrain` accepted)"); 62 } else if(ms==BehaviourDescription::HENCKY){ 63 throw_if(fs!="MieheApelLambrechtLogarithmicStrain", 64 "incompatible finite strain strategy '"+fs+"' " 65 "(only `MieheApelLambrechtLogarithmicStrain` accepted)"); 66 } else { 67 throw_if(true,"unsupported finite strain strategy"); 68 } 69 } 70 } // end of AbaqusInterfaceBase::checkFiniteStrainStrategyDefinitionConsistency 71 72 void checkFiniteStrainStrategyDefinitionConsistency(const BehaviourDescription & bd)73 AbaqusInterfaceBase::checkFiniteStrainStrategyDefinitionConsistency(const BehaviourDescription& bd){ 74 auto throw_if = [](const bool c,const std::string& msg){ 75 tfel::raise_if(c,"AbaqusInterfaceBase::checkFiniteStrainStrategyDefinitionConsistency: "+msg); 76 }; 77 if(bd.getBehaviourType()!=BehaviourDescription::STANDARDSTRAINBASEDBEHAVIOUR){ 78 throw_if(bd.hasAttribute(AbaqusInterfaceBase::finiteStrainStrategy), 79 "finite strain strategy is only supported for strain based behaviours"); 80 } else { 81 if(bd.hasAttribute(AbaqusInterfaceBase::finiteStrainStrategy)){ 82 const auto fs = bd.getAttribute<std::string>(AbaqusInterfaceBase::finiteStrainStrategy); 83 AbaqusInterfaceBase::checkFiniteStrainStrategyDefinitionConsistency(bd,fs); 84 } 85 } 86 } // end of AbaqusInterfaceBase::checkFiniteStrainStrategyDefinitionConsistency 87 hasFiniteStrainStrategy(const BehaviourDescription & bd)88 bool AbaqusInterfaceBase::hasFiniteStrainStrategy(const BehaviourDescription& bd){ 89 checkFiniteStrainStrategyDefinitionConsistency(bd); 90 if(bd.isStrainMeasureDefined()){ 91 return bd.getStrainMeasure()!=BehaviourDescription::LINEARISED; 92 } 93 return bd.hasAttribute(AbaqusInterfaceBase::finiteStrainStrategy); 94 } // end of AbaqusInterfaceBase::hasFiniteStrainStrategy 95 getFiniteStrainStrategy(const BehaviourDescription & bd)96 std::string AbaqusInterfaceBase::getFiniteStrainStrategy(const BehaviourDescription& bd){ 97 checkFiniteStrainStrategyDefinitionConsistency(bd); 98 auto throw_if = [](const bool c,const std::string& msg){ 99 tfel::raise_if(c,"AbaqusInterfaceBase::getFiniteStrainStrategy: "+msg); 100 }; 101 if(bd.isStrainMeasureDefined()){ 102 const auto ms = bd.getStrainMeasure(); 103 if(ms==BehaviourDescription::GREENLAGRANGE){ 104 return "FiniteRotationSmallStrain"; 105 } else if(ms==BehaviourDescription::HENCKY){ 106 return "MieheApelLambrechtLogarithmicStrain"; 107 } else { 108 throw_if(true,"unsupported strain measure"); 109 } 110 } 111 throw_if(!bd.hasAttribute(AbaqusInterfaceBase::finiteStrainStrategy), 112 "no finite strain strategy defined"); 113 return bd.getAttribute<std::string>(AbaqusInterfaceBase::finiteStrainStrategy); 114 } // end of AbaqusInterfaceBase::getFiniteStrainStrategy 115 hasOrthotropyManagementPolicy(const BehaviourDescription & mb)116 bool AbaqusInterfaceBase::hasOrthotropyManagementPolicy(const BehaviourDescription& mb){ 117 return mb.hasAttribute(AbaqusInterfaceBase::orthotropyManagementPolicy); 118 } // end of AbaqusInterfaceBase::hasOrthotropyManagementPolicy 119 getOrthotropyManagementPolicy(const BehaviourDescription & mb)120 std::string AbaqusInterfaceBase::getOrthotropyManagementPolicy(const BehaviourDescription& mb){ 121 return mb.getAttribute<std::string>(AbaqusInterfaceBase::orthotropyManagementPolicy); 122 } // end of AbaqusInterfaceBase::getOrthotropyManagementPolicy 123 124 void checkOrthotropyManagementPolicyConsistency(const BehaviourDescription & mb)125 AbaqusInterfaceBase::checkOrthotropyManagementPolicyConsistency(const BehaviourDescription& mb){ 126 if(AbaqusInterfaceBase::hasOrthotropyManagementPolicy(mb)){ 127 tfel::raise_if(mb.getSymmetryType()!=mfront::ORTHOTROPIC, 128 "AbaqusInterfaceBase::checkOrthotropyManagementPolicyConsistency: " 129 "orthotropy management policy is only valid " 130 "for orthotropic behaviour"); 131 } 132 } // end of AbaqusInterfaceBase::checkOrthotropyManagementPolicyConsistency 133 134 std::string getLibraryName(const BehaviourDescription & mb) const135 AbaqusInterfaceBase::getLibraryName(const BehaviourDescription& mb) const 136 { 137 auto lib = std::string{}; 138 if(mb.getLibrary().empty()){ 139 if(!mb.getMaterialName().empty()){ 140 lib = this->getInterfaceName()+mb.getMaterialName(); 141 } else { 142 lib = this->getInterfaceName()+"Behaviour"; 143 } 144 } else { 145 lib = this->getInterfaceName()+mb.getLibrary(); 146 } 147 return makeUpperCase(lib); 148 } // end of AbaqusInterfaceBase::getLibraryName 149 150 std::pair<bool,tfel::utilities::CxxTokenizer::TokensContainer::const_iterator> treatCommonKeywords(BehaviourDescription & bd,const std::string & k,tokens_iterator current,const tokens_iterator end)151 AbaqusInterfaceBase::treatCommonKeywords(BehaviourDescription& bd, 152 const std::string& k, 153 tokens_iterator current, 154 const tokens_iterator end) 155 { 156 auto throw_if = [](const bool b,const std::string& m){ 157 tfel::raise_if(b,"AbaqusInterfaceBase::treatCommonKeywords: "+m); 158 }; 159 if (k=="@AbaqusFiniteStrainStrategy"){ 160 throw_if(bd.hasAttribute(AbaqusInterfaceBase::finiteStrainStrategy), 161 "a finite strain strategy has already been defined"); 162 throw_if(current==end,"unexpected end of file"); 163 const auto fs = current->value; 164 throw_if(++current==end,"unexpected end of file"); 165 throw_if(current->value!=";","expected ';', read '"+current->value+'\''); 166 ++(current); 167 AbaqusInterfaceBase::checkFiniteStrainStrategyDefinitionConsistency(bd,fs); 168 bd.setAttribute(AbaqusInterfaceBase::finiteStrainStrategy,fs,false); 169 return {true,current}; 170 } 171 if(k=="@AbaqusOrthotropyManagementPolicy"){ 172 auto read = [&throw_if](const std::string& s){ 173 throw_if((s!="Native")&&(s!="MFront"), 174 "unsupported orthotropy management " 175 "policy '"+s+"'\n" 176 "The only supported policies are " 177 "'MFront' and 'Native'"); 178 return s; 179 }; 180 throw_if(bd.getSymmetryType()!=mfront::ORTHOTROPIC, 181 "orthotropy management policy is only valid " 182 "for orthotropic behaviour"); 183 throw_if(bd.hasAttribute(AbaqusInterfaceBase::orthotropyManagementPolicy), 184 "an orthotropy management policy has already been defined"); 185 throw_if(current==end,"unexpected end of file"); 186 bd.setAttribute(AbaqusInterfaceBase::orthotropyManagementPolicy, 187 read(current->value),false); 188 throw_if(++current==end,"unexpected end of file"); 189 throw_if(current->value!=";","expected ';', read '"+current->value+'\''); 190 ++(current); 191 return {true,current}; 192 } 193 return {false,current}; 194 } // end of AbaqusInterfaceBase::treatCommonKeyword 195 196 unsigned short getStateVariablesOffset(const BehaviourDescription & bd,const Hypothesis h) const197 AbaqusInterfaceBase::getStateVariablesOffset(const BehaviourDescription& bd, 198 const Hypothesis h) const{ 199 if((bd.hasAttribute(AbaqusInterfaceBase::orthotropyManagementPolicy))&& 200 (bd.getAttribute<std::string>(AbaqusInterfaceBase::orthotropyManagementPolicy)=="MFront")){ 201 if((h==ModellingHypothesis::AXISYMMETRICAL)|| 202 (h==ModellingHypothesis::PLANESTRAIN)|| 203 (h==ModellingHypothesis::PLANESTRESS)){ 204 return 2u; 205 } else if(h==ModellingHypothesis::TRIDIMENSIONAL){ 206 return 6u; 207 } 208 tfel::raise("AbaqusInterfaceBase::getStateVariablesOffset: " 209 "invalid hypothesis"); 210 } 211 return 0u; 212 } 213 214 std::vector<std::string> getCommonKeywords() const215 AbaqusInterfaceBase::getCommonKeywords() const{ 216 return {"@AbaqusFiniteStrainStrategy","@AbaqusOrthotropyManagementPolicy"}; 217 } // end of AbaqusInterfaceBase::getCommonKeywords 218 getFunctionNameBasis(const std::string & name) const219 std::string AbaqusInterfaceBase::getFunctionNameBasis( 220 const std::string& name) const { 221 return makeUpperCase(name); 222 } // end of AbaqusInterfaceBase::getFunctionName 223 getFunctionNameForHypothesis(const std::string & name,const Hypothesis h) const224 std::string AbaqusInterfaceBase::getFunctionNameForHypothesis(const std::string& name, 225 const Hypothesis h) const 226 { 227 const auto s = [h]() -> std::string { 228 if(h==ModellingHypothesis::AXISYMMETRICAL){ 229 return "AXIS"; 230 } else if(h==ModellingHypothesis::PLANESTRAIN){ 231 return "PSTRAIN"; 232 } else if(h==ModellingHypothesis::PLANESTRESS){ 233 return "PSTRESS"; 234 } else if(h==ModellingHypothesis::TRIDIMENSIONAL){ 235 return "3D"; 236 } 237 tfel::raise("AbaqusInterfaceBase::getFunctionNameForHypothesis: " 238 "invalid hypothesis."); 239 }(); 240 return makeUpperCase(name)+"_"+s; 241 } // end of AbaqusInterfaceBase::getFunctionNameForHypothesis 242 243 std::set<AbaqusInterfaceBase::Hypothesis> getModellingHypothesesToBeTreated(const BehaviourDescription & mb) const244 AbaqusInterfaceBase::getModellingHypothesesToBeTreated(const BehaviourDescription& mb) const 245 { 246 auto h = std::set<Hypothesis>{}; 247 const auto& bh = mb.getModellingHypotheses(); 248 if(bh.find(ModellingHypothesis::AXISYMMETRICAL)!=bh.end()){ 249 h.insert(ModellingHypothesis::AXISYMMETRICAL); 250 } 251 if(bh.find(ModellingHypothesis::PLANESTRAIN)!=bh.end()){ 252 h.insert(ModellingHypothesis::PLANESTRAIN); 253 } 254 if(bh.find(ModellingHypothesis::PLANESTRESS)!=bh.end()){ 255 h.insert(ModellingHypothesis::PLANESTRESS); 256 } 257 if(bh.find(ModellingHypothesis::TRIDIMENSIONAL)!=bh.end()){ 258 h.insert(ModellingHypothesis::TRIDIMENSIONAL); 259 } 260 if(h.empty()){ 261 tfel::raise("AbaqusInterfaceBase::getModellingHypothesesToBeTreated : " 262 "no hypotheses selected. This means that the given beahviour " 263 "can't be used neither in 'AxisymmetricalGeneralisedPlaneStrain' " 264 "nor in 'AxisymmetricalGeneralisedPlaneStress', so it does not " 265 "make sense to use the Abaqus interface"); 266 } 267 return h; 268 } // end of AbaqusInterfaceBase::getModellingHypothesesToBeTreated 269 writeAbaqusBehaviourTraits(std::ostream & out,const BehaviourDescription & mb,const Hypothesis h) const270 void AbaqusInterfaceBase::writeAbaqusBehaviourTraits( 271 std::ostream& out, 272 const BehaviourDescription& mb, 273 const Hypothesis h) const { 274 using namespace std; 275 const auto mvs = mb.getMainVariablesSize(); 276 const auto mprops = this->buildMaterialPropertiesList(mb,h); 277 if (h == ModellingHypothesis::UNDEFINEDHYPOTHESIS) { 278 out << "template<tfel::material::ModellingHypothesis::Hypothesis " 279 "H,typename Type"; 280 if (mb.useQt()) { 281 out << ",bool use_qt"; 282 } 283 } else { 284 out << "template<typename Type"; 285 if (mb.useQt()) { 286 out << ",bool use_qt"; 287 } 288 } 289 out << ">\n"; 290 out << "struct AbaqusTraits<tfel::material::" << mb.getClassName() << "<"; 291 if (h == ModellingHypothesis::UNDEFINEDHYPOTHESIS) { 292 out << "H"; 293 } else { 294 out << "tfel::material::ModellingHypothesis::" 295 << ModellingHypothesis::toUpperCaseString(h); 296 } 297 out << ",Type,"; 298 if(mb.useQt()){ 299 out << "use_qt"; 300 } else { 301 out << "false"; 302 } 303 out << "> >\n{\n"; 304 out << "//! behaviour type\n"; 305 if(mb.getBehaviourType()==BehaviourDescription::STANDARDSTRAINBASEDBEHAVIOUR){ 306 out << "static " << constexpr_c << " AbaqusBehaviourType btype = abaqus::STANDARDSTRAINBASEDBEHAVIOUR;\n"; 307 } else if(mb.getBehaviourType()==BehaviourDescription::STANDARDFINITESTRAINBEHAVIOUR){ 308 out << "static " << constexpr_c << " AbaqusBehaviourType btype = abaqus::STANDARDFINITESTRAINBEHAVIOUR;\n"; 309 } else { 310 tfel::raise("AbaqusInterfaceBase::writeAbaqusBehaviourTraits : " 311 "unsupported behaviour type"); 312 } 313 out << "//! space dimension\n"; 314 if(h==ModellingHypothesis::UNDEFINEDHYPOTHESIS){ 315 out << "static " << constexpr_c << " unsigned short N = tfel::material::ModellingHypothesisToSpaceDimension<H>::value;\n"; 316 } else { 317 out << "static " << constexpr_c << " unsigned short N = tfel::material::ModellingHypothesisToSpaceDimension<" 318 << "tfel::material::ModellingHypothesis::" 319 << ModellingHypothesis::toUpperCaseString(h) 320 << ">::value;\n"; 321 } 322 out << "// tiny vector size\n"; 323 out << "static " << constexpr_c << " unsigned short TVectorSize = N;\n"; 324 out << "// symmetric tensor size\n"; 325 out << "static " << constexpr_c << " unsigned short StensorSize = tfel::math::StensorDimeToSize<N>::value;\n"; 326 out << "// tensor size\n"; 327 out << "static " << constexpr_c << " unsigned short TensorSize = tfel::math::TensorDimeToSize<N>::value;\n"; 328 out << "// size of the driving variable array\n"; 329 out << "static " << constexpr_c << " unsigned short GradientSize = " << mvs.first << ";\n"; 330 out << "// size of the thermodynamic force variable array (STRESS)\n"; 331 out << "static " << constexpr_c << " unsigned short ThermodynamicForceVariableSize = " << mvs.second << ";\n"; 332 if(mb.getAttribute(BehaviourDescription::requiresUnAlteredStiffnessTensor,false)){ 333 out << "static " << constexpr_c << " bool requiresUnAlteredStiffnessTensor = true;\n"; 334 } else { 335 out << "static " << constexpr_c << " bool requiresUnAlteredStiffnessTensor = false;\n"; 336 } 337 if(mb.getAttribute(BehaviourDescription::requiresStiffnessTensor,false)){ 338 out << "static " << constexpr_c << " bool requiresStiffnessTensor = true;\n"; 339 } else { 340 out << "static " << constexpr_c << " bool requiresStiffnessTensor = false;\n"; 341 } 342 if(mb.getAttribute(BehaviourDescription::requiresThermalExpansionCoefficientTensor,false)){ 343 out << "static " << constexpr_c << " bool requiresThermalExpansionCoefficientTensor = true;\n"; 344 } else { 345 out << "static " << constexpr_c << " bool requiresThermalExpansionCoefficientTensor = false;\n"; 346 } 347 if(mb.getSymmetryType()==mfront::ISOTROPIC){ 348 out << "static " << constexpr_c << " AbaqusSymmetryType type = abaqus::ISOTROPIC;\n"; 349 } else if (mb.getSymmetryType()==mfront::ORTHOTROPIC){ 350 out << "static " << constexpr_c << " AbaqusSymmetryType type = abaqus::ORTHOTROPIC;\n"; 351 } else { 352 tfel::raise("AbaqusInterfaceBase::writeAbaqusBehaviourTraits: " 353 "unsupported behaviour type.\n" 354 "The abaqus interface only support isotropic or orthotropic " 355 "behaviour at this time."); 356 } 357 // computing material properties size 358 auto msize = SupportedTypes::TypeSize{}; 359 if(!mprops.first.empty()){ 360 const auto& m = mprops.first.back(); 361 msize = m.offset; 362 msize += SupportedTypes::getTypeSize(m.type,m.arraySize); 363 msize -= mprops.second; 364 } 365 out << "static " << constexpr_c << " unsigned short material_properties_nb = " << msize << ";\n"; 366 if(mb.getElasticSymmetryType()==mfront::ISOTROPIC){ 367 out << "static " << constexpr_c << " AbaqusSymmetryType etype = abaqus::ISOTROPIC;\n"; 368 if(mb.getAttribute(BehaviourDescription::requiresStiffnessTensor,false)){ 369 out << "static " << constexpr_c << " unsigned short elasticPropertiesOffset = 2u;\n"; 370 } else { 371 out << "static " << constexpr_c << " unsigned short elasticPropertiesOffset = 0u;\n"; 372 } 373 if(mb.getAttribute(BehaviourDescription::requiresThermalExpansionCoefficientTensor,false)){ 374 out << "static " << constexpr_c << " unsigned short thermalExpansionPropertiesOffset = 1u;\n"; 375 } else { 376 out << "static " << constexpr_c << " unsigned short thermalExpansionPropertiesOffset = 0u;\n"; 377 } 378 } else if (mb.getElasticSymmetryType()==mfront::ORTHOTROPIC){ 379 out << "static " << constexpr_c << " AbaqusSymmetryType etype = abaqus::ORTHOTROPIC;\n"; 380 if(mb.getAttribute(BehaviourDescription::requiresStiffnessTensor,false)){ 381 out << "static " << constexpr_c << " unsigned short elasticPropertiesOffset " 382 << "= AbaqusOrthotropicElasticPropertiesOffset<N>::value;\n"; 383 } else { 384 out << "static " << constexpr_c << " unsigned short elasticPropertiesOffset = 0u;\n"; 385 } 386 if(mb.getAttribute(BehaviourDescription::requiresThermalExpansionCoefficientTensor,false)){ 387 out << "static " << constexpr_c << " unsigned short thermalExpansionPropertiesOffset = 3u;\n"; 388 } else { 389 out << "static " << constexpr_c << " unsigned short thermalExpansionPropertiesOffset = 0u;\n"; 390 } 391 } else { 392 tfel::raise("AbaqusInterfaceBase::writeAbaqusBehaviourTraits: " 393 "unsupported behaviour type.\n" 394 "The abaqus interface only support isotropic or " 395 "orthotropic behaviour at this time."); 396 } 397 out << "}; // end of class AbaqusTraits\n\n"; 398 } 399 writeMTestFileGeneratorSetModellingHypothesis(std::ostream & out) const400 void AbaqusInterfaceBase::writeMTestFileGeneratorSetModellingHypothesis( 401 std::ostream& out) const { 402 out << "mg.setModellingHypothesis(h);\n"; 403 } // end of AbaqusInterfaceBase::writeMTestFileGeneratorSetModellingHypothesis 404 405 void writeInputFileExample(const BehaviourDescription & mb,const FileDescription & fd,const bool b) const406 AbaqusInterfaceBase::writeInputFileExample(const BehaviourDescription& mb, 407 const FileDescription& fd, 408 const bool b) const{ 409 auto throw_if = [](const bool c,const std::string& m){ 410 tfel::raise_if(c,"AbaqusInterfaceBase::writeInputFileExample: "+m); 411 }; 412 const auto name = mb.getLibrary()+mb.getClassName(); 413 const auto mn = this->getLibraryName(mb)+"_"+mb.getClassName(); 414 const auto fn = (b ? "abaqus/" : "abaqus-explicit/") +name+".inp"; 415 std::ofstream out{fn}; 416 throw_if(!out,"could not open file '"+fn+"'"); 417 // header 418 out << "** \n" 419 << "** File generated by MFront from the " << fd.fileName << " source\n" 420 << "** Example of how to use the " << mb.getClassName() << " behaviour law\n" 421 << "** Author " << fd.authorName << '\n' 422 << "** Date " << fd.date << '\n' 423 << "**\n\n"; 424 // loop over hypothesis 425 for(const auto & h : this->getModellingHypothesesToBeTreated(mb)){ 426 const auto& d = mb.getBehaviourData(h); 427 const auto mps = this->buildMaterialPropertiesList(mb,h); 428 auto msize = SupportedTypes::TypeSize{}; 429 if(!mps.first.empty()){ 430 const auto& m = mps.first.back(); 431 msize = m.offset; 432 msize += SupportedTypes::getTypeSize(m.type,m.arraySize); 433 } 434 const auto& persistentVarsHolder = d.getPersistentVariables(); 435 auto vs = SupportedTypes::TypeSize{}; 436 for(const auto& v : persistentVarsHolder){ 437 vs+=SupportedTypes::getTypeSize(v.type,v.arraySize); 438 } 439 const auto vsize = vs.getValueForModellingHypothesis(h)+ 440 this->getStateVariablesOffset(mb,h); 441 const auto& externalStateVarsHolder = d.getExternalStateVariables(); 442 out << "** Example for the '" << ModellingHypothesis::toString(h) << "' modelling hypothesis\n"; 443 if(!externalStateVarsHolder.empty()){ 444 out << "** This behaviour requires " << externalStateVarsHolder.size() 445 << " field variables to be defined:\n"; 446 int i=1; 447 for(auto pv=std::next(externalStateVarsHolder.begin()); // skipping the temperature 448 pv!=externalStateVarsHolder.end();++pv,++i){ 449 out << "** " << i << ": " << mb.getExternalName(h,pv->name); 450 } 451 } 452 out << "*Material, name=" 453 << this->getFunctionNameForHypothesis(mn,h) << '\n'; 454 if(!b){ 455 out << "*DENSITY\n<density>\n"; 456 } 457 if(vsize!=0){ 458 out << "*Depvar\n" << vsize << ",\n"; 459 int i=1; 460 if(mb.hasAttribute(AbaqusInterfaceBase::orthotropyManagementPolicy)){ 461 const auto omp = 462 mb.getAttribute<std::string>(AbaqusInterfaceBase::orthotropyManagementPolicy); 463 if(omp=="MFront"){ 464 if((h==ModellingHypothesis::AXISYMMETRICAL)|| 465 (h==ModellingHypothesis::PLANESTRAIN)|| 466 (h==ModellingHypothesis::PLANESTRESS)){ 467 out << i++ << ", FirstOrthotropicAxis_1\n"; 468 out << i++ << ", FirstOrthotropicAxis_2\n"; 469 } else if(h==ModellingHypothesis::TRIDIMENSIONAL){ 470 out << i++ << ", FirstOrthotropicAxis_1\n"; 471 out << i++ << ", FirstOrthotropicAxis_2\n"; 472 out << i++ << ", FirstOrthotropicAxis_3\n"; 473 out << i++ << ", SecondOrthotropicAxis_1\n"; 474 out << i++ << ", SecondOrthotropicAxis_2\n"; 475 out << i++ << ", SecondOrthotropicAxis_3\n"; 476 } 477 } else { 478 throw_if(omp!="Native","unsupported orthotropy " 479 "management policy"); 480 } 481 } 482 for(const auto& v : persistentVarsHolder){ 483 const auto vn = mb.getExternalName(h,v.name); 484 if(v.arraySize==1){ 485 this->writeDepvar(out,i,h,v,vn); 486 } else { 487 for(unsigned short a=0;a!=v.arraySize;++a){ 488 this->writeDepvar(out,i,h,v,vn+'['+std::to_string(a)+']'); 489 } 490 } 491 } 492 } 493 if(!mps.first.empty()){ 494 out << "** The material properties are given as if we used parameters to explicitly\n" 495 << "** display their names. Users shall replace those declaration by\n" 496 << "** theirs values and/or declare those parameters in the appropriate *parameters\n" 497 << "** section of the input file\n"; 498 } 499 out << "*User Material, constants=" << msize.getValueForModellingHypothesis(h); 500 if(!mb.getAttribute(h,BehaviourData::isConsistentTangentOperatorSymmetric,false)){ 501 out << ", unsymm"; 502 } 503 out << '\n'; 504 if(!mps.first.empty()){ 505 int i=1; 506 auto write = [&i,&out](const std::string& n){ 507 if(i%9==0){ 508 out << "\n"; 509 i=1; 510 } 511 out << '<' << n << '>'; 512 ++i; 513 }; 514 for(auto pm =mps.first.begin();pm!=mps.first.end();){ 515 if(pm->arraySize==1u){ 516 write(pm->name); 517 } else { 518 for(unsigned short a=0;a!=pm->arraySize;){ 519 write(pm->name+"_"+std::to_string(a)); 520 if(++a!=pm->arraySize){ 521 out << ", "; 522 } 523 } 524 } 525 if(++pm!=mps.first.end()){ 526 out << ", "; 527 } 528 } 529 } 530 out << "\n\n"; 531 } 532 } // end of AbaqusInterfaceBase::writeInputFileExample 533 534 void writeDepvar(std::ostream & out,int & i,const Hypothesis & h,const VariableDescription & v,const std::string & n) const535 AbaqusInterfaceBase::writeDepvar(std::ostream& out, 536 int& i, 537 const Hypothesis& h, 538 const VariableDescription& v, 539 const std::string& n) const { 540 if(SupportedTypes::getTypeFlag(v.type)==SupportedTypes::SCALAR){ 541 out << i++ << ", " << n << '\n'; 542 } else if(SupportedTypes::getTypeFlag(v.type)==SupportedTypes::STENSOR){ 543 out << i++ << ", " << n << "_11\n"; 544 out << i++ << ", " << n << "_22\n"; 545 out << i++ << ", " << n << "_33\n"; 546 out << i++ << ", " << n << "_12\n"; 547 if(h==ModellingHypothesis::TRIDIMENSIONAL){ 548 out << i++ << ", " << n << "_13\n"; 549 out << i++ << ", " << n << "_23\n"; 550 } 551 } else if(SupportedTypes::getTypeFlag(v.type)==SupportedTypes::TENSOR){ 552 out << i++ << ", " << n << "_11\n"; 553 out << i++ << ", " << n << "_22\n"; 554 out << i++ << ", " << n << "_33\n"; 555 out << i++ << ", " << n << "_12\n"; 556 out << i++ << ", " << n << "_21\n"; 557 if(h==ModellingHypothesis::TRIDIMENSIONAL){ 558 out << i++ << ", " << n << "_13\n"; 559 out << i++ << ", " << n << "_31\n"; 560 out << i++ << ", " << n << "_23\n"; 561 out << i++ << ", " << n << "_32\n"; 562 } 563 } else { 564 tfel::raise("AbaqusInterfaceBase::writeDepvar: " 565 "unsupported variable type"); 566 } 567 } 568 569 AbaqusInterfaceBase::~AbaqusInterfaceBase() = default; 570 571 } // end of namespace mfront 572