1 /*!
2  * \file   mfront/src/SwiftIsotropicHardeningRule.cxx
3  * \brief
4  * \author Thomas Helfer
5  * \date   15/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 #include <sstream>
15 #include "TFEL/Raise.hxx"
16 #include "MFront/BehaviourBrick/BrickUtilities.hxx"
17 #include "MFront/BehaviourBrick/OptionDescription.hxx"
18 #include "MFront/BehaviourBrick/SwiftIsotropicHardeningRule.hxx"
19 
20 namespace mfront {
21 
22   namespace bbrick {
23 
initialize(BehaviourDescription & bd,AbstractBehaviourDSL & dsl,const std::string & fid,const std::string & id,const DataMap & d)24     void SwiftIsotropicHardeningRule::initialize(BehaviourDescription& bd,
25                                                   AbstractBehaviourDSL& dsl,
26                                                   const std::string& fid,
27                                                   const std::string& id,
28                                                   const DataMap& d) {
29       using namespace tfel::glossary;
30       constexpr const auto uh = ModellingHypothesis::UNDEFINEDHYPOTHESIS;
31       // this shall be captured in gcc 4.7.2
32       auto get_mp = [&dsl, &bd, &fid, &id, &d, this](
33           const std::string& mpn, const std::string& t, const std::string& vn) {
34         if (d.count(mpn) == 0) {
35           tfel::raise(
36               "SwiftIsotropicHardeningRule::initialize: "
37               "material property '" +
38               mpn + "' is not defined");
39         }
40         const auto ni = IsotropicHardeningRule::getVariableId(vn, fid, id);
41         auto mp = getBehaviourDescriptionMaterialProperty(dsl, mpn, d.at(mpn));
42         declareParameterOrLocalVariable(bd, mp, t, ni);
43         return mp;
44       };
45       mfront::bbrick::check(d, this->getOptions());
46       this->R0 = get_mp("R0", "stress", "R0");
47       this->p0 = get_mp("p0", "strain", "p0");
48       this->n = get_mp("n", "real", "E");
49       const auto Rel = id.empty() ? "Rel" + fid : "Rel" + fid + "_" + id;
50       const auto R = id.empty() ? "R" + fid : "R" + fid + "_" + id;
51       const auto dR = "d" + R + "_ddp" + fid;
52       bd.reserveName(uh, Rel);
53       bd.reserveName(uh, R);
54       bd.reserveName(uh, dR);
55     }  // end of SwiftIsotropicHardeningRule::initialize
56 
getOptions() const57     std::vector<OptionDescription> SwiftIsotropicHardeningRule::getOptions()
58         const {
59       std::vector<OptionDescription> opts;
60       opts.emplace_back("R0", "Yield strength",
61                         OptionDescription::MATERIALPROPERTY);
62       opts.emplace_back("p0", "Small numerical parameter",
63                         OptionDescription::MATERIALPROPERTY);
64       opts.emplace_back("n", "Swift exponent",
65                         OptionDescription::MATERIALPROPERTY);
66       return opts;
67     }  // end of SwiftIsotropicHardeningRule::getOptions
68 
computeElasticPrediction(const std::string & fid,const std::string & id) const69     std::string SwiftIsotropicHardeningRule::computeElasticPrediction(
70         const std::string& fid, const std::string& id) const {
71       const auto Rel = id.empty() ? "Rel" + fid : "Rel" + fid + "_" + id;
72       const auto R0n = IsotropicHardeningRule::getVariableId("R0", fid, id);
73       const auto p0n = IsotropicHardeningRule::getVariableId("p0", fid, id);
74       const auto nn = IsotropicHardeningRule::getVariableId("E", fid, id);
75       const auto pn = "p" + fid;
76       auto c = "const auto " + Rel + " = ";
77       c += "(this->" + R0n + ")*";
78       c += "pow((this->" + pn + "+this->" + p0n + ")/(this->" + p0n +
79            "),this->" + nn + ");\n";
80       return c;
81     }  // end of SwiftIsotropicHardeningRule::computeElasticPrediction
82 
computeElasticLimit(const std::string & fid,const std::string & id) const83     std::string SwiftIsotropicHardeningRule::computeElasticLimit(
84         const std::string& fid, const std::string& id) const {
85       const auto R = id.empty() ? "R" + fid : "R" + fid + "_" + id;
86       const auto R0n = IsotropicHardeningRule::getVariableId("R0", fid, id);
87       const auto p0n = IsotropicHardeningRule::getVariableId("p0", fid, id);
88       const auto nn = IsotropicHardeningRule::getVariableId("E", fid, id);
89       const auto pn = "p" + fid;
90       auto c = "const auto " + R + " = (this->" + pn + "+(this->theta)*(this->d" + pn + ")>this->" +
91            p0n + ") ? (this->" + R0n + ")*";
92       c += "pow((this->" + pn + "+(this->theta)*(this->d" + pn + ")+this->" +
93            p0n + ")/(this->" + p0n + "),this->" + nn + ") : this->" + R0n +
94            ";\n";
95       return c;
96     }  // end of SwiftIsotropicHardeningRule::computeElasticLimit
97 
computeElasticLimitAndDerivative(const std::string & fid,const std::string & id) const98     std::string SwiftIsotropicHardeningRule::computeElasticLimitAndDerivative(
99         const std::string& fid, const std::string& id) const {
100       const auto R = id.empty() ? "R" + fid : "R" + fid + "_" + id;
101       const auto dR = "d" + R + "_ddp" + fid;
102       const auto R0n = IsotropicHardeningRule::getVariableId("R0", fid, id);
103       const auto p0n = IsotropicHardeningRule::getVariableId("p0", fid, id);
104       const auto nn = IsotropicHardeningRule::getVariableId("E", fid, id);
105       const auto pn = "p" + fid;
106       auto c = "const auto " + R + " = (this->" + pn + "+(this->theta)*(this->d" + pn + ")>this->" +
107            p0n + ") ? (this->" + R0n + ")*";
108       c += "pow((this->" + pn + "+(this->theta)*(this->d" + pn + ")+this->" +
109            p0n + ")/(this->" + p0n + "),this->" + nn + ") : this->" + R0n +
110            ";\n";
111       c += "const auto " + dR + " = ";
112       c += "(this->theta)*(this->" + nn + ")*" + R + "*((this->" + p0n +
113            ")/(this->" + pn + "+(this->theta)*(this->d" + pn + ")+this->" + p0n +
114            "));\n";
115       return c;
116     }  // end of SwiftIsotropicHardeningRule::computeElasticLimitAndDerivative
117 
endTreatment(BehaviourDescription & bd,const AbstractBehaviourDSL & dsl,const std::string & fid,const std::string & id) const118     void SwiftIsotropicHardeningRule::endTreatment(
119         BehaviourDescription& bd,
120         const AbstractBehaviourDSL& dsl,
121         const std::string& fid,
122         const std::string& id) const {
123       auto mts = getMiddleOfTimeStepModifier(bd);
124       // computation of the material properties
125       if ((!this->R0.is<BehaviourDescription::ConstantMaterialProperty>()) &&
126           (!this->p0.is<BehaviourDescription::ConstantMaterialProperty>()) &&
127           (!this->n.is<BehaviourDescription::ConstantMaterialProperty>())) {
128         constexpr const auto uh = ModellingHypothesis::UNDEFINEDHYPOTHESIS;
129         CodeBlock i;
130         std::ostringstream mps;
131         if (!this->R0.is<BehaviourDescription::ConstantMaterialProperty>()) {
132           const auto R0n = IsotropicHardeningRule::getVariableId("R0", fid, id);
133           mps << "this->" + R0n + " = ";
134           dsl.writeMaterialPropertyEvaluation(mps, this->R0, mts);
135           mps << ";\n";
136         }
137         if (!this->p0.is<BehaviourDescription::ConstantMaterialProperty>()) {
138           const auto p0n = IsotropicHardeningRule::getVariableId("p0", fid, id);
139           mps << "this->" + p0n + " = ";
140           dsl.writeMaterialPropertyEvaluation(mps, this->p0, mts);
141           mps << ";\n";
142         }
143         if (!this->n.is<BehaviourDescription::ConstantMaterialProperty>()) {
144           const auto nn = IsotropicHardeningRule::getVariableId("E", fid, id);
145           mps << "this->" + nn + " = ";
146           dsl.writeMaterialPropertyEvaluation(mps, this->n, mts);
147           mps << ";\n";
148         }
149         i.code += mps.str();
150         bd.setCode(uh, BehaviourData::BeforeInitializeLocalVariables, i,
151                    BehaviourData::CREATEORAPPEND, BehaviourData::AT_BEGINNING);
152       }
153     }  // end of SwiftIsotropicHardeningRule::endTreatment
154 
155     SwiftIsotropicHardeningRule::~SwiftIsotropicHardeningRule() = default;
156 
157   }  // end of namespace bbrick
158 
159 }  // end of namespace mfront
160