1 /*!
2  * \file  mfront/src/MTestFileGeneratorBase.cxx
3  * \brief
4  * \author Thomas Helfer
5  * \brief 09 juil. 2013
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<iostream>
15 
16 #include<fstream>
17 #include<iterator>
18 #include<stdexcept>
19 #include"TFEL/Raise.hxx"
20 #include"MFront/MTestFileGeneratorBase.hxx"
21 
22 // fixing a bug on current glibc++ cygwin versions (19/08/2015)
23 #if defined __CYGWIN__ &&  (!defined _GLIBCXX_USE_C99)
24 #include<sstream>
25 namespace std{
26   template<typename T>
to_string(const T & v)27   std::string to_string(const T& v){
28     std::ostringstream s;
29     s << v;
30     return s.str();
31   }
32 }
33 #endif /* defined __CYGWIN__ &&  (!defined _GLIBCXX_USE_C99) */
34 
35 namespace mfront{
36 
37   MTestFileGeneratorBase::InternalStateVariable::~InternalStateVariable() = default;
38 
getIdentifier()39   unsigned int MTestFileGeneratorBase::getIdentifier() {
40     static unsigned int i = 0;
41     return ++i;
42   }
43 
MTestFileGeneratorBase()44   MTestFileGeneratorBase::MTestFileGeneratorBase()
45     : hypothesis(tfel::material::ModellingHypothesis::UNDEFINEDHYPOTHESIS),
46       handleThermalExpansion(false),
47       hasRotationMatrix(false)
48   {} // end of MTestFileGeneratorBase::MTestFileGeneratorBase
49 
setHandleThermalExpansion(const bool b)50   void MTestFileGeneratorBase::setHandleThermalExpansion(const bool b) {
51     this->handleThermalExpansion = b;
52   }
53 
setModellingHypothesis(const tfel::material::ModellingHypothesis::Hypothesis h)54   void MTestFileGeneratorBase::setModellingHypothesis(
55       const tfel::material::ModellingHypothesis::Hypothesis h) {
56     using namespace tfel::material;
57     tfel::raise_if(this->hypothesis!=ModellingHypothesis::UNDEFINEDHYPOTHESIS,
58 		   "MTestFileGeneratorBase::setModellingHypothesis: "
59 		   "modelling hypothesis already set");
60     tfel::raise_if(h==ModellingHypothesis::UNDEFINEDHYPOTHESIS,
61 		   "MTestFileGeneratorBase::setModellingHypothesis: "
62 		   "invalid modelling hypothesis");
63     this->hypothesis = h;
64   } // end of MTestFileGeneratorBase::setModellingHypothesis
65 
66   void
addTime(const MTestFileGeneratorBase::real t)67   MTestFileGeneratorBase::addTime(const MTestFileGeneratorBase::real t)
68   {
69     tfel::raise_if(!this->times.insert(t).second,
70 		   "MTestFileGeneratorBase::addTime: "
71 		   "time '"+std::to_string(t)+"' already defined");
72   } // end of MTestFileGeneratorBase::addTime
73 
setRotationMatrix(const real m00,const real m01,const real m02,const real m10,const real m11,const real m12,const real m20,const real m21,const real m22)74   void MTestFileGeneratorBase::setRotationMatrix(const real m00,
75                                                  const real m01,
76                                                  const real m02,
77                                                  const real m10,
78                                                  const real m11,
79                                                  const real m12,
80                                                  const real m20,
81                                                  const real m21,
82                                                  const real m22) {
83     this->hasRotationMatrix = true;
84     this->m[0] = m00;
85     this->m[1] = m01;
86     this->m[2] = m02;
87     this->m[3] = m10;
88     this->m[4] = m11;
89     this->m[5] = m12;
90     this->m[6] = m20;
91     this->m[7] = m21;
92     this->m[8] = m22;
93   } // end of MTestFileGeneratorBase::addTime
94 
addMaterialProperty(const std::string & n,const MTestFileGeneratorBase::real v)95   void MTestFileGeneratorBase::addMaterialProperty(
96       const std::string& n, const MTestFileGeneratorBase::real v) {
97     tfel::raise_if(!(this->mps.insert({n,v}).second),
98 		   "MTestFileGeneratorBase::addMaterialProperty: "
99 		   "material property '"+n+"' already defined");
100   } // end of MTestFileGeneratorBase::addMaterialProperty
101 
102   void
addInternalStateVariable(const std::string & n,const SupportedTypes::TypeFlag f,const MTestFileGeneratorBase::real * const v)103   MTestFileGeneratorBase::addInternalStateVariable(const std::string& n,
104 						   const SupportedTypes::TypeFlag f,
105 						   const MTestFileGeneratorBase::real* const v)
106   {
107     for(const auto& iv : this->ivs){
108       tfel::raise_if(iv.name==n,
109 		     "MTestFileGeneratorBase::addInternalStateVariable: "
110 		     "variable already declared '"+n+"'");
111     }
112     InternalStateVariable iv;
113     iv.name = n;
114     iv.type = f;
115     if(iv.type==SupportedTypes::SCALAR){
116       iv.values[0] = v[0];
117     } else if(iv.type==SupportedTypes::STENSOR){
118       std::copy(v,v+this->getStensorSize(),iv.values);
119     } else {
120       tfel::raise("MTestFileGeneratorBase::addInternalStateVariable : "
121 		  "unsupported type for variable '"+n+"'");
122     }
123     this->ivs.push_back(iv);
124   } // end of MTestFileGeneratorBase::addInternalStateVariable
125 
126   void
addExternalStateVariableValue(const std::string & n,const MTestFileGeneratorBase::real t,const MTestFileGeneratorBase::real v)127   MTestFileGeneratorBase::addExternalStateVariableValue(const std::string& n,
128 							const MTestFileGeneratorBase::real t,
129 							const MTestFileGeneratorBase::real v)
130   {
131     tfel::raise_if(!this->evs[n].insert({t,v}).second,
132 		   "MTestFileGeneratorBase::addExternalStateVariableValue: "
133 		   "time '"+std::to_string(t)+"' already defined "
134 		   "for variable '"+n+"'");
135   } // end of MTestFileGeneratorBase::addValue
136 
generate(const std::string & n) const137   void MTestFileGeneratorBase::generate(const std::string& n) const
138   {
139     std::ofstream file(n+"-"+std::to_string(getIdentifier())+".mtest");
140     tfel::raise_if(!file,"MTestFileGeneratorBase::generate: "
141 		   "can't open file '"+n+".mtest'");
142     file << "@MaximumNumberOfSubSteps 1;\n";
143     if(this->handleThermalExpansion){
144       file << "@HandleThermalExpansion true;\n";
145     } else {
146       file << "@HandleThermalExpansion false;\n";
147     }
148     this->writeModellingHypothesis(file);
149     this->writeBehaviourDeclaration(file);
150     this->writeRotationMatrix(file);
151     this->writeMaterialProperties(file);
152     this->writeInternalStateVariables(file);
153     this->writeExternalStateVariables(file);
154     this->writeGradients(file);
155     this->writeTimes(file);
156   } // end of MTestFileGeneratorBase::generate
157 
writeRotationMatrix(std::ostream & os) const158   void MTestFileGeneratorBase::writeRotationMatrix(std::ostream& os) const {
159     if(this->hasRotationMatrix){
160       os.precision(14);
161       os << "@RotationMatrix {{" << m[0] << "," << m[1] << "," << m[2] << "},\n"
162          << "                 {" << m[3] << "," << m[4] << "," << m[5] << "},\n"
163          << "                 {" << m[6] << "," << m[7] << "," << m[8]
164          << "}};\n\n";
165     }
166   }
167 
writeModellingHypothesis(std::ostream & os) const168   void MTestFileGeneratorBase::writeModellingHypothesis(
169       std::ostream& os) const {
170     using namespace tfel::material;
171     tfel::raise_if(this->hypothesis==ModellingHypothesis::UNDEFINEDHYPOTHESIS,
172 		   "MTestFileGeneratorBase::writeModellingHypothesis: "
173 		   "undefined modelling hypothesis");
174     os << "@ModellingHypothesis '"
175        << ModellingHypothesis::toString(this->hypothesis)
176        << "';\n";
177   }
178 
writeMaterialProperties(std::ostream & os) const179   void MTestFileGeneratorBase::writeMaterialProperties(std::ostream& os) const {
180     if(this->mps.empty()){
181       return;
182     }
183     os << "// Material properties\n";
184     for(const auto& mp : this->mps){
185       os.precision(14);
186       os << "@MaterialProperty<constant> '" << mp.first
187 	 << "' " << mp.second << ";\n";
188     }
189     os << '\n';
190   } // end of MTestFileGeneratorBase::writeMaterialProperties
191 
writeTimes(std::ostream & os) const192   void MTestFileGeneratorBase::writeTimes(std::ostream& os) const
193   {
194     tfel::raise_if(this->times.empty(),
195 		   "MTestFileGeneratorBase::writeTimes: "
196 		   "no times defined");
197     tfel::raise_if(this->times.size()<2,
198 		   "MTestFileGeneratorBase::writeTimes : "
199 		   "only one time given");
200     os << "// Times\n"
201        << "@Times {";
202     os.precision(14);
203     for(auto p=this->times.begin();p!=times.end();){
204       os << *p;
205       if(++p!=times.end()){
206 	os << ", ";
207       }
208     }
209     os << "};\n\n";
210   } // end of MTestFileGeneratorBase::writeTimes
211 
212   void
writeInternalStateVariables(std::ostream & os) const213   MTestFileGeneratorBase::writeInternalStateVariables(std::ostream& os) const
214   {
215     if(this->ivs.empty()){
216       return;
217     }
218     os << "// Internal state variables\n";
219     for(const auto& iv : this->ivs){
220       os << "@InternalStateVariable '" << iv.name << "' ";
221       os.precision(14);
222       if(iv.type==SupportedTypes::SCALAR){
223 	os << iv.values[0] << ";\n";
224       } else if(iv.type==SupportedTypes::STENSOR){
225 	os << "{";
226 	for(unsigned short i=0;i!=this->getStensorSize();){
227 	  os << iv.values[i];
228 	  if(++i!=this->getStensorSize()){
229 	    os << ",";
230 	  }
231 	}
232 	os << "};\n";
233       } else {
234 	tfel::raise("MTestFileGeneratorBase::writeInternalStateVariables : "
235 		    "unsupported internal state variable type");
236       }
237     }
238     os << '\n';
239   } // end of MTestFileGeneratorBase::writeMaterialProperties
240 
241   void
writeExternalStateVariables(std::ostream & os) const242   MTestFileGeneratorBase::writeExternalStateVariables(std::ostream& os) const
243   {
244     if(this->evs.empty()){
245       return;
246     }
247     os << "// External state variables\n";
248     for(const auto& ev : this->evs){
249       const auto& n = ev.first;
250       const auto& v = ev.second;
251       if(v.size()==1){
252 	os.precision(14);
253 	os << "@ExternalStateVariable '"
254 	   << n << "' " << v.begin()->second << ";\n";
255       } else {
256 	os.precision(14);
257 	os << "@ExternalStateVariable<evolution> '" << n<< "' {" ;
258 	for(auto pv=v.begin();pv!=v.end();){
259 	  os << pv->first << " : " << pv->second;
260 	  if(++pv!=v.end()){
261 	    os << ",\n";
262 	  }
263 	}
264 	os << "};\n";
265       }
266     }
267     os << '\n';
268   } // end of MTestFileGeneratorBase::writeExternalStateVariables
269 
270   std::vector<std::string>
getDeformationGradientComponentsNames() const271   MTestFileGeneratorBase::getDeformationGradientComponentsNames() const
272   {
273     using namespace tfel::material;
274     const std::string exts[9u]  = {"FXX","FYY","FZZ",
275 				   "FXY","FYX","FXZ",
276 				   "FZX","FYZ","FZY"};
277     const std::string aexts[5u] = {"FRR","FZZ","FTT",
278 				   "FRZ","FZR"};
279     std::vector<std::string> n;
280     tfel::raise_if(this->hypothesis==ModellingHypothesis::UNDEFINEDHYPOTHESIS,
281 		   "MTestFileGeneratorBase::getDeformationGradientsComponentsNames: "
282 		   "undefined modelling hypothesis");
283     if((this->hypothesis==ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRAIN)||
284        (this->hypothesis==ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRESS)){
285       copy(aexts,aexts+3u,back_inserter(n));
286     } else if(this->hypothesis==ModellingHypothesis::AXISYMMETRICAL){
287       copy(aexts,aexts+5u,back_inserter(n));
288     } else if((this->hypothesis==ModellingHypothesis::PLANESTRESS)||
289 	      (this->hypothesis==ModellingHypothesis::PLANESTRAIN)||
290 	      (this->hypothesis==ModellingHypothesis::GENERALISEDPLANESTRAIN)){
291       copy(exts,exts+5u,back_inserter(n));
292     } else if(this->hypothesis==ModellingHypothesis::TRIDIMENSIONAL){
293       copy(exts,exts+9u,back_inserter(n));
294     } else {
295       tfel::raise("MTestFileGeneratorBase::getDeformationGradientsComponentsNames: "
296 		  "unsupported hypothesis");
297     }
298     return n;
299   }
300 
301   std::vector<std::string>
getStrainComponentsNames() const302   MTestFileGeneratorBase::getStrainComponentsNames() const
303   {
304     using namespace tfel::material;
305     const std::string exts[6u]  = {"EXX","EYY","EZZ",
306 				   "EXY","EXZ","EYZ"};
307     const std::string aexts[4u] = {"ERR","EZZ","ETT","ERZ"};
308     std::vector<std::string> n;
309     tfel::raise_if(this->hypothesis==ModellingHypothesis::UNDEFINEDHYPOTHESIS,
310 		   "MTestFileGeneratorBase::getStrainComponentsNames: "
311 		   "undefined modelling hypothesis");
312     if((this->hypothesis==ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRAIN)||
313        (this->hypothesis==ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRESS)){
314       copy(aexts,aexts+3u,back_inserter(n));
315     } else if(this->hypothesis==ModellingHypothesis::AXISYMMETRICAL){
316       copy(aexts,aexts+4u,back_inserter(n));
317     } else if((this->hypothesis==ModellingHypothesis::PLANESTRESS)||
318 	      (this->hypothesis==ModellingHypothesis::PLANESTRAIN)||
319 	      (this->hypothesis==ModellingHypothesis::GENERALISEDPLANESTRAIN)){
320       copy(exts,exts+4u,back_inserter(n));
321     } else if(this->hypothesis==ModellingHypothesis::TRIDIMENSIONAL){
322       copy(exts,exts+6u,back_inserter(n));
323     } else {
324       tfel::raise("MTestFileGeneratorBase::getStrainComponentsNames: "
325 		  "unsupported hypothesis");
326     }
327     return n;
328   }
329 
330   std::vector<std::string>
getStressComponentsNames() const331   MTestFileGeneratorBase::getStressComponentsNames() const
332   {
333     using namespace tfel::material;
334     const std::string exts[6u]  = {"SXX","SYY","SZZ",
335 				   "SXY","SXZ","SYZ"};
336     const std::string aexts[4u] = {"SRR","SZZ","STT","SRZ"};
337     std::vector<std::string> n;
338     tfel::raise_if(this->hypothesis==ModellingHypothesis::UNDEFINEDHYPOTHESIS,
339 		   "MTestFileGeneratorBase::getStressComponentsNames: "
340 		   "undefined modelling hypothesis");
341     if((this->hypothesis==ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRAIN)||
342        (this->hypothesis==ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRESS)){
343       copy(aexts,aexts+3u,back_inserter(n));
344     } else if(this->hypothesis==ModellingHypothesis::AXISYMMETRICAL){
345       copy(aexts,aexts+4u,
346 	   back_inserter(n));
347     } else if((this->hypothesis==ModellingHypothesis::PLANESTRESS)||
348 	      (this->hypothesis==ModellingHypothesis::PLANESTRAIN)||
349 	      (this->hypothesis==ModellingHypothesis::GENERALISEDPLANESTRAIN)){
350       copy(exts,exts+4u,
351 	   back_inserter(n));
352     } else if(this->hypothesis==ModellingHypothesis::TRIDIMENSIONAL){
353       copy(exts,exts+6u,
354 	   back_inserter(n));
355     } else {
356       tfel::raise("MTestFileGeneratorBase::getStressComponentsNames: "
357 		  "unsupported hypothesis");
358     }
359     return n;
360   }
361 
getTVectorSize() const362   unsigned short MTestFileGeneratorBase::getTVectorSize() const
363   {
364     using namespace tfel::material;
365     tfel::raise_if(this->hypothesis==ModellingHypothesis::UNDEFINEDHYPOTHESIS,
366 		   "MTestFileGeneratorBase::getTVectorSize: "
367 		   "undefined modelling hypothesis");
368     if((this->hypothesis==ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRAIN)||
369        (this->hypothesis==ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRESS)){
370       return 1u;
371     } else if((this->hypothesis==ModellingHypothesis::AXISYMMETRICAL)||
372 	      (this->hypothesis==ModellingHypothesis::PLANESTRESS)||
373 	      (this->hypothesis==ModellingHypothesis::PLANESTRAIN)||
374 	      (this->hypothesis==ModellingHypothesis::GENERALISEDPLANESTRAIN)){
375       return 2u;
376     } else if(this->hypothesis==ModellingHypothesis::TRIDIMENSIONAL){
377       return 3u;
378     }
379     tfel::raise("MTestFileGeneratorBase::getTVectorSize : "
380 		"unsupported modelling hypothesis");
381   } // end of MTestFileGeneratorBase::getTVectorSize
382 
getStensorSize() const383   unsigned short MTestFileGeneratorBase::getStensorSize() const
384   {
385     using namespace tfel::material;
386     tfel::raise_if(this->hypothesis==ModellingHypothesis::UNDEFINEDHYPOTHESIS,
387 		   "MTestFileGeneratorBase::getStensorSize: "
388 		   "undefined modelling hypothesis");
389     if((this->hypothesis==ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRAIN)||
390        (this->hypothesis==ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRESS)){
391       return 3u;
392     } else if((this->hypothesis==ModellingHypothesis::AXISYMMETRICAL)||
393 	      (this->hypothesis==ModellingHypothesis::PLANESTRESS)||
394 	      (this->hypothesis==ModellingHypothesis::PLANESTRAIN)||
395 	      (this->hypothesis==ModellingHypothesis::GENERALISEDPLANESTRAIN)){
396       return 4u;
397     } else if(this->hypothesis==ModellingHypothesis::TRIDIMENSIONAL){
398       return 6u;
399     }
400     tfel::raise("MTestFileGeneratorBase::getStensorSize : "
401 		"unsupported modelling hypothesis");
402   } // end of MTestFileGeneratorBase::getStensorSize
403 
getTensorSize() const404   unsigned short MTestFileGeneratorBase::getTensorSize() const
405   {
406     using namespace tfel::material;
407     tfel::raise_if(this->hypothesis==ModellingHypothesis::UNDEFINEDHYPOTHESIS,
408 		   "MTestFileGeneratorBase::getTensorSize: "
409 		   "undefined modelling hypothesis");
410     if((this->hypothesis==ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRAIN)||
411        (this->hypothesis==ModellingHypothesis::AXISYMMETRICALGENERALISEDPLANESTRESS)){
412       return 3u;
413     } else if((this->hypothesis==ModellingHypothesis::AXISYMMETRICAL)||
414 	      (this->hypothesis==ModellingHypothesis::PLANESTRESS)||
415 	      (this->hypothesis==ModellingHypothesis::PLANESTRAIN)||
416 	      (this->hypothesis==ModellingHypothesis::GENERALISEDPLANESTRAIN)){
417       return 5u;
418     } else if(this->hypothesis==ModellingHypothesis::TRIDIMENSIONAL){
419       return 9u;
420     }
421     tfel::raise("MTestFileGeneratorBase::getTensorSize : "
422 		"unsupported modelling hypothesis");
423   } // end of MTestFileGeneratorBase::getTensorSize
424 
425   MTestFileGeneratorBase::~MTestFileGeneratorBase() = default;
426 
427 } // end of namespace mfront
428