1/*!
2 * \file   BrickUtilities.ixx
3 * \brief
4 * \author Thomas Helfer
5 * \date   26/03/2018
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#ifndef LIB_MFRONT_BEHAVIOURBRICK_BRICKUTILITIES_IXX
15#define LIB_MFRONT_BEHAVIOURBRICK_BRICKUTILITIES_IXX
16
17namespace mfront {
18
19  namespace bbrick {
20
21    template <std::size_t N>
22    std::array<BehaviourDescription::MaterialProperty, N>
23    getArrayOfBehaviourDescriptionMaterialProperties(
24        AbstractBehaviourDSL& dsl,
25        const std::string& n,
26        const tfel::utilities::Data& d){
27      std::array<BehaviourDescription::MaterialProperty, N> mps;
28      if (!d.is<std::vector<tfel::utilities::Data>>()) {
29        tfel::raise(
30            "getArrayOfBehaviourDescriptionMaterialProperties: "
31            "error while extracting array of material properties '" +
32            n + "', invalid type for the given data");
33      }
34      const auto& vd = d.get<std::vector<tfel::utilities::Data>>();
35      if (vd.size() != N) {
36        tfel::raise(
37            "getArrayOfBehaviourDescriptionMaterialProperties: "
38            "error while extracting array of material properties '" +
39            n +
40            "', invalid size for the given data (expected an array of size '" +
41            std::to_string(N) + "', but an array of size '" +
42            std::to_string(vd.size()) + "' was given)");
43      }
44      auto i = typename std::array<BehaviourDescription::MaterialProperty,
45                                   N>::size_type{};
46      for (const auto& e : vd) {
47        mps[i] = getBehaviourDescriptionMaterialProperty(dsl, n, e);
48        ++i;
49      }
50      return mps;
51    }
52
53    template <std::size_t N>
54    bool areAllConstantMaterialProperties(
55        const std::array<BehaviourDescription::MaterialProperty, N> & mps){
56      for (const auto& mp : mps) {
57        if (!mp.template is<BehaviourDescription::ConstantMaterialProperty>()) {
58          return false;
59        }
60      }
61      return true;
62    }  // end of areAllConstantMaterialProperties
63
64    template <std::size_t N>
65    void declareParameterOrLocalVariable(
66        BehaviourDescription& bd,
67        std::array<BehaviourDescription::MaterialProperty, N>& mps,
68        const std::string& t,
69        const std::string& n) {
70      constexpr const auto h =
71          tfel::material::ModellingHypothesis::UNDEFINEDHYPOTHESIS;
72      const auto b = areAllConstantMaterialProperties(mps);
73      if (b) {
74        for (auto& mp : mps) {
75          auto& cmp =
76              mp.template get<BehaviourDescription::ConstantMaterialProperty>();
77          cmp.name = n;
78        }
79        // declare associated parameter
80        VariableDescription m(t, n, N, 0u);
81        bd.addParameter(h, m);
82        for (decltype(mps.size()) i = 0; i != mps.size(); ++i) {
83          auto& cmp = mps[i]
84                          .template get<
85                              BehaviourDescription::ConstantMaterialProperty>();
86          bd.setParameterDefaultValue(h, n, i, cmp.value);
87        }
88      } else {
89        VariableDescription m(t, n, N, 0u);
90        bd.addLocalVariable(h, m);
91      }
92    } // end of declareParameterOrLocalVariable
93
94    template <std::size_t N>
95    void declareParameterOrLocalVariable(
96        BehaviourDescription& bd,
97        std::array<BehaviourDescription::MaterialProperty, N>& mps,
98        const std::string& t,
99        const std::string& n,
100        const std::string& en) {
101      constexpr const auto h =
102          tfel::material::ModellingHypothesis::UNDEFINEDHYPOTHESIS;
103      declareParameterOrLocalVariable(bd, mps, t, n);
104      if (areAllConstantMaterialProperties(mps)){
105        bd.setEntryName(h, n, en);
106      }
107    } // end of declareParameterOrLocalVariable
108
109    template <std::size_t N>
110    void declareParameterOrLocalVariable(
111        BehaviourDescription& bd,
112        std::array<BehaviourDescription::MaterialProperty, N>& mps,
113        const std::string& t,
114        const std::string& n,
115        const tfel::glossary::GlossaryEntry& g) {
116      constexpr const auto h =
117          tfel::material::ModellingHypothesis::UNDEFINEDHYPOTHESIS;
118      declareParameterOrLocalVariable(bd, mps, t, n);
119      if (areAllConstantMaterialProperties(mps)){
120        bd.setGlossaryName(h, n, g);
121      }
122    }  // end of declareParameterOrLocalVariable
123
124    template <std::size_t N>
125    std::string generateMaterialPropertiesInitializationCode(
126        const AbstractBehaviourDSL& dsl,
127        const BehaviourDescription& bd,
128        const std::string& n,
129        const std::array<BehaviourDescription::MaterialProperty, N>& mps) {
130      auto c = std::string{};
131      if (!areAllConstantMaterialProperties(mps)) {
132        for (decltype(mps.size()) i = 0; i != mps.size(); ++i) {
133          const auto& mp = mps[i];
134          const auto vn = n + "[" + std::to_string(i) + "]";
135          if (!mp.template is<
136                  BehaviourDescription::ConstantMaterialProperty>()) {
137            c += generateMaterialPropertyInitializationCode(dsl, bd, vn, mp);
138          } else {
139            const auto& cmp = mp.template get<
140                BehaviourDescription::ConstantMaterialProperty>();
141            c += "this->" + vn + " = " + std::to_string(i) + "] = " +
142                 std::to_string(cmp.value) + ";\n";
143          }
144        }
145      }
146      return c;
147    } // end of generateMaterialPropertiesInitializationCode
148
149  }  // end of namespace bbrick
150
151}  // end of namespace mfront
152
153#endif /* LIB_MFRONT_BEHAVIOURBRICK_BRICKUTILITIES_IXX */
154