1 /*!
2  * \file   mfront/src/PorosityNucleationModelBase.cxx
3  * \brief
4  * \author Thomas Helfer
5  * \date   05/04/2020
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/Utilities/Data.hxx"
16 #include "TFEL/Glossary/Glossary.hxx"
17 #include "TFEL/Glossary/GlossaryEntry.hxx"
18 #include "MFront/BehaviourBrick/BrickUtilities.hxx"
19 #include "MFront/BehaviourBrick/OptionDescription.hxx"
20 #include "MFront/BehaviourBrick/PorosityNucleationModelBase.hxx"
21 
22 namespace mfront {
23 
24   namespace bbrick {
25 
26     std::vector<PorosityNucleationModelBase::MaterialCoefficientDescription>
getMaterialCoefficientDescriptions() const27     PorosityNucleationModelBase::getMaterialCoefficientDescriptions() const {
28       return {};
29     }  // end of getMaterialCoefficientDescriptions
30 
getOptions() const31     std::vector<OptionDescription> PorosityNucleationModelBase::getOptions() const {
32       std::vector<OptionDescription> opts;
33       opts.emplace_back(
34           "save_individual_porosity_increase",
35           "if appropriate, save the porosity increase induced "
36           "by this inelastic flow in a dedicated auxiliary state variable",
37           OptionDescription::BOOLEAN);
38       opts.emplace_back("porosity_evolution_algorithm",
39                         "reserved for internal use", OptionDescription::STRING);
40       for (const auto& mc : this->getMaterialCoefficientDescriptions()) {
41         opts.emplace_back(mc.name, mc.description,
42                           OptionDescription::MATERIALPROPERTY);
43       }
44       return opts;
45     }  // end of PorosityNucleationModelBase::getOptions()
46 
initialize(BehaviourDescription & bd,AbstractBehaviourDSL & dsl,const std::string & id,const DataMap & d)47     void PorosityNucleationModelBase::initialize(BehaviourDescription& bd,
48                                                  AbstractBehaviourDSL& dsl,
49                                                  const std::string& id,
50                                                  const DataMap& d) {
51       constexpr const auto uh = ModellingHypothesis::UNDEFINEDHYPOTHESIS;
52       auto raise = [](const std::string& m) {
53         tfel::raise("PorosityNucleationModelBase::initialize: " + m);
54       };  // end of raise
55       // checking options
56       mfront::bbrick::check(d, this->getOptions());
57       // parsing options
58       for (const auto& e : d) {
59         if (e.first == "save_individual_porosity_increase") {
60           if (!e.second.is<bool>()) {
61             raise("'save_individual_porosity_increase' is not a boolean");
62           }
63           this->save_porosity_increase = e.second.get<bool>();
64         } else if (e.first == "porosity_evolution_algorithm") {
65           if (!e.second.is<std::string>()) {
66             raise("'porosity_evolution_algorithm' is not a boolean");
67           }
68           const auto& a = e.second.get<std::string>();
69           if (a == "standard_implicit_scheme") {
70             this->porosity_evolution_algorithm =
71                 PorosityEvolutionAlgorithm::STANDARD_IMPLICIT_SCHEME;
72           } else if (a == "staggered_scheme") {
73             this->porosity_evolution_algorithm =
74                 PorosityEvolutionAlgorithm::STAGGERED_SCHEME;
75           } else {
76             raise("internal error: unsupported porosity evolution algorithm");
77           }
78         }  // other options must be treated in child classes
79       }
80       // treating material coefficients
81       for (const auto& mc : this->getMaterialCoefficientDescriptions()) {
82         const auto mc_n = PorosityNucleationModel::getVariableId(mc.name, id);
83         tfel::raise_if(
84             d.count(mc.name) == 0,
85             "ChuNeedleman1980StrainBasedPorosityNucleationModel::initialize: "
86             "material property '" +
87                 mc_n + "' is not defined");
88         this->material_coefficients.insert(
89             {mc.name, getBehaviourDescriptionMaterialProperty(dsl, mc.name,
90                                                               d.at(mc.name))});
91         declareParameterOrLocalVariable(
92             bd, this->material_coefficients[mc.name], mc.type, mc_n);
93       }
94       //
95       addLocalVariable(bd, "real", "dfn" + id);
96       if ((this->save_porosity_increase) ||
97           (this->requiresSavingNucleatedPorosity())) {
98         VariableDescription fn("real", "fn" + id, 1u, 0u);
99         const auto g =
100             tfel::glossary::Glossary::PorosityIncreaseDueToNucleation;
101         if (id.empty()) {
102           fn.setGlossaryName(g);
103         } else {
104           fn.setEntryName(g.getKey() + id);
105         }
106         bd.addAuxiliaryStateVariable(uh, fn);
107       }
108     }  // end of PorosityNucleationModelBase::initialize
109 
endTreatment(BehaviourDescription & bd,const AbstractBehaviourDSL & dsl,const StressPotential &,const std::map<std::string,std::shared_ptr<bbrick::InelasticFlow>> & iflows,const std::string & id) const110     void PorosityNucleationModelBase::endTreatment(
111         BehaviourDescription& bd,
112         const AbstractBehaviourDSL& dsl,
113         const StressPotential&,
114         const std::map<std::string, std::shared_ptr<bbrick::InelasticFlow>>&
115             iflows,
116         const std::string& id) const {
117       constexpr const auto uh = ModellingHypothesis::UNDEFINEDHYPOTHESIS;
118       // a simple check
119       if (iflows.empty()) {
120         tfel::raise(
121             "PorosityNucleationModelBase::endTreatment: "
122             "no inelastic flow declared");
123       }
124       // initialize
125       auto c = std::string{};
126       for (const auto& mc : this->getMaterialCoefficientDescriptions()) {
127         const auto mc_n = PorosityNucleationModel::getVariableId(mc.name, id);
128         c += generateMaterialPropertyInitializationCode(
129             dsl, bd, mc_n, this->material_coefficients.at(mc.name));
130       }
131       CodeBlock init;
132       init.code = c;
133       bd.setCode(uh, BehaviourData::BeforeInitializeLocalVariables, init,
134                  BehaviourData::CREATEORAPPEND, BehaviourData::AT_BEGINNING);
135       //
136       if ((this->save_porosity_increase) ||
137           (this->requiresSavingNucleatedPorosity())) {
138         CodeBlock uav;
139         uav.code = "this->fn" + id + " += this->dfn" + id + ";\n";
140         bd.setCode(uh, BehaviourData::UpdateAuxiliaryStateVariables, uav,
141                    BehaviourData::CREATEORAPPEND, BehaviourData::AT_BEGINNING);
142       }
143     }  // end of PorosityNucleationModelBase::endTreatment
144 
completeVariableDeclaration(BehaviourDescription &,const AbstractBehaviourDSL &,const std::map<std::string,std::shared_ptr<bbrick::InelasticFlow>> & iflows,const std::string &) const145     void PorosityNucleationModelBase::completeVariableDeclaration(
146         BehaviourDescription&,
147         const AbstractBehaviourDSL&,
148         const std::map<std::string, std::shared_ptr<bbrick::InelasticFlow>>&
149             iflows,
150         const std::string&) const {
151       if (iflows.empty()) {
152         tfel::raise(
153             "PorosityNucleationModelBase::"
154             "completeVariableDeclaration: no inelastic flow declared");
155       }
156     }  // end of PorosityNucleationModelBase::completeVariableDeclaration
157 
158     PorosityNucleationModelBase::~PorosityNucleationModelBase() = default;
159 
160   }  // end of namespace bbrick
161 
162 }  // end of namespace mfront
163