v0.15.0
Loading...
Searching...
No Matches
ElasticSpring.hpp
Go to the documentation of this file.
1/**
2 * @file ElasticSpring.hpp
3 * @author your name (you@domain.com)
4 * @brief Implementation of elastic spring bc
5 * @version 0.13.2
6 * @date 2022-09-18
7 *
8 * @copyright Copyright (c) 2022
9 *
10 */
11
12namespace ElasticExample {
13
14template <CubitBC BC> struct SpringBcType {};
15
16template <CubitBC BC> struct GetSpringStiffness;
17
18template <> struct GetSpringStiffness<BLOCKSET> {
20
21 static MoFEMErrorCode getStiffness(double &normal_stiffness,
22 double &tangent_stiffness,
23 boost::shared_ptr<Range> &ents,
24 MoFEM::Interface &m_field, int ms_id) {
26
27 auto cubit_meshset_ptr =
28 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
29 BLOCKSET);
30 std::vector<double> block_data;
31 CHKERR cubit_meshset_ptr->getAttributes(block_data);
32 if (block_data.size() != 2) {
33 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
34 "Expected that block has two attribute");
35 }
36 normal_stiffness = block_data[0];
37 tangent_stiffness = block_data[1];
38
39 MOFEM_LOG_CHANNEL("WORLD");
40 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "SpringBc")
41 << "Normal stiffness " << normal_stiffness;
42 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "SpringBc")
43 << "Tangent stiffness " << tangent_stiffness;
44
45 ents = boost::make_shared<Range>();
46 CHKERR
47 m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
48 *(ents), true);
49
50 MOFEM_LOG_CHANNEL("SYNC");
51 MOFEM_TAG_AND_LOG("SYNC", Sev::noisy, "SpringBc") << *ents;
52 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
53
55 }
56};
57
58} // namespace ElasticExample
59
60template <int FIELD_DIM, AssemblyType A, typename EleOp>
61struct OpFluxRhsImpl<ElasticExample::SpringBcType<BLOCKSET>, 1, FIELD_DIM, A,
62 GAUSS, EleOp> : OpBaseImpl<A, EleOp> {
63
65
66 OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id, std::string field_name,
67 boost::shared_ptr<MatrixDouble> u_ptr, double scale);
68
69protected:
72 double rhsScale;
73 boost::shared_ptr<MatrixDouble> uPtr;
74 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &data);
75};
76
77template <int FIELD_DIM, AssemblyType A, typename EleOp>
78struct OpFluxLhsImpl<ElasticExample::SpringBcType<BLOCKSET>, 1, FIELD_DIM, A,
79 GAUSS, EleOp> : OpBaseImpl<A, EleOp> {
80
82
83 OpFluxLhsImpl(MoFEM::Interface &m_field, int ms_id,
84 std::string row_field_name, std::string col_field_name);
85
86protected:
89 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
90 EntitiesFieldData::EntData &col_data);
91};
92
93template <int FIELD_DIM, AssemblyType A, typename EleOp>
94OpFluxRhsImpl<ElasticExample::SpringBcType<BLOCKSET>, 1, FIELD_DIM, A, GAUSS,
95 EleOp>::OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
96 std::string field_name,
97 boost::shared_ptr<MatrixDouble> u_ptr,
98 double scale)
99 : OpBase(field_name, field_name, OpBase::OPROW), uPtr(u_ptr),
100 rhsScale(scale) {
102 this->normalStiffness, this->tangentStiffness,
103 this->entsPtr, m_field, ms_id),
104 "Can not read spring stiffness data from blockset");
105}
106
107template <int FIELD_DIM, AssemblyType A, typename EleOp>
108MoFEMErrorCode
110 GAUSS, EleOp>::iNtegrate(EntitiesFieldData::EntData
111 &row_data) {
115 // get element volume
116 const double vol = OpBase::getMeasure();
117 // get integration weights
118 auto t_w = OpBase::getFTensor0IntegrationWeight();
119 // get base function gradient on rows
120 auto t_row_base = row_data.getFTensor0N();
121
122 // get coordinate at integration points
123 auto t_normal = OpBase::getFTensor1NormalsAtGaussPts();
124
125 // get displacements
126 auto t_u = getFTensor1FromMat<FIELD_DIM>(*uPtr);
127 // loop over integration points
128 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
129 // take into account Jacobian
130 const double alpha = t_w * vol * rhsScale;
131
132 auto l2_norm = t_normal(i) * t_normal(i);
133
134 // normal projection matrix
136 t_P(i, j) = t_normal(i) * t_normal(j) / l2_norm;
137 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
138 // tangential projection matrix
140 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
141 // spring stiffness
143 t_D(i, j) = normalStiffness * t_P(i, j) + tangentStiffness * t_Q(i, j);
144
145 // calculate spring resistance
147 t_reaction(i) = t_D(i, j) * t_u(j);
148
149 // loop over rows base functions
150 auto t_nf = getFTensor1FromArray<FIELD_DIM, FIELD_DIM>(OpBase::locF);
151 int rr = 0;
152 for (; rr != OpBase::nbRows / FIELD_DIM; ++rr) {
153 t_nf(i) += (alpha * t_row_base) * t_reaction(i);
154 ++t_row_base;
155 ++t_nf;
156 }
157
158 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
159 ++t_row_base;
160
161 ++t_w;
162 ++t_u;
163 ++t_normal;
164 }
166}
167
168template <int FIELD_DIM, AssemblyType A, typename EleOp>
169OpFluxLhsImpl<ElasticExample::SpringBcType<BLOCKSET>, 1, FIELD_DIM, A, GAUSS,
170 EleOp>::OpFluxLhsImpl(MoFEM::Interface &m_field, int ms_id,
171 std::string row_field_name,
172 std::string col_field_name)
173 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL) {
175 this->normalStiffness, this->tangentStiffness,
176 this->entsPtr, m_field, ms_id),
177 "Can not read spring stiffness data from blockset");
178}
179
180template <int FIELD_DIM, AssemblyType A, typename EleOp>
181MoFEMErrorCode
183 GAUSS,
184 EleOp>::iNtegrate(EntitiesFieldData::EntData &row_data,
185 EntitiesFieldData::EntData &col_data) {
186
189
191 // get element volume
192 const double vol = OpBase::getMeasure();
193 // get integration weights
194 auto t_w = OpBase::getFTensor0IntegrationWeight();
195 // get base function gradient on rows
196 auto t_row_base = row_data.getFTensor0N();
197
198 // get coordinate at integration points
199 auto t_normal = OpBase::getFTensor1NormalsAtGaussPts();
200
201 // loop over integration points
202 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
203 // take into account Jacobian
204 const double alpha = t_w * vol;
205
206 auto l2_norm = t_normal(i) * t_normal(i);
207
208 // normal projection matrix
210 t_P(i, j) = t_normal(i) * t_normal(j) / l2_norm;
211 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
212 // tangential projection matrix
214 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
215 // spring stiffness
217 t_D(i, j) = normalStiffness * t_P(i, j) + tangentStiffness * t_Q(i, j);
218
219 // loop over rows base functions
220 int rr = 0;
221 for (; rr != OpBase::nbRows / FIELD_DIM; rr++) {
222 // get column base functions gradient at gauss point gg
223 auto t_col_base = col_data.getFTensor0N(gg, 0);
224 // get sub matrix for the row
225 auto t_m = OpBase::template getLocMat<FIELD_DIM>(FIELD_DIM * rr);
226 // loop over columns
227 for (int cc = 0; cc != OpBase::nbCols / FIELD_DIM; cc++) {
228 // calculate element of local matrix
229 t_m(i, j) += t_D(i, j) * (alpha * t_row_base * t_col_base);
230 ++t_col_base;
231 ++t_m;
232 }
233 ++t_row_base;
234 }
235 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
236 ++t_row_base;
237
238 ++t_normal;
239 ++t_w; // move to another integration weight
240 }
242}
243
244template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
245 IntegrationType I, typename OpBase>
246struct AddFluxToRhsPipelineImpl<
247
248 OpFluxRhsImpl<ElasticExample::SpringBcType<BCTYPE>, BASE_DIM, FIELD_DIM, A,
249 I, OpBase>,
250 A, I, OpBase
251
252 > {
253
255
256 static MoFEMErrorCode add(
257
258 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
259 MoFEM::Interface &m_field, std::string field_name,
260 boost::shared_ptr<MatrixDouble> u_ptr, double scale,
261 std::string block_name, Sev sev
262
263 ) {
265
266 using OP = OpFluxRhsImpl<ElasticExample::SpringBcType<BLOCKSET>, BASE_DIM,
268
269 auto add_op = [&](auto &&meshset_vec_ptr) {
270 for (auto m : meshset_vec_ptr) {
271 MOFEM_TAG_AND_LOG("WORLD", sev, "OpSpringRhs") << "Add " << *m;
272 pipeline.push_back(
273 new OP(m_field, m->getMeshsetId(), field_name, u_ptr, scale));
274 }
275 MOFEM_LOG_CHANNEL("WORLD");
276 };
277
278 switch (BCTYPE) {
279 case BLOCKSET:
280 add_op(
281
282 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
283 std::regex(
284
285 (boost::format("%s(.*)") % block_name).str()
286
287 ))
288
289 );
290
291 break;
292 default:
293 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
294 "Handling of bc type not implemented");
295 break;
296 }
298 }
299};
300
301template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
302 IntegrationType I, typename OpBase>
303struct AddFluxToLhsPipelineImpl<
304
305 OpFluxLhsImpl<ElasticExample::SpringBcType<BCTYPE>, BASE_DIM, FIELD_DIM, A,
306 I, OpBase>,
307 A, I, OpBase
308
309 > {
310
312
313 static MoFEMErrorCode add(
314
315 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
316 MoFEM::Interface &m_field, std::string row_field_name,
317 std::string col_field_name, std::string block_name, Sev sev
318
319 ) {
321
322 using OP = OpFluxLhsImpl<ElasticExample::SpringBcType<BLOCKSET>, BASE_DIM,
324
325 auto add_op = [&](auto &&meshset_vec_ptr) {
326 for (auto m : meshset_vec_ptr) {
327 MOFEM_TAG_AND_LOG("WORLD", sev, "OpSpringLhs") << "Add " << *m;
328 pipeline.push_back(
329 new OP(m_field, m->getMeshsetId(), row_field_name, col_field_name));
330 }
331 MOFEM_LOG_CHANNEL("WORLD");
332 };
333
334 switch (BCTYPE) {
335 case BLOCKSET:
336 add_op(
337
338 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
339 std::regex(
340
341 (boost::format("%s(.*)") % block_name).str()
342
343 ))
344
345 );
346
347 break;
348 default:
349 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
350 "Handling of bc type not implemented");
351 break;
352 }
354 }
355};
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
constexpr int FIELD_DIM
Kronecker Delta class.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
CubitBC
Types of sets and boundary conditions.
@ BLOCKSET
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr int BASE_DIM
constexpr auto t_kd
IntegrationType
Form integrator integration types.
AssemblyType
[Storage and set boundary conditions]
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'j', 3 > j
constexpr IntegrationType I
constexpr AssemblyType A
double scale
Definition plastic.cpp:123
constexpr auto field_name
FTensor::Index< 'm', 3 > m
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, std::string row_field_name, std::string col_field_name, std::string block_name, Sev sev)
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, std::string field_name, boost::shared_ptr< MatrixDouble > u_ptr, double scale, std::string block_name, Sev sev)
static MoFEMErrorCode getStiffness(double &normal_stiffness, double &tangent_stiffness, boost::shared_ptr< Range > &ents, MoFEM::Interface &m_field, int ms_id)
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
Deprecated interface functions.
VectorDouble locF
local entity vector
int nbRows
number of dofs on rows
int nbIntegrationPts
number of integration points
int nbCols
number if dof on column
int nbRowBaseFunctions
number or row base functions
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)