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), rhsScale(scale) {
101 this->normalStiffness, this->tangentStiffness,
102 this->entsPtr, m_field, ms_id),
103 "Can not read spring stiffness data from blockset");
104}
105
106template <int FIELD_DIM, AssemblyType A, typename EleOp>
107MoFEMErrorCode
109 GAUSS, EleOp>::iNtegrate(EntitiesFieldData::EntData
110 &row_data) {
114 // get element volume
115 const double vol = OpBase::getMeasure();
116 // get integration weights
117 auto t_w = OpBase::getFTensor0IntegrationWeight();
118 // get base function gradient on rows
119 auto t_row_base = row_data.getFTensor0N();
120
121 // get coordinate at integration points
122 auto t_normal = OpBase::getFTensor1NormalsAtGaussPts();
123
124 // get displacements
125 auto t_u = getFTensor1FromMat<FIELD_DIM>(*uPtr);
126 // loop over integration points
127 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
128 // take into account Jacobian
129 const double alpha = t_w * vol * rhsScale;
130
131 auto l2_norm = t_normal(i) * t_normal(i);
132
133 // normal projection matrix
135 t_P(i, j) = t_normal(i) * t_normal(j) / l2_norm;
136 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
137 // tangential projection matrix
139 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
140 // spring stiffness
142 t_D(i, j) = normalStiffness * t_P(i, j) + tangentStiffness * t_Q(i, j);
143
144 // calculate spring resistance
146 t_reaction(i) = t_D(i, j) * t_u(j);
147
148 // loop over rows base functions
149 auto t_nf = getFTensor1FromArray<FIELD_DIM, FIELD_DIM>(OpBase::locF);
150 int rr = 0;
151 for (; rr != OpBase::nbRows / FIELD_DIM; ++rr) {
152 t_nf(i) += (alpha * t_row_base) * t_reaction(i);
153 ++t_row_base;
154 ++t_nf;
155 }
156
157 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
158 ++t_row_base;
159
160 ++t_w;
161 ++t_u;
162 ++t_normal;
163 }
165}
166
167template <int FIELD_DIM, AssemblyType A, typename EleOp>
168OpFluxLhsImpl<ElasticExample::SpringBcType<BLOCKSET>, 1, FIELD_DIM, A, GAUSS,
169 EleOp>::OpFluxLhsImpl(MoFEM::Interface &m_field, int ms_id,
170 std::string row_field_name,
171 std::string col_field_name)
172 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL) {
174 this->normalStiffness, this->tangentStiffness,
175 this->entsPtr, m_field, ms_id),
176 "Can not read spring stiffness data from blockset");
177}
178
179template <int FIELD_DIM, AssemblyType A, typename EleOp>
180MoFEMErrorCode
182 GAUSS,
183 EleOp>::iNtegrate(EntitiesFieldData::EntData &row_data,
184 EntitiesFieldData::EntData &col_data) {
185
188
190 // get element volume
191 const double vol = OpBase::getMeasure();
192 // get integration weights
193 auto t_w = OpBase::getFTensor0IntegrationWeight();
194 // get base function gradient on rows
195 auto t_row_base = row_data.getFTensor0N();
196
197 // get coordinate at integration points
198 auto t_normal = OpBase::getFTensor1NormalsAtGaussPts();
199
200 // loop over integration points
201 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
202 // take into account Jacobian
203 const double alpha = t_w * vol;
204
205 auto l2_norm = t_normal(i) * t_normal(i);
206
207 // normal projection matrix
209 t_P(i, j) = t_normal(i) * t_normal(j) / l2_norm;
210 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
211 // tangential projection matrix
213 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
214 // spring stiffness
216 t_D(i, j) = normalStiffness * t_P(i, j) + tangentStiffness * t_Q(i, j);
217
218 // loop over rows base functions
219 int rr = 0;
220 for (; rr != OpBase::nbRows / FIELD_DIM; rr++) {
221 // get column base functions gradient at gauss point gg
222 auto t_col_base = col_data.getFTensor0N(gg, 0);
223 // get sub matrix for the row
224 auto t_m = OpBase::template getLocMat<FIELD_DIM>(FIELD_DIM * rr);
225 // loop over columns
226 for (int cc = 0; cc != OpBase::nbCols / FIELD_DIM; cc++) {
227 // calculate element of local matrix
228 t_m(i, j) += t_D(i, j) * (alpha * t_row_base * t_col_base);
229 ++t_col_base;
230 ++t_m;
231 }
232 ++t_row_base;
233 }
234 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
235 ++t_row_base;
236
237 ++t_normal;
238 ++t_w; // move to another integration weight
239 }
241}
242
243template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
244 IntegrationType I, typename OpBase>
245struct AddFluxToRhsPipelineImpl<
246
247 OpFluxRhsImpl<ElasticExample::SpringBcType<BCTYPE>, BASE_DIM, FIELD_DIM, A,
248 I, OpBase>,
249 A, I, OpBase
250
251 > {
252
254
255 static MoFEMErrorCode add(
256
257 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
258 MoFEM::Interface &m_field, std::string field_name,
259 boost::shared_ptr<MatrixDouble> u_ptr, double scale,
260 std::string block_name, Sev sev
261
262 ) {
264
265 using OP = OpFluxRhsImpl<ElasticExample::SpringBcType<BLOCKSET>, BASE_DIM,
267
268 auto add_op = [&](auto &&meshset_vec_ptr) {
269 for (auto m : meshset_vec_ptr) {
270 MOFEM_TAG_AND_LOG("WORLD", sev, "OpSpringRhs") << "Add " << *m;
271 pipeline.push_back(
272 new OP(m_field, m->getMeshsetId(), field_name, u_ptr, scale));
273 }
274 MOFEM_LOG_CHANNEL("WORLD");
275 };
276
277 switch (BCTYPE) {
278 case BLOCKSET:
279 add_op(
280
281 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
282 std::regex(
283
284 (boost::format("%s(.*)") % block_name).str()
285
286 ))
287
288 );
289
290 break;
291 default:
292 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
293 "Handling of bc type not implemented");
294 break;
295 }
297 }
298};
299
300template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
301 IntegrationType I, typename OpBase>
302struct AddFluxToLhsPipelineImpl<
303
304 OpFluxLhsImpl<ElasticExample::SpringBcType<BCTYPE>, BASE_DIM, FIELD_DIM, A,
305 I, OpBase>,
306 A, I, OpBase
307
308 > {
309
311
312 static MoFEMErrorCode add(
313
314 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
315 MoFEM::Interface &m_field, std::string row_field_name,
316 std::string col_field_name, std::string block_name, Sev sev
317
318 ) {
320
321 using OP = OpFluxLhsImpl<ElasticExample::SpringBcType<BLOCKSET>, BASE_DIM,
323
324 auto add_op = [&](auto &&meshset_vec_ptr) {
325 for (auto m : meshset_vec_ptr) {
326 MOFEM_TAG_AND_LOG("WORLD", sev, "OpSpringLhs") << "Add " << *m;
327 pipeline.push_back(
328 new OP(m_field, m->getMeshsetId(), row_field_name, col_field_name));
329 }
330 MOFEM_LOG_CHANNEL("WORLD");
331 };
332
333 switch (BCTYPE) {
334 case BLOCKSET:
335 add_op(
336
337 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
338 std::regex(
339
340 (boost::format("%s(.*)") % block_name).str()
341
342 ))
343
344 );
345
346 break;
347 default:
348 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
349 "Handling of bc type not implemented");
350 break;
351 }
353 }
354};
#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)