v0.16.0
Loading...
Searching...
No Matches
KelvinVoigtDamper.hpp
Go to the documentation of this file.
1/** \file KelvinVoigtDamper.hpp
2 * \brief Implementation dashpot, i.e. damper
3 * \ingroup nonlinear_elastic_elem
4 *
5 */
6
7
8
9#ifndef __KELVIN_VOIGT_DAMPER_HPP__
10#define __KELVIN_VOIGT_DAMPER_HPP__
11
12#ifndef WITH_ADOL_C
13#error "MoFEM need to be compiled with ADOL-C"
14#endif
15
16/** \brief Implementation of Kelvin Voigt Damper
17\ingroup nonlinear_elastic_elem
18
19*/
21
23
25
26 /** \brief Dumper material parameters
27 \ingroup nonlinear_elastic_elem
28 */
31 double vBeta; ///< Poisson ration spring alpha
32 double gBeta; ///< Sheer modulus spring alpha
33 bool lInear;
34 BlockMaterialData() : vBeta(0), gBeta(1), lInear(false) {}
35 };
36
37 std::map<int, BlockMaterialData> blockMaterialDataMap;
38
39 /** \brief Constitutive model functions
40 \ingroup nonlinear_elastic_elem
41
42 */
43 template <typename TYPE> struct ConstitutiveEquation {
44
48
51
52 ConstitutiveEquation(BlockMaterialData &data, bool is_displacement = true)
53 : dAta(data), isDisplacement(is_displacement) {}
54 virtual ~ConstitutiveEquation() = default;
55
56 MatrixBoundedArray<TYPE, 9> F; ///< Gradient of deformation
57 MatrixBoundedArray<TYPE, 9> FDot; ///< Rate of gradient of deformation
58 MatrixBoundedArray<TYPE, 9>
59 gradientUDot; ///< Rate of gradient of displacements
60 MatrixBoundedArray<TYPE, 9> engineringStrainDot;
61 MatrixBoundedArray<TYPE, 9>
62 dashpotCauchyStress; ///< Stress generated by spring beta
63 MatrixBoundedArray<TYPE, 9>
64 dashpotFirstPiolaKirchhoffStress; ///< Stress generated by spring beta
65 MatrixBoundedArray<TYPE, 9> invF; ///< Inverse of gradient of deformation
66
68 TYPE J; ///< Jacobian of gradient of deformation
69
70 /** \brief Calculate strain rate
71
72 \f[
73 \dot{\varepsilon}_{ij} = \frac{1}{2}
74 \left(
75 \frac{\partial v_i}{\partial X_j}
76 +
77 \frac{\partial v_j}{\partial X_i}
78 \right)
79 \f]
80
81 */
82 virtual MoFEMErrorCode calculateEngineeringStrainDot() {
84 gradientUDot.resize(3, 3, false);
85 noalias(gradientUDot) = FDot;
86
87 // for (int ii = 0; ii < 3; ii++)
88 // gradientUDot(ii, ii) -= 1;
89
91 for (int ii = 0; ii < 3; ii++) {
93 }
94 engineringStrainDot.resize(3, 3, false);
98 }
99
100 /** \brief Calculate Cauchy dashpot stress
101
102 Calculate dashpot Cauchy stress. It has to be pull back to reference
103 configuration before use in total Lagrangian formulation.
104
105 \f[
106 \sigma^\beta_{ij} = 2G^\beta\left[
107 \dot{\varepsilon}_{ij}
108 + \frac{v^\beta}{1-2v^\beta}\dot{\varepsilon}_{kk}\delta_{ij}
109 \right]
110 \f]
111
112 */
113 virtual MoFEMErrorCode calculateDashpotCauchyStress() {
115 dashpotCauchyStress.resize(3, 3, false);
116 double a = 2.0 * dAta.gBeta;
117 double b = a * (dAta.vBeta / (1.0 - 2.0 * dAta.vBeta));
119 for (int ii = 0; ii < 3; ii++) {
121 }
123 }
124
125 /** \brief Calculate First Piola-Kirchhoff Stress Dashpot stress
126
127 \f[
128 P^\beta_{ij} = J \sigma^\beta_{ik} F^{-1}_{jk}
129 \f]
130
131 */
132 virtual MoFEMErrorCode calculateFirstPiolaKirchhoffStress() {
134 dashpotFirstPiolaKirchhoffStress.resize(3, 3, false);
135 if (dAta.lInear) {
137 } else {
138
139 invF.resize(3, 3, false);
140
141 using Mat3 = MatrixBoundedArray<TYPE, 9>;
142 auto t_dashpotFirstPiolaKirchhoffStress =
143 GetFTensor2FromArrayImpl<3, 3, 0, Mat3>::get(
145 auto t_dashpotCauchyStress =
146 GetFTensor2FromArrayImpl<3, 3, 0, Mat3>::get(dashpotCauchyStress,
147 0, 0);
148 auto t_F = GetFTensor2FromArrayImpl<3, 3, 0, Mat3>::get(F, 0, 0);
149 auto t_invF =
150 GetFTensor2FromArrayImpl<3, 3, 0, Mat3>::get(invF, 0, 0);
151 if (isDisplacement) {
152 t_F(0, 0) += 1;
153 t_F(1, 1) += 1;
154 t_F(2, 2) += 1;
155 }
156
157 J = determinantTensor3by3(t_F);
158 CHKERR invertTensor3by3(t_F, J, t_invF);
159 t_dashpotFirstPiolaKirchhoffStress(i, j) =
160 J * (t_dashpotCauchyStress(i, k) * t_invF(j, k));
161 }
163 }
164 };
165
166 typedef boost::ptr_map<int, KelvinVoigtDamper::ConstitutiveEquation<adouble>>
169
170 /** \brief Common data for nonlinear_elastic_elem model
171 \ingroup nonlinear_elastic_elem
172 */
173 struct CommonData {
174
178
179 std::map<std::string, std::vector<VectorDouble>> dataAtGaussPts;
180 std::map<std::string, std::vector<MatrixDouble>> gradAtGaussPts;
181
182 boost::shared_ptr<MatrixDouble> dataAtGaussTmpPtr;
183 boost::shared_ptr<MatrixDouble> gradDataAtGaussTmpPtr;
184
185 std::vector<MatrixDouble> dashpotFirstPiolaKirchhoffStress;
186
187 std::vector<double *> jacRowPtr;
188 std::vector<MatrixDouble> jacStress;
189
193
194 CommonData() : recordOn(true), skipThis(true) {
195 dataAtGaussTmpPtr = boost::make_shared<MatrixDouble>();
196 dataAtGaussTmpPtr->resize(3, 1);
197 gradDataAtGaussTmpPtr = boost::make_shared<MatrixDouble>();
198 gradDataAtGaussTmpPtr->resize(9, 1);
199 meshNodePositionName = "MESH_NODE_POSITIONS";
200 }
201 };
203
204 /// \brief definition of volume element
206
208 int addToRule; ///< Takes into account HO geometry
209
210 DamperFE(MoFEM::Interface &m_field, CommonData &common_data)
212 commonData(common_data), addToRule(1) {}
213
214 int getRule(int order) { return order + addToRule; }
215
216 MoFEMErrorCode preProcess() {
217
220
221 // if (ts_ctx == CTX_TSSETIFUNCTION) {
222
223 // CHKERR mField.getInterface<VecManager>()->setOtherLocalGhostVector(
224 // problemPtr, commonData.spatialPositionName,
225 // commonData.spatialPositionNameDot, COL, ts_u_t, INSERT_VALUES,
226 // SCATTER_REVERSE);
227 // }
228
230 }
231
232 MoFEMErrorCode postProcess() {
233
235
236 // CHKERR MoFEM::VolumeElementForcesAndSourcesCore::postProcess();
237
238 // if (ts_ctx == CTX_TSSETIFUNCTION) {
239 // CHKERR VecAssemblyBegin(ts_F);
240 // CHKERR VecAssemblyEnd(ts_F);
241 // }
242 // if (ts_ctx == CTX_TSSETIJACOBIAN) {
243 // CHKERR MatAssemblyBegin(ts_B, MAT_FLUSH_ASSEMBLY);
244 // CHKERR MatAssemblyEnd(ts_B, MAT_FLUSH_ASSEMBLY);
245 // }
246
248 }
249 };
250
252
254 : mField(m_field), feRhs(m_field, commonData),
255 feLhs(m_field, commonData) {}
256
259
264 EntityType zeroAtType;
265
266 OpGetDataAtGaussPts(const std::string field_name, CommonData &common_data,
267 bool calc_val, bool calc_grad, bool calc_dot = false,
268 EntityType zero_at_type = MBVERTEX)
269 : MoFEM::VolumeElementForcesAndSourcesCore::UserDataOperator(
271 commonData(common_data), calcVal(calc_val), calcGrad(calc_grad),
272 calcDot(calc_dot), zeroAtType(zero_at_type) {}
273
274 /** \brief Operator field value
275 *
276 */
277 MoFEMErrorCode doWork(int side, EntityType type,
278 EntitiesFieldData::EntData &data) {
280
281 int nb_dofs = data.getFieldData().size();
282 if (nb_dofs == 0) {
284 }
285 int rank = data.getFieldDofs()[0]->getNbOfCoeffs();
286 int nb_gauss_pts = data.getN().size1();
287
289 if (calcDot)
291 // Initialize
292 if (calcVal) {
293 commonData.dataAtGaussPts[field_name].resize(nb_gauss_pts);
294 for (int gg = 0; gg < nb_gauss_pts; gg++) {
295 commonData.dataAtGaussPts[field_name][gg].resize(rank, false);
297 }
298 }
299 if (calcGrad) {
300 commonData.gradAtGaussPts[field_name].resize(nb_gauss_pts);
301 for (int gg = 0; gg < nb_gauss_pts; gg++) {
302 commonData.gradAtGaussPts[field_name][gg].resize(rank, 3, false);
304 }
305 }
306
307 // Zero values
308 // if (type == zeroAtType) {
309 // for (int gg = 0; gg < nb_gauss_pts; gg++) {
310 // if (calcVal) {
311 // commonData.dataAtGaussPts[rowFieldName][gg].clear();
312 // }
313 // if (calcGrad) {
314 // commonData.gradAtGaussPts[rowFieldName][gg].clear();
315 // }
316 // }
317 // }
318
319 if (calcVal) {
320 auto t_disp = getFTensor1FromMat<3>(*commonData.dataAtGaussTmpPtr);
321 for (int gg = 0; gg < nb_gauss_pts; gg++) {
322 for (int rr1 = 0; rr1 < rank; rr1++)
323 commonData.dataAtGaussPts[field_name][gg][rr1] = t_disp(rr1);
324 ++t_disp;
325 }
326 }
327
328 if (calcGrad) {
329 auto t_diff_disp =
330 getFTensor2FromMat<3, 3>(*commonData.gradDataAtGaussTmpPtr);
331 for (int gg = 0; gg < nb_gauss_pts; gg++) {
332 for (int rr1 = 0; rr1 < rank; rr1++) {
333 for (int rr2 = 0; rr2 < 3; rr2++) {
334 commonData.gradAtGaussPts[field_name][gg](rr1, rr2) =
335 t_diff_disp(rr1, rr2);
336 }
337 }
338 ++t_diff_disp;
339 }
340 }
341
343 }
344 };
345
348
349 std::vector<int> tagS;
352
355 bool &recordOn;
356 std::map<int, int> &nbActiveVariables;
357 std::map<int, int> &nbActiveResults;
358
359 OpJacobian(const std::string field_name, std::vector<int> tags,
361 CommonData &common_data, bool calculate_residual,
362 bool calculate_jacobian)
363 : MoFEM::VolumeElementForcesAndSourcesCore::UserDataOperator(
365 tagS(tags), cE(ce), commonData(common_data),
366 calculateResidualBool(calculate_residual),
367 calculateJacobianBool(calculate_jacobian),
368 recordOn(common_data.recordOn),
370 nbActiveResults(common_data.nbActiveResults) {}
371
373 VectorDouble activeVariables;
374
375 MoFEMErrorCode recordDamperStress() {
377
378 if (tagS[DAMPERSTRESS] < 0) {
380 }
381
382 cE.F.resize(3, 3, false);
383 cE.FDot.resize(3, 3, false);
384 MatrixDouble &F =
386 MatrixDouble &F_dot =
388 trace_on(tagS[DAMPERSTRESS]);
389 {
390 // Activate gradient of defamation
392 for (int dd1 = 0; dd1 < 3; dd1++) {
393 for (int dd2 = 0; dd2 < 3; dd2++) {
394 cE.F(dd1, dd2) <<= F(dd1, dd2);
396 }
397 }
398 for (int dd1 = 0; dd1 < 3; dd1++) {
399 for (int dd2 = 0; dd2 < 3; dd2++) {
400 cE.FDot(dd1, dd2) <<= F_dot(dd1, dd2);
402 }
403 }
404
405 // Do calculations
409
410 // Results
413 commonData.dashpotFirstPiolaKirchhoffStress[0].resize(3, 3, false);
414 for (int d1 = 0; d1 < 3; d1++) {
415 for (int d2 = 0; d2 < 3; d2++) {
419 }
420 }
421 }
422 trace_off();
424 }
425
426 MoFEMErrorCode calculateFunction(TagEvaluate te, double *ptr) {
428
429 int r;
430 // play recorder for values
431 r = ::function(tagS[te], nbActiveResults[tagS[te]],
432 nbActiveVariables[tagS[te]], &activeVariables[0], ptr);
433 if (r < 3) { // function is locally analytic
434 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
435 "ADOL-C function evaluation with error r = %d", r);
436 }
437
439 }
440
441 MoFEMErrorCode calculateJacobian(TagEvaluate te) {
443
444 try {
445 int r;
446 r = jacobian(tagS[te], nbActiveResults[tagS[te]],
448 &(commonData.jacRowPtr[0]));
449 if (r < 3) {
450 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
451 "ADOL-C function evaluation with error");
452 }
453 } catch (const std::exception &ex) {
454 std::ostringstream ss;
455 ss << "throw in method: " << ex.what() << std::endl;
456 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "%s",
457 ss.str().c_str());
458 }
460 }
461
464
465 if (tagS[DAMPERSTRESS] < 0) {
467 }
468
470 for (int gg = 0; gg < nbGaussPts; gg++) {
471
472 MatrixDouble &F =
474 MatrixDouble &F_dot =
476 int nb_active_variables = 0;
477
478 // Activate gradient of defamation
479 for (int dd1 = 0; dd1 < 3; dd1++) {
480 for (int dd2 = 0; dd2 < 3; dd2++) {
481 activeVariables[nb_active_variables++] = F(dd1, dd2);
482 }
483 }
484 // Activate rate of gradient of defamation
485 for (int dd1 = 0; dd1 < 3; dd1++) {
486 for (int dd2 = 0; dd2 < 3; dd2++) {
487 activeVariables[nb_active_variables++] = F_dot(dd1, dd2);
488 }
489 }
490
491 if (nb_active_variables != nbActiveVariables[tagS[DAMPERSTRESS]]) {
492 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE,
493 "Number of active variables does not much");
494 }
495
497 if (gg == 0) {
499 }
500 commonData.dashpotFirstPiolaKirchhoffStress[gg].resize(3, 3, false);
504 }
505
507 if (gg == 0) {
510 }
513 false);
514 for (int dd = 0; dd < nbActiveResults[tagS[DAMPERSTRESS]]; dd++) {
515 commonData.jacRowPtr[dd] = &commonData.jacStress[gg](dd, 0);
516 }
518 }
519 }
520
522 }
523
524 MoFEMErrorCode doWork(int row_side, EntityType row_type,
525 EntitiesFieldData::EntData &row_data) {
527
528 if (row_type != MBVERTEX)
530 nbGaussPts = row_data.getN().size1();
531
532 commonData.skipThis = false;
533 if (cE.dAta.tEts.find(getNumeredEntFiniteElementPtr()->getEnt()) ==
534 cE.dAta.tEts.end()) {
535 commonData.skipThis = true;
537 }
538
539 if (recordOn) {
541 }
543
545 }
546 };
547
551 : MoFEM::VolumeElementForcesAndSourcesCore::UserDataOperator(
553
554 VectorDouble nF;
555 MoFEMErrorCode aSemble(int row_side, EntityType row_type,
556 EntitiesFieldData::EntData &row_data) {
558 int nb_dofs = row_data.getIndices().size();
559 int *indices_ptr = &row_data.getIndices()[0];
560 CHKERR VecSetValues(getFEMethod()->ts_F, nb_dofs, indices_ptr, &nF[0],
561 ADD_VALUES);
563 }
564 };
565
566 /** \brief Assemble internal force vector
567 \ingroup nonlinear_elastic_elem
568
569 */
570 struct OpRhsStress : public AssembleVector {
573 : AssembleVector(common_data.spatialPositionName),
574 commonData(common_data) {}
575 MoFEMErrorCode doWork(int row_side, EntityType row_type,
576 EntitiesFieldData::EntData &row_data) {
578
579 if (commonData.skipThis) {
581 }
582
583 int nb_dofs = row_data.getIndices().size();
584 if (!nb_dofs) {
586 }
587 nF.resize(nb_dofs, false);
588 nF.clear();
589 int nb_gauss_pts = row_data.getN().size1();
590 for (int gg = 0; gg != nb_gauss_pts; gg++) {
591 const MatrixAdaptor &diffN = row_data.getDiffN(gg, nb_dofs / 3);
592 const MatrixDouble &stress =
594 double val = getVolume() * getGaussPts()(3, gg);
595 for (int dd = 0; dd < nb_dofs / 3; dd++) {
596 for (int rr = 0; rr < 3; rr++) {
597 for (int nn = 0; nn < 3; nn++) {
598 nF[3 * dd + rr] += val * diffN(dd, nn) * stress(rr, nn);
599 }
600 }
601 }
602 }
603 CHKERR aSemble(row_side, row_type, row_data);
605 }
606 };
607
610 AssembleMatrix(string row_name, string col_name)
611 : MoFEM::VolumeElementForcesAndSourcesCore::UserDataOperator(
612 row_name, col_name, UserDataOperator::OPROWCOL) {}
613
614 MatrixDouble K, transK;
615 MoFEMErrorCode aSemble(int row_side, int col_side, EntityType row_type,
616 EntityType col_type,
617 EntitiesFieldData::EntData &row_data,
618 EntitiesFieldData::EntData &col_data) {
620 int nb_row = row_data.getIndices().size();
621 int nb_col = col_data.getIndices().size();
622 int *row_indices_ptr = &row_data.getIndices()[0];
623 int *col_indices_ptr = &col_data.getIndices()[0];
624 CHKERR MatSetValues(getFEMethod()->ts_B, nb_row, row_indices_ptr, nb_col,
625 col_indices_ptr, &K(0, 0), ADD_VALUES);
626 if (sYmm) {
627 // Assemble of diagonal terms
628 if (row_side != col_side || row_type != col_type) {
629 transK.resize(nb_col, nb_row, false);
630 noalias(transK) = trans(K);
631 CHKERR MatSetValues(getFEMethod()->ts_B, nb_col, col_indices_ptr,
632 nb_row, row_indices_ptr, &transK(0, 0),
633 ADD_VALUES);
634 }
635 }
637 }
638 };
639
640 /** \brief Assemble matrix
641 */
642 struct OpLhsdxdx : public AssembleMatrix {
644 OpLhsdxdx(CommonData &common_data)
645 : AssembleMatrix(common_data.spatialPositionName,
646 common_data.spatialPositionName),
647 commonData(common_data) {}
648 MatrixDouble dStress_dx;
649 MoFEMErrorCode get_dStress_dx(EntitiesFieldData::EntData &col_data,
650 int gg) {
652 int nb_col = col_data.getIndices().size();
653 dStress_dx.resize(9, nb_col, false);
654 dStress_dx.clear();
655 const MatrixAdaptor diffN = col_data.getDiffN(gg, nb_col / 3);
656 MatrixDouble &jac_stress = commonData.jacStress[gg];
657 for (int dd = 0; dd < nb_col / 3; dd++) { // DoFs in column
658 for (int jj = 0; jj < 3; jj++) { // cont. DoFs in column
659 double a = diffN(dd, jj);
660 for (int rr = 0; rr < 3; rr++) { // Loop over dsigma_ii/dX_rr
661 for (int ii = 0; ii < 9;
662 ii++) { // ii represents components of stress tensor
663 dStress_dx(ii, 3 * dd + rr) += jac_stress(ii, 3 * rr + jj) * a;
664 }
665 }
666 }
667 }
669 }
670 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
671 EntityType col_type,
672 EntitiesFieldData::EntData &row_data,
673 EntitiesFieldData::EntData &col_data) {
675
676 if (commonData.skipThis) {
678 }
679
680 int nb_row = row_data.getIndices().size();
681 int nb_col = col_data.getIndices().size();
682 if (nb_row == 0)
684 if (nb_col == 0)
686 K.resize(nb_row, nb_col, false);
687 K.clear();
688 int nb_gauss_pts = row_data.getN().size1();
689 for (int gg = 0; gg != nb_gauss_pts; gg++) {
690 CHKERR get_dStress_dx(col_data, gg);
691 double val = getVolume() * getGaussPts()(3, gg);
692 // std::cerr << dStress_dx << std::endl;
693 dStress_dx *= val;
694 const MatrixAdaptor &diffN = row_data.getDiffN(gg, nb_row / 3);
695 { // integrate element stiffness matrix
696 for (int dd1 = 0; dd1 < nb_row / 3; dd1++) {
697 for (int rr1 = 0; rr1 < 3; rr1++) {
698 for (int dd2 = 0; dd2 < nb_col / 3; dd2++) {
699 for (int rr2 = 0; rr2 < 3; rr2++) {
700 K(3 * dd1 + rr1, 3 * dd2 + rr2) +=
701 (diffN(dd1, 0) * dStress_dx(3 * rr1 + 0, 3 * dd2 + rr2) +
702 diffN(dd1, 1) * dStress_dx(3 * rr1 + 1, 3 * dd2 + rr2) +
703 diffN(dd1, 2) * dStress_dx(3 * rr1 + 2, 3 * dd2 + rr2));
704 }
705 }
706 }
707 }
708 }
709 }
710 // std::cerr << "G " << getNumeredEntFiniteElementPtr()->getRefEnt() <<
711 // std::endl << K << std::endl;
712 CHKERR aSemble(row_side, col_side, row_type, col_type, row_data,
713 col_data);
714
716 }
717 };
718
719 /** \brief Assemble matrix
720 */
721 struct OpLhsdxdot : public AssembleMatrix {
723 OpLhsdxdot(CommonData &common_data)
724 : AssembleMatrix(common_data.spatialPositionName,
725 common_data.spatialPositionName),
726 commonData(common_data) {}
727 MatrixDouble dStress_dot;
728 MoFEMErrorCode get_dStress_dot(EntitiesFieldData::EntData &col_data,
729 int gg) {
731 int nb_col = col_data.getIndices().size();
732 dStress_dot.resize(9, nb_col, false);
733 dStress_dot.clear();
734 const MatrixAdaptor diffN = col_data.getDiffN(gg, nb_col / 3);
735 MatrixDouble &jac_stress = commonData.jacStress[gg];
736 for (int dd = 0; dd < nb_col / 3; dd++) { // DoFs in column
737 for (int jj = 0; jj < 3; jj++) { // cont. DoFs in column
738 double a = diffN(dd, jj);
739 for (int rr = 0; rr < 3; rr++) { // Loop over dsigma_ii/dX_rr
740 for (int ii = 0; ii < 9;
741 ii++) { // ii represents components of stress tensor
742 dStress_dot(ii, 3 * dd + rr) +=
743 jac_stress(ii, 9 + 3 * rr + jj) * a * getFEMethod()->ts_a;
744 }
745 }
746 }
747 }
749 }
750 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
751 EntityType col_type,
752 EntitiesFieldData::EntData &row_data,
753 EntitiesFieldData::EntData &col_data) {
755
756 if (commonData.skipThis) {
758 }
759
760 int nb_row = row_data.getIndices().size();
761 int nb_col = col_data.getIndices().size();
762 if (nb_row == 0)
764 if (nb_col == 0)
766 K.resize(nb_row, nb_col, false);
767 K.clear();
768 int nb_gauss_pts = row_data.getN().size1();
769 for (int gg = 0; gg != nb_gauss_pts; gg++) {
770 CHKERR get_dStress_dot(col_data, gg);
771 double val = getVolume() * getGaussPts()(3, gg);
772 // std::cerr << dStress_dot << std::endl;
773 dStress_dot *= val;
774 const MatrixAdaptor &diffN = row_data.getDiffN(gg, nb_row / 3);
775 { // integrate element stiffness matrix
776 for (int dd1 = 0; dd1 < nb_row / 3; dd1++) {
777 for (int rr1 = 0; rr1 < 3; rr1++) {
778 for (int dd2 = 0; dd2 < nb_col / 3; dd2++) {
779 for (int rr2 = 0; rr2 < 3; rr2++) {
780 K(3 * dd1 + rr1, 3 * dd2 + rr2) +=
781 (diffN(dd1, 0) * dStress_dot(3 * rr1 + 0, 3 * dd2 + rr2) +
782 diffN(dd1, 1) * dStress_dot(3 * rr1 + 1, 3 * dd2 + rr2) +
783 diffN(dd1, 2) * dStress_dot(3 * rr1 + 2, 3 * dd2 + rr2));
784 }
785 }
786 }
787 }
788 }
789 }
790 // std::cerr << "G " << getNumeredEntFiniteElementPtr()->getRefEnt() <<
791 // std::endl << K << std::endl;
792 CHKERR aSemble(row_side, col_side, row_type, col_type, row_data,
793 col_data);
794
796 }
797 };
798
799 MoFEMErrorCode setBlockDataMap() {
801
803 if (it->getName().compare(0, 6, "DAMPER") == 0) {
804 std::vector<double> data;
805 CHKERR it->getAttributes(data);
806 if (data.size() < 2) {
807 SETERRQ(PETSC_COMM_SELF, 1, "Data inconsistency");
808 }
809 CHKERR mField.get_moab().get_entities_by_type(
810 it->meshset, MBTET, blockMaterialDataMap[it->getMeshsetId()].tEts,
811 true);
812 blockMaterialDataMap[it->getMeshsetId()].gBeta = data[0];
813 blockMaterialDataMap[it->getMeshsetId()].vBeta = data[1];
814 }
815 }
817 }
818
819 MoFEMErrorCode setOperators(const int tag) {
821
822 for (auto &&fe_ptr : {&feRhs, &feLhs}) {
823 // CHKERR AddHOOps<3, 3, 3>::add(
824 // fe_ptr->getOpPtrVector(), {H1}, commonData.meshNodePositionName);
825 fe_ptr->getOpPtrVector().push_back(
826 new OpCalculateVectorFieldGradient<3, 3>(
829 fe_ptr->getOpPtrVector().push_back(new OpGetDataAtGaussPts(
830 commonData.spatialPositionName, commonData, false, true, false));
831 fe_ptr->getOpPtrVector().push_back(
832 new OpCalculateVectorFieldGradientDot<3, 3>(
835 fe_ptr->getOpPtrVector().push_back(new OpGetDataAtGaussPts(
836 commonData.spatialPositionName, commonData, false, true, true));
837 }
838
839 // attach tags for each recorder
840 std::vector<int> tags;
841 tags.push_back(tag);
842
843 ConstitutiveEquationMap::iterator mit = constitutiveEquationMap.begin();
844 for (; mit != constitutiveEquationMap.end(); mit++) {
846 constitutiveEquationMap.at(mit->first);
847 // Right hand side operators
848 feRhs.getOpPtrVector().push_back(new OpJacobian(
849 commonData.spatialPositionName, tags, ce, commonData, true, false));
850 feRhs.getOpPtrVector().push_back(new OpRhsStress(commonData));
851
852 // Left hand side operators
853 feLhs.getOpPtrVector().push_back(new OpJacobian(
854 commonData.spatialPositionName, tags, ce, commonData, false, true));
855 feLhs.getOpPtrVector().push_back(new OpLhsdxdx(commonData));
856 feLhs.getOpPtrVector().push_back(new OpLhsdxdot(commonData));
857 }
858
860 }
861};
862
863#endif //__KELVIN_VOIGT_DAMPER_HPP__
ForcesAndSourcesCore::UserDataOperator UserDataOperator
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 ...
@ BLOCKSET
@ MOFEM_IMPOSSIBLE_CASE
Definition definitions.h:35
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
@ 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.
constexpr int order
@ F
#define _IT_CUBITMESHSETS_BY_SET_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet having a particular BC meshset in a moFEM field.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
constexpr auto field_name
MoFEMErrorCode aSemble(int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
AssembleMatrix(string row_name, string col_name)
MoFEMErrorCode aSemble(int row_side, EntityType row_type, EntitiesFieldData::EntData &row_data)
double vBeta
Poisson ration spring alpha.
double gBeta
Sheer modulus spring alpha.
Common data for nonlinear_elastic_elem model.
std::map< int, int > nbActiveVariables
boost::shared_ptr< MatrixDouble > dataAtGaussTmpPtr
std::vector< MatrixDouble > dashpotFirstPiolaKirchhoffStress
std::vector< double * > jacRowPtr
std::vector< MatrixDouble > jacStress
std::map< std::string, std::vector< MatrixDouble > > gradAtGaussPts
std::map< std::string, std::vector< VectorDouble > > dataAtGaussPts
boost::shared_ptr< MatrixDouble > gradDataAtGaussTmpPtr
MatrixBoundedArray< TYPE, 9 > FDot
Rate of gradient of deformation.
MatrixBoundedArray< TYPE, 9 > invF
Inverse of gradient of deformation.
MatrixBoundedArray< TYPE, 9 > F
Gradient of deformation.
virtual MoFEMErrorCode calculateFirstPiolaKirchhoffStress()
Calculate First Piola-Kirchhoff Stress Dashpot stress.
MatrixBoundedArray< TYPE, 9 > gradientUDot
Rate of gradient of displacements.
virtual MoFEMErrorCode calculateDashpotCauchyStress()
Calculate Cauchy dashpot stress.
MatrixBoundedArray< TYPE, 9 > engineringStrainDot
virtual MoFEMErrorCode calculateEngineeringStrainDot()
Calculate strain rate.
MatrixBoundedArray< TYPE, 9 > dashpotFirstPiolaKirchhoffStress
Stress generated by spring beta.
ConstitutiveEquation(BlockMaterialData &data, bool is_displacement=true)
MatrixBoundedArray< TYPE, 9 > dashpotCauchyStress
Stress generated by spring beta.
TYPE J
Jacobian of gradient of deformation.
definition of volume element
int addToRule
Takes into account HO geometry.
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
DamperFE(MoFEM::Interface &m_field, CommonData &common_data)
MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
OpGetDataAtGaussPts(const std::string field_name, CommonData &common_data, bool calc_val, bool calc_grad, bool calc_dot=false, EntityType zero_at_type=MBVERTEX)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator field value.
std::map< int, int > & nbActiveVariables
MoFEMErrorCode calculateJacobian(TagEvaluate te)
MoFEMErrorCode doWork(int row_side, EntityType row_type, EntitiesFieldData::EntData &row_data)
std::map< int, int > & nbActiveResults
KelvinVoigtDamper::ConstitutiveEquation< adouble > & cE
MoFEMErrorCode calculateAtIntPtsDamperStress()
MoFEMErrorCode calculateFunction(TagEvaluate te, double *ptr)
OpJacobian(const std::string field_name, std::vector< int > tags, KelvinVoigtDamper::ConstitutiveEquation< adouble > &ce, CommonData &common_data, bool calculate_residual, bool calculate_jacobian)
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
MoFEMErrorCode get_dStress_dot(EntitiesFieldData::EntData &col_data, int gg)
OpLhsdxdot(CommonData &common_data)
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
OpLhsdxdx(CommonData &common_data)
MoFEMErrorCode get_dStress_dx(EntitiesFieldData::EntData &col_data, int gg)
Assemble internal force vector.
OpRhsStress(CommonData &common_data)
MoFEMErrorCode doWork(int row_side, EntityType row_type, EntitiesFieldData::EntData &row_data)
Implementation of Kelvin Voigt Damper.
MoFEMErrorCode setBlockDataMap()
ConstitutiveEquationMap constitutiveEquationMap
std::map< int, BlockMaterialData > blockMaterialDataMap
KelvinVoigtDamper(MoFEM::Interface &m_field)
MoFEMErrorCode setOperators(const int tag)
boost::ptr_map< int, KelvinVoigtDamper::ConstitutiveEquation< adouble > > ConstitutiveEquationMap
MoFEM::Interface & mField
virtual moab::Interface & get_moab()=0
bool sYmm
If true assume that matrix is symmetric structure.
Deprecated interface functions.
boost::shared_ptr< const NumeredEntFiniteElement > getNumeredEntFiniteElementPtr() const
Return raw pointer to NumeredEntFiniteElement.
@ OPCOL
operator doWork function is executed on FE columns
@ OPROW
operator doWork function is executed on FE rows
@ OPROWCOL
operator doWork is executed on FE rows &columns
const FEMethod * getFEMethod() const
Return raw pointer to Finite Element Method object.
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
virtual MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
boost::ptr_deque< UserDataOperator > & getOpPtrVector()
Use to push back operator for row operator.
PetscReal ts_a
Shift parameter for U_t (see PETSc Time Solver documentation)