v0.14.0
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 
12 namespace ElasticExample {
13 
14 template <CubitBC BC> struct SpringBcType {};
15 
16 template <CubitBC BC> struct GetSpringStiffness;
17 
18 template <> struct GetSpringStiffness<BLOCKSET> {
19  GetSpringStiffness() = delete;
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 
60 template <int FIELD_DIM, AssemblyType A, typename EleOp>
61 struct 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 
69 protected:
72  double rhsScale;
73  boost::shared_ptr<MatrixDouble> uPtr;
75 };
76 
77 template <int FIELD_DIM, AssemblyType A, typename EleOp>
78 struct 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 
86 protected:
89  MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
90  EntitiesFieldData::EntData &col_data);
91 };
92 
93 template <int FIELD_DIM, AssemblyType A, typename EleOp>
94 OpFluxRhsImpl<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 
106 template <int FIELD_DIM, AssemblyType A, typename EleOp>
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 
167 template <int FIELD_DIM, AssemblyType A, typename EleOp>
168 OpFluxLhsImpl<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 
179 template <int FIELD_DIM, AssemblyType A, typename EleOp>
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 
243 template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
244  IntegrationType I, typename OpBase>
245 struct AddFluxToRhsPipelineImpl<
246 
247  OpFluxRhsImpl<ElasticExample::SpringBcType<BCTYPE>, BASE_DIM, FIELD_DIM, A,
248  I, OpBase>,
249  A, I, OpBase
250 
251  > {
252 
253  AddFluxToRhsPipelineImpl() = delete;
254 
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 
300 template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
301  IntegrationType I, typename OpBase>
302 struct AddFluxToLhsPipelineImpl<
303 
304  OpFluxLhsImpl<ElasticExample::SpringBcType<BCTYPE>, BASE_DIM, FIELD_DIM, A,
305  I, OpBase>,
306  A, I, OpBase
307 
308  > {
309 
310  AddFluxToLhsPipelineImpl() = delete;
311 
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 };
MoFEM::UnknownInterface::getInterface
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Definition: UnknownInterface.hpp:93
ElasticExample::GetSpringStiffness
Definition: ElasticSpring.hpp:16
MoFEM::OpBaseImpl::nbIntegrationPts
int nbIntegrationPts
number of integration points
Definition: FormsIntegrators.hpp:238
MOFEM_LOG_SEVERITY_SYNC
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
Definition: LogManager.hpp:352
FTensor::Tensor1< double, FIELD_DIM >
MOFEM_LOG_CHANNEL
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
Definition: LogManager.hpp:284
OpFluxRhsImpl< ElasticExample::SpringBcType< BLOCKSET >, 1, FIELD_DIM, A, GAUSS, EleOp >::rhsScale
double rhsScale
Definition: ElasticSpring.hpp:72
MoFEM::OpFluxRhsImpl
Definition: Natural.hpp:39
AddFluxToLhsPipelineImpl< OpFluxLhsImpl< ElasticExample::SpringBcType< BCTYPE >, BASE_DIM, FIELD_DIM, A, I, OpBase >, A, I, OpBase >::add
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)
Definition: ElasticSpring.hpp:312
MoFEM::CoreInterface::get_comm
virtual MPI_Comm & get_comm() const =0
CHK_THROW_MESSAGE
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:609
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
FTensor::Kronecker_Delta
Kronecker Delta class.
Definition: Kronecker_Delta.hpp:15
MoFEM::PETSC
@ PETSC
Definition: FormsIntegrators.hpp:105
A
constexpr AssemblyType A
Definition: operators_tests.cpp:30
scale
double scale
Definition: plastic.cpp:119
BASE_DIM
constexpr int BASE_DIM
Definition: dg_projection.cpp:15
FTensor::Tensor2
Definition: Tensor2_value.hpp:16
MoFEM::DeprecatedCoreInterface
Deprecated interface functions.
Definition: DeprecatedCoreInterface.hpp:16
FIELD_DIM
constexpr int FIELD_DIM
Definition: child_and_parent.cpp:15
MoFEM::OpFluxLhsImpl
Definition: Natural.hpp:43
I
constexpr IntegrationType I
Definition: operators_tests.cpp:31
EleOp
MoFEM::OpBaseImpl::locF
VectorDouble locF
local entity vector
Definition: FormsIntegrators.hpp:251
AddFluxToRhsPipelineImpl< OpFluxRhsImpl< ElasticExample::SpringBcType< BCTYPE >, BASE_DIM, FIELD_DIM, A, I, OpBase >, A, I, OpBase >::add
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)
Definition: ElasticSpring.hpp:255
MoFEM::Sev
MoFEM::LogManager::SeverityLevel Sev
Definition: CoreTemplates.hpp:17
MoFEM::OpBaseImpl
Definition: FormsIntegrators.hpp:178
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:548
OpFluxRhsImpl< ElasticExample::SpringBcType< BLOCKSET >, 1, FIELD_DIM, A, GAUSS, EleOp >::tangentStiffness
double tangentStiffness
Definition: ElasticSpring.hpp:71
MoFEM::CoreInterface::get_moab
virtual moab::Interface & get_moab()=0
ElasticExample::GetSpringStiffness< BLOCKSET >::getStiffness
static MoFEMErrorCode getStiffness(double &normal_stiffness, double &tangent_stiffness, boost::shared_ptr< Range > &ents, MoFEM::Interface &m_field, int ms_id)
Definition: ElasticSpring.hpp:21
ElasticExample
Definition: CalculateTraction.hpp:10
ElasticExample::SpringBcType
Definition: ElasticSpring.hpp:14
OpFluxLhsImpl< ElasticExample::SpringBcType< BLOCKSET >, 1, FIELD_DIM, A, GAUSS, EleOp >::normalStiffness
double normalStiffness
Definition: ElasticSpring.hpp:87
MoFEM::GAUSS
@ GAUSS
Definition: FormsIntegrators.hpp:136
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
t_kd
constexpr auto t_kd
Definition: free_surface.cpp:137
EntData
EntitiesFieldData::EntData EntData
Definition: child_and_parent.cpp:37
field_name
constexpr auto field_name
Definition: poisson_2d_homogeneous.cpp:13
FTensor::Index< 'i', FIELD_DIM >
MoFEM::IntegrationType
IntegrationType
Form integrator integration types.
Definition: FormsIntegrators.hpp:136
MoFEM::OpBaseImpl::nbRowBaseFunctions
int nbRowBaseFunctions
number or row base functions
Definition: FormsIntegrators.hpp:239
MoFEM::OpBaseImpl::nbCols
int nbCols
number if dof on column
Definition: FormsIntegrators.hpp:237
MOFEM_TAG_AND_LOG
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
Definition: LogManager.hpp:362
MoFEM::OpBaseImpl::nbRows
int nbRows
number of dofs on rows
Definition: FormsIntegrators.hpp:236
MoFEM::AssemblyType
AssemblyType
[Storage and set boundary conditions]
Definition: FormsIntegrators.hpp:104
BLOCKSET
@ BLOCKSET
Definition: definitions.h:161
j
FTensor::Index< 'j', 3 > j
Definition: matrix_function.cpp:19
OpFluxLhsImpl< ElasticExample::SpringBcType< BLOCKSET >, 1, FIELD_DIM, A, GAUSS, EleOp >::tangentStiffness
double tangentStiffness
Definition: ElasticSpring.hpp:88
OpBaseImpl
MOFEM_DATA_INCONSISTENCY
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
OpFluxRhsImpl< ElasticExample::SpringBcType< BLOCKSET >, 1, FIELD_DIM, A, GAUSS, EleOp >::uPtr
boost::shared_ptr< MatrixDouble > uPtr
Definition: ElasticSpring.hpp:73
OpFluxRhsImpl< ElasticExample::SpringBcType< BLOCKSET >, 1, FIELD_DIM, A, GAUSS, EleOp >::normalStiffness
double normalStiffness
Definition: ElasticSpring.hpp:70
m
FTensor::Index< 'm', 3 > m
Definition: shallow_wave.cpp:80
OP
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:429
MOFEM_NOT_IMPLEMENTED
@ MOFEM_NOT_IMPLEMENTED
Definition: definitions.h:32
MoFEMFunctionBegin
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:359
CubitBC
CubitBC
Types of sets and boundary conditions.
Definition: definitions.h:157