1 /*! 2 * \file ModelDescription.cxx 3 * \brief 4 * \author Thomas Helfer 5 * \date 21 janv. 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<algorithm> 15 #include"TFEL/Raise.hxx" 16 #include"TFEL/Utilities/CxxTokenizer.hxx" 17 #include"TFEL/Glossary/Glossary.hxx" 18 #include"TFEL/Glossary/GlossaryEntry.hxx" 19 #include"MFront/ModelDescription.hxx" 20 21 namespace mfront 22 { 23 24 ModelDescription::Function::Function() = default; 25 ModelDescription::Function::Function(const ModelDescription::Function&) = default; 26 ModelDescription::Function::Function(ModelDescription::Function&&) = default; 27 ModelDescription::Function& 28 ModelDescription::Function::operator=(const ModelDescription::Function&) = default; 29 ModelDescription::Function& 30 ModelDescription::Function::operator=(ModelDescription::Function&&) = default; 31 ModelDescription::Function::~Function() = default; 32 33 std::pair<std::string,unsigned short> decomposeVariableName(const std::string & n) const34 ModelDescription::decomposeVariableName(const std::string& n) const 35 { 36 auto get = [&n](const VariableDescriptionContainer& vc) 37 -> std::pair<std::string,unsigned short> 38 { 39 using size_type = unsigned short; 40 for(const auto& v:vc){ 41 if(v.name==n){ 42 return {v.name,0u}; 43 } 44 const auto d = v.getAttribute<size_type>(VariableDescription::depth,0); 45 for(size_type j=1;j<=d;++j){ 46 auto fn = v.name + "_" + std::to_string(j); 47 if(fn==n){ 48 return {v.name,j}; 49 } 50 } 51 } 52 return {}; 53 }; 54 auto r = get(this->outputs); 55 if(!r.first.empty()){ 56 return r; 57 } 58 r = get(this->inputs); 59 tfel::raise_if(r.first.empty(),"decomposeVariableName: " 60 "field name '"+n+"' has not been found"); 61 return r; 62 } // end of ModelDescription::decomposeVariableName 63 64 ModelDescription::ModelDescription() = default; 65 ModelDescription::ModelDescription(const ModelDescription&) = default; 66 ModelDescription::ModelDescription(ModelDescription&&) = default; 67 ModelDescription& 68 ModelDescription::operator=(const ModelDescription&) = default; 69 ModelDescription& 70 ModelDescription::operator=(ModelDescription&&) = default; 71 reserveName(const std::string & n)72 void ModelDescription::reserveName(const std::string& n){ 73 tfel::raise_if(!this->reservedNames.insert(n).second, 74 "ModelDescription::reserveName: " 75 "name '"+n+"' already reserved"); 76 } 77 isNameReserved(const std::string & n) const78 bool ModelDescription::isNameReserved(const std::string& n) const{ 79 return this->reservedNames.count(n)!=0; 80 } 81 registerMemberName(const std::string & n)82 void ModelDescription::registerMemberName(const std::string& n) 83 { 84 this->reserveName(n); 85 tfel::raise_if(!this->memberNames.insert(n).second, 86 "ModelDescription::registerMemberName: " 87 "name '"+n+"' already reserved"); 88 } // end of ModelDescription::registerMemberName 89 registerStaticMemberName(const std::string & n)90 void ModelDescription::registerStaticMemberName(const std::string& n) 91 { 92 this->reserveName(n); 93 tfel::raise_if(!this->staticMemberNames.insert(n).second, 94 "ModelDescription::registerStaticMemberName: " 95 "name '"+n+"' already reserved"); 96 } // end of ModelDescription::registerStaticMemberName 97 98 VariableDescription& getVariableDescription(const std::string & n)99 ModelDescription::getVariableDescription(const std::string& n) 100 { 101 if(this->outputs.contains(n)){ 102 return this->outputs.getVariable(n); 103 } 104 if(this->inputs.contains(n)){ 105 return this->inputs.getVariable(n); 106 } 107 if(this->parameters.contains(n)){ 108 return this->parameters.getVariable(n); 109 } 110 if(this->constantMaterialProperties.contains(n)){ 111 return this->constantMaterialProperties.getVariable(n); 112 } 113 tfel::raise("ModelDescription::getVariableDescription: " 114 "No variable named '"+n+"'.\n" 115 "'"+n+"' is neither:\n" 116 "- An output.\n" 117 "- An input.\n" 118 "- A parameter.\n" 119 "- A constant material properties."); 120 } // end of ModelDescription::getVariableDescription 121 122 const VariableDescription& getVariableDescription(const std::string & n) const123 ModelDescription::getVariableDescription(const std::string& n) const 124 { 125 if(this->outputs.contains(n)){ 126 return this->outputs.getVariable(n); 127 } 128 if(this->inputs.contains(n)){ 129 return this->inputs.getVariable(n); 130 } 131 if(this->parameters.contains(n)){ 132 return this->parameters.getVariable(n); 133 } 134 if(this->constantMaterialProperties.contains(n)){ 135 return this->constantMaterialProperties.getVariable(n); 136 } 137 tfel::raise("ModelDescription::getVariableDescription: " 138 "No variable named '"+n+"'.\n" 139 "'"+n+"' is neither:\n" 140 "- An output.\n" 141 "- An input.\n" 142 "- A parameter.\n" 143 "- A constant material properties."); 144 } // end of ModelDescription::getVariableDescription 145 checkVariableExistence(const std::string & v) const146 void ModelDescription::checkVariableExistence(const std::string& v) const{ 147 tfel::raise_if((!this->inputs.contains(v))&& 148 (!this->outputs.contains(v))&& 149 (!this->parameters.contains(v))&& 150 (!this->staticVars.contains(v))&& 151 (!this->constantMaterialProperties.contains(v)), 152 "ModelDescription::checkVariableExistence: " 153 "no variable named '"+v+"'"); 154 } // end of ModelDescription::checkVariableExistence 155 setGlossaryName(const std::string & v,const std::string & g)156 void ModelDescription::setGlossaryName(const std::string& v, 157 const std::string& g){ 158 this->checkVariableExistence(v); 159 const auto& glossary = tfel::glossary::Glossary::getGlossary(); 160 tfel::raise_if(!glossary.contains(g), 161 "ModelDescription::setGlossaryName: " 162 "no glossary name '"+g+"'"); 163 tfel::raise_if((this->glossaryNames.find(v)!=this->glossaryNames.end())|| 164 (this->entryNames.find(v)!=this->entryNames.end()), 165 "ModelDescription::setGlossaryName: " 166 "an external name has already been set " 167 "for variable '"+v+"'"); 168 if(v!=g){ 169 this->reserveName(g); 170 } 171 const auto gn = glossary.getGlossaryEntry(g).getKey(); 172 this->getVariableDescription(v).setGlossaryName(g); 173 this->glossaryNames.insert({v,gn}); 174 } 175 setEntryName(const std::string & v,const std::string & e)176 void ModelDescription::setEntryName(const std::string& v, 177 const std::string& e){ 178 this->checkVariableExistence(v); 179 tfel::raise_if(!tfel::utilities::CxxTokenizer::isValidIdentifier(e,false), 180 "ModelDescription::setEntryName: " 181 "'"+e+"' is a not a valid entry name"); 182 tfel::raise_if(tfel::glossary::Glossary::getGlossary().contains(e), 183 "ModelDescription::setEntryName: " 184 "'"+e+"' is a glossary name"); 185 tfel::raise_if((this->glossaryNames.find(v)!=this->glossaryNames.end())|| 186 (this->entryNames.find(v)!=this->entryNames.end()), 187 "ModelDescription::setEntryName: " 188 "an external name has already been set " 189 "for variable '"+v+"'"); 190 if(v!=e){ 191 this->reserveName(e); 192 } 193 this->getVariableDescription(v).setEntryName(e); 194 this->entryNames.insert({v,e}); 195 } 196 getReservedNames()197 std::set<std::string>& ModelDescription::getReservedNames(){ 198 return this->reservedNames; 199 } 200 201 const std::set<std::string>& getReservedNames() const202 ModelDescription::getReservedNames() const{ 203 return this->reservedNames; 204 } 205 addMaterialLaw(const std::string & m)206 void ModelDescription::addMaterialLaw(const std::string& m) 207 { 208 if(std::find(this->materialLaws.begin(), 209 this->materialLaws.end(),m)==this->materialLaws.end()){ 210 this->materialLaws.push_back(m); 211 } 212 } // end of ModelDescription::addMaterialLaw 213 appendToIncludes(const std::string & c)214 void ModelDescription::appendToIncludes(const std::string& c) 215 { 216 this->includes+=c; 217 if(!this->includes.empty()){ 218 if(*(this->includes.rbegin())!='\n'){ 219 this->includes+='\n'; 220 } 221 } 222 } // end of ModelDescription::appendToIncludes 223 appendToMembers(const std::string & c)224 void ModelDescription::appendToMembers(const std::string& c) 225 { 226 this->members+=c; 227 if(!this->members.empty()){ 228 if(*(this->members.rbegin())!='\n'){ 229 this->members+='\n'; 230 } 231 } 232 } // end of ModelDescription::appendToMembers 233 appendToPrivateCode(const std::string & c)234 void ModelDescription::appendToPrivateCode(const std::string& c) 235 { 236 this->privateCode+=c; 237 if(!this->privateCode.empty()){ 238 if(*(this->privateCode.rbegin())!='\n'){ 239 this->privateCode+='\n'; 240 } 241 } 242 } // end of ModelDescription::appendToPrivateCode 243 appendToSources(const std::string & c)244 void ModelDescription::appendToSources(const std::string& c) 245 { 246 this->sources+=c; 247 if(!this->sources.empty()){ 248 if(*(this->sources.rbegin())!='\n'){ 249 this->sources+='\n'; 250 } 251 } 252 } // end of ModelDescription::appendToSources 253 254 ModelDescription::~ModelDescription() = default; 255 256 } // end of namespace mfront 257