1 /*!
2  * \file   mfront/src/StandardPorousStressCriterionBase.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 "TFEL/Raise.hxx"
15 #include "TFEL/Glossary/Glossary.hxx"
16 #include "TFEL/Glossary/GlossaryEntry.hxx"
17 #include "MFront/BehaviourBrick/BrickUtilities.hxx"
18 #include "MFront/BehaviourBrick/StressPotential.hxx"
19 #include "MFront/BehaviourBrick/OptionDescription.hxx"
20 #include "MFront/BehaviourBrick/StandardPorousStressCriterionBase.hxx"
21 
22 namespace mfront {
23 
24   namespace bbrick {
25 
StandardPorousStressCriterionBase(const std::string & n)26     StandardPorousStressCriterionBase::StandardPorousStressCriterionBase(
27         const std::string& n)
28         : name(n) {}  // end of
29     // StandardPorousStressCriterionBase::StandardPorousStressCriterionBase
30 
initialize(BehaviourDescription & bd,AbstractBehaviourDSL & dsl,const std::string & id,const DataMap & d,const Role r)31     void StandardPorousStressCriterionBase::initialize(
32         BehaviourDescription& bd,
33         AbstractBehaviourDSL& dsl,
34         const std::string& id,
35         const DataMap& d,
36         const Role r) {
37       StressCriterionBase::initialize(bd, dsl, id, d, r);
38       const auto mhs = this->getSupportedBehaviourSymmetries();
39       if (std::find(mhs.begin(), mhs.end(), mfront::ISOTROPIC) == mhs.end()) {
40         tfel::raise(
41             "StandardPorousStressCriterionBase::initialize: "
42             "expected an isotropic criterion");
43       }
44       bd.appendToIncludes("#include \"TFEL/Material/" + name +
45                           "StressCriterion.hxx\"\n");
46       const auto params =
47           StressCriterion::getVariableId("sscb_parameters", id, r);
48       for (const auto& mp : this->getOptions()) {
49         if (mp.type != OptionDescription::MATERIALPROPERTY) {
50           break;
51         }
52         const auto n = StressCriterion::getVariableId(mp.name, id, r);
53         if (d.count(mp.name) == 0) {
54           tfel::raise(
55               "StandardPorousStressCriterionBase::initialize: "
56               "material property '" +
57               mp.name + "' is not defined");
58         }
59         auto mpd = getBehaviourDescriptionMaterialProperty(dsl, mp.name,
60                                                            d.at(mp.name));
61         declareParameterOrLocalVariable(bd, mpd, "real", n);
62         this->mps.insert({mp.name, mpd});
63       }
64       addLocalVariable(bd,
65                        this->name + "StressCriterionParameters<StressStensor>",
66                        params, 1u);
67     }  // end of StandardPorousStressCriterionBase::initialize
68 
isCoupledWithPorosityEvolution() const69     bool StandardPorousStressCriterionBase::isCoupledWithPorosityEvolution()
70         const {
71       return true;
72     }  // end of
73        // StandardPorousStressCriterionBase::isCoupledWithPorosityEvolution()
74 
isNormalDeviatoric() const75     bool StandardPorousStressCriterionBase::isNormalDeviatoric() const {
76       return false;
77     }  // end of Hosford1972StressCriterion::StandardPorousStressCriterionBase
78 
endTreatment(BehaviourDescription & bd,const AbstractBehaviourDSL & dsl,const std::string & id,const Role r)79     void StandardPorousStressCriterionBase::endTreatment(
80         BehaviourDescription& bd,
81         const AbstractBehaviourDSL& dsl,
82         const std::string& id,
83         const Role r) {
84       constexpr const auto uh =
85           tfel::material::ModellingHypothesis::UNDEFINEDHYPOTHESIS;
86       StressCriterionBase::endTreatment(bd, dsl, id, r);
87       const auto params =
88           StressCriterion::getVariableId("sscb_parameters", id, r);
89       auto c = std::string{};
90       for (const auto& mp : this->getOptions()) {
91         if (mp.type != OptionDescription::MATERIALPROPERTY) {
92           break;
93         }
94         const auto n = StressCriterion::getVariableId(mp.name, id, r);
95         c += generateMaterialPropertyInitializationCode(dsl, bd, n,
96                                                         this->mps.at(mp.name));
97         c += params + "." + mp.name + " = this->" + n + ";\n";
98       }
99       if (!c.empty()) {
100         CodeBlock i;
101         i.code = c;
102         bd.setCode(uh, BehaviourData::BeforeInitializeLocalVariables, i,
103                    BehaviourData::CREATEORAPPEND, BehaviourData::AT_BEGINNING);
104       }
105     }  // end of StandardPorousStressCriterionBase::endTreatment
106 
computeElasticPrediction(const std::string & id,const BehaviourDescription & bd,const StressPotential & sp) const107     std::string StandardPorousStressCriterionBase::computeElasticPrediction(
108         const std::string& id,
109         const BehaviourDescription& bd,
110         const StressPotential& sp) const {
111       constexpr const auto uh =
112           tfel::material::ModellingHypothesis::UNDEFINEDHYPOTHESIS;
113       const auto params = StressCriterion::getVariableId(
114           "sscb_parameters", id, StressCriterion::STRESSCRITERION);
115       const auto& f =
116           bd.getBehaviourData(uh).getStateVariableDescriptionByExternalName(
117               tfel::glossary::Glossary::Porosity);
118       return "const auto seqel" + id + " = compute" + this->name +
119              "Stress(sel" + id + ", this->" + f.name + ", this->" + params +
120              ", " + sp.getEquivalentStressLowerBound(bd) + ");\n";
121     }  // end of StandardPorousStressCriterionBase::computeElasticPrediction
122 
computeCriterion(const std::string & id,const BehaviourDescription & bd,const StressPotential & sp) const123     std::string StandardPorousStressCriterionBase::computeCriterion(
124         const std::string& id,
125         const BehaviourDescription& bd,
126         const StressPotential& sp) const {
127       const auto params = StressCriterion::getVariableId(
128           "sscb_parameters", id, StressCriterion::STRESSCRITERION);
129       constexpr const auto uh =
130           tfel::material::ModellingHypothesis::UNDEFINEDHYPOTHESIS;
131       const auto& f =
132           bd.getBehaviourData(uh).getStateVariableDescriptionByExternalName(
133               tfel::glossary::Glossary::Porosity);
134       return "const auto seq" + id + " = compute" + this->name + "Stress(s" +
135              id + ", " + f.name + "_ ,this->" + params + "," +
136              sp.getEquivalentStressLowerBound(bd) + ");\n";
137     }  // end of StandardPorousStressCriterionBase::computeCriterion
138 
computeNormal(const std::string & id,const BehaviourDescription & bd,const StressPotential & sp,const Role r) const139     std::string StandardPorousStressCriterionBase::computeNormal(
140         const std::string& id,
141         const BehaviourDescription& bd,
142         const StressPotential& sp,
143         const Role r) const {
144       constexpr const auto uh =
145           tfel::material::ModellingHypothesis::UNDEFINEDHYPOTHESIS;
146       const auto params =
147           StressCriterion::getVariableId("sscb_parameters", id, r);
148       const auto& f =
149           bd.getBehaviourData(uh).getStateVariableDescriptionByExternalName(
150               tfel::glossary::Glossary::Porosity);
151       const auto n = "n" + id;
152       const auto s = "s" + id;
153       const auto seq = "seq" + id;
154       const auto seqf = "seqf" + id;
155       const auto f_ = f.name + "_";
156       auto c = std::string{};
157       if ((r == STRESSCRITERION) || (r == STRESSANDFLOWCRITERION)) {
158 #if __cplusplus >= 201703L
159         c += "const auto [" + seq + ",d" + seq + "_d" + s + "] = ";
160         c += "compute" + this->name + "StressNormal(" + s + ", " + f_ +
161              ", this->" + params + ", " + sp.getEquivalentStressLowerBound(bd) +
162              ");\n";
163 #else  /* __cplusplus >= 201703L */
164         c += "stress " + seq + ";\n";
165         c += "Stensor d" + seq + "_d" + s + ";\n";
166         c += "std::tie(" + seq + ",d" + seq + "_d" + s + ") = ";
167         c += "compute" + this->name + "StressNormal(" + s + ", " + f_ +
168              ", this->" + params + ", " + sp.getEquivalentStressLowerBound(bd) +
169              ");\n";
170 #endif /* __cplusplus >= 201703L */
171       }
172       if (r == STRESSANDFLOWCRITERION) {
173         c += "const auto& " + n + " = d" + seq + "_d" + s + ";\n";
174       }
175       if (r == FLOWCRITERION) {
176 #if __cplusplus >= 201703L
177         c += "const auto [" + seqf +  //
178              ", " + n + ", " +        //
179              ", d" + seqf + "_d" + f.name + "] = ";
180         c += "compute" + this->name + "StressNormal(" + s + ", " + f_ +
181              ", this->" + params + ", " + sp.getEquivalentStressLowerBound(bd) +
182              ");\n";
183 #else  /* __cplusplus >= 201703L */
184         c += "stress " + seqf + ";\n";
185         c += "Stensor " + n + ";\n";
186         c += "real d" + seqf + "_d" + f.name + ";\n";
187         c += "std::tie(" + seqf + "," + n +  //
188              ", d" + seqf + "_d" + f.name + ") = ";
189         c += "compute" + this->name + "StressNormal(" + s + ", " + f_ +
190              ",this->" + params + ", " + sp.getEquivalentStressLowerBound(bd) +
191              ");\n";
192 #endif /* __cplusplus >= 201703L */
193       }
194       return c;
195     }  // end of StandardPorousStressCriterionBase::computeNormal
196 
computeNormalDerivative(const std::string & id,const BehaviourDescription & bd,const StressPotential & sp,const Role r) const197     std::string StandardPorousStressCriterionBase::computeNormalDerivative(
198         const std::string& id,
199         const BehaviourDescription& bd,
200         const StressPotential& sp,
201         const Role r) const {
202       constexpr const auto uh =
203           tfel::material::ModellingHypothesis::UNDEFINEDHYPOTHESIS;
204       const auto params =
205           StressCriterion::getVariableId("sscb_parameters", id, r);
206       const auto& f =
207           bd.getBehaviourData(uh).getStateVariableDescriptionByExternalName(
208               tfel::glossary::Glossary::Porosity);
209       const auto n = "n" + id;
210       const auto s = "s" + id;
211       const auto seq = "seq" + id;
212       const auto seqf = "seqf" + id;
213       const auto f_ = f.name + "_";
214       auto c = std::string{};
215       if ((r == STRESSCRITERION) || (r == STRESSANDFLOWCRITERION)) {
216 #if __cplusplus >= 201703L
217         c += "const auto [" + seq +              //
218              ",d" + seq + "_d" + s +             //
219              ",d" + seq + "_d" + f.name +        //
220              ",d2" + seq + "_d" + s + "d" + s +  //
221              ",d2" + seq + "_d" + s + "d" + f.name + "] = ";
222         c += "compute" + this->name + "StressSecondDerivative(" + s + ", " +
223              f_ + ", this->" + params + ", " +
224              sp.getEquivalentStressLowerBound(bd) + ");\n";
225 #else  /* __cplusplus >= 201703L */
226         c += "stress " + seq + ";\n";
227         c += "Stensor d" + seq + "_d" + s + ";\n";
228         c += "real d" + seq + "_d" + f.name + ";\n";
229         c += "Stensor4 d2" + seq + "_d" + s + "d" + s + ";\n";
230         c += "Stensor  d2" + seq + "_d" + s + "d" + f.name + ";\n";
231         c += "std::tie(" + seq +                 //
232              ",d" + seq + "_d" + s +             //
233              ",d" + seq + "_d" + f.name +        //
234              ",d2" + seq + "_d" + s + "d" + s +  //
235              ",d2" + seq + "_d" + s + "d" + f.name + ") = ";
236         c += "compute" + this->name + "StressSecondDerivative(" + s + ", " +
237              f_ + ", this->" + params + ", " +
238              sp.getEquivalentStressLowerBound(bd) + ");\n";
239 #endif /* __cplusplus >= 201703L */
240       }
241       if (r == STRESSANDFLOWCRITERION) {
242         c += "const auto& " + n + " = d" + seq + "_d" + s + ";\n";
243         c += "const auto& d" + n + "_d" + s + " = ";
244         c += "d2" + seq + "_d" + s + "d" + s + ";\n";
245         c += "const auto& d" + n + "_d" + f.name + " = ";
246         c += "d2" + seq + "_d" + s + "d" + f.name + ";\n";
247       }
248       if (r == FLOWCRITERION) {
249 #if __cplusplus >= 201703L
250         c += "const auto [" + seqf +  //
251              ", n" + id +             //
252              ", dseqf_d" + f.name +   //
253              ", d" + n + "_d" + s +   //
254              ", d" + n + "_d" + f.name + "] = ";
255         c += "compute" + this->name + "StressSecondDerivative(" + s + ", " +
256              f_ + ", this->" + params + ", " +
257              sp.getEquivalentStressLowerBound(bd) + ");\n";
258 #else  /* __cplusplus >= 201703L */
259         c += "stress " + seqf + ";\n";
260         c += "Stensor " + n + ";\n";
261         c += "real d" + seqf + "_d" + f.name + ";\n";
262         c += "Stensor4 d" + n + "_d" + s + ";\n";
263         c += "Stensor2 d" + n + "_d" + f.name + ";\n";
264         c += "std::tie(" + seqf +            //
265              ", " + n +                      //
266              ", d" + seqf + "_d" + f.name +  //
267              ", d" + n + "_d" + s +          //
268              ", d" + n + "_d" + f.name + ") = ";
269         c += "compute" + this->name + "StressSecondDerivative(" + s + ", " +
270              f_ + ", this->" + params + ", " +
271              sp.getEquivalentStressLowerBound(bd) + ");\n";
272 #endif /* __cplusplus >= 201703L */
273       }
274       return c;
275     }  // end of StandardPorousStressCriterionBase::computeNormalDerivative
276 
277     StandardPorousStressCriterionBase::~StandardPorousStressCriterionBase() =
278         default;
279 
280   }  // end of namespace bbrick
281 
282 }  // end of namespace mfront
283