v0.16.0
Loading...
Searching...
No Matches
PostProcStresses.hpp
Go to the documentation of this file.
1/** \file PostProcStresses.hpp
2 * \brief Post-processing stresses for non-linear analysis
3 * \ingroup nonlinear_elastic_elem
4 *
5 * Implementation of method for post-processing stresses.
6 */
7
8
9
10#ifndef __POSTPROCSTRESSES_HPP__
11#define __POSTPROCSTRESSES_HPP__
12
13#ifndef WITH_ADOL_C
14#error "MoFEM need to be compiled with ADOL-C"
15#endif
16
19
20 moab::Interface &postProcMesh;
21 std::vector<EntityHandle> &mapGaussPts;
23
25 boost::shared_ptr<MatrixDouble> fieldValuesPtr;
26 boost::shared_ptr<MatrixDouble> meshPositionsPtr;
27 boost::shared_ptr<MatrixDouble> fieldGradientPtr;
28 const std::string meshPositionsFieldName;
29 const bool fieldDisp;
31 const double maxVal;
32 const bool printCauchy;
33
34 PostProcStress(moab::Interface &post_proc_mesh,
35 std::vector<EntityHandle> &map_gauss_pts,
36 Range &post_proc_elements,
37 const std::string field_name,
39 boost::shared_ptr<MatrixDouble> field_values_ptr,
40 boost::shared_ptr<MatrixDouble> mesh_positions_ptr,
41 boost::shared_ptr<MatrixDouble> field_gradient_ptr,
42 const std::string mesh_positions_field_name =
43 "MESH_NODE_POSITIONS",
44 const bool field_disp = false,
45 const bool replace_nonanumber_by_max_value = false,
46 const double max_val = 1e16,
47 const bool print_cauchy_stress = false)
48 : MoFEM::VolumeElementForcesAndSourcesCore::UserDataOperator(
50 postProcMesh(post_proc_mesh), mapGaussPts(map_gauss_pts),
51 postProcElements(post_proc_elements), dAta(data),
52 fieldValuesPtr(field_values_ptr), meshPositionsPtr(mesh_positions_ptr),
53 fieldGradientPtr(field_gradient_ptr),
54 meshPositionsFieldName(mesh_positions_field_name),
55 fieldDisp(field_disp),
56 replaceNonANumberByMaxValue(replace_nonanumber_by_max_value),
57 maxVal(max_val), printCauchy(print_cauchy_stress) {}
58
60
61 MoFEMErrorCode doWork(int side, EntityType type,
62 EntitiesFieldData::EntData &data) {
64
65 if (type != MBVERTEX)
67 if (data.getIndices().size() == 0)
69 if (dAta.tEts.find(getNumeredEntFiniteElementPtr()->getEnt()) ==
70 dAta.tEts.end()) {
72 }
73
74 const auto &dof_ptr = data.getFieldDofs()[0];
75
76 int id = dAta.iD;
77
78 Tag th_id;
79 int def_block_id = -1;
80 CHKERR postProcMesh.tag_get_handle("BLOCK_ID", 1, MB_TYPE_INTEGER, th_id,
81 MB_TAG_CREAT | MB_TAG_SPARSE,
82 &def_block_id);
83 CHKERR postProcMesh.tag_clear_data(th_id, postProcElements, &id);
84
85 string tag_name_piola1 = dof_ptr->getName() + "_PIOLA1_STRESS";
86 string tag_name_energy = dof_ptr->getName() + "_ENERGY_DENSITY";
87
88 int tag_length = 9;
89 double def_VAL[tag_length];
90 bzero(def_VAL, tag_length * sizeof(double));
91 Tag th_piola1, th_energy, th_cauchy;
92 CHKERR postProcMesh.tag_get_handle(tag_name_piola1.c_str(), tag_length,
93 MB_TYPE_DOUBLE, th_piola1,
94 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
95 CHKERR postProcMesh.tag_get_handle(tag_name_energy.c_str(), 1,
96 MB_TYPE_DOUBLE, th_energy,
97 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
98
99 if (printCauchy) {
100 string tag_name_cauchy = "MED_" + dof_ptr->getName() + "_CAUCHY_STRESS";
101 CHKERR postProcMesh.tag_get_handle(tag_name_cauchy.c_str(), tag_length,
102 MB_TYPE_DOUBLE, th_cauchy,
103 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
104 }
105
106 int nb_gauss_pts = data.getN().size1();
107 if (mapGaussPts.size() != (unsigned int)nb_gauss_pts) {
108 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
109 "Nb. of integration points is not equal to number points on "
110 "post-processing mesh");
111 }
112 if (!fieldGradientPtr ||
113 fieldGradientPtr->size1() != (unsigned int)nb_gauss_pts ||
114 fieldGradientPtr->size2() != 9) {
115 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
116 "Gradient of field not found, filed <%s> not found",
117 rowFieldName.c_str());
118 }
119
120 auto make_field_values = [](auto values_ptr) {
121 std::vector<VectorDouble> values;
122 if (!values_ptr)
123 return values;
124 values.resize(values_ptr->size1());
125 for (size_t gg = 0; gg != values_ptr->size1(); ++gg) {
126 values[gg].resize(values_ptr->size2(), false);
127 for (size_t rr = 0; rr != values_ptr->size2(); ++rr) {
128 values[gg][rr] = (*values_ptr)(gg, rr);
129 }
130 }
131 return values;
132 };
133
134 auto make_gradients = [](auto gradient_ptr) {
135 std::vector<MatrixDouble> gradients;
136 if (!gradient_ptr)
137 return gradients;
138 const size_t field_rank = gradient_ptr->size2() / 3;
139 gradients.resize(gradient_ptr->size1());
140 for (size_t gg = 0; gg != gradient_ptr->size1(); ++gg) {
141 gradients[gg].resize(field_rank, 3, false);
142 for (size_t rr = 0; rr != field_rank; ++rr) {
143 for (size_t cc = 0; cc != 3; ++cc) {
144 gradients[gg](rr, cc) = (*gradient_ptr)(gg, 3 * rr + cc);
145 }
146 }
147 }
148 return gradients;
149 };
150
151 std::map<std::string, std::vector<VectorDouble>> field_map{
152 {rowFieldName, make_field_values(fieldValuesPtr)},
153 {meshPositionsFieldName, make_field_values(meshPositionsPtr)}};
154 std::map<std::string, std::vector<MatrixDouble>> gradient_map{
155 {rowFieldName, make_gradients(fieldGradientPtr)}};
156
157 MatrixDouble3by3 H, invH;
158 double detH;
159
161 dAta.materialDoublePtr->opPtr = this;
162 CHKERR dAta.materialDoublePtr->getDataOnPostProcessor(field_map,
163 gradient_map);
164
167
168 MatrixDouble3by3 maxP(3, 3);
169 maxP.clear();
170
171 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
172
173 dAta.materialDoublePtr->gG = gg;
174 dAta.materialDoublePtr->F.resize(3, 3);
175 noalias(dAta.materialDoublePtr->F) =
176 gradient_map[rowFieldName][gg];
177 if (fieldDisp) {
178 for (int dd = 0; dd != 3; dd++) {
179 dAta.materialDoublePtr->F(dd, dd) += 1;
180 }
181 }
182 if (gradient_map[meshPositionsFieldName].size() ==
183 (unsigned int)nb_gauss_pts) {
184 H.resize(3, 3);
185 invH.resize(3, 3);
186 noalias(H) = gradient_map[meshPositionsFieldName][gg];
187 detH = determinantTensor3by3(H);
188 CHKERR invertTensor3by3(H, detH, invH);
189 noalias(dAta.materialDoublePtr->F) =
190 prod(dAta.materialDoublePtr->F, invH);
191 }
192
193 int nb_active_variables = 9;
194 CHKERR dAta.materialDoublePtr->setUserActiveVariables(
195 nb_active_variables);
196 CHKERR dAta.materialDoublePtr->calculateP_PiolaKirchhoffI(
198 CHKERR dAta.materialDoublePtr->calculateElasticEnergy(
200 CHKERR postProcMesh.tag_set_data(th_piola1, &mapGaussPts[gg], 1,
201 &dAta.materialDoublePtr->P(0, 0));
202 CHKERR postProcMesh.tag_set_data(th_energy, &mapGaussPts[gg], 1,
203 &dAta.materialDoublePtr->eNergy);
204 if (printCauchy) {
205 dAta.materialDoublePtr->sigmaCauchy.resize(3, 3);
206 CHKERR dAta.materialDoublePtr->calculateCauchyStress(
208 CHKERR postProcMesh.tag_set_data(
209 th_cauchy, &mapGaussPts[gg], 1,
210 &dAta.materialDoublePtr->sigmaCauchy(0, 0));
211 }
212 }
213
215 MatrixDouble3by3 P(3, 3);
216 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
217 double val_energy;
218 CHKERR postProcMesh.tag_get_data(th_energy, &mapGaussPts[gg], 1,
219 &val_energy);
220 if (!std::isnormal(val_energy)) {
221 CHKERR postProcMesh.tag_set_data(th_energy, &mapGaussPts[gg], 1,
222 &maxVal);
223 CHKERR postProcMesh.tag_get_data(th_piola1, &mapGaussPts[gg], 1,
224 &P(0, 0));
225 for (unsigned int r = 0; r != P.size1(); ++r) {
226 for (unsigned int c = 0; c != P.size2(); ++c) {
227 if (!std::isnormal(P(r, c)))
228 P(r, c) = copysign(maxVal, P(r, c));
229 }
230 }
231 CHKERR postProcMesh.tag_set_data(th_piola1, &mapGaussPts[gg], 1,
232 &P(0, 0));
233 }
234 }
235 }
236
238 }
239};
240
241/// \deprecated Use PostProcStress
243
244#endif //__POSTPROCSTRESSES_HPP__
ForcesAndSourcesCore::UserDataOperator UserDataOperator
std::string type
DEPRECATED typedef PostProcStress PostPorcStress
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define DEPRECATED
Definition definitions.h:17
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
const double c
speed of light (cm/ns)
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
constexpr auto field_name
boost::shared_ptr< const NumeredEntFiniteElement > getNumeredEntFiniteElementPtr() const
Return raw pointer to NumeredEntFiniteElement.
@ OPROW
operator doWork function is executed on FE rows
data for calculation heat conductivity and heat capacity elements
boost::shared_ptr< FunctionsToCalculatePiolaKirchhoffI< double > > materialDoublePtr
Range tEts
constrains elements in block set
common data used by volume elements
std::map< std::string, std::vector< VectorDouble > > dataAtGaussPts
std::map< std::string, std::vector< MatrixDouble > > gradAtGaussPts
NonlinearElasticElement::BlockData & dAta
const bool replaceNonANumberByMaxValue
std::vector< EntityHandle > & mapGaussPts
boost::shared_ptr< MatrixDouble > fieldGradientPtr
const double maxVal
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
boost::shared_ptr< MatrixDouble > meshPositionsPtr
boost::shared_ptr< MatrixDouble > fieldValuesPtr
moab::Interface & postProcMesh
NonlinearElasticElement::CommonData nonLinearElementCommonData
const std::string meshPositionsFieldName
PostProcStress(moab::Interface &post_proc_mesh, std::vector< EntityHandle > &map_gauss_pts, Range &post_proc_elements, const std::string field_name, NonlinearElasticElement::BlockData &data, boost::shared_ptr< MatrixDouble > field_values_ptr, boost::shared_ptr< MatrixDouble > mesh_positions_ptr, boost::shared_ptr< MatrixDouble > field_gradient_ptr, const std::string mesh_positions_field_name="MESH_NODE_POSITIONS", const bool field_disp=false, const bool replace_nonanumber_by_max_value=false, const double max_val=1e16, const bool print_cauchy_stress=false)
double H
Hardening.
Definition plastic.cpp:129