1 /*!
2  * \file  BehaviourQuery.cxx
3  * \brief
4  * \author Thomas Helfer
5  * \date   04 mars 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 #if (defined _WIN32 || defined _WIN64 || defined __CYGWIN__)
15 #ifndef NOMINMAX
16 #define NOMINMAX
17 #endif
18 #include <windows.h>
19 #ifdef small
20 #undef small
21 #endif /* small */
22 #include <cstdlib>
23 #endif
24 #include <algorithm>
25 #include <iostream>
26 #include <sstream>
27 #include "TFEL/Raise.hxx"
28 #include "TFEL/Utilities/StringAlgorithms.hxx"
29 #include "TFEL/Glossary/Glossary.hxx"
30 #include "TFEL/Glossary/GlossaryEntry.hxx"
31 #include "MFront/MFrontHeader.hxx"
32 #include "MFront/MFrontLogStream.hxx"
33 #include "MFront/AbstractBehaviourDSL.hxx"
34 #include "MFront/FileDescription.hxx"
35 #include "MFront/TargetsDescription.hxx"
36 #include "MFront/BehaviourDescription.hxx"
37 #include "MFront/BehaviourQuery.hxx"
38 
39 namespace mfront {
40 
display_variable(const mfront::VariableDescription & v)41   static void display_variable(const mfront::VariableDescription& v) {
42     const auto& n = v.getExternalName();
43     if (n == v.name) {
44       std::cout << "- " << displayName(v);
45     } else {
46       std::cout << "- " << n;
47     }
48     if (v.arraySize != 1u) {
49       std::cout << '[' << v.arraySize << ']';
50     }
51     if (n != v.name) {
52       std::cout << " (" << mfront::displayName(v) << ")";
53     }
54     if (!v.description.empty()) {
55       std::cout << ": " << v.description;
56     } else {
57       const auto& glossary = tfel::glossary::Glossary::getGlossary();
58       if (glossary.contains(n)) {
59         std::cout << ": " << glossary.getGlossaryEntry(n).getShortDescription();
60       }
61     }
62     std::cout << '\n';
63   }  // end of display_variable
64 
getAttribute(const std::string & n,const BehaviourDescription & d,const tfel::material::ModellingHypothesis::Hypothesis h)65   static const BehaviourAttribute& getAttribute(
66       const std::string& n,
67       const BehaviourDescription& d,
68       const tfel::material::ModellingHypothesis::Hypothesis h) {
69     const auto& as1 = d.getAttributes();
70     const auto& as2 = d.getBehaviourData(h).getAttributes();
71     auto p = as2.find(n);
72     if (p != as2.end()) {
73       return p->second;
74     }
75     p = as1.find(n);
76     if (p != as2.end()) {
77       return p->second;
78     }
79     return p->second;
80   }
81 
to_string(const BehaviourDescription::SlipSystem & gs,const bool f=false)82   static std::string to_string(const BehaviourDescription::SlipSystem& gs,
83                                const bool f = false) {
84     using SlipSystemsDescription = BehaviourDescription::SlipSystemsDescription;
85     using std::to_string;
86     auto r = std::string{};
87     const auto bb = f ? '<' : '[';
88     const auto be = f ? '>' : ']';
89     const auto pb = f ? '{' : '(';
90     const auto pe = f ? '}' : ')';
91     if (gs.is<SlipSystemsDescription::system3d>()) {
92       const auto& p = gs.get<SlipSystemsDescription::system3d>().plane;
93       const auto& b = gs.get<SlipSystemsDescription::system3d>().burgers;
94       r += bb + to_string(b[0]) + ',' + to_string(b[1]) + ',' +
95            to_string(b[2]) + be;
96       r += pb + to_string(p[0]) + ',' + to_string(p[1]) + ',' +
97            to_string(p[2]) + pe;
98     } else {
99       tfel::raise_if(!gs.is<SlipSystemsDescription::system4d>(),
100                      "to_string: internal error "
101                      "(unsupported slip system type)");
102       const auto& p = gs.get<SlipSystemsDescription::system4d>().plane;
103       const auto& b = gs.get<SlipSystemsDescription::system4d>().burgers;
104       r += bb + to_string(b[0]) + ',' + to_string(b[1]) + ',' +
105            to_string(b[2]) + ',' + to_string(b[3]) + be;
106       r += pb + to_string(p[0]) + ',' + to_string(p[1]) + ',' +
107            to_string(p[2]) + ',' + to_string(p[3]) + pe;
108     }
109     return r;
110   }  // end of to_string
111 
to_string(const std::array<long double,9u> & a)112   static std::string to_string(const std::array<long double, 9u>& a) {
113     auto r = std::string{};
114     r += '[';
115     for (decltype(a.size()) i = 0; i != a.size();) {
116       r += std::to_string(a[i]);
117       if (++i != 9) {
118         r += ',';
119       }
120     }
121     r += ']';
122     return r;
123   }
124 
extract_crystal_direction(const std::string & o)125   static tfel::material::SlipSystemsDescription::vec extract_crystal_direction(
126       const std::string& o) {
127     using tfel::utilities::tokenize;
128     auto throw_if = [](const bool c, const std::string& msg) {
129       tfel::raise_if(c, "extract_crystal_direction: " + msg);
130     };
131     auto throw_if2 = [throw_if](const bool c) {
132       throw_if(c, "ill defined direction");
133     };
134     throw_if2(o.size() < 2);
135     throw_if2((o[0] != '<') || (o.back() != '>'));
136     const auto ds = tokenize(o.substr(1, o.size() - 2), ',');
137     auto dc = tfel::material::SlipSystemsDescription::vec{};
138     if (ds.size() == 3u) {
139       tfel::material::SlipSystemsDescription::vec3d d3d;
140       d3d[0] = std::stoi(ds[0]);
141       d3d[1] = std::stoi(ds[1]);
142       d3d[2] = std::stoi(ds[2]);
143       dc = d3d;
144     } else {
145       throw_if2(ds.size() != 4);
146       tfel::material::SlipSystemsDescription::vec4d d4d;
147       d4d[0] = std::stoi(ds[0]);
148       d4d[1] = std::stoi(ds[1]);
149       d4d[2] = std::stoi(ds[2]);
150       d4d[3] = std::stoi(ds[3]);
151       dc = d4d;
152     }
153     return dc;
154   }  // end of extract_crystal_direction
155 
BehaviourQuery(const int argc,const char * const * const argv,std::shared_ptr<AbstractBehaviourDSL> d,const std::string & f)156   BehaviourQuery::BehaviourQuery(const int argc,
157                                  const char* const* const argv,
158                                  std::shared_ptr<AbstractBehaviourDSL> d,
159                                  const std::string& f)
160       : tfel::utilities::ArgumentParserBase<BehaviourQuery>(argc, argv),
161         dsl(d),
162         file(f) {
163     this->registerCommandLineCallBacks();
164     this->parseArguments();
165     this->finalizeArgumentsParsing();
166     // registring interfaces
167     if (!this->interfaces.empty()) {
168       dsl->setInterfaces(this->interfaces);
169     }
170   }  // end of BehaviourQuery::BehaviourQuery
171 
registerCommandLineCallBacks()172   void BehaviourQuery::registerCommandLineCallBacks() {
173     using Parser = tfel::utilities::ArgumentParserBase<BehaviourQuery>;
174     Parser::registerNewCallBack("--verbose", &BehaviourQuery::treatVerbose,
175                                 "set verbose output", true);
176     Parser::registerNewCallBack("--verbose", &BehaviourQuery::treatVerbose,
177                                 "set verbose output", true);
178     Parser::registerNewCallBack("--unicode-output",
179                                 &BehaviourQuery::treatUnicodeOutput,
180                                 "allow/disallow unicode output", true);
181     Parser::registerNewCallBack(
182         "--include", "-I", &BehaviourQuery::treatSearchPath,
183         "add a new path at the beginning of the search paths", true);
184     Parser::registerNewCallBack("--install-path",
185                                 &BehaviourQuery::treatInstallPath,
186                                 "set the installation directory", true);
187     Parser::registerNewCallBack("--install-prefix",
188                                 &BehaviourQuery::treatInstallPath,
189                                 "set the installation directory "
190                                 "(same as --install-path)",
191                                 true);
192     Parser::registerNewCallBack(
193         "--search-path", &BehaviourQuery::treatSearchPath,
194         "add a new path at the beginning of the search paths", true);
195     Parser::registerNewCallBack("--debug", &BehaviourQuery::treatDebug,
196                                 "set debug mode");
197     Parser::registerNewCallBack(
198         "--warning", "-W", &BehaviourQuery::treatWarning, "print warnings");
199     Parser::registerNewCallBack("--pedantic", &BehaviourQuery::treatPedantic,
200                                 "print pedantic warning message");
201     Parser::registerNewCallBack("--interface", &BehaviourQuery::treatInterface,
202                                 "define an interface", true);
203     Parser::registerNewCallBack("--modelling-hypothesis",
204                                 &BehaviourQuery::treatModellingHypothesis,
205                                 "select a modelling hypothesis", true);
206     Parser::registerCallBack("--no-gui",
207                              CallBack("do not display errors using "
208                                       "a message box (windows only)",
209                                       [] {}, false));
210 #ifdef MFRONT_HAVE_MADNEX
211     Parser::registerNewCallBack("--material",
212                                 &BehaviourQuery::treatMaterialIdentifier,
213                                 "specify a material identifier", true);
214     Parser::registerNewCallBack(
215         "--material-property", &BehaviourQuery::treatMaterialPropertyIdentifier,
216         "specify a material property identifier (can be a regular expression)",
217         true);
218     Parser::registerNewCallBack(
219         "--behaviour", &BehaviourQuery::treatBehaviourIdentifier,
220         "specify a behaviour identifier (can be a regular expression)", true);
221     Parser::registerNewCallBack(
222         "--model", &BehaviourQuery::treatModelIdentifier,
223         "specify a model identifier (can be a regular expression)", true);
224 #endif /* MFRONT_HAVE_MADNEX */
225     // standard queries
226     const std::vector<std::pair<const char*, const char*>> sq = {
227         {"--author", "show the author name"},
228         {"--description", "show the file description"},
229         {"--date", "show the file implementation date"},
230         {"--material", "show the material name"},
231         {"--library", "show the library name"},
232         {"--type",
233          "return the behaviour type\n"
234          "The value returned has the following meaning:\n"
235          "- 0: general behaviour\n"
236          "- 1: strain based behaviour\n"
237          "- 2: finite strain behaviour\n"
238          "- 3: cohesive zone model\n"},
239         {"--is-strain-measure-defined",
240          "return 'true' is a strain measure "
241          "has been defined, 'false' otherwise"},
242         {"--strain-measure",
243          "return the strain measure used by the behaviour.\n"
244          "The following strain measure are defined: "
245          "- 'Linearised': HPP behaviour\n"
246          "- 'GreenLagrange'\n"
247          "- 'Hencky'\n"},
248         {"--symmetry",
249          "return the behaviour symmetry. If the returned value is 0, "
250          "the behaviour is isotropic. If the returned value is 1, "
251          "the behaviour is orthotropic."},
252         {"--elastic-symmetry",
253          "return the symmetry of the elastic part of the behaviour. "
254          "If the returned value is 0, this part of the behaviour is isotropic. "
255          "If the returned value is 1, this part of the behaviour is "
256          "orthotropic."
257          "the behaviour is orthotropic."},
258         {"--has-crystal-structure",
259          "return `true` if a crystal structure has been defined"},
260         {"--crystal-structure", "return the crystal structure"},
261         {"--slip-systems", "list all the slip systems, sorted by family"},
262         {"--slip-systems-by-index", "list all the slip systems"},
263         {"--orientation-tensors",
264          "list all the orientation tensors, sorted by family"},
265         {"--orientation-tensors-by-index", "list all the orientation tensors"},
266         {"--orientation-tensors-by-slip-system",
267          "list all the orientation tensors"},
268         {"--interaction-matrix", "show the interaction matrix"},
269         {"--dislocations-mean-free-path-interaction-matrix",
270          "show the interaction matrix associated to the effect of dislocations "
271          "of the "
272          "mean-free-path of a dislocation"},
273         {"--interaction-matrix-structure",
274          "show the structure of the interaction matrix"},
275         {"--supported-modelling-hypotheses",
276          "show the list of supported modelling hypothesis"},
277         {"--gradients", "show the list of the gradients"},
278         {"--thermodynamic-forces", "show the list of the thermodynamic forces"},
279         {"--tangent-operator-blocks",
280          "show the list of blocks in the tangent operator"},
281         {"--material-properties",
282          "show the list of material properties for the selected modelling "
283          "hypothesis"},
284         {"--state-variables",
285          "show the list of state variables for the selected modelling "
286          "hypothesis"},
287         {"--auxiliary-state-variables",
288          "show the auxiliary state variables properties for the selected "
289          "modelling hypothesis"},
290         {"--external-state-variables",
291          "show the list of external state variables for the selected modelling "
292          "hypothesis"},
293         {"--integration-variables",
294          "show the list of integration variables for the selected modelling "
295          "hypothesis"},
296         {"--persistent-variables",
297          "show the list of persistent variables for the selected modelling "
298          "hypothesis"},
299         {"--local-variables",
300          "show the list of local variables for the selected modelling "
301          "hypothesis"},
302         {"--parameters",
303          "show the list of parameters for the selected modelling hypothesis"},
304         {"--static-variables",
305          "show the list of static variables for the selected modelling "
306          "hypothesis"},
307         {"--attributes",
308          "show the list of attributes of the behaviour description"},
309         {"--code-blocks",
310          "show the list of code-blocks of the behaviour description for "
311          " the selected modelling hypothesis"},
312         {"--parameters-file",
313          "display the name of a text file which can be used to modify the "
314          "default value of the parameters"}};
315     for (const auto& q : sq) {
316       Parser::registerNewCallBack(q.first, &BehaviourQuery::treatStandardQuery,
317                                   q.second);
318     }
319     const std::vector<std::pair<const char*, const char*>> sq2 = {
320         {"--attribute-type", "display an attribute type"},
321         {"--attribute-value", "display an attribute value"},
322         {"--parameter-type", "display a parameter type"},
323         {"--parameter-default-value", "display a parameter default value"},
324         {"--static-variable-value", "display the value of a static variable"},
325         {"--has-bounds",
326          "return `true` if a variable has bounds, `false` otherwise"},
327         {"--schmid-factors",
328          "compute the Schmid factor for all"
329          " slip systems for a given direction"},
330         {"--schmid-factors-by-index",
331          "compute the Schmid factor for all"
332          " slip systems for a given direction"},
333         {"--bounds-type",
334          "return the bounds type associated to a variable.\n"
335          "The returned value has the follwing meaning:\n"
336          "- `None`\n"
337          "- `Lower`\n"
338          "- `Upper`\n"
339          "- `LowerAndUpper`"},
340         {"--bounds-value", "show the bounds value associated as a range"},
341         {"--has-physical-bounds",
342          "return `true` if a variable has physical bounds, `false` otherwise"},
343         {"--physical-bounds-type",
344          "return the physical bounds type associated to a variable.\n"
345          "The returned value has the follwing meaning:\n"
346          "- `None`\n"
347          "- `Lower`\n"
348          "- `Upper`\n"
349          "- `LowerAndUpper`"},
350         {"--physical-bounds-value",
351          "show the bounds value associated as a range"}};
352     for (const auto& q : sq2) {
353       Parser::registerNewCallBack(q.first, &BehaviourQuery::treatStandardQuery2,
354                                   q.second, true);
355     }
356     Parser::registerNewCallBack("--generated-sources",
357                                 &BehaviourQuery::treatGeneratedSources,
358                                 "show all the generated sources");
359     Parser::registerNewCallBack("--generated-headers",
360                                 &BehaviourQuery::treatGeneratedHeaders,
361                                 "show all the generated headers");
362     Parser::registerNewCallBack("--cppflags", &BehaviourQuery::treatCppFlags,
363                                 "show all the global headers");
364     Parser::registerNewCallBack("--libraries-dependencies",
365                                 &BehaviourQuery::treatLibrariesDependencies,
366                                 "show all the libraries dependencies");
367     Parser::registerNewCallBack("--specific-targets",
368                                 &BehaviourQuery::treatSpecificTargets,
369                                 "show all the specific targets");
370   }  // end of BehaviourQuery::registerCommandLineCallBacks
371 
treatStandardQuery()372   void BehaviourQuery::treatStandardQuery() {
373     using namespace tfel::utilities;
374     using tfel::material::ModellingHypothesis;
375     using std::cout;
376     const auto& q = this->getCurrentCommandLineArgument();
377     const auto& qn = q.as_string();
378     if (qn == "--author") {
379       this->queries2.push_back({"author", [](const FileDescription& fd,
380                                              const BehaviourDescription&) {
381                                   const auto& a = fd.authorName;
382                                   cout << (!a.empty() ? a : "(undefined)")
383                                        << '\n';
384                                 }});
385     } else if (qn == "--description") {
386       this->queries2.push_back(
387           {"description",
388            [](const FileDescription& fd, const BehaviourDescription&) {
389              if (!fd.description.empty()) {
390                const auto d = tokenize(fd.description, '\n');
391                for (const auto& l : d) {
392                  if ((l.size() >= 2) && ((l)[0] == '*') && ((l)[1] == ' ')) {
393                    cout << l.substr(2) << '\n';
394                  } else {
395                    cout << l << '\n';
396                  }
397                }
398              } else {
399                cout << "(undefined)\n";
400              }
401            }});
402     } else if (qn == "--date") {
403       this->queries2.push_back(
404           {"date", [](const FileDescription& fd, const BehaviourDescription&) {
405              const auto& d = fd.date;
406              cout << (!d.empty() ? d : "(undefined)") << '\n';
407            }});
408     } else if (qn == "--material") {
409       this->queries2.push_back({"material", [](const FileDescription&,
410                                                const BehaviourDescription& d) {
411                                   const auto& m = d.getMaterialName();
412                                   cout << (!m.empty() ? m : "(undefined)")
413                                        << '\n';
414                                 }});
415     } else if (qn == "--library") {
416       this->queries2.push_back({"library", [](const FileDescription&,
417                                               const BehaviourDescription& d) {
418                                   const auto& l = d.getLibrary();
419                                   cout << (!l.empty() ? l : "(undefined)")
420                                        << '\n';
421                                 }});
422     } else if (qn == "--type") {
423       this->queries2.push_back(
424           {"type", [](const FileDescription&, const BehaviourDescription& d) {
425              const auto t = d.getBehaviourType();
426              if (t == BehaviourDescription::GENERALBEHAVIOUR) {
427                std::cout << 0 << std::endl;
428              } else if (t ==
429                         BehaviourDescription::STANDARDSTRAINBASEDBEHAVIOUR) {
430                std::cout << 1 << std::endl;
431              } else if (t ==
432                         BehaviourDescription::STANDARDFINITESTRAINBEHAVIOUR) {
433                std::cout << 2 << std::endl;
434              } else if (t == BehaviourDescription::COHESIVEZONEMODEL) {
435                std::cout << 3 << std::endl;
436              } else {
437                tfel::raise("unsupported behaviour type");
438              }
439            }});
440     } else if (qn == "--is-strain-measure-defined") {
441       this->queries2.push_back(
442           {"is-strain-measure-defined",
443            [](const FileDescription&, const BehaviourDescription& d) {
444              const auto t = d.getBehaviourType();
445              tfel::raise_if(
446                  t != BehaviourDescription::STANDARDSTRAINBASEDBEHAVIOUR,
447                  "the behaviour is not based on strain");
448              cout << (d.isStrainMeasureDefined() ? "true\n" : "false\n");
449            }});
450     } else if (qn == "--strain-measure") {
451       this->queries2.push_back(
452           {"strain-measure",
453            [](const FileDescription&, const BehaviourDescription& d) {
454              const auto t = d.getBehaviourType();
455              tfel::raise_if(
456                  t != BehaviourDescription::STANDARDSTRAINBASEDBEHAVIOUR,
457                  "the behaviour is not based on a strain measure");
458              tfel::raise_if(!d.isStrainMeasureDefined(),
459                             "no strain measure defined");
460              const auto ss = d.getStrainMeasure();
461              if (ss == BehaviourDescription::LINEARISED) {
462                cout << "Linearised";
463              } else if (ss == BehaviourDescription::GREENLAGRANGE) {
464                cout << "GreenLagrange\n";
465              } else if (ss == BehaviourDescription::HENCKY) {
466                cout << "Hencky\n";
467              } else {
468                tfel::raise_if(true,
469                               "internal error "
470                               "(unsupported strain measure)");
471              }
472            }});
473     } else if (qn == "--symmetry") {
474       this->queries2.push_back({"symmetry", [](const FileDescription&,
475                                                const BehaviourDescription& d) {
476                                   const auto s = d.getSymmetryType();
477                                   if (s == mfront::ISOTROPIC) {
478                                     cout << 0 << '\n';
479                                   } else if (s == mfront::ORTHOTROPIC) {
480                                     cout << 1 << '\n';
481                                   } else {
482                                     tfel::raise("unsupported symmetry");
483                                   }
484                                 }});
485     } else if (qn == "--has-crystal-structure") {
486       this->queries2.push_back(
487           {"has-crystal-structure",
488            [](const FileDescription&, const BehaviourDescription& d) {
489              if (d.hasCrystalStructure()) {
490                cout << "true\n";
491              } else {
492                cout << "false\n";
493              }
494            }});
495     } else if (qn == "--crystal-structure") {
496       this->queries2.push_back(
497           {"crystal-structure",
498            [](const FileDescription&, const BehaviourDescription& d) {
499              using tfel::material::CrystalStructure;
500              const auto s = d.getCrystalStructure();
501              if (s == CrystalStructure::Cubic) {
502                cout << "Cubic\n";
503              } else if (s == CrystalStructure::HCP) {
504                cout << "Hexagonal closed-packed\n";
505              } else if (s == CrystalStructure::FCC) {
506                cout << "Face-centered cubic\n";
507              } else if (s == CrystalStructure::BCC) {
508                cout << "Body-centered cubic\n";
509              } else {
510                tfel::raise("unsupported crystal structure");
511              }
512            }});
513     } else if (qn == "--slip-systems") {
514       this->queries2.push_back(
515           {"slip-systems",
516            [](const FileDescription&, const BehaviourDescription& d) {
517              tfel::raise_if(!d.areSlipSystemsDefined(),
518                             "no slip system defined");
519              const auto& ssd = d.getSlipSystems();
520              const auto nss = ssd.getNumberOfSlipSystemsFamilies();
521              for (size_t i = 0; i != nss; ++i) {
522                const auto gss = ssd.getSlipSystems(i);
523                cout << "- " << to_string(ssd.getSlipSystemFamily(i), true)
524                     << ":";
525                for (const auto& gs : gss) {
526                  cout << " " << to_string(gs);
527                }
528                cout << '\n';
529              }
530            }});
531     } else if (qn == "--slip-systems-by-index") {
532       this->queries2.push_back(
533           {"slip-systems-by-index",
534            [](const FileDescription&, const BehaviourDescription& d) {
535              tfel::raise_if(!d.areSlipSystemsDefined(),
536                             "no slip system defined");
537              const auto& ssd = d.getSlipSystems();
538              const auto nss = ssd.getNumberOfSlipSystemsFamilies();
539              auto r = size_t{};
540              for (size_t i = 0; i != nss; ++i) {
541                const auto gss = ssd.getSlipSystems(i);
542                for (const auto& gs : gss) {
543                  cout << "- " << r << ": " << to_string(gs) << '\n';
544                  ++r;
545                }
546              }
547            }});
548     } else if (qn == "--orientation-tensors") {
549       this->queries2.push_back(
550           {"orientation-tensors",
551            [](const FileDescription&, const BehaviourDescription& d) {
552              tfel::raise_if(!d.areSlipSystemsDefined(),
553                             "no slip system defined");
554              const auto& ssd = d.getSlipSystems();
555              const auto nss = ssd.getNumberOfSlipSystemsFamilies();
556              for (size_t i = 0; i != nss; ++i) {
557                const auto os = ssd.getOrientationTensors(i);
558                cout << "- " << to_string(ssd.getSlipSystemFamily(i), true)
559                     << ":";
560                for (const auto& o : os) {
561                  cout << " " << to_string(o);
562                }
563                cout << '\n';
564              }
565            }});
566     } else if (qn == "--orientation-tensors-by-index") {
567       this->queries2.push_back(
568           {"orientation-tensors-by-index",
569            [](const FileDescription&, const BehaviourDescription& d) {
570              tfel::raise_if(!d.areSlipSystemsDefined(),
571                             "no slip system defined");
572              const auto& ssd = d.getSlipSystems();
573              const auto nss = ssd.getNumberOfSlipSystemsFamilies();
574              auto r = size_t{};
575              for (size_t i = 0; i != nss; ++i) {
576                const auto os = ssd.getOrientationTensors(i);
577                for (const auto& o : os) {
578                  cout << "- " << r << ": " << to_string(o) << '\n';
579                  ++r;
580                }
581              }
582            }});
583     } else if (qn == "--orientation-tensors-by-slip-system") {
584       this->queries2.push_back(
585           {"orientation-tensors-by-slip-system",
586            [](const FileDescription&, const BehaviourDescription& d) {
587              tfel::raise_if(!d.areSlipSystemsDefined(),
588                             "no slip system defined");
589              const auto& ssd = d.getSlipSystems();
590              const auto nss = ssd.getNumberOfSlipSystemsFamilies();
591              auto r = size_t{};
592              for (size_t i = 0; i != nss; ++i) {
593                const auto os = ssd.getOrientationTensors(i);
594                const auto ss = ssd.getSlipSystems(i);
595                for (decltype(ss.size()) j = 0; j != ss.size(); ++j) {
596                  cout << "- " << to_string(ss[j]) << ": " << to_string(os[j])
597                       << '\n';
598                  ++r;
599                }
600              }
601            }});
602     } else if (qn == "--interaction-matrix-structure") {
603       this->queries2.push_back(
604           {"interaction-matrix-structure",
605            [](const FileDescription&, const BehaviourDescription& d) {
606              tfel::raise_if(!d.areSlipSystemsDefined(),
607                             "no slip system defined");
608              const auto& im = d.getInteractionMatrixStructure();
609              const auto r = im.rank();
610              const auto& ssis_r = im.getSlidingSystemsInteraction();
611              cout << "- number of independent coefficients: " << r << '\n';
612              auto i = size_t{};
613              for (const auto& ssis : ssis_r) {
614                cout << "- rank " << i << ':';
615                for (const auto& ssi : ssis) {
616                  cout << " (" << to_string(ssi.g1) << ':' << to_string(ssi.g2)
617                       << ')';
618                }
619                cout << '\n';
620                ++i;
621              }
622            }});
623     } else if (qn == "--interaction-matrix") {
624       this->queries2.push_back(
625           {"interaction-matrix",
626            [](const FileDescription&, const BehaviourDescription& d) {
627              tfel::raise_if(!d.areSlipSystemsDefined(),
628                             "no slip system defined");
629              const auto& ssd = d.getSlipSystems();
630              const auto& im = d.getInteractionMatrixStructure();
631              const auto nss = ssd.getNumberOfSlipSystemsFamilies();
632              for (size_t i = 0; i != nss; ++i) {
633                for (const auto& gs1 : ssd.getSlipSystems(i)) {
634                  cout << '|';
635                  for (size_t j = 0; j != nss; ++j) {
636                    for (const auto& gs2 : ssd.getSlipSystems(j)) {
637                      cout << " " << im.getRank(gs1, gs2);
638                    }
639                  }
640                  cout << " |\n";
641                }
642              }
643              if (d.hasInteractionMatrix()) {
644                cout << "with:\n";
645                const auto& ivs = ssd.getInteractionMatrix();
646                for (size_t i = 0; i != ivs.size(); ++i) {
647                  cout << "- coefficient '" << i << "': " << ivs[i] << '\n';
648                }
649              }
650            }});
651     } else if (qn == "--dislocations-mean-free-path-interaction-matrix") {
652       this->queries2.push_back(
653           {"dislocations-mean-free-path-interaction-matrix",
654            [](const FileDescription&, const BehaviourDescription& d) {
655              tfel::raise_if(!d.areSlipSystemsDefined(),
656                             "no slip system defined");
657              const auto& ssd = d.getSlipSystems();
658              const auto& im = d.getInteractionMatrixStructure();
659              const auto nss = ssd.getNumberOfSlipSystemsFamilies();
660              for (size_t i = 0; i != nss; ++i) {
661                for (const auto& gs1 : ssd.getSlipSystems(i)) {
662                  cout << '|';
663                  for (size_t j = 0; j != nss; ++j) {
664                    for (const auto& gs2 : ssd.getSlipSystems(j)) {
665                      cout << " " << im.getRank(gs1, gs2);
666                    }
667                  }
668                  cout << " |\n";
669                }
670              }
671              if (d.hasDislocationsMeanFreePathInteractionMatrix()) {
672                cout << "with:\n";
673                const auto& ivs =
674                    ssd.getDislocationsMeanFreePathInteractionMatrix();
675                for (size_t i = 0; i != ivs.size(); ++i) {
676                  cout << "- coefficient '" << i << "': " << ivs[i] << '\n';
677                }
678              }
679            }});
680     } else if (qn == "--elastic-symmetry") {
681       this->queries2.push_back(
682           {"elastic-symmetry",
683            [](const FileDescription&, const BehaviourDescription& d) {
684              const auto s = d.getElasticSymmetryType();
685              if (s == mfront::ISOTROPIC) {
686                cout << 0 << '\n';
687              } else if (s == mfront::ORTHOTROPIC) {
688                cout << 1 << '\n';
689              } else {
690                tfel::raise("unsupported elastic symmetry");
691              }
692            }});
693     } else if (qn == "--supported-modelling-hypotheses") {
694       this->queries2.push_back(
695           {"supported-modelling-hypotheses",
696            [](const FileDescription&, const BehaviourDescription& d) {
697              const auto& mh = d.getModellingHypotheses();
698              for (const auto& h : mh) {
699                cout << ModellingHypothesis::toString(h) << " ";
700              }
701              cout << '\n';
702            }});
703     } else if (qn == "--gradients") {
704       this->queries2.push_back({"gradients", [](const FileDescription&,
705                                                 const BehaviourDescription& d) {
706                                   for (const auto& v : d.getMainVariables()) {
707                                     display_variable(v.first);
708                                   }
709                                 }});
710     } else if (qn == "--thermodynamic-forces") {
711       this->queries2.push_back(
712           {"thermodynamic-forces",
713            [](const FileDescription&, const BehaviourDescription& d) {
714              for (const auto& v : d.getMainVariables()) {
715                display_variable(v.second);
716              }
717            }});
718     } else if (qn == "--tangent-operator-blocks") {
719       this->queries2.push_back(
720           {"tangent-operator-blocks",
721            [](const FileDescription&, const BehaviourDescription& d) {
722              for (const auto& b : d.getTangentOperatorBlocks()) {
723                std::cout << "-" << d.getTangentOperatorBlockSymbolicName(b)
724                          << ": derivative of '" << b.first.getExternalName()
725                          << "' with respect to '" << b.second.getExternalName()
726                          << "'\n";
727              }
728              std::cout << '\n';
729            }});
730     } else if (qn == "--material-properties") {
731       this->queries.emplace_back("material-properties",
732                                  this->generateVariablesListQuery<
733                                      &BehaviourData::getMaterialProperties>());
734     } else if (qn == "--state-variables") {
735       this->queries.emplace_back("state-variables",
736                                  this->generateVariablesListQuery<
737                                      &BehaviourData::getStateVariables>());
738     } else if (qn == "--static-variables") {
739       auto nq = [](const FileDescription&, const BehaviourDescription& bd,
740                    const Hypothesis h) {
741         using namespace std;
742         using namespace tfel::glossary;
743         const auto& d = bd.getBehaviourData(h);
744         const auto& vars = d.getStaticVariables();
745         for (const auto& v : vars) {
746           const auto& n = d.getExternalName(v.name);
747           cout << "- " << n;
748           if (v.arraySize != 1u) {
749             cout << '[' << v.arraySize << ']';
750           }
751           if (n != v.name) {
752             cout << " (" << mfront::displayName(v) << ")";
753           }
754           if (!v.description.empty()) {
755             cout << ": " << v.description;
756           } else {
757             const auto& glossary = Glossary::getGlossary();
758             if (glossary.contains(n)) {
759               cout << ": "
760                    << glossary.getGlossaryEntry(n).getShortDescription();
761             }
762           }
763           cout << endl;
764         }
765       };
766       this->queries.emplace_back("static-variables", nq);
767     } else if (qn == "--auxiliary-state-variables") {
768       this->queries.emplace_back(
769           "auxiliary-state-variables",
770           this->generateVariablesListQuery<
771               &BehaviourData::getAuxiliaryStateVariables>());
772     } else if (qn == "--external-state-variables") {
773       this->queries.emplace_back(
774           "external-state-variables",
775           this->generateVariablesListQuery<
776               &BehaviourData::getExternalStateVariables>());
777     } else if (qn == "--integration-variables") {
778       this->queries.emplace_back(
779           "integration-state-variables",
780           this->generateVariablesListQuery<
781               &BehaviourData::getIntegrationVariables>());
782     } else if (qn == "--persistent-variables") {
783       this->queries.emplace_back("persistent-state-variables",
784                                  this->generateVariablesListQuery<
785                                      &BehaviourData::getPersistentVariables>());
786     } else if (qn == "--local-variables") {
787       this->queries.emplace_back("local-state-variables",
788                                  this->generateVariablesListQuery<
789                                      &BehaviourData::getLocalVariables>());
790     } else if (qn == "--parameters") {
791       this->queries.emplace_back(
792           "parameters",
793           this->generateVariablesListQuery<&BehaviourData::getParameters>());
794     } else if (qn == "--attributes") {
795       this->queries.push_back(
796           {"attributes", [](const FileDescription&,
797                             const BehaviourDescription& d, const Hypothesis h) {
798              const auto& as1 = d.getAttributes();
799              if (!as1.empty()) {
800                for (const auto& a : as1) {
801                  cout << a.first << " ";
802                }
803              }
804              const auto& as2 = d.getBehaviourData(h).getAttributes();
805              for (const auto& a : as2) {
806                cout << a.first << " ";
807              }
808              cout << '\n';
809            }});
810     } else if (qn == "--code-blocks") {
811       this->queries.push_back(
812           {"code-blocks", [](const FileDescription&,
813                             const BehaviourDescription& d, const Hypothesis h) {
814              const auto& names = d.getBehaviourData(h).getCodeBlockNames();
815              for (const auto& n : names) {
816                cout << "- " << n << '\n';
817              }
818            }});
819     } else if (qn == "--parameters-file") {
820       this->queries.push_back(
821           {"parameters-file",
822            [](const FileDescription&, const BehaviourDescription& d,
823               const Hypothesis h) {
824              if (h != ModellingHypothesis::UNDEFINEDHYPOTHESIS) {
825                cout << mfront::getParametersFileName(d, h) << '\n';
826              } else {
827                cout << mfront::getParametersFileName(d) << '\n';
828              }
829            }});
830     } else {
831       tfel::raise(
832           "Behaviour::treatStandardQuery : "
833           "unsupported query '" +
834           qn + "'");
835     }
836   }
837 
treatStandardQuery2()838   void BehaviourQuery::treatStandardQuery2() {
839     using namespace std;
840     using namespace tfel::utilities;
841     using tfel::material::ModellingHypothesis;
842     const auto& q = this->getCurrentCommandLineArgument();
843     const auto& qn = q.as_string();
844     const auto o = q.getOption();
845     tfel::raise_if(o.empty(),
846                    "Behaviour::treatStandardQuery2 : "
847                    "no option given to the '" +
848                        qn + "' query");
849     if (qn == "--attribute-type") {
850       auto l = [o](const FileDescription&, const BehaviourDescription& d,
851                    const Hypothesis h) {
852         const auto& a = getAttribute(o, d, h);
853         if (a.is<bool>()) {
854           cout << "bool\n";
855         } else if (a.is<unsigned short>()) {
856           cout << "unsigned short\n";
857         } else if (a.is<string>()) {
858           cout << "string\n";
859         } else {
860           tfel::raise(
861               "Behaviour::treatStandardQuery2 : "
862               "unsupported attribute type");
863         }
864       };
865       this->queries.push_back({"attribute-type", l});
866     } else if (qn == "--attribute-value") {
867       auto l = [o](const FileDescription&, const BehaviourDescription& d,
868                    const Hypothesis h) {
869         const auto& a = getAttribute(o, d, h);
870         if (a.is<bool>()) {
871           if (a.get<bool>()) {
872             cout << "true\n";
873           } else {
874             cout << "false\n";
875           }
876         } else if (a.is<unsigned short>()) {
877           cout << a.get<unsigned short>() << '\n';
878         } else if (a.is<string>()) {
879           cout << a.get<string>() << '\n';
880         } else if (a.is<vector<string>>()) {
881           const auto& vs = a.get<vector<string>>();
882           bool first = true;
883           for (const auto& v : vs) {
884             if (!first) {
885               cout << " ";
886             }
887             cout << v;
888             first = false;
889           }
890           cout << '\n';
891         } else {
892           tfel::raise(
893               "Behaviour::treatStandardQuery2 : "
894               "unsupported attribute type");
895         }
896       };
897       this->queries.push_back({"attributes-value", l});
898     } else if (qn == "--has-bounds") {
899       auto l = [o](const FileDescription&, const BehaviourDescription& d,
900                    const Hypothesis h) {
901         const auto vn = extractVariableNameAndArrayPosition(o);
902         const auto& n = std::get<0>(vn);
903         const auto& bd = d.getBehaviourData(h);
904         const auto& p = bd.getVariableDescriptionByExternalName(n);
905         if (std::get<1>(vn)) {
906           cout << (p.hasBounds(std::get<2>(vn)) ? "true" : "false") << '\n';
907         } else {
908           cout << (p.hasBounds() ? "true" : "false") << '\n';
909         }
910       };
911       this->queries.push_back({"has-bounds", l});
912     } else if (qn == "--bounds-type") {
913       auto l = [o](const FileDescription&, const BehaviourDescription& d,
914                    const Hypothesis h) {
915         const auto& bd = d.getBehaviourData(h);
916         const auto vn = extractVariableNameAndArrayPosition(o);
917         const auto& n = std::get<0>(vn);
918         const auto& p = bd.getVariableDescriptionByExternalName(n);
919         const auto& b =
920             std::get<1>(vn) ? p.getBounds(std::get<2>(vn)) : p.getBounds();
921         if (b.boundsType == VariableBoundsDescription::LOWER) {
922           cout << "Lower\n";
923         } else if (b.boundsType == VariableBoundsDescription::UPPER) {
924           cout << "Upper\n";
925         } else if (b.boundsType == VariableBoundsDescription::LOWERANDUPPER) {
926           cout << "LowerAndUpper\n";
927         } else {
928           tfel::raise("unsupported bounds type");
929         }
930       };
931       this->queries.push_back({"bounds-type", l});
932     } else if (qn == "--bounds-value") {
933       auto l = [o](const FileDescription&, const BehaviourDescription& d,
934                    const Hypothesis h) {
935         const auto& bd = d.getBehaviourData(h);
936         const auto vn = extractVariableNameAndArrayPosition(o);
937         const auto& n = std::get<0>(vn);
938         const auto& p = bd.getVariableDescriptionByExternalName(n);
939         const auto& b =
940             std::get<1>(vn) ? p.getBounds(std::get<2>(vn)) : p.getBounds();
941         if (b.boundsType == VariableBoundsDescription::LOWER) {
942           cout << "[" << b.lowerBound << ":*[\n";
943         } else if (b.boundsType == VariableBoundsDescription::UPPER) {
944           cout << "]*:" << b.upperBound << "]\n";
945         } else if (b.boundsType == VariableBoundsDescription::LOWERANDUPPER) {
946           cout << "[" << b.lowerBound << ":" << b.upperBound << "]\n";
947         } else {
948           tfel::raise("unsupported bounds type");
949         }
950       };
951       this->queries.push_back({"bounds-value", l});
952     } else if (qn == "--has-physical-bounds") {
953       auto l = [o](const FileDescription&, const BehaviourDescription& d,
954                    const Hypothesis h) {
955         const auto vn = extractVariableNameAndArrayPosition(o);
956         const auto& n = std::get<0>(vn);
957         const auto& bd = d.getBehaviourData(h);
958         const auto& p = bd.getVariableDescriptionByExternalName(n);
959         if (std::get<1>(vn)) {
960           cout << (p.hasPhysicalBounds(std::get<2>(vn)) ? "true" : "false")
961                << '\n';
962         } else {
963           cout << (p.hasPhysicalBounds() ? "true" : "false") << '\n';
964         }
965       };
966       this->queries.push_back({"has-physical-bounds", l});
967     } else if (qn == "--physical-bounds-type") {
968       auto l = [o](const FileDescription&, const BehaviourDescription& d,
969                    const Hypothesis h) {
970         const auto& bd = d.getBehaviourData(h);
971         const auto vn = extractVariableNameAndArrayPosition(o);
972         const auto& n = std::get<0>(vn);
973         const auto& p = bd.getVariableDescriptionByExternalName(n);
974         const auto& b = (std::get<1>(vn) ? p.getPhysicalBounds(std::get<2>(vn))
975                                          : p.getPhysicalBounds());
976         if (b.boundsType == VariableBoundsDescription::LOWER) {
977           cout << "Lower\n";
978         } else if (b.boundsType == VariableBoundsDescription::UPPER) {
979           cout << "Upper\n";
980         } else if (b.boundsType == VariableBoundsDescription::LOWERANDUPPER) {
981           cout << "LowerAndUpper\n";
982         } else {
983           tfel::raise("unsupported physical bounds type");
984         }
985       };
986       this->queries.push_back({"physical-bounds-type", l});
987     } else if (qn == "--physical-bounds-value") {
988       auto l = [o](const FileDescription&, const BehaviourDescription& d,
989                    const Hypothesis h) {
990         const auto& bd = d.getBehaviourData(h);
991         const auto vn = extractVariableNameAndArrayPosition(o);
992         const auto& n = std::get<0>(vn);
993         const auto& p = bd.getVariableDescriptionByExternalName(n);
994         const auto& b = (std::get<1>(vn) ? p.getPhysicalBounds(std::get<2>(vn))
995                                          : p.getPhysicalBounds());
996         if (b.boundsType == VariableBoundsDescription::LOWER) {
997           cout << "[" << b.lowerBound << ":*[\n";
998         } else if (b.boundsType == VariableBoundsDescription::UPPER) {
999           cout << "]*:" << b.upperBound << "]\n";
1000         } else if (b.boundsType == VariableBoundsDescription::LOWERANDUPPER) {
1001           cout << "[" << b.lowerBound << ":" << b.upperBound << "]\n";
1002         } else {
1003           tfel::raise("unsupported bounds type");
1004         }
1005       };
1006       this->queries.push_back({"physical-bounds-value", l});
1007     } else if (qn == "--parameter-type") {
1008       auto l = [o](const FileDescription&, const BehaviourDescription& d,
1009                    const Hypothesis h) {
1010         const auto& bd = d.getBehaviourData(h);
1011         const auto& p = bd.getParameterDescriptionByExternalName(o);
1012         cout << p.type << '\n';
1013       };
1014       this->queries.push_back({"parameter-type", l});
1015     } else if (qn == "--parameter-default-value") {
1016       auto l = [o](const FileDescription&, const BehaviourDescription& d,
1017                    const Hypothesis h) {
1018         const auto& bd = d.getBehaviourData(h);
1019         const auto& p = bd.getParameterDescriptionByExternalName(o);
1020         const auto& n = p.name;
1021         if (p.type == "real") {
1022           if (p.arraySize == 1) {
1023             cout << bd.getFloattingPointParameterDefaultValue(n) << '\n';
1024           } else {
1025             for (unsigned short i = 0; i != p.arraySize;) {
1026               cout << bd.getFloattingPointParameterDefaultValue(n, i);
1027               if (++i != p.arraySize) {
1028                 cout << " ";
1029               }
1030             }
1031             cout << '\n';
1032           }
1033         } else if (p.type == "int") {
1034           cout << bd.getIntegerParameterDefaultValue(n) << '\n';
1035         } else if (p.type == "ushort") {
1036           cout << bd.getUnsignedShortParameterDefaultValue(n) << '\n';
1037         } else {
1038           tfel::raise(
1039               "Behaviour::treatStandardQuery2 : "
1040               "unsupported parameter type");
1041         }
1042       };
1043       this->queries.push_back({"parameter-default-value", l});
1044     } else if (qn == "--static-variable-value") {
1045       auto l = [o](const FileDescription&, const BehaviourDescription& d,
1046                    const Hypothesis h) {
1047         const auto& bd = d.getBehaviourData(h);
1048         for (const auto& sv : bd.getStaticVariables()) {
1049           if (sv.name == o) {
1050             std::cout << sv.value << '\n';
1051             return;
1052           }
1053         }
1054         tfel::raise(
1055             "Behaviour::treatStandardQuery2 : "
1056             "no static variable '" +
1057             o + "'");
1058       };
1059       this->queries.push_back({"static-variable-value", l});
1060     } else if (qn == "--schmid-factors") {
1061       auto l = [o](const FileDescription&, const BehaviourDescription& d) {
1062         tfel::raise_if(!d.areSlipSystemsDefined(), "no slip system defined");
1063         const auto dc = extract_crystal_direction(o);
1064         const auto& ssd = d.getSlipSystems();
1065         const auto nss = ssd.getNumberOfSlipSystemsFamilies();
1066         for (size_t i = 0; i != nss; ++i) {
1067           const auto sfs = ssd.getSchmidFactors(dc, i);
1068           cout << "- " << to_string(ssd.getSlipSystemFamily(i), true) << ":";
1069           for (const auto& sf : sfs) {
1070             cout << " " << std::to_string(sf);
1071           }
1072           cout << '\n';
1073         }
1074       };
1075       this->queries2.push_back({"schmid-factors", l});
1076     } else if (qn == "--schmid-factors-by-index") {
1077       auto l = [o](const FileDescription&, const BehaviourDescription& d) {
1078         tfel::raise_if(!d.areSlipSystemsDefined(), "no slip system defined");
1079         const auto dc = extract_crystal_direction(o);
1080         const auto& ssd = d.getSlipSystems();
1081         const auto sfs = ssd.getSchmidFactors(dc);
1082         size_t idx = 0;
1083         for (size_t i = 0; i != sfs.size(); ++i) {
1084           for (const auto sf : sfs[i]) {
1085             cout << "- " << idx << ": " << std::to_string(sf) << '\n';
1086             ++idx;
1087           }
1088         }
1089       };
1090       this->queries2.push_back({"schmid-factors-by-index", l});
1091     } else {
1092       tfel::raise(
1093           "Behaviour::treatStandardQuery : "
1094           "unsupported query '" +
1095           qn + "'");
1096     }
1097   }
1098 
1099   template <const VariableDescriptionContainer& (BehaviourData::*m)() const>
generateVariablesListQuery()1100   typename BehaviourQuery::query BehaviourQuery::generateVariablesListQuery() {
1101     return [](const FileDescription&, const BehaviourDescription& bd,
1102               const Hypothesis h) {
1103       const auto& d = bd.getBehaviourData(h);
1104       const auto& vars = (d.*m)();
1105       for (const auto& v : vars) {
1106         display_variable(v);
1107       }
1108     };
1109   }
1110 
treatGeneratedSources()1111   void BehaviourQuery::treatGeneratedSources() {
1112     auto ldsl = this->dsl;
1113     auto q = [ldsl](const FileDescription&, const BehaviourDescription&) {
1114       for (const auto& l : ldsl->getTargetsDescription().libraries) {
1115         std::cout << l.name << " : ";  //< library
1116         std::copy(l.sources.begin(), l.sources.end(),
1117                   std::ostream_iterator<std::string>(std::cout, " "));
1118         std::cout << '\n';
1119       }
1120     };
1121     this->queries2.push_back({"generated-sources", q});
1122   }  // end of BehaviourQuery::treatGeneratedSources
1123 
treatGeneratedHeaders()1124   void BehaviourQuery::treatGeneratedHeaders() {
1125     auto ldsl = this->dsl;
1126     auto q = [ldsl](const FileDescription&, const BehaviourDescription&) {
1127       const auto headers = ldsl->getTargetsDescription().headers;
1128       std::copy(headers.begin(), headers.end(),
1129                 std::ostream_iterator<std::string>(std::cout, " "));
1130       std::cout << '\n';
1131     };
1132     this->queries2.push_back({"generated-headers", q});
1133   }  // end of BehaviourQuery::treatGeneratedHeaders
1134 
treatCppFlags()1135   void BehaviourQuery::treatCppFlags() {
1136     auto ldsl = this->dsl;
1137     auto q = [ldsl](const FileDescription&, const BehaviourDescription&) {
1138       for (const auto& l : ldsl->getTargetsDescription().libraries) {
1139         std::cout << l.name << " : ";
1140         std::copy(l.cppflags.begin(), l.cppflags.end(),
1141                   std::ostream_iterator<std::string>(std::cout, " "));
1142         std::cout << '\n';
1143       }
1144     };
1145     this->queries2.push_back({"cppflags", q});
1146   }  // end of BehaviourQuery::treatCppFlags
1147 
treatLibrariesDependencies()1148   void BehaviourQuery::treatLibrariesDependencies() {
1149     auto ldsl = this->dsl;
1150     auto q = [ldsl](const FileDescription&, const BehaviourDescription&) {
1151       for (const auto& l : ldsl->getTargetsDescription().libraries) {
1152         std::cout << l.name << " : ";
1153         std::copy(l.ldflags.begin(), l.ldflags.end(),
1154                   std::ostream_iterator<std::string>(std::cout, " "));
1155         std::cout << '\n';
1156       }
1157     };
1158     this->queries2.push_back({"libraries-dependencies", q});
1159   }  // end of BehaviourQuery::treatLibrariesDependencies
1160 
treatSpecificTargets()1161   void BehaviourQuery::treatSpecificTargets() {
1162     auto ldsl = this->dsl;
1163     auto l = [ldsl](const FileDescription&, const BehaviourDescription&) {
1164       const auto targets = ldsl->getTargetsDescription().specific_targets;
1165       for (const auto& t : targets) {
1166         std::cout << t.first << " : ";
1167         std::copy(t.second.deps.begin(), t.second.deps.end(),
1168                   std::ostream_iterator<std::string>(std::cout, " "));
1169         std::cout << '\n' << "> rule : ";
1170         std::copy(t.second.cmds.begin(), t.second.cmds.end(),
1171                   std::ostream_iterator<std::string>(std::cout, "\n> rule : "));
1172         std::cout << '\n';
1173       }
1174     };
1175     this->queries2.push_back({"specific-targets", l});
1176   }  // end of BehaviourQuery::treatSpecificTargets
1177 
treatModellingHypothesis()1178   void BehaviourQuery::treatModellingHypothesis() {
1179     const auto& o = this->getCurrentCommandLineArgument().getOption();
1180     tfel::raise_if(o.empty(),
1181                    "BehaviourQuery::treatModellingHypothesis: "
1182                    "no option given to --modelling-hypothesis"
1183                    "command line option");
1184     tfel::raise_if(this->hypothesis != ModellingHypothesis::UNDEFINEDHYPOTHESIS,
1185                    "BehaviourQuery::treatModellingHypothesis: "
1186                    "modelling hypothesis already defined");
1187     this->hypothesis = ModellingHypothesis::fromString(o);
1188   }  // end of BehaviourQuery::treatModellingHypothesis
1189 
exe()1190   void BehaviourQuery::exe() {
1191     using namespace std;
1192     if (getVerboseMode() >= VERBOSE_LEVEL2) {
1193       getLogStream() << "Treating file '" << this->file << "'\n";
1194     }
1195     // analysing the file
1196     this->dsl->analyseFile(this->file, this->ecmds, this->substitutions);
1197     const auto& fd = this->dsl->getFileDescription();
1198     const auto& d = this->dsl->getBehaviourDescription();
1199     // checks
1200     if (!this->queries.empty()) {
1201       if (this->hypothesis == ModellingHypothesis::UNDEFINEDHYPOTHESIS) {
1202         if (d.areAllMechanicalDataSpecialised()) {
1203           ostringstream msg;
1204           const auto& mh = d.getModellingHypotheses();
1205           if (mh.size() == 1u) {
1206             this->hypothesis = *(mh.begin());
1207           } else {
1208             msg << "BehaviourQuery::exe : all mechanical data are "
1209                    "specialised.\n"
1210                 << "A modelling hypothesis must be specified using "
1211                 << "the '--modelling-hypothesis' command line option.\n"
1212                 << "The supported modelling hypothesis are : \n";
1213             for (const auto h : mh) {
1214               msg << "- " << ModellingHypothesis::toString(h) << '\n';
1215             }
1216             tfel::raise(msg.str());
1217           }
1218         }
1219       } else {
1220         const auto& mh = d.getModellingHypotheses();
1221         tfel::raise_if(
1222             mh.find(this->hypothesis) == mh.end(),
1223             "BehaviourQuery::exe: the specified modelling hypothesis "
1224             "('" +
1225                 ModellingHypothesis::toString(this->hypothesis) +
1226                 "') "
1227                 "is not supported by the behaviour");
1228       }
1229     }
1230     // treating the queries
1231     for (const auto& q : this->queries) {
1232       if (getVerboseMode() >= VERBOSE_LEVEL2) {
1233         getLogStream() << "Treating query '" << q.first << "'\n";
1234       }
1235       q.second(fd, d, this->hypothesis);
1236     }
1237     for (const auto& q : this->queries2) {
1238       if (getVerboseMode() >= VERBOSE_LEVEL2) {
1239         getLogStream() << "Treating query '" << q.first << "'\n";
1240       }
1241       q.second(fd, d);
1242     }
1243   }  // end of BehaviourQuery::exe
1244 
1245   const tfel::utilities::Argument&
getCurrentCommandLineArgument() const1246   BehaviourQuery::getCurrentCommandLineArgument() const {
1247     return *(this->currentArgument);
1248   }
1249 
treatUnknownArgument()1250   void BehaviourQuery::treatUnknownArgument() {
1251     if (!MFrontBase::treatUnknownArgumentBase()) {
1252 #if !(defined _WIN32 || defined _WIN64 || defined __CYGWIN__)
1253       ArgumentParserBase<BehaviourQuery>::treatUnknownArgument();
1254 #else
1255       const auto& a = static_cast<const std::string&>(
1256           this->getCurrentCommandLineArgument());
1257       std::cerr << "mfront : unsupported option '" << a << "'\n";
1258       ::exit(EXIT_FAILURE);
1259 #endif /* __CYGWIN__ */
1260     }
1261   }
1262 
getVersionDescription() const1263   std::string BehaviourQuery::getVersionDescription() const {
1264     return MFrontHeader::getHeader();
1265   }
1266 
getUsageDescription() const1267   std::string BehaviourQuery::getUsageDescription() const {
1268     return "Usage: " + this->programName + " [options] [files]";
1269   }
1270 
1271   BehaviourQuery::~BehaviourQuery() = default;
1272 
1273 }  // end of namespace mfront
1274 
1275