v0.16.0
Loading...
Searching...
No Matches
HookeElement.hpp
Go to the documentation of this file.
1/**
2 * \file HookeElement.hpp
3 * \example mofem/users_modules/basic_finite_elements/src/HookeElement.hpp
4 *
5 * \brief Operators and data structures for linear elastic
6 * analysis
7 *
8 * Implemention of operators for Hooke material. Implementation is extended to
9 * the case when the mesh is moving as results of topological changes, also the
10 * calculation of material forces and associated tangent matrices are added to
11 * implementation.
12 *
13 * In other words, spatial deformation is small but topological changes large.
14 */
15
16
17
18#ifndef __HOOKE_ELEMENT_HPP
19#define __HOOKE_ELEMENT_HPP
20
21#ifndef __BASICFINITEELEMENTS_HPP__
23#endif // __BASICFINITEELEMENTS_HPP__
24
25#ifndef __NONLINEAR_ELASTIC_HPP
26
28
29 /** \brief data for calculation heat conductivity and heat capacity elements
30 * \ingroup nonlinear_elastic_elem
31 */
32 struct BlockData {
33 int iD;
34 double E;
36 Range tEts; ///< constrains elements in block set
39 };
40};
41
42#endif // __NONLINEAR_ELASTIC_HPP
43
44/** \brief structure grouping operators and data used for calculation of
45 * nonlinear elastic element \ingroup nonlinear_elastic_elem
46 *
47 * In order to assemble matrices and right hand vectors, the loops over
48 * elements, entities over that elements and finally loop over integration
49 * points are executed.
50 *
51 * Following implementation separate those three categories of loops and to each
52 * loop attach operator.
53 *
54 */
55
56#ifndef __CONVECTIVE_MASS_ELEMENT_HPP
58 /** \brief data for calculation inertia forces
59 * \ingroup user_modules
60 */
61 struct BlockData {
62 double rho0; ///< reference density
63 VectorDouble a0; ///< constant acceleration
64 Range tEts; ///< elements in block set
65 };
66}
67
68#endif //__CONVECTIVE_MASS_ELEMENT_HPP
69struct HookeElement {
70
73
75 using UserDataOperator = ForcesAndSourcesCore::UserDataOperator;
77 VolumeElementForcesAndSourcesCore::UserDataOperator;
78
80
81 boost::shared_ptr<MatrixDouble> smallStrainMat;
82 boost::shared_ptr<MatrixDouble> hMat;
83 boost::shared_ptr<MatrixDouble> FMat;
84
85 boost::shared_ptr<MatrixDouble> HMat;
86 boost::shared_ptr<VectorDouble> detHVec;
87 boost::shared_ptr<MatrixDouble> invHMat;
88
89 boost::shared_ptr<MatrixDouble> cauchyStressMat;
90 boost::shared_ptr<MatrixDouble> stiffnessMat;
91 boost::shared_ptr<VectorDouble> energyVec;
92 boost::shared_ptr<MatrixDouble> eshelbyStressMat;
93
94 boost::shared_ptr<MatrixDouble> eshelbyStress_dx;
95
97
98 smallStrainMat = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
99 hMat = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
100 FMat = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
101
102 HMat = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
103 detHVec = boost::shared_ptr<VectorDouble>(new VectorDouble());
104 invHMat = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
105
106 cauchyStressMat = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
107 stiffnessMat = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
108 energyVec = boost::shared_ptr<VectorDouble>(new VectorDouble());
109 eshelbyStressMat = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
110
111 eshelbyStress_dx = boost::shared_ptr<MatrixDouble>(new MatrixDouble());
112 }
113
116 };
117
118 template <bool D = false>
120
121 OpCalculateStrain(const std::string row_field, const std::string col_field,
122 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
123
124 MoFEMErrorCode doWork(int row_side, EntityType row_type, EntData &row_data);
125
126 private:
127 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
128 };
129
131
132 OpCalculateStrainAle(const std::string row_field,
133 const std::string col_field,
134 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
135
136 MoFEMErrorCode doWork(int row_side, EntityType row_type, EntData &row_data);
137
138 private:
139 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
140 };
141
142#define MAT_TO_DDG(SM) \
143 &(*SM)(0, 0), &(*SM)(1, 0), &(*SM)(2, 0), &(*SM)(3, 0), &(*SM)(4, 0), \
144 &(*SM)(5, 0), &(*SM)(6, 0), &(*SM)(7, 0), &(*SM)(8, 0), &(*SM)(9, 0), \
145 &(*SM)(10, 0), &(*SM)(11, 0), &(*SM)(12, 0), &(*SM)(13, 0), \
146 &(*SM)(14, 0), &(*SM)(15, 0), &(*SM)(16, 0), &(*SM)(17, 0), \
147 &(*SM)(18, 0), &(*SM)(19, 0), &(*SM)(20, 0), &(*SM)(21, 0), \
148 &(*SM)(22, 0), &(*SM)(23, 0), &(*SM)(24, 0), &(*SM)(25, 0), \
149 &(*SM)(26, 0), &(*SM)(27, 0), &(*SM)(28, 0), &(*SM)(29, 0), \
150 &(*SM)(30, 0), &(*SM)(31, 0), &(*SM)(32, 0), &(*SM)(33, 0), \
151 &(*SM)(34, 0), &(*SM)(35, 0)
152
153 template <int S = 0> struct OpCalculateStress : public VolUserDataOperator {
154
155 OpCalculateStress(const std::string row_field, const std::string col_field,
156 boost::shared_ptr<DataAtIntegrationPts> data_at_pts);
157
158 MoFEMErrorCode doWork(int row_side, EntityType row_type, EntData &row_data);
159
160 protected:
161 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
162 };
163
165
166 OpCalculateEnergy(const std::string row_field, const std::string col_field,
167 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
169
170 MoFEMErrorCode doWork(int row_side, EntityType row_type, EntData &row_data);
171
172 protected:
173 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
175 };
176
178
180 const std::string row_field, const std::string col_field,
181 boost::shared_ptr<DataAtIntegrationPts> data_at_pts);
182
183 MoFEMErrorCode doWork(int row_side, EntityType row_type, EntData &row_data);
184
185 protected:
186 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
187 };
188
189 template <int S = 0>
191
193 const std::string row_field, const std::string col_field,
194 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr,
195 boost::shared_ptr<DataAtIntegrationPts> data_at_pts);
196
197 MoFEMErrorCode doWork(int row_side, EntityType row_type, EntData &row_data);
198
199 protected:
200 boost::shared_ptr<map<int, BlockData>>
201 blockSetsPtr; ///< Structure keeping data about problem, like
202 ///< material parameters
203 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
204 };
205
206 /** * @brief Assemble mass matrix for elastic element TODO: CHANGE FORMULA *
207 * \f[
208 * {\bf{M}} = \int\limits_\Omega
209 * \f]
210 *
211 */
214
219
220 boost::shared_ptr<DataAtIntegrationPts> commonData;
221
222 OpCalculateMassMatrix(const std::string row_field,
223 const std::string col_field, BlockData &data,
224 MassBlockData &mass_data,
225 boost::shared_ptr<DataAtIntegrationPts> &common_data,
226 bool symm = true)
228 row_field, col_field, OPROWCOL, symm),
229 commonData(common_data), dAta(data), massData(mass_data) {}
230
231 PetscErrorCode doWork(int row_side, int col_side, EntityType row_type,
232 EntityType col_type,
234 EntitiesFieldData::EntData &col_data) {
236
237 auto get_tensor2 = [](MatrixDouble &m, const int r, const int c) {
239 &m(3 * r + 0, 3 * c + 0), &m(3 * r + 0, 3 * c + 1),
240 &m(3 * r + 0, 3 * c + 2), &m(3 * r + 1, 3 * c + 0),
241 &m(3 * r + 1, 3 * c + 1), &m(3 * r + 1, 3 * c + 2),
242 &m(3 * r + 2, 3 * c + 0), &m(3 * r + 2, 3 * c + 1),
243 &m(3 * r + 2, 3 * c + 2));
244 };
245
246 const int row_nb_dofs = row_data.getIndices().size();
247 if (!row_nb_dofs)
249 const int col_nb_dofs = col_data.getIndices().size();
250 if (!col_nb_dofs)
252 if (dAta.tEts.find(getFEEntityHandle()) == dAta.tEts.end()) {
254 }
255 if (massData.tEts.find(getFEEntityHandle()) == massData.tEts.end()) {
257 }
258
259 const bool diagonal_block =
260 (row_type == col_type) && (row_side == col_side);
261 // get number of integration points
262 // Set size can clear local tangent matrix
263 locK.resize(row_nb_dofs, col_nb_dofs, false);
264 locK.clear();
265
266 const int row_nb_gauss_pts = row_data.getN().size1();
267 const int row_nb_base_functions = row_data.getN().size2();
268
269 FTensor::Index<'i', 3> i;
270 FTensor::Index<'j', 3> j;
271 FTensor::Index<'k', 3> k;
272 FTensor::Index<'l', 3> l;
273
274 double density = massData.rho0;
275
276 // get integration weights
277 auto t_w = getFTensor0IntegrationWeight();
278
279 // integrate local matrix for entity block
280 for (int gg = 0; gg != row_nb_gauss_pts; gg++) {
281
282 auto t_row_base_func = row_data.getFTensor0N(gg, 0);
283
284 // Get volume and integration weight
285 double w = getVolume() * t_w;
286
287 for (int row_bb = 0; row_bb != row_nb_dofs / 3; row_bb++) {
288 auto t_col_base_func = col_data.getFTensor0N(gg, 0);
289 for (int col_bb = 0; col_bb != col_nb_dofs / 3; col_bb++) {
290 auto t_assemble = get_tensor2(locK, row_bb, col_bb);
291 t_assemble(i, j) += density * t_row_base_func * t_col_base_func * w;
292 // Next base function for column
293 ++t_col_base_func;
294 }
295 // Next base function for row
296 ++t_row_base_func;
297 }
298 // Next integration point for getting weight
299 ++t_w;
300 }
301
302 CHKERR MatSetValues(getKSPB(), row_data, col_data, &locK(0, 0),
303 ADD_VALUES);
304
305 // is symmetric
306 if (row_type != col_type || row_side != col_side) {
307 translocK.resize(col_nb_dofs, row_nb_dofs, false);
308 noalias(translocK) = trans(locK);
309
310 CHKERR MatSetValues(getKSPB(), col_data, row_data, &translocK(0, 0),
311 ADD_VALUES);
312 }
313
315 }
316 };
317
319 protected:
320 boost::shared_ptr<map<int, BlockData>>
321 blockSetsPtr; ///< Structure keeping data about problem, like
322 ///< material parameters
323 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
324
325 boost::shared_ptr<VectorDouble> rhoAtGaussPtsPtr;
326 const double rhoN; ///< exponent n in E(p) = E * (p / p_0)^n
327 const double rHo0; ///< p_0 reference density in E(p) = E * (p / p_0)^n
328 // // where p is density, E - youngs modulus
329 public:
331 const std::string row_field, const std::string col_field,
332 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr,
333 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
334 boost::shared_ptr<VectorDouble> rho_at_gauss_pts, const double rho_n,
335 const double rho_0);
336
337 MoFEMErrorCode doWork(int row_side, EntityType row_type, EntData &row_data);
338 };
339
341
342 OpAssemble(const std::string row_field, const std::string col_field,
343 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
344 const char type, bool symm = false);
345
346 /**
347 * \brief Do calculations for give operator
348 * @param row_side row side number (local number) of entity on element
349 * @param col_side column side number (local number) of entity on element
350 * @param row_type type of row entity MBVERTEX, MBEDGE, MBTRI or MBTET
351 * @param col_type type of column entity MBVERTEX, MBEDGE, MBTRI or MBTET
352 * @param row_data data for row
353 * @param col_data data for column
354 * @return error code
355 */
356 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
357 EntityType col_type, EntData &row_data,
358 EntData &col_data);
359
360 MoFEMErrorCode doWork(int row_side, EntityType row_type, EntData &row_data);
361
362 protected:
363 // Finite element stiffness sub-matrix K_ij
367
368 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
369
372
373 int nbRows; ///< number of dofs on rows
374 int nbCols; ///< number if dof on column
375 int nbIntegrationPts; ///< number of integration points
376 bool isDiag; ///< true if this block is on diagonal
377
378 virtual MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data);
379
380 virtual MoFEMErrorCode iNtegrate(EntData &row_data);
381
382 /**
383 * \brief Assemble local entity block matrix
384 * @param row_data row data (consist base functions on row entity)
385 * @param col_data column data (consist base functions on column
386 * entity)
387 * @return error code
388 */
389 MoFEMErrorCode aSsemble(EntData &row_data, EntData &col_data);
390
391 /**
392 * \brief Assemble local entity right-hand vector
393 * @param row_data row data (consist base functions on row entity)
394 * @param col_data column data (consist base functions on column
395 * entity)
396 * @return error code
397 */
398 MoFEMErrorCode aSsemble(EntData &row_data);
399 };
400
401 struct OpRhs_dx : public OpAssemble {
402
403 OpRhs_dx(const std::string row_field, const std::string col_field,
404 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
405
406 protected:
407 MoFEMErrorCode iNtegrate(EntData &row_data);
408 };
409
410 template <int S = 0> struct OpLhs_dx_dx : public OpAssemble {
411
412 OpLhs_dx_dx(const std::string row_field, const std::string col_field,
413 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
414
415 protected:
416 /**
417 * \brief Integrate B^T D B operator
418 * @param row_data row data (consist base functions on row entity)
419 * @param col_data column data (consist base functions on column entity)
420 * @return error code
421 */
422 MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data);
423 };
424
425 struct OpAleRhs_dx : public OpAssemble {
426
427 OpAleRhs_dx(const std::string row_field, const std::string col_field,
428 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
429
430 protected:
431 MoFEMErrorCode iNtegrate(EntData &row_data);
432 };
433
434 template <int S = 0> struct OpAleLhs_dx_dx : public OpAssemble {
435
436 OpAleLhs_dx_dx(const std::string row_field, const std::string col_field,
437 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
438
439 protected:
440 /**
441 * \brief Integrate B^T D B operator
442 * @param row_data row data (consist base functions on row entity)
443 * @param col_data column data (consist base functions on column entity)
444 * @return error code
445 */
446 MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data);
447 };
448
449 template <int S = 0> struct OpAleLhs_dx_dX : public OpAssemble {
450
451 OpAleLhs_dx_dX(const std::string row_field, const std::string col_field,
452 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
453
454 protected:
455 /**
456 * \brief Integrate tangent stiffness for spatial momentum
457 * @param row_data row data (consist base functions on row entity)
458 * @param col_data column data (consist base functions on column entity)
459 * @return error code
460 */
461 MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data);
462 };
463
465
466 boost::shared_ptr<VectorDouble> rhoAtGaussPtsPtr;
467 boost::shared_ptr<MatrixDouble> rhoGradAtGaussPtsPtr;
468 const double rhoN;
469 const double rHo0;
470
472 const std::string row_field, const std::string col_field,
473 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
474 boost::shared_ptr<VectorDouble> rho_at_gauss_pts,
475 boost::shared_ptr<MatrixDouble> rho_grad_at_gauss_pts,
476 const double rho_n, const double rho_0);
477
478 protected:
479 /**
480 * \brief Integrate tangent stiffness for spatial momentum
481 * @param row_data row data (consist base functions on row entity)
482 * @param col_data column data (consist base functions on column entity)
483 * @return error code
484 */
485 MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data);
486 };
487
489
490 boost::shared_ptr<VectorDouble> rhoAtGaussPtsPtr;
491 boost::shared_ptr<MatrixDouble> rhoGradAtGaussPtsPtr;
492 const double rhoN;
493 const double rHo0;
494
496 const std::string row_field, const std::string col_field,
497 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
498 boost::shared_ptr<VectorDouble> rho_at_gauss_pts,
499 boost::shared_ptr<MatrixDouble> rho_grad_at_gauss_pts,
500 const double rho_n, const double rho_0);
501
502 protected:
503 /**
504 * \brief Integrate tangent stiffness for material momentum
505 * @param row_data row data (consist base functions on row entity)
506 * @param col_data column data (consist base functions on column entity)
507 * @return error code
508 */
509 MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data);
510 };
511
512 struct OpAleRhs_dX : public OpAssemble {
513
514 OpAleRhs_dX(const std::string row_field, const std::string col_field,
515 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
516
517 protected:
518 MoFEMErrorCode iNtegrate(EntData &row_data);
519 };
520
521 template <int S = 0> struct OpAleLhs_dX_dX : public OpAssemble {
522
523 OpAleLhs_dX_dX(const std::string row_field, const std::string col_field,
524 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
525
526 protected:
527 /**
528 * \brief Integrate tangent stiffness for material momentum
529 * @param row_data row data (consist base functions on row entity)
530 * @param col_data column data (consist base functions on column entity)
531 * @return error code
532 */
533 MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data);
534 };
535
536 template <int S = 0> struct OpAleLhsPre_dX_dx : public VolUserDataOperator {
537
538 OpAleLhsPre_dX_dx(const std::string row_field, const std::string col_field,
539 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts);
540
541 MoFEMErrorCode doWork(int row_side, EntityType row_type, EntData &row_data);
542
543 private:
544 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
545 };
546
547 struct OpAleLhs_dX_dx : public OpAssemble {
548
549 OpAleLhs_dX_dx(const std::string row_field, const std::string col_field,
550 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
551 : OpAssemble(row_field, col_field, data_at_pts, OPROWCOL, false) {}
552
553 protected:
554 /**
555 * \brief Integrate tangent stiffness for material momentum
556 * @param row_data row data (consist base functions on row entity)
557 * @param col_data column data (consist base functions on column entity)
558 * @return error code
559 */
560 MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data);
561 };
562
563 template <int S> struct OpAnalyticalInternalStrain_dx : public OpAssemble {
564
565 typedef boost::function<
566
568
570
571 )
572
573 >
575
577 const std::string row_field,
578 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
579 StrainFunction strain_fun);
580
581 protected:
582 MoFEMErrorCode iNtegrate(EntData &row_data);
584 };
585
586 template <int S> struct OpAnalyticalInternalAleStrain_dX : public OpAssemble {
587
588 typedef boost::function<
589
591
593
594 )
595
596 >
598
600 const std::string row_field,
601 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
602 StrainFunction strain_fun,
603 boost::shared_ptr<MatrixDouble> mat_pos_at_pts_ptr);
604
605 protected:
606 MoFEMErrorCode iNtegrate(EntData &row_data);
608 boost::shared_ptr<MatrixDouble> matPosAtPtsPtr;
609 };
610
611 template <int S> struct OpAnalyticalInternalAleStrain_dx : public OpAssemble {
612
613 typedef boost::function<
614
616
618
619 )
620
621 >
623
625 const std::string row_field,
626 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
627 StrainFunction strain_fun,
628 boost::shared_ptr<MatrixDouble> mat_pos_at_pts_ptr);
629
630 protected:
631 MoFEMErrorCode iNtegrate(EntData &row_data);
633 boost::shared_ptr<MatrixDouble> matPosAtPtsPtr;
634 };
635
636 template <class ELEMENT>
637 struct OpPostProcHookeElement : public ELEMENT::UserDataOperator {
638 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
639 map<int, BlockData>
640 &blockSetsPtr; // FIXME: (works only with the first block)
641 moab::Interface &postProcMesh;
642 std::vector<EntityHandle> &mapGaussPts;
643 bool isALE;
645
646 OpPostProcHookeElement(const string row_field,
647 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
648 map<int, BlockData> &block_sets_ptr,
649 moab::Interface &post_proc_mesh,
650 std::vector<EntityHandle> &map_gauss_pts,
651 bool is_ale = false, bool is_field_disp = true);
652
653 MoFEMErrorCode doWork(int side, EntityType type,
655 };
656
657 static MoFEMErrorCode
659 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr);
660
661 static MoFEMErrorCode
663 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr,
664 const std::string element_name, const std::string x_field,
665 const std::string X_field, const bool ale);
666
667 static MoFEMErrorCode
668 setOperators(boost::shared_ptr<ForcesAndSourcesCore> fe_lhs_ptr,
669 boost::shared_ptr<ForcesAndSourcesCore> fe_rhs_ptr,
670 boost::shared_ptr<map<int, BlockData>> block_sets_ptr,
671 const std::string x_field, const std::string X_field,
672 const bool ale, const bool field_disp,
673 const EntityType type = MBTET,
674 boost::shared_ptr<DataAtIntegrationPts> data_at_pts = nullptr);
675
676 static MoFEMErrorCode
677 calculateEnergy(DM dm, boost::shared_ptr<map<int, BlockData>> block_sets_ptr,
678 const std::string x_field, const std::string X_field,
679 const bool ale, const bool field_disp,
680 SmartPetscObj<Vec> &v_energy_ptr);
681
682private:
684};
685
686template <bool D>
687HookeElement::OpCalculateStrain<D>::OpCalculateStrain(
688 const std::string row_field, const std::string col_field,
689 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
690 : VolUserDataOperator(row_field, col_field, OPROW, true),
691 dataAtPts(data_at_pts) {
692 std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE], false);
693}
694
695template <bool D>
696MoFEMErrorCode HookeElement::OpCalculateStrain<D>::doWork(int row_side,
697 EntityType row_type,
698 EntData &row_data) {
700 FTensor::Index<'i', 3> i;
701 FTensor::Index<'j', 3> j;
702 // get number of integration points
703 const int nb_integration_pts = getGaussPts().size2();
704 dataAtPts->smallStrainMat->resize(6, nb_integration_pts, false);
705 auto t_strain = getFTensor2SymmetricFromMat<3, -1, CoeffsByGauss>(
706 *(dataAtPts->smallStrainMat));
707 auto t_h =
708 getFTensor2FromMat<3, 3>(*(dataAtPts->hMat));
709
710 for (int gg = 0; gg != nb_integration_pts; ++gg) {
711 t_strain(i, j) = (t_h(i, j) || t_h(j, i)) / 2.;
712
713 // If displacement field, not field o spatial positons is given
714 if (!D) {
715 t_strain(0, 0) -= 1;
716 t_strain(1, 1) -= 1;
717 t_strain(2, 2) -= 1;
718 }
719
720 ++t_strain;
721 ++t_h;
722 }
724}
725
726template <int S>
727HookeElement::OpAleLhs_dx_dx<S>::OpAleLhs_dx_dx(
728 const std::string row_field, const std::string col_field,
729 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
730 : OpAssemble(row_field, col_field, data_at_pts, OPROWCOL, true) {}
731
732template <int S>
733MoFEMErrorCode HookeElement::OpAleLhs_dx_dx<S>::iNtegrate(EntData &row_data,
734 EntData &col_data) {
736
737 // get sub-block (3x3) of local stiffens matrix, here represented by
738 // second order tensor
739 auto get_tensor2 = [](MatrixDouble &m, const int r, const int c) {
741 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 1, c + 0),
742 &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 2, c + 0), &m(r + 2, c + 1),
743 &m(r + 2, c + 2));
744 };
745
746 FTensor::Index<'i', 3> i;
747 FTensor::Index<'j', 3> j;
748 FTensor::Index<'k', 3> k;
749 FTensor::Index<'l', 3> l;
750
751 // get element volume
752 double vol = getVolume();
753
754 // get intergrayion weights
755 auto t_w = getFTensor0IntegrationWeight();
756
757 // get derivatives of base functions on rows
758 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
759 const int row_nb_base_fun = row_data.getN().size2();
760
761 // Elastic stiffness tensor (4th rank tensor with minor and major
762 // symmetry)
764 MAT_TO_DDG(dataAtPts->stiffnessMat));
765
766 auto t_invH =
767 getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->invHMat);
768 auto &det_H = *dataAtPts->detHVec;
769
770 // iterate over integration points
771 for (int gg = 0; gg != nbIntegrationPts; ++gg) {
772
773 // calculate scalar weight times element volume
774 double a = t_w * vol * det_H[gg];
775
776 // iterate over row base functions
777 int rr = 0;
778 for (; rr != nbRows / 3; ++rr) {
779
780 // get sub matrix for the row
781 auto t_m = get_tensor2(K, 3 * rr, 0);
782
783 FTensor::Tensor1<double, 3> t_row_diff_base_pulled;
784 t_row_diff_base_pulled(i) = t_row_diff_base(j) * t_invH(j, i);
785
787 // I mix up the indices here so that it behaves like a
788 // Dg. That way I don't have to have a separate wrapper
789 // class Christof_Expr, which simplifies things.
790 t_rowD(l, j, k) = t_D(i, j, k, l) * (a * t_row_diff_base_pulled(i));
791
792 // get derivatives of base functions for columns
793 auto t_col_diff_base = col_data.getFTensor1DiffN<3>(gg, 0);
794
795 // iterate column base functions
796 for (int cc = 0; cc != nbCols / 3; ++cc) {
797
798 FTensor::Tensor1<double, 3> t_col_diff_base_pulled;
799 t_col_diff_base_pulled(j) = t_col_diff_base(i) * t_invH(i, j);
800
801 // integrate block local stiffens matrix
802 t_m(i, j) += t_rowD(i, j, k) * t_col_diff_base_pulled(k);
803
804 // move to next column base function
805 ++t_col_diff_base;
806
807 // move to next block of local stiffens matrix
808 ++t_m;
809 }
810
811 // move to next row base function
812 ++t_row_diff_base;
813 }
814
815 for (; rr != row_nb_base_fun; ++rr)
816 ++t_row_diff_base;
817
818 // move to next integration weight
819 ++t_w;
820 ++t_D;
821 ++t_invH;
822 }
823
825}
826
827template <int S>
828HookeElement::OpCalculateHomogeneousStiffness<S>::
829 OpCalculateHomogeneousStiffness(
830 const std::string row_field, const std::string col_field,
831 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr,
832 boost::shared_ptr<DataAtIntegrationPts> data_at_pts)
833 : VolUserDataOperator(row_field, col_field, OPROW, true),
834 blockSetsPtr(block_sets_ptr), dataAtPts(data_at_pts) {
835 std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE], false);
836}
837
838template <int S>
839MoFEMErrorCode HookeElement::OpCalculateHomogeneousStiffness<S>::doWork(
840 int row_side, EntityType row_type, EntData &row_data) {
842
843 for (auto &m : (*blockSetsPtr)) {
844 if (m.second.tEts.find(getFEEntityHandle()) != m.second.tEts.end()) {
845
846 dataAtPts->stiffnessMat->resize(36, 1, false);
848 MAT_TO_DDG(dataAtPts->stiffnessMat));
849 const double young = m.second.E;
850 const double poisson = m.second.PoissonRatio;
851
852 // coefficient used in intermediate calculation
853 const double coefficient = young / ((1 + poisson) * (1 - 2 * poisson));
854
855 FTensor::Index<'i', 3> i;
856 FTensor::Index<'j', 3> j;
857 FTensor::Index<'k', 3> k;
858 FTensor::Index<'l', 3> l;
859
860 t_D(i, j, k, l) = 0.;
861
862 t_D(0, 0, 0, 0) = 1 - poisson;
863 t_D(1, 1, 1, 1) = 1 - poisson;
864 t_D(2, 2, 2, 2) = 1 - poisson;
865
866 t_D(0, 1, 0, 1) = 0.5 * (1 - 2 * poisson);
867 t_D(0, 2, 0, 2) = 0.5 * (1 - 2 * poisson);
868 t_D(1, 2, 1, 2) = 0.5 * (1 - 2 * poisson);
869
870 t_D(0, 0, 1, 1) = poisson;
871 t_D(1, 1, 0, 0) = poisson;
872 t_D(0, 0, 2, 2) = poisson;
873 t_D(2, 2, 0, 0) = poisson;
874 t_D(1, 1, 2, 2) = poisson;
875 t_D(2, 2, 1, 1) = poisson;
876
877 t_D(i, j, k, l) *= coefficient;
878
879 break;
880 }
881 }
882
884}
885
886template <int S>
887HookeElement::OpCalculateStress<S>::OpCalculateStress(
888 const std::string row_field, const std::string col_field,
889 boost::shared_ptr<DataAtIntegrationPts> data_at_pts)
890 : VolUserDataOperator(row_field, col_field, OPROW, true),
891 dataAtPts(data_at_pts) {
892 std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE], false);
893}
894
895template <int S>
896MoFEMErrorCode HookeElement::OpCalculateStress<S>::doWork(int row_side,
897 EntityType row_type,
898 EntData &row_data) {
900 // get number of integration points
901 const int nb_integration_pts = getGaussPts().size2();
902 auto t_strain = getFTensor2SymmetricFromMat<3, -1, CoeffsByGauss>(
903 *(dataAtPts->smallStrainMat));
904 dataAtPts->cauchyStressMat->resize(6, nb_integration_pts, false);
905 auto t_cauchy_stress =
907 *(dataAtPts->cauchyStressMat));
908
909 FTensor::Index<'i', 3> i;
910 FTensor::Index<'j', 3> j;
911 FTensor::Index<'k', 3> k;
912 FTensor::Index<'l', 3> l;
913
914 // elastic stiffness tensor (4th rank tensor with minor and major
915 // symmetry)
917 MAT_TO_DDG(dataAtPts->stiffnessMat));
918 for (int gg = 0; gg != nb_integration_pts; ++gg) {
919 t_cauchy_stress(i, j) = t_D(i, j, k, l) * t_strain(k, l);
920 ++t_strain;
921 ++t_cauchy_stress;
922 ++t_D;
923 }
925}
926
927template <int S>
928HookeElement::OpLhs_dx_dx<S>::OpLhs_dx_dx(
929 const std::string row_field, const std::string col_field,
930 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
931 : OpAssemble(row_field, col_field, data_at_pts, OPROWCOL, true) {}
932
933template <int S>
934MoFEMErrorCode HookeElement::OpLhs_dx_dx<S>::iNtegrate(EntData &row_data,
935 EntData &col_data) {
937
938 // get sub-block (3x3) of local stiffens matrix, here represented by
939 // second order tensor
940 auto get_tensor2 = [](MatrixDouble &m, const int r, const int c) {
942 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 1, c + 0),
943 &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 2, c + 0), &m(r + 2, c + 1),
944 &m(r + 2, c + 2));
945 };
946
947 FTensor::Index<'i', 3> i;
948 FTensor::Index<'j', 3> j;
949 FTensor::Index<'k', 3> k;
950 FTensor::Index<'l', 3> l;
951
952 // get element volume
953 double vol = getVolume();
954
955 // get intergrayion weights
956 auto t_w = getFTensor0IntegrationWeight();
957
958 // get derivatives of base functions on rows
959 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
960 const int row_nb_base_fun = row_data.getN().size2();
961
962 // Elastic stiffness tensor (4th rank tensor with minor and major
963 // symmetry)
965 MAT_TO_DDG(dataAtPts->stiffnessMat));
966
967 // iterate over integration points
968 for (int gg = 0; gg != nbIntegrationPts; ++gg) {
969
970 // calculate scalar weight times element volume
971 double a = t_w * vol;
972
973 // iterate over row base functions
974 int rr = 0;
975 for (; rr != nbRows / 3; ++rr) {
976
977 // get sub matrix for the row
978 auto t_m = get_tensor2(K, 3 * rr, 0);
979
980 // get derivatives of base functions for columns
981 auto t_col_diff_base = col_data.getFTensor1DiffN<3>(gg, 0);
982
984 // I mix up the indices here so that it behaves like a
985 // Dg. That way I don't have to have a separate wrapper
986 // class Christof_Expr, which simplifies things.
987 t_rowD(l, j, k) = t_D(i, j, k, l) * (a * t_row_diff_base(i));
988
989 // iterate column base functions
990 for (int cc = 0; cc != nbCols / 3; ++cc) {
991
992 // integrate block local stiffens matrix
993 t_m(i, j) += t_rowD(i, j, k) * t_col_diff_base(k);
994
995 // move to next column base function
996 ++t_col_diff_base;
997
998 // move to next block of local stiffens matrix
999 ++t_m;
1000 }
1001
1002 // move to next row base function
1003 ++t_row_diff_base;
1004 }
1005
1006 for (; rr != row_nb_base_fun; ++rr)
1007 ++t_row_diff_base;
1008
1009 // move to next integration weight
1010 ++t_w;
1011 ++t_D;
1012 }
1013
1015}
1016
1017template <int S>
1018HookeElement::OpAleLhs_dx_dX<S>::OpAleLhs_dx_dX(
1019 const std::string row_field, const std::string col_field,
1020 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
1021 : OpAssemble(row_field, col_field, data_at_pts, OPROWCOL, false) {}
1022
1023template <int S>
1024MoFEMErrorCode HookeElement::OpAleLhs_dx_dX<S>::iNtegrate(EntData &row_data,
1025 EntData &col_data) {
1027
1028 // get sub-block (3x3) of local stiffens matrix, here represented by
1029 // second order tensor
1030 auto get_tensor2 = [](MatrixDouble &m, const int r, const int c) {
1032 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 1, c + 0),
1033 &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 2, c + 0), &m(r + 2, c + 1),
1034 &m(r + 2, c + 2));
1035 };
1036
1037 FTensor::Index<'i', 3> i;
1038 FTensor::Index<'j', 3> j;
1039 FTensor::Index<'k', 3> k;
1040 FTensor::Index<'l', 3> l;
1041 FTensor::Index<'m', 3> m;
1042 FTensor::Index<'n', 3> n;
1043
1044 // get element volume
1045 double vol = getVolume();
1046
1047 // get intergrayion weights
1048 auto t_w = getFTensor0IntegrationWeight();
1049
1050 // get derivatives of base functions on rows
1051 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
1052 const int row_nb_base_fun = row_data.getN().size2();
1053
1054 // Elastic stiffness tensor (4th rank tensor with minor and major
1055 // symmetry)
1057 MAT_TO_DDG(dataAtPts->stiffnessMat));
1058
1059 auto t_cauchy_stress =
1061 *(dataAtPts->cauchyStressMat));
1062 auto t_h = getFTensor2FromMat<3, 3>(*dataAtPts->hMat);
1063 auto t_invH =
1064 getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->invHMat);
1065 auto &det_H = *dataAtPts->detHVec;
1066
1067 // iterate over integration points
1068 for (int gg = 0; gg != nbIntegrationPts; ++gg) {
1069
1070 // calculate scalar weight times element volume
1071 double a = t_w * vol * det_H[gg];
1072
1074 t_F_dX(i, j, k, l) = -(t_h(i, m) * t_invH(m, k)) * t_invH(l, j);
1075
1076 // iterate over row base functions
1077 int rr = 0;
1078 for (; rr != nbRows / 3; ++rr) {
1079
1080 // get sub matrix for the row
1081 auto t_m = get_tensor2(K, 3 * rr, 0);
1082
1083 FTensor::Tensor1<double, 3> t_row_diff_base_pulled;
1084 t_row_diff_base_pulled(i) = t_row_diff_base(j) * t_invH(j, i);
1085
1086 FTensor::Tensor1<double, 3> t_row_stress;
1087 t_row_stress(i) = a * t_row_diff_base_pulled(j) * t_cauchy_stress(i, j);
1088
1089 FTensor::Tensor3<double, 3, 3, 3> t_row_diff_base_pulled_dX;
1090 t_row_diff_base_pulled_dX(j, k, l) =
1091 -(t_invH(i, k) * t_row_diff_base(i)) * t_invH(l, j);
1092
1093 FTensor::Tensor3<double, 3, 3, 3> t_row_dX_stress;
1094 t_row_dX_stress(i, k, l) =
1095 a * (t_row_diff_base_pulled_dX(j, k, l) * t_cauchy_stress(j, i));
1096
1098 t_row_D(l, j, k) = (a * t_row_diff_base_pulled(i)) * t_D(i, j, k, l);
1099
1100 FTensor::Tensor3<double, 3, 3, 3> t_row_stress_dX;
1101 // FIXME: This operator is not implemented, doing operation by hand
1102 // t_row_stress_dX(i, m, n) = t_row_D(i, k, l) * t_F_dX(k, l, m, n);
1103 t_row_stress_dX(i, j, k) = 0;
1104 for (int ii = 0; ii != 3; ++ii)
1105 for (int mm = 0; mm != 3; ++mm)
1106 for (int nn = 0; nn != 3; ++nn) {
1107 auto &v = t_row_stress_dX(ii, mm, nn);
1108 for (int kk = 0; kk != 3; ++kk)
1109 for (int ll = 0; ll != 3; ++ll)
1110 v += t_row_D(ii, kk, ll) * t_F_dX(kk, ll, mm, nn);
1111 }
1112
1113 // get derivatives of base functions for columns
1114 auto t_col_diff_base = col_data.getFTensor1DiffN<3>(gg, 0);
1115
1116 // iterate column base functions
1117 for (int cc = 0; cc != nbCols / 3; ++cc) {
1118
1119 t_m(i, k) += t_row_stress(i) * (t_invH(j, k) * t_col_diff_base(j));
1120 t_m(i, k) += t_row_dX_stress(i, k, l) * t_col_diff_base(l);
1121 t_m(i, k) += t_row_stress_dX(i, k, l) * t_col_diff_base(l);
1122
1123 // move to next column base function
1124 ++t_col_diff_base;
1125
1126 // move to next block of local stiffens matrix
1127 ++t_m;
1128 }
1129
1130 // move to next row base function
1131 ++t_row_diff_base;
1132 }
1133
1134 for (; rr != row_nb_base_fun; ++rr)
1135 ++t_row_diff_base;
1136
1137 // move to next integration weight
1138 ++t_w;
1139 ++t_D;
1140 ++t_cauchy_stress;
1141 ++t_invH;
1142 ++t_h;
1143 }
1144
1146}
1147
1148template <int S>
1149HookeElement::OpAleLhs_dX_dX<S>::OpAleLhs_dX_dX(
1150 const std::string row_field, const std::string col_field,
1151 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
1152 : OpAssemble(row_field, col_field, data_at_pts, OPROWCOL, true) {}
1153
1154template <int S>
1155MoFEMErrorCode HookeElement::OpAleLhs_dX_dX<S>::iNtegrate(EntData &row_data,
1156 EntData &col_data) {
1158
1159 // get sub-block (3x3) of local stiffens matrix, here represented by
1160 // second order tensor
1161 auto get_tensor2 = [](MatrixDouble &m, const int r, const int c) {
1163 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 1, c + 0),
1164 &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 2, c + 0), &m(r + 2, c + 1),
1165 &m(r + 2, c + 2));
1166 };
1167
1168 FTensor::Index<'i', 3> i;
1169 FTensor::Index<'j', 3> j;
1170 FTensor::Index<'k', 3> k;
1171 FTensor::Index<'l', 3> l;
1172 FTensor::Index<'m', 3> m;
1173 FTensor::Index<'n', 3> n;
1174
1175 // get element volume
1176 double vol = getVolume();
1177
1178 // get intergrayion weights
1179 auto t_w = getFTensor0IntegrationWeight();
1180
1181 // get derivatives of base functions on rows
1182 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
1183 const int row_nb_base_fun = row_data.getN().size2();
1184
1185 // Elastic stiffness tensor (4th rank tensor with minor and major
1186 // symmetry)
1188 MAT_TO_DDG(dataAtPts->stiffnessMat));
1189 auto t_cauchy_stress =
1191 *(dataAtPts->cauchyStressMat));
1192 auto t_strain = getFTensor2SymmetricFromMat<3, -1, CoeffsByGauss>(
1193 *(dataAtPts->smallStrainMat));
1194 auto t_eshelby_stress =
1196 *dataAtPts->eshelbyStressMat);
1197 auto t_h = getFTensor2FromMat<3, 3>(*dataAtPts->hMat);
1198 auto t_invH =
1199 getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->invHMat);
1200 auto t_F = getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->FMat);
1201 auto &det_H = *dataAtPts->detHVec;
1202
1203 // iterate over integration points
1204 for (int gg = 0; gg != nbIntegrationPts; ++gg) {
1205
1206 // calculate scalar weight times element volume
1207 double a = t_w * vol * det_H[gg];
1208
1210 t_F_dX(i, j, k, l) = -(t_h(i, m) * t_invH(m, k)) * t_invH(l, j);
1211
1213 t_D_strain_dX(i, j, m, n) = 0.;
1214 for (int ii = 0; ii != 3; ++ii)
1215 for (int jj = 0; jj != 3; ++jj)
1216 for (int ll = 0; ll != 3; ++ll)
1217 for (int kk = 0; kk != 3; ++kk) {
1218 auto &v = t_D_strain_dX(ii, jj, kk, ll);
1219 for (int mm = 0; mm != 3; ++mm)
1220 for (int nn = 0; nn != 3; ++nn)
1221 v += t_D(ii, jj, mm, nn) * t_F_dX(mm, nn, kk, ll);
1222 }
1223
1224 FTensor::Tensor4<double, 3, 3, 3, 3> t_eshelby_stress_dX;
1225 t_eshelby_stress_dX(i, j, m, n) = t_F(k, i) * t_D_strain_dX(k, j, m, n);
1226
1227 for (int ii = 0; ii != 3; ++ii)
1228 for (int jj = 0; jj != 3; ++jj)
1229 for (int mm = 0; mm != 3; ++mm)
1230 for (int nn = 0; nn != 3; ++nn) {
1231 auto &v = t_eshelby_stress_dX(ii, jj, mm, nn);
1232 for (int kk = 0; kk != 3; ++kk)
1233 v += t_F_dX(kk, ii, mm, nn) * t_cauchy_stress(kk, jj);
1234 }
1235
1236 t_eshelby_stress_dX(i, j, k, l) *= -1;
1237
1239 t_energy_dX(k, l) = t_F_dX(i, j, k, l) * t_cauchy_stress(i, j);
1240 t_energy_dX(k, l) +=
1241 (t_strain(m, n) * t_D(m, n, i, j)) * t_F_dX(i, j, k, l);
1242 t_energy_dX(k, l) /= 2.;
1243
1244 for (int kk = 0; kk != 3; ++kk)
1245 for (int ll = 0; ll != 3; ++ll) {
1246 auto v = t_energy_dX(kk, ll);
1247 for (int ii = 0; ii != 3; ++ii)
1248 t_eshelby_stress_dX(ii, ii, kk, ll) += v;
1249 }
1250
1251 // iterate over row base functions
1252 int rr = 0;
1253 for (; rr != nbRows / 3; ++rr) {
1254
1255 // get sub matrix for the row
1256 auto t_m = get_tensor2(K, 3 * rr, 0);
1257
1258 FTensor::Tensor1<double, 3> t_row_diff_base_pulled;
1259 t_row_diff_base_pulled(i) = t_row_diff_base(j) * t_invH(j, i);
1260
1261 FTensor::Tensor1<double, 3> t_row_stress;
1262 t_row_stress(i) = a * t_row_diff_base_pulled(j) * t_eshelby_stress(i, j);
1263
1264 FTensor::Tensor3<double, 3, 3, 3> t_row_diff_base_pulled_dX;
1265 t_row_diff_base_pulled_dX(j, k, l) =
1266 -(t_row_diff_base(i) * t_invH(i, k)) * t_invH(l, j);
1267
1268 FTensor::Tensor3<double, 3, 3, 3> t_row_dX_stress;
1269 t_row_dX_stress(i, k, l) =
1270 a * (t_row_diff_base_pulled_dX(j, k, l) * t_eshelby_stress(i, j));
1271
1272 FTensor::Tensor3<double, 3, 3, 3> t_row_stress_dX;
1273 t_row_stress_dX(i, m, n) =
1274 a * t_row_diff_base_pulled(j) * t_eshelby_stress_dX(i, j, m, n);
1275
1276 // get derivatives of base functions for columns
1277 auto t_col_diff_base = col_data.getFTensor1DiffN<3>(gg, 0);
1278
1279 // iterate column base functions
1280 for (int cc = 0; cc != nbCols / 3; ++cc) {
1281
1282 t_m(i, k) += t_row_stress(i) * (t_invH(j, k) * t_col_diff_base(j));
1283 t_m(i, k) += t_row_dX_stress(i, k, l) * t_col_diff_base(l);
1284 t_m(i, k) += t_row_stress_dX(i, k, l) * t_col_diff_base(l);
1285
1286 // move to next column base function
1287 ++t_col_diff_base;
1288
1289 // move to next block of local stiffens matrix
1290 ++t_m;
1291 }
1292
1293 // move to next row base function
1294 ++t_row_diff_base;
1295 }
1296
1297 for (; rr != row_nb_base_fun; ++rr)
1298 ++t_row_diff_base;
1299
1300 // move to next integration weight
1301 ++t_w;
1302 ++t_D;
1303 ++t_cauchy_stress;
1304 ++t_strain;
1305 ++t_eshelby_stress;
1306 ++t_h;
1307 ++t_invH;
1308 ++t_F;
1309 }
1310
1312}
1313
1314template <int S>
1315HookeElement::OpAleLhsPre_dX_dx<S>::OpAleLhsPre_dX_dx(
1316 const std::string row_field, const std::string col_field,
1317 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
1318 : VolUserDataOperator(row_field, col_field, OPROW, true),
1319 dataAtPts(data_at_pts) {
1320 std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE], false);
1321}
1322
1323template <int S>
1324MoFEMErrorCode HookeElement::OpAleLhsPre_dX_dx<S>::doWork(int row_side,
1325 EntityType row_type,
1326 EntData &row_data) {
1328
1329 const int nb_integration_pts = row_data.getN().size1();
1330
1331 auto get_eshelby_stress_dx = [this, nb_integration_pts]() {
1333 t_eshelby_stress_dx;
1334 dataAtPts->eshelbyStress_dx->resize(81, nb_integration_pts, false);
1335 int mm = 0;
1336 for (int ii = 0; ii != 3; ++ii)
1337 for (int jj = 0; jj != 3; ++jj)
1338 for (int kk = 0; kk != 3; ++kk)
1339 for (int ll = 0; ll != 3; ++ll)
1340 t_eshelby_stress_dx.ptr(ii, jj, kk, ll) =
1341 &(*dataAtPts->eshelbyStress_dx)(mm++, 0);
1342 return t_eshelby_stress_dx;
1343 };
1344
1345 auto t_eshelby_stress_dx = get_eshelby_stress_dx();
1346
1347 FTensor::Index<'i', 3> i;
1348 FTensor::Index<'j', 3> j;
1349 FTensor::Index<'k', 3> k;
1350 FTensor::Index<'l', 3> l;
1351 FTensor::Index<'m', 3> m;
1352 FTensor::Index<'n', 3> n;
1353
1354 // Elastic stiffness tensor (4th rank tensor with minor and major
1355 // symmetry)
1357 MAT_TO_DDG(dataAtPts->stiffnessMat));
1358 auto t_cauchy_stress =
1360 *(dataAtPts->cauchyStressMat));
1361 auto t_invH =
1362 getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->invHMat);
1363 auto t_F = getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->FMat);
1364
1365 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1366
1367 t_eshelby_stress_dx(i, j, m, n) =
1368 (t_F(k, i) * t_D(k, j, m, l)) * t_invH(n, l);
1369 for (int ii = 0; ii != 3; ++ii)
1370 for (int jj = 0; jj != 3; ++jj)
1371 for (int mm = 0; mm != 3; ++mm)
1372 for (int nn = 0; nn != 3; ++nn) {
1373 auto &v = t_eshelby_stress_dx(ii, jj, mm, nn);
1374 v += t_invH(nn, ii) * t_cauchy_stress(mm, jj);
1375 }
1376 t_eshelby_stress_dx(i, j, k, l) *= -1;
1377
1379 t_energy_dx(m, n) = t_invH(n, j) * t_cauchy_stress(m, j);
1380
1381 for (int mm = 0; mm != 3; ++mm)
1382 for (int nn = 0; nn != 3; ++nn) {
1383 auto v = t_energy_dx(mm, nn);
1384 for (int ii = 0; ii != 3; ++ii)
1385 t_eshelby_stress_dx(ii, ii, mm, nn) += v;
1386 }
1387
1388 ++t_D;
1389 ++t_invH;
1390 ++t_cauchy_stress;
1391 ++t_eshelby_stress_dx;
1392 ++t_F;
1393 }
1394
1396}
1397
1398template <class ELEMENT>
1399HookeElement::OpPostProcHookeElement<ELEMENT>::OpPostProcHookeElement(
1400 const string row_field, boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
1401 map<int, BlockData> &block_sets_ptr, moab::Interface &post_proc_mesh,
1402 std::vector<EntityHandle> &map_gauss_pts, bool is_ale, bool is_field_disp)
1403 : ELEMENT::UserDataOperator(row_field, UserDataOperator::OPROW),
1404 dataAtPts(data_at_pts), blockSetsPtr(block_sets_ptr),
1405 postProcMesh(post_proc_mesh), mapGaussPts(map_gauss_pts), isALE(is_ale),
1406 isFieldDisp(is_field_disp) {}
1407
1408template <class ELEMENT>
1409MoFEMErrorCode HookeElement::OpPostProcHookeElement<ELEMENT>::doWork(
1410 int side, EntityType type, EntitiesFieldData::EntData &data) {
1412
1413 if (type != MBVERTEX) {
1415 }
1416
1417 auto tensor_to_tensor = [](const auto &t1, auto &t2) {
1418 t2(0, 0) = t1(0, 0);
1419 t2(1, 1) = t1(1, 1);
1420 t2(2, 2) = t1(2, 2);
1421 t2(0, 1) = t2(1, 0) = t1(1, 0);
1422 t2(0, 2) = t2(2, 0) = t1(2, 0);
1423 t2(1, 2) = t2(2, 1) = t1(2, 1);
1424 };
1425
1426 std::array<double, 9> def_val;
1427 def_val.fill(0);
1428
1429 auto make_tag = [&](auto name, auto size) {
1430 Tag th;
1431 CHKERR postProcMesh.tag_get_handle(name, size, MB_TYPE_DOUBLE, th,
1432 MB_TAG_CREAT | MB_TAG_SPARSE,
1433 def_val.data());
1434 return th;
1435 };
1436
1437 auto th_stress = make_tag("STRESS", 9);
1438 auto th_psi = make_tag("ENERGY", 1);
1439
1440 const int nb_integration_pts = mapGaussPts.size();
1441
1442 FTensor::Index<'i', 3> i;
1443 FTensor::Index<'j', 3> j;
1444 FTensor::Index<'k', 3> k;
1445 FTensor::Index<'l', 3> l;
1446
1447 auto t_h = getFTensor2FromMat<3, 3>(*dataAtPts->hMat);
1448 auto t_H = getFTensor2FromMat<3, 3>(*dataAtPts->HMat);
1449
1450 dataAtPts->stiffnessMat->resize(36, 1, false);
1452 MAT_TO_DDG(dataAtPts->stiffnessMat));
1453
1454 EntityHandle ent = this->getFEEntityHandle();
1455 auto type = type_from_handle(ent);
1456 EntityHandle ent_3d = ent;
1457 if (type == MBTRI || type == MBQUAD) {
1458 Range ents;
1459 auto &m_field = this->getPtrFE()->mField;
1460 CHKERR m_field.get_moab().get_adjacencies(&ent, 1, 3, false, ents,
1461 moab::Interface::UNION);
1462#ifndef NDEBUG
1463 if (ents.empty())
1464 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1465 "Could not find a 3D element adjacent to a given face element");
1466#endif
1467 ent_3d = ents.front();
1468 }
1469
1470 bool found_block = false;
1471 int block_id = -1;
1472 for (auto &m : (blockSetsPtr)) {
1473 if (m.second.tEts.find(ent_3d) != m.second.tEts.end()) {
1474 const double young = m.second.E;
1475 const double poisson = m.second.PoissonRatio;
1476 const double coefficient = young / ((1 + poisson) * (1 - 2 * poisson));
1477 block_id = m.second.iD;
1478
1479 t_D(i, j, k, l) = 0.;
1480 t_D(0, 0, 0, 0) = t_D(1, 1, 1, 1) = t_D(2, 2, 2, 2) = 1 - poisson;
1481 t_D(0, 1, 0, 1) = t_D(0, 2, 0, 2) = t_D(1, 2, 1, 2) =
1482 0.5 * (1 - 2 * poisson);
1483 t_D(0, 0, 1, 1) = t_D(1, 1, 0, 0) = t_D(0, 0, 2, 2) = t_D(2, 2, 0, 0) =
1484 t_D(1, 1, 2, 2) = t_D(2, 2, 1, 1) = poisson;
1485 t_D(i, j, k, l) *= coefficient;
1486
1487 found_block = true;
1488 break;
1489 }
1490 }
1491 if (!found_block)
1492 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1493 "Element not found in any of material blocksets");
1494
1495 int def_val_int = 0;
1496 Tag tag_mat;
1497 CHKERR postProcMesh.tag_get_handle("MAT_ELASTIC", 1, MB_TYPE_INTEGER, tag_mat,
1498 MB_TAG_CREAT | MB_TAG_SPARSE, &def_val_int);
1499 double detH = 0.;
1503 FTensor::Tensor2<double, 3, 3> t_small_strain;
1505 FTensor::Tensor2_symmetric<double, 3> t_small_strain_symm;
1506
1507 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1508
1509 if (isFieldDisp) {
1510 t_h(0, 0) += 1;
1511 t_h(1, 1) += 1;
1512 t_h(2, 2) += 1;
1513 }
1514
1515 if (!isALE) {
1516 t_small_strain_symm(i, j) = (t_h(i, j) || t_h(j, i)) / 2.;
1517 } else {
1518 CHKERR determinantTensor3by3(t_H, detH);
1519 CHKERR invertTensor3by3(t_H, detH, t_invH);
1520 t_F(i, j) = t_h(i, k) * t_invH(k, j);
1521 t_small_strain_symm(i, j) = (t_F(i, j) || t_F(j, i)) / 2.;
1522 ++t_H;
1523 }
1524
1525 t_small_strain_symm(0, 0) -= 1;
1526 t_small_strain_symm(1, 1) -= 1;
1527 t_small_strain_symm(2, 2) -= 1;
1528
1529 // symmetric tensors need improvement
1530 t_stress_symm(i, j) = t_D(i, j, k, l) * t_small_strain_symm(k, l);
1531 tensor_to_tensor(t_stress_symm, t_stress);
1532
1533 const double psi = 0.5 * t_stress_symm(i, j) * t_small_strain_symm(i, j);
1534
1535 CHKERR postProcMesh.tag_set_data(th_psi, &mapGaussPts[gg], 1, &psi);
1536 CHKERR postProcMesh.tag_set_data(th_stress, &mapGaussPts[gg], 1,
1537 &t_stress(0, 0));
1538 CHKERR postProcMesh.tag_set_data(tag_mat, &mapGaussPts[gg], 1,
1539 &block_id);
1540
1541 ++t_h;
1542 }
1543
1545}
1546
1547template <int S>
1548HookeElement::OpAnalyticalInternalStrain_dx<S>::OpAnalyticalInternalStrain_dx(
1549 const std::string row_field,
1550 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
1551 StrainFunction strain_fun)
1552 : OpAssemble(row_field, row_field, data_at_pts, OPROW, true),
1553 strainFun(strain_fun) {}
1554
1555template <int S>
1557HookeElement::OpAnalyticalInternalStrain_dx<S>::iNtegrate(EntData &row_data) {
1558 FTensor::Index<'i', 3> i;
1559 FTensor::Index<'j', 3> j;
1560 FTensor::Index<'k', 3> k;
1561 FTensor::Index<'l', 3> l;
1563
1564 auto get_tensor1 = [](VectorDouble &v, const int r) {
1566 &v(r + 0), &v(r + 1), &v(r + 2));
1567 };
1568
1569 const int nb_integration_pts = getGaussPts().size2();
1570 auto t_coords = getFTensor1CoordsAtGaussPts();
1571
1572 // get element volume
1573 double vol = getVolume();
1574 auto t_w = getFTensor0IntegrationWeight();
1575
1576 nF.resize(nbRows, false);
1577 nF.clear();
1578
1579 // elastic stiffness tensor (4th rank tensor with minor and major
1580 // symmetry)
1582 MAT_TO_DDG(dataAtPts->stiffnessMat));
1583
1584 // get derivatives of base functions on rows
1585 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
1586 const int row_nb_base_fun = row_data.getN().size2();
1587
1588 for (size_t gg = 0; gg != nb_integration_pts; ++gg) {
1589
1590 auto t_fun_strain = strainFun(t_coords);
1592 t_stress(i, j) = -t_D(i, j, k, l) * t_fun_strain(k, l);
1593
1594 // calculate scalar weight times element volume
1595 double a = t_w * vol;
1596
1597 auto t_nf = get_tensor1(nF, 0);
1598
1599 int rr = 0;
1600 for (; rr != nbRows / 3; ++rr) {
1601 t_nf(i) += a * t_row_diff_base(j) * t_stress(i, j);
1602 ++t_row_diff_base;
1603 ++t_nf;
1604 }
1605
1606 for (; rr != row_nb_base_fun; ++rr)
1607 ++t_row_diff_base;
1608
1609 ++t_w;
1610 ++t_coords;
1611 ++t_D;
1612 }
1613
1615}
1616
1617template <int S>
1618HookeElement::OpAnalyticalInternalAleStrain_dX<S>::
1619 OpAnalyticalInternalAleStrain_dX(
1620 const std::string row_field,
1621 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
1622 StrainFunction strain_fun,
1623 boost::shared_ptr<MatrixDouble> mat_pos_at_pts_ptr)
1624 : OpAssemble(row_field, row_field, data_at_pts, OPROW, true),
1625 strainFun(strain_fun), matPosAtPtsPtr(mat_pos_at_pts_ptr) {}
1626
1627template <int S>
1628MoFEMErrorCode HookeElement::OpAnalyticalInternalAleStrain_dX<S>::iNtegrate(
1629 EntData &row_data) {
1630 FTensor::Index<'i', 3> i;
1631 FTensor::Index<'j', 3> j;
1632 FTensor::Index<'k', 3> k;
1633 FTensor::Index<'l', 3> l;
1635
1636 auto get_tensor1 = [](VectorDouble &v, const int r) {
1638 &v(r + 0), &v(r + 1), &v(r + 2));
1639 };
1640
1641 const int nb_integration_pts = getGaussPts().size2();
1642
1643 auto get_coords = [&]() {
1644 return getFTensor1FromMat<3>(*matPosAtPtsPtr);
1645 };
1646 auto t_coords = get_coords();
1647
1648 // get element volume
1649 double vol = getVolume();
1650 auto t_w = getFTensor0IntegrationWeight();
1651
1652 nF.resize(nbRows, false);
1653 nF.clear();
1654
1655 // elastic stiffness tensor (4th rank tensor with minor and major
1656 // symmetry)
1658 MAT_TO_DDG(dataAtPts->stiffnessMat));
1659 auto t_F = getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(
1660 *(dataAtPts->FMat));
1661 auto &det_H = *dataAtPts->detHVec;
1662 auto t_invH =
1663 getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->invHMat);
1664
1665 // get derivatives of base functions on rows
1666 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
1667 const int row_nb_base_fun = row_data.getN().size2();
1668
1669 for (size_t gg = 0; gg != nb_integration_pts; ++gg) {
1670
1671 auto t_fun_strain = strainFun(t_coords);
1673 t_stress(i, j) = -t_D(i, j, k, l) * t_fun_strain(k, l);
1674 FTensor::Tensor2<double, 3, 3> t_eshelby_stress;
1675 t_eshelby_stress(i, j) = -t_F(k, i) * t_stress(k, j);
1676
1677 // calculate scalar weight times element volume
1678 double a = t_w * vol * det_H[gg];
1679
1680 auto t_nf = get_tensor1(nF, 0);
1681
1682 int rr = 0;
1683 for (; rr != nbRows / 3; ++rr) {
1684 FTensor::Tensor1<double, 3> t_row_diff_base_pulled;
1685 t_row_diff_base_pulled(i) = t_row_diff_base(j) * t_invH(j, i);
1686 t_nf(i) += a * t_row_diff_base_pulled(j) * t_eshelby_stress(i, j);
1687 ++t_row_diff_base;
1688 ++t_nf;
1689 }
1690
1691 for (; rr != row_nb_base_fun; ++rr)
1692 ++t_row_diff_base;
1693
1694 ++t_w;
1695 ++t_coords;
1696 ++t_F;
1697 ++t_invH;
1698 ++t_D;
1699 }
1700
1702}
1703
1704template <int S>
1705HookeElement::OpAnalyticalInternalAleStrain_dx<S>::
1706 OpAnalyticalInternalAleStrain_dx(
1707 const std::string row_field,
1708 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
1709 StrainFunction strain_fun,
1710 boost::shared_ptr<MatrixDouble> mat_pos_at_pts_ptr)
1711 : OpAssemble(row_field, row_field, data_at_pts, OPROW, true),
1712 strainFun(strain_fun), matPosAtPtsPtr(mat_pos_at_pts_ptr) {}
1713
1714template <int S>
1715MoFEMErrorCode HookeElement::OpAnalyticalInternalAleStrain_dx<S>::iNtegrate(
1716 EntData &row_data) {
1717 FTensor::Index<'i', 3> i;
1718 FTensor::Index<'j', 3> j;
1719 FTensor::Index<'k', 3> k;
1720 FTensor::Index<'l', 3> l;
1722
1723 auto get_tensor1 = [](VectorDouble &v, const int r) {
1725 &v(r + 0), &v(r + 1), &v(r + 2));
1726 };
1727
1728 const int nb_integration_pts = getGaussPts().size2();
1729
1730 auto get_coords = [&]() {
1731 return getFTensor1FromMat<3>(*matPosAtPtsPtr);
1732 };
1733 auto t_coords = get_coords();
1734
1735 // get element volume
1736 double vol = getVolume();
1737 auto t_w = getFTensor0IntegrationWeight();
1738
1739 nF.resize(nbRows, false);
1740 nF.clear();
1741
1742 // elastic stiffness tensor (4th rank tensor with minor and major
1743 // symmetry)
1745 MAT_TO_DDG(dataAtPts->stiffnessMat));
1746 auto &det_H = *dataAtPts->detHVec;
1747 auto t_invH =
1748 getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->invHMat);
1749
1750 // get derivatives of base functions on rows
1751 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
1752 const int row_nb_base_fun = row_data.getN().size2();
1753
1754 for (size_t gg = 0; gg != nb_integration_pts; ++gg) {
1755
1756 auto t_fun_strain = strainFun(t_coords);
1758 t_stress(i, j) = -t_D(i, j, k, l) * t_fun_strain(k, l);
1759
1760 // calculate scalar weight times element volume
1761 double a = t_w * vol * det_H[gg];
1762
1763 auto t_nf = get_tensor1(nF, 0);
1764
1765 int rr = 0;
1766 for (; rr != nbRows / 3; ++rr) {
1767 FTensor::Tensor1<double, 3> t_row_diff_base_pulled;
1768 t_row_diff_base_pulled(i) = t_row_diff_base(j) * t_invH(j, i);
1769 t_nf(i) += a * t_row_diff_base_pulled(j) * t_stress(i, j);
1770 ++t_row_diff_base;
1771 ++t_nf;
1772 }
1773
1774 for (; rr != row_nb_base_fun; ++rr)
1775 ++t_row_diff_base;
1776
1777 ++t_w;
1778 ++t_coords;
1779 ++t_invH;
1780 ++t_D;
1781 }
1782
1784}
1785
1786#endif // __HOOKE_ELEMENT_HPP
static MoFEMErrorCode addElasticElement(MoFEM::Interface &m_field, boost::shared_ptr< map< int, BlockData > > &block_sets_ptr, const std::string element_name, const std::string x_field, const std::string X_field, const bool ale)
static MoFEMErrorCode setOperators(boost::shared_ptr< ForcesAndSourcesCore > fe_lhs_ptr, boost::shared_ptr< ForcesAndSourcesCore > fe_rhs_ptr, boost::shared_ptr< map< int, BlockData > > block_sets_ptr, const std::string x_field, const std::string X_field, const bool ale, const bool field_disp, const EntityType type=MBTET, boost::shared_ptr< DataAtIntegrationPts > data_at_pts=nullptr)
#define MAT_TO_DDG(SM)
static MoFEMErrorCode setBlocks(MoFEM::Interface &m_field, boost::shared_ptr< map< int, BlockData > > &block_sets_ptr)
MatrixDouble invJac
static MoFEMErrorCode calculateEnergy(DM dm, boost::shared_ptr< map< int, BlockData > > block_sets_ptr, const std::string x_field, const std::string X_field, const bool ale, const bool field_disp, SmartPetscObj< Vec > &v_energy_ptr)
std::string type
constexpr double a
#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 MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
double D
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
UBlasVector< double > VectorDouble
Definition Types.hpp:68
UBlasVector< int > VectorInt
Definition Types.hpp:67
auto type_from_handle(const EntityHandle h)
get type from entity handle
auto getFTensor2FromMat(M &data)
Get tensor rank 2 (matrix) form data matrix.
static auto getFTensor2SymmetricFromMat(M &data)
Get symmetric tensor rank 2 (matrix) form data matrix.
MoFEMErrorCode invertTensor3by3(ublas::matrix< T, L, A > &jac_data, ublas::vector< T, A > &det_data, ublas::matrix< T, L, A > &inv_jac_data)
Calculate inverse of tensor rank 2 at integration points.
MoFEMErrorCode MatSetValues(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const double *ptr, InsertMode iora)
Assemble PETSc matrix.
static auto determinantTensor3by3(T &t)
Calculate the determinant of a 3x3 matrix or a tensor of rank 2.
FTensor::Index< 'm', 3 > m
data for calculation inertia forces
VectorDouble a0
constant acceleration
structure grouping operators and data used for calculation of mass (convective) element \ nonlinear_e...
boost::shared_ptr< MatrixDouble > HMat
boost::shared_ptr< MatrixDouble > invHMat
boost::shared_ptr< MatrixDouble > smallStrainMat
boost::shared_ptr< MatrixDouble > cauchyStressMat
boost::shared_ptr< MatrixDouble > eshelbyStress_dx
boost::shared_ptr< MatrixDouble > FMat
boost::shared_ptr< MatrixDouble > eshelbyStressMat
boost::shared_ptr< MatrixDouble > stiffnessMat
boost::shared_ptr< MatrixDouble > hMat
boost::shared_ptr< VectorDouble > energyVec
boost::shared_ptr< VectorDouble > detHVec
std::array< bool, MBMAXTYPE > doEntities
If true operator is executed for entity.
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
auto getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
intrusive_ptr for managing petsc objects
data for calculation heat conductivity and heat capacity elements
Range tEts
constrains elements in block set
structure grouping operators and data used for calculation of nonlinear elastic element
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< VectorDouble > rhoAtGaussPtsPtr
boost::shared_ptr< MatrixDouble > rhoGradAtGaussPtsPtr
boost::shared_ptr< VectorDouble > rhoAtGaussPtsPtr
boost::shared_ptr< MatrixDouble > rhoGradAtGaussPtsPtr
OpAleLhs_dX_dx(const std::string row_field, const std::string col_field, boost::shared_ptr< DataAtIntegrationPts > &data_at_pts)
boost::shared_ptr< MatrixDouble > matPosAtPtsPtr
boost::function< FTensor::Tensor2_symmetric< double, 3 >(FTensor::Tensor1< FTensor::PackPtr< double *, 1 >, 3 > &t_coords) > StrainFunction
boost::shared_ptr< MatrixDouble > matPosAtPtsPtr
boost::function< FTensor::Tensor2_symmetric< double, 3 >(FTensor::Tensor1< FTensor::PackPtr< double *, 1 >, 3 > &t_coords) > StrainFunction
boost::function< FTensor::Tensor2_symmetric< double, 3 >(FTensor::Tensor1< FTensor::PackPtr< double *, 3 >, 3 > &t_coords) > StrainFunction
int nbCols
number if dof on column
bool isDiag
true if this block is on diagonal
VectorDouble nF
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
int nbIntegrationPts
number of integration points
int nbRows
number of dofs on rows
MatrixDouble transK
VectorInt colIndices
VectorInt rowIndices
MatrixDouble K
SmartPetscObj< Vec > ghostVec
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts
boost::shared_ptr< map< int, BlockData > > blockSetsPtr
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
Assemble mass matrix for elastic element TODO: CHANGE FORMULA *.
OpCalculateMassMatrix(const std::string row_field, const std::string col_field, BlockData &data, MassBlockData &mass_data, boost::shared_ptr< DataAtIntegrationPts > &common_data, bool symm=true)
PetscErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
MassBlockData & massData
boost::shared_ptr< DataAtIntegrationPts > commonData
const double rHo0
p_0 reference density in E(p) = E * (p / p_0)^n
boost::shared_ptr< map< int, BlockData > > blockSetsPtr
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< VectorDouble > rhoAtGaussPtsPtr
const double rhoN
exponent n in E(p) = E * (p / p_0)^n
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
std::vector< EntityHandle > & mapGaussPts
map< int, BlockData > & blockSetsPtr
moab::Interface & postProcMesh
boost::shared_ptr< DataAtIntegrationPts > dataAtPts