v0.16.0
Loading...
Searching...
No Matches
CohesiveInterfaceElement.hpp
Go to the documentation of this file.
1/** \file CohesiveInterfaceElement.hpp
2 \brief Implementation of linear interface element
3
4*/
5
6namespace CohesiveElement {
7
8/** \brief Cohesive element implementation
9
10 \bug Interface element not working with HO geometry.
11*/
13
14 struct CommonData {
15 MatrixDouble gapGlob;
16 MatrixDouble gapLoc;
17 ublas::vector<MatrixDouble> R;
18 };
20
26 int getRule(int order) { return 2 * order; };
27 };
31
33 : feRhs(m_field), feLhs(m_field), feHistory(m_field){};
34
36
37 MyPrism &getFeRhs() { return feRhs; }
38 MyPrism &getFeLhs() { return feLhs; }
40
41 /** \brief Constitutive (physical) equation for interface
42
43 This is linear degradation model. Material parameters are: strength
44 \f$f_t\f$, interface fracture energy \f$G_f\f$, elastic material stiffness
45 \f$E\f$. Parameter \f$\beta\f$ controls how interface opening is calculated.
46
47 Model parameter is interface penalty thickness \f$h\f$.
48
49 */
51
55 : mField(m_field), isInitialised(false){};
56
57 virtual ~PhysicalEquation() {}
58
59 double h, youngModulus, beta, ft, Gf;
62
63 double E0, g0, kappa1;
64
65 /** \brief Initialize history variable data
66
67 Create tag on the prism/interface to store damage history variable
68
69 */
70 MoFEMErrorCode iNitailise(const FEMethod *fe_method) {
72
73 double def_damaged = 0;
74 CHKERR mField.get_moab().tag_get_handle(
75 "DAMAGED_PRISM", 1, MB_TYPE_INTEGER, thDamagedPrism,
76 MB_TAG_CREAT | MB_TAG_SPARSE, &def_damaged);
77 const int def_len = 0;
78 CHKERR mField.get_moab().tag_get_handle(
79 "_KAPPA", def_len, MB_TYPE_DOUBLE, thKappa,
80 MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN, nullptr);
81 E0 = youngModulus / h;
82 g0 = ft / E0;
83 kappa1 = 2 * Gf / ft;
85 }
86
87 /** \brief Calculate gap opening
88
89 \f[
90 g = \sqrt{ g_n^2 + \beta(g_{s1}^2 + g_{s2}^2)}
91 \f]
92
93 */
94 double calcG(int gg, MatrixDouble gap_loc) {
95 return sqrt(pow(gap_loc(gg, 0), 2) +
96 beta * (pow(gap_loc(gg, 1), 2) + pow(gap_loc(gg, 2), 2)));
97 }
98
99 double *kappaPtr;
101
102 /** \brief Get pointer from the mesh to histoy variables \f$\kappa\f$
103 */
104 MoFEMErrorCode getKappa(int nb_gauss_pts, const FEMethod *fe_method) {
106 EntityHandle ent = fe_method->numeredEntFiniteElementPtr->getEnt();
107
108 rval = mField.get_moab().tag_get_by_ptr(
109 thKappa, &ent, 1, (const void **)&kappaPtr, &kappaSize);
110 if (rval != MB_SUCCESS || kappaSize != nb_gauss_pts) {
111 VectorDouble kappa;
112 kappa.resize(nb_gauss_pts);
113 kappa.clear();
114 int tag_size[1];
115 tag_size[0] = nb_gauss_pts;
116 void const *tag_data[] = {&kappa[0]};
117 CHKERR mField.get_moab().tag_set_by_ptr(thKappa, &ent, 1, tag_data,
118 tag_size);
119 CHKERR mField.get_moab().tag_get_by_ptr(
120 thKappa, &ent, 1, (const void **)&kappaPtr, &kappaSize);
121 }
123 }
124
125 MatrixDouble Dglob, Dloc;
126
127 /** \brief Calculate stiffness material matrix
128
129 \f[
130 \mathbf{D}_\textrm{loc} = (1-\Omega) \mathbf{I} E_0
131 \f]
132 where \f$E_0\f$ is initial interface penalty stiffness
133
134 \f[
135 \mathbf{D}_\textrm{glob} = \mathbf{R}^\textrm{T} \mathbf{D}_\textrm{loc}\mathbf{R}
136 \f]
137
138 */
139 MoFEMErrorCode calcDglob(const double omega, MatrixDouble &R) {
141 Dglob.resize(3, 3);
142 Dloc.resize(3, 3);
143 Dloc.clear();
144 double E = (1 - omega) * E0;
145 Dloc(0, 0) = E;
146 Dloc(1, 1) = E;
147 Dloc(2, 2) = E;
148 Dglob = prod(Dloc, R);
149 Dglob = prod(trans(R), Dglob);
151 }
152
153 /** \brief Calculate damage
154
155 \f[
156 \Omega = \frac{1}{2} \frac{(2 G_f E_0+f_t^2)\kappa}{(ft+E_0 \kappa)G_f}
157 \f]
158
159 */
160 MoFEMErrorCode calcOmega(const double kappa, double &omega) {
162 omega = 0;
163 if (kappa >= kappa1) {
164 omega = 1;
166 } else if (kappa > 0) {
167 double a = (2.0 * Gf * E0 + ft * ft) * kappa;
168 double b = (ft + E0 * kappa) * Gf;
169 omega = 0.5 * a / b;
170 }
172 }
173
174 /** \brief Calculate tangent material stiffness
175 */
176 MoFEMErrorCode calcTangetDglob(const double omega, double g,
177 const VectorDouble &gap_loc,
178 MatrixDouble &R) {
180 Dglob.resize(3, 3);
181 Dloc.resize(3, 3);
182 double domega =
183 0.5 * (2 * Gf * E0 + ft * ft) / ((ft + (g - ft / E0) * E0) * Gf) -
184 0.5 * ((g - ft / E0) * (2 * Gf * E0 + ft * ft) * E0) /
185 (pow(ft + (g - ft / E0) * E0, 2) * Gf);
186 Dloc.resize(3, 3);
187 //r0
188 Dloc(0, 0) = (1 - omega) * E0 - domega * E0 * gap_loc[0] * gap_loc[0] / g;
189 Dloc(0, 1) = -domega * E0 * gap_loc[0] * beta * gap_loc[1] / g;
190 Dloc(0, 2) = -domega * E0 * gap_loc[0] * beta * gap_loc[2] / g;
191 //r1
192 Dloc(1, 0) = -domega * E0 * gap_loc[1] * gap_loc[0] / g;
193 Dloc(1, 1) =
194 (1 - omega) * E0 - domega * E0 * gap_loc[1] * beta * gap_loc[1] / g;
195 Dloc(1, 2) = -domega * E0 * gap_loc[1] * beta * gap_loc[2] / g;
196 //r2
197 Dloc(2, 0) = -domega * E0 * gap_loc[2] * gap_loc[0] / g;
198 Dloc(2, 1) = -domega * E0 * gap_loc[2] * beta * gap_loc[1] / g;
199 Dloc(2, 2) =
200 (1 - omega) * E0 - domega * E0 * gap_loc[2] * beta * gap_loc[2] / g;
201 Dglob = prod(Dloc, R);
202 Dglob = prod(trans(R), Dglob);
204 }
205
206 /** \brief Calculate tractions
207
208 \f[
209 \mathbf{t} = \mathbf{D}_\textrm{glob}\mathbf{g}
210 \f]
211
212 */
213 virtual MoFEMErrorCode calculateTraction(VectorDouble &traction, int gg,
214 CommonData &common_data,
215 const FEMethod *fe_method) {
217
218 if (!isInitialised) {
219 CHKERR iNitailise(fe_method);
220 isInitialised = true;
221 }
222 if (gg == 0) {
223 CHKERR getKappa(common_data.gapGlob.size1(), fe_method);
224 }
225 double g = calcG(gg, common_data.gapLoc);
226 double kappa = fmax(g - g0, kappaPtr[gg]);
227 double omega = 0;
229 CHKERR calcDglob(omega, common_data.R[gg]);
230 traction.resize(3);
231 ublas::matrix_row<MatrixDouble> gap_glob(common_data.gapGlob, gg);
232 noalias(traction) = prod(Dglob, gap_glob);
234 }
235
236 /** \brief Calculate tangent stiffness
237 */
238 virtual MoFEMErrorCode
239 calculateTangentStiffeness(MatrixDouble &tangent_matrix, int gg,
240 CommonData &common_data,
241 const FEMethod *fe_method) {
243
244 try {
245 if (!isInitialised) {
246 CHKERR iNitailise(fe_method);
247 isInitialised = true;
248 }
249 if (gg == 0) {
250 CHKERR getKappa(common_data.gapGlob.size1(), fe_method);
251 }
252 double g = calcG(gg, common_data.gapLoc);
253 double kappa = fmax(g - g0, kappaPtr[gg]);
254 double omega = 0;
256 int iter;
257 CHKERR SNESGetIterationNumber(fe_method->snes, &iter);
258 if ((kappa <= kappaPtr[gg]) || (kappa >= kappa1) || (iter <= 1)) {
259 CHKERR calcDglob(omega, common_data.R[gg]);
260 } else {
261 ublas::matrix_row<MatrixDouble> g_loc(common_data.gapLoc, gg);
262 CHKERR calcTangetDglob(omega, g, g_loc, common_data.R[gg]);
263 }
264 tangent_matrix.resize(3, 3);
265 noalias(tangent_matrix) = Dglob;
266 } catch (const std::exception &ex) {
267 std::ostringstream ss;
268 ss << "throw in method: " << ex.what() << std::endl;
269 SETERRQ(PETSC_COMM_SELF, 1, ss.str().c_str());
270 }
272 }
273
274 /** \brief Update history variables when converged
275 */
276 virtual MoFEMErrorCode updateHistory(CommonData &common_data,
277 const FEMethod *fe_method) {
279
280 if (!isInitialised) {
281 CHKERR iNitailise(fe_method);
282 isInitialised = true;
283 }
284 CHKERR getKappa(common_data.gapGlob.size1(), fe_method);
285 bool all_gauss_pts_damaged = true;
286 for (unsigned int gg = 0; gg < common_data.gapGlob.size1(); gg++) {
287 double omega = 0;
288 double g = calcG(gg, common_data.gapLoc);
289 double kappa = fmax(g - g0, kappaPtr[gg]);
290 kappaPtr[gg] = kappa;
292 //if(omega < 1.) {
293 all_gauss_pts_damaged = false;
294 //}
295 }
296 if (all_gauss_pts_damaged) {
297 EntityHandle ent = fe_method->numeredEntFiniteElementPtr->getEnt();
298 int set_prism_as_demaged = 1;
299 CHKERR mField.get_moab().tag_set_data(thDamagedPrism, &ent, 1,
300 &set_prism_as_demaged);
301 }
303 }
304 };
305
306 /** \brief Set negative sign to shape functions on face 4
307 */
309 : public FlatPrismElementForcesAndSourcesCore::UserDataOperator {
310
312 : FlatPrismElementForcesAndSourcesCore::UserDataOperator(
314
315 MoFEMErrorCode doWork(int side, EntityType type,
316 EntitiesFieldData::EntData &data) {
318 if (data.getN().size1() == 0)
320 if (data.getN().size2() == 0)
322 switch (type) {
323 case MBVERTEX:
324 for (unsigned int gg = 0; gg < data.getN().size1(); gg++) {
325 for (int nn = 3; nn < 6; nn++) {
326 data.getN()(gg, nn) *= -1;
327 }
328 }
329 break;
330 case MBEDGE:
331 if (side < 3)
333 data.getN() *= -1;
334 break;
335 case MBTRI:
336 if (side == 3)
338 data.getN() *= -1;
339 break;
340 default:
341 SETERRQ(PETSC_COMM_SELF, 1, "data inconsitency");
342 }
344 }
345 };
346
347 /** \brief Operator calculate gap, normal vector and rotation matrix
348 */
350 : public FlatPrismElementForcesAndSourcesCore::UserDataOperator {
351
353 OpCalculateGapGlobal(const std::string field_name, CommonData &common_data)
354 : FlatPrismElementForcesAndSourcesCore::UserDataOperator(
356 commonData(common_data) {}
357
358 MoFEMErrorCode doWork(int side, EntityType type,
359 EntitiesFieldData::EntData &data) {
361 try {
362 int nb_dofs = data.getIndices().size();
363 if (nb_dofs == 0)
365 int nb_gauss_pts = data.getN().size1();
366 if (type == MBVERTEX) {
367 commonData.R.resize(nb_gauss_pts);
368 for (int gg = 0; gg < nb_gauss_pts; gg++) {
369 commonData.R[gg].resize(3, 3);
370 double nrm2_normal = 0;
371 double nrm2_tangent1 = 0;
372 double nrm2_tangent2 = 0;
373 for (int dd = 0; dd < 3; dd++) {
374 nrm2_normal += pow(getNormalsAtGaussPtsF3()(gg, dd), 2);
375 nrm2_tangent1 += pow(getTangent1AtGaussPtF3()(gg, dd), 2);
376 nrm2_tangent2 += pow(getTangent2AtGaussPtF3()(gg, dd), 2);
377 }
378 nrm2_normal = sqrt(nrm2_normal);
379 nrm2_tangent1 = sqrt(nrm2_tangent1);
380 nrm2_tangent2 = sqrt(nrm2_tangent2);
381 for (int dd = 0; dd < 3; dd++) {
382 commonData.R[gg](0, dd) =
383 getNormalsAtGaussPtsF3()(gg, dd) / nrm2_normal;
384 commonData.R[gg](1, dd) =
385 getTangent1AtGaussPtF3()(gg, dd) / nrm2_tangent1;
386 commonData.R[gg](2, dd) =
387 getTangent2AtGaussPtF3()(gg, dd) / nrm2_tangent2;
388 }
389 }
390 }
391 if (type == MBVERTEX) {
392 commonData.gapGlob.resize(nb_gauss_pts, 3);
393 commonData.gapGlob.clear();
394 }
395 for (int gg = 0; gg < nb_gauss_pts; gg++) {
396 for (int dd = 0; dd < 3; dd++) {
397 commonData.gapGlob(gg, dd) += cblas_ddot(
398 nb_dofs / 3, &data.getN(gg)[0], 1, &data.getFieldData()[dd], 3);
399 }
400 }
401 } catch (const std::exception &ex) {
402 std::ostringstream ss;
403 ss << "throw in method: " << ex.what() << std::endl;
404 SETERRQ(PETSC_COMM_SELF, 1, ss.str().c_str());
405 }
407 }
408 };
409
410 /** \brief Operator calculate gap in local coordinate system
411 */
413 : public FlatPrismElementForcesAndSourcesCore::UserDataOperator {
414
416 OpCalculateGapLocal(const std::string field_name, CommonData &common_data)
417 : FlatPrismElementForcesAndSourcesCore::UserDataOperator(
419 commonData(common_data) {}
420
421 MoFEMErrorCode doWork(int side, EntityType type,
422 EntitiesFieldData::EntData &data) {
424 try {
425 if (type == MBVERTEX) {
426 int nb_gauss_pts = data.getN().size1();
427 commonData.gapLoc.resize(nb_gauss_pts, 3);
428 for (int gg = 0; gg < nb_gauss_pts; gg++) {
429 ublas::matrix_row<MatrixDouble> gap_glob(commonData.gapGlob, gg);
430 ublas::matrix_row<MatrixDouble> gap_loc(commonData.gapLoc, gg);
431 gap_loc = prod(commonData.R[gg], gap_glob);
432 }
433 }
434 } catch (const std::exception &ex) {
435 std::ostringstream ss;
436 ss << "throw in method: " << ex.what() << std::endl;
437 SETERRQ(PETSC_COMM_SELF, 1, ss.str().c_str());
438 }
440 }
441 };
442
443 /** \brief Operator calculate right hand side vector
444 */
445 struct OpRhs : public FlatPrismElementForcesAndSourcesCore::UserDataOperator {
446
449 OpRhs(const std::string field_name, CommonData &common_data,
450 PhysicalEquation &physical_eqations)
451 : FlatPrismElementForcesAndSourcesCore::UserDataOperator(
453 commonData(common_data), physicalEqations(physical_eqations) {}
454
455 VectorDouble traction, Nf;
456 MoFEMErrorCode doWork(int side, EntityType type,
457 EntitiesFieldData::EntData &data) {
459
460 try {
461 int nb_dofs = data.getIndices().size();
462 if (nb_dofs == 0)
464 if (physicalEqations.pRisms.find(
465 getNumeredEntFiniteElementPtr()->getEnt()) ==
466 physicalEqations.pRisms.end()) {
468 }
469 Nf.resize(nb_dofs);
470 Nf.clear();
471 int nb_gauss_pts = data.getN().size1();
472 for (int gg = 0; gg < nb_gauss_pts; gg++) {
474 getFEMethod());
475 double w = getGaussPts()(2, gg) *
476 cblas_dnrm2(3, &getNormalsAtGaussPtsF3()(gg, 0), 1) * 0.5;
477 for (int nn = 0; nn < nb_dofs / 3; nn++) {
478 for (int dd = 0; dd < 3; dd++) {
479 Nf[3 * nn + dd] += w * data.getN(gg)[nn] * traction[dd];
480 }
481 }
482 }
483 CHKERR VecSetValues(getFEMethod()->snes_f, data.getIndices().size(),
484 &data.getIndices()[0], &Nf[0], ADD_VALUES);
485 } catch (const std::exception &ex) {
486 std::ostringstream ss;
487 ss << "throw in method: " << ex.what() << std::endl;
488 SETERRQ(PETSC_COMM_SELF, 1, ss.str().c_str());
489 }
491 }
492 };
493
494 /** \brief Operator calculate element stiffens matrix
495 */
496 struct OpLhs : public FlatPrismElementForcesAndSourcesCore::UserDataOperator {
497
500 OpLhs(const std::string field_name, CommonData &common_data,
501 PhysicalEquation &physical_eqations)
502 : FlatPrismElementForcesAndSourcesCore::UserDataOperator(
504 commonData(common_data), physicalEqations(physical_eqations) {
505 sYmm = false;
506 }
507
508 MatrixDouble K, D, ND;
509 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
510 EntityType col_type,
511 EntitiesFieldData::EntData &row_data,
512 EntitiesFieldData::EntData &col_data) {
514
515 try {
516 int nb_row = row_data.getIndices().size();
517 if (nb_row == 0)
519 int nb_col = col_data.getIndices().size();
520 if (nb_col == 0)
522 if (physicalEqations.pRisms.find(
523 getNumeredEntFiniteElementPtr()->getEnt()) ==
524 physicalEqations.pRisms.end()) {
526 }
527 ND.resize(nb_row, 3);
528 K.resize(nb_row, nb_col);
529 K.clear();
530 int nb_gauss_pts = row_data.getN().size1();
531 for (int gg = 0; gg < nb_gauss_pts; gg++) {
533 getFEMethod());
534 double w = getGaussPts()(2, gg) *
535 cblas_dnrm2(3, &getNormalsAtGaussPtsF3()(gg, 0), 1) * 0.5;
536 ND.clear();
537 for (int nn = 0; nn < nb_row / 3; nn++) {
538 for (int dd = 0; dd < 3; dd++) {
539 for (int DD = 0; DD < 3; DD++) {
540 ND(3 * nn + dd, DD) += row_data.getN(gg)[nn] * D(dd, DD);
541 }
542 }
543 }
544 for (int nn = 0; nn < nb_row / 3; nn++) {
545 for (int dd = 0; dd < 3; dd++) {
546 for (int NN = 0; NN < nb_col / 3; NN++) {
547 for (int DD = 0; DD < 3; DD++) {
548 K(3 * nn + dd, 3 * NN + DD) +=
549 w * ND(3 * nn + dd, DD) * col_data.getN(gg)[NN];
550 }
551 }
552 }
553 }
554 }
555 CHKERR MatSetValues(getFEMethod()->snes_B, nb_row,
556 &row_data.getIndices()[0], nb_col,
557 &col_data.getIndices()[0], &K(0, 0), ADD_VALUES);
558 } catch (const std::exception &ex) {
559 std::ostringstream ss;
560 ss << "throw in method: " << ex.what() << std::endl;
561 SETERRQ(PETSC_COMM_SELF, 1, ss.str().c_str());
562 }
564 }
565 };
566
567 /** \brief Operator update history variables
568 */
570 : public FlatPrismElementForcesAndSourcesCore::UserDataOperator {
571
574 OpHistory(const std::string field_name, CommonData &common_data,
575 PhysicalEquation &physical_eqations)
576 : FlatPrismElementForcesAndSourcesCore::UserDataOperator(
578 commonData(common_data), physicalEqations(physical_eqations) {}
579
580 MoFEMErrorCode doWork(int side, EntityType type,
581 EntitiesFieldData::EntData &data) {
583
584 if (type != MBVERTEX)
586 if (physicalEqations.pRisms.find(
587 getNumeredEntFiniteElementPtr()->getEnt()) ==
588 physicalEqations.pRisms.end()) {
590 }
593 }
594 };
595
596 /** \brief Driver function settting all operators needed for interface element
597 */
598 MoFEMErrorCode
599 addOps(const std::string field_name,
600 boost::ptr_vector<CohesiveInterfaceElement::PhysicalEquation>
601 &interfaces) {
603
604 //Rhs
606 feRhs.getOpPtrVector().push_back(
608 feRhs.getOpPtrVector().push_back(
610 //Lhs
612 feLhs.getOpPtrVector().push_back(
614 feLhs.getOpPtrVector().push_back(
616 //History
617 feHistory.getOpPtrVector().push_back(
619 feHistory.getOpPtrVector().push_back(
621 feHistory.getOpPtrVector().push_back(
623
624 //add equations/data for physical interfaces
625 boost::ptr_vector<CohesiveInterfaceElement::PhysicalEquation>::iterator pit;
626 for (pit = interfaces.begin(); pit != interfaces.end(); pit++) {
627 feRhs.getOpPtrVector().push_back(new OpRhs(field_name, commonData, *pit));
628 feLhs.getOpPtrVector().push_back(new OpLhs(field_name, commonData, *pit));
629 feHistory.getOpPtrVector().push_back(
630 new OpHistory(field_name, commonData, *pit));
631 }
632
634 }
635};
636
637} // namespace CohesiveElement
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 CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
constexpr int order
constexpr double omega
Save field DOFS on vertices/tags.
double kappa
@ R
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
constexpr auto field_name
constexpr double g
Operator calculate gap, normal vector and rotation matrix.
OpCalculateGapGlobal(const std::string field_name, CommonData &common_data)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
OpCalculateGapLocal(const std::string field_name, CommonData &common_data)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
OpHistory(const std::string field_name, CommonData &common_data, PhysicalEquation &physical_eqations)
Operator calculate element stiffens matrix.
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
OpLhs(const std::string field_name, CommonData &common_data, PhysicalEquation &physical_eqations)
OpRhs(const std::string field_name, CommonData &common_data, PhysicalEquation &physical_eqations)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
double calcG(int gg, MatrixDouble gap_loc)
Calculate gap opening.
virtual MoFEMErrorCode calculateTangentStiffeness(MatrixDouble &tangent_matrix, int gg, CommonData &common_data, const FEMethod *fe_method)
Calculate tangent stiffness.
MoFEMErrorCode iNitailise(const FEMethod *fe_method)
Initialize history variable data.
MoFEMErrorCode calcOmega(const double kappa, double &omega)
Calculate damage.
MoFEMErrorCode calcTangetDglob(const double omega, double g, const VectorDouble &gap_loc, MatrixDouble &R)
Calculate tangent material stiffness.
MoFEMErrorCode calcDglob(const double omega, MatrixDouble &R)
Calculate stiffness material matrix.
virtual MoFEMErrorCode updateHistory(CommonData &common_data, const FEMethod *fe_method)
Update history variables when converged.
MoFEMErrorCode getKappa(int nb_gauss_pts, const FEMethod *fe_method)
Get pointer from the mesh to histoy variables .
virtual MoFEMErrorCode calculateTraction(VectorDouble &traction, int gg, CommonData &common_data, const FEMethod *fe_method)
Calculate tractions.
MoFEMErrorCode addOps(const std::string field_name, boost::ptr_vector< CohesiveInterfaceElement::PhysicalEquation > &interfaces)
Driver function settting all operators needed for interface element.
virtual moab::Interface & get_moab()=0
Deprecated interface functions.
boost::ptr_deque< UserDataOperator > & getOpPtrVector()
Use to push back operator for row operator.