v0.16.0
Loading...
Searching...
No Matches
HookeElement.cpp
Go to the documentation of this file.
1/** \file HookeElement.cpp
2 * \example mofem/users_modules/basic_finite_elements/src/impl/HookeElement.cpp
3 * \brief Operators and data structures for linear elastic analysis
4 *
5 * See as well header file HookeElement.hpp
6 *
7 * Implemention of operators for Hooke material. Implementation is extended to
8 * the case when the mesh is moving as results of topological changes, also the
9 * calculation of material forces and associated tangent matrices are added to
10 * implementation.
11 *
12 * In other words spatial deformation is small but topological changes large.
13
14 */
15
16
17
18#include <MoFEM.hpp>
19using namespace MoFEM;
20#include <HookeElement.hpp>
21
22HookeElement::OpCalculateStrainAle::OpCalculateStrainAle(
23 const std::string row_field, const std::string col_field,
24 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
25 : VolUserDataOperator(row_field, col_field, OPROW, false),
26 dataAtPts(data_at_pts) {
27 std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE], false);
28}
29
30MoFEMErrorCode HookeElement::OpCalculateStrainAle::doWork(int row_side,
31 EntityType row_type,
32 EntData &row_data) {
34 FTensor::Index<'i', 3> i;
35 FTensor::Index<'j', 3> j;
36 FTensor::Index<'k', 3> k;
37 // get number of integration points
38 const int nb_integration_pts = getGaussPts().size2();
39 auto t_h = getFTensor2FromMat<3, 3>(*dataAtPts->hMat);
40 auto t_H = getFTensor2FromMat<3, 3>(*dataAtPts->HMat);
41
42 dataAtPts->detHVec->resize(nb_integration_pts, false);
43 dataAtPts->invHMat->resize(9, nb_integration_pts, false);
44 dataAtPts->FMat->resize(9, nb_integration_pts, false);
45 dataAtPts->smallStrainMat->resize(6, nb_integration_pts, false);
46
47 auto t_detH = getFTensor0FromVec(*dataAtPts->detHVec);
48 auto t_invH =
49 getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->invHMat);
50 auto t_F = getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->FMat);
51 auto t_strain = getFTensor2SymmetricFromMat<3, -1, CoeffsByGauss>(
52 *dataAtPts->smallStrainMat);
53
54 for (int gg = 0; gg != nb_integration_pts; ++gg) {
55 CHKERR determinantTensor3by3(t_H, t_detH);
56 CHKERR invertTensor3by3(t_H, t_detH, t_invH);
57 t_F(i, j) = t_h(i, k) * t_invH(k, j);
58 t_strain(i, j) = (t_F(i, j) || t_F(j, i)) / 2.;
59
60 t_strain(0, 0) -= 1;
61 t_strain(1, 1) -= 1;
62 t_strain(2, 2) -= 1;
63
64 ++t_strain;
65 ++t_h;
66 ++t_H;
67 ++t_detH;
68 ++t_invH;
69 ++t_F;
70 }
72}
73
74HookeElement::OpCalculateEnergy::OpCalculateEnergy(
75 const std::string row_field, const std::string col_field,
76 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
77 SmartPetscObj<Vec> ghost_vec)
78 : VolUserDataOperator(row_field, col_field, OPROW, true),
79 dataAtPts(data_at_pts), ghostVec(ghost_vec, true) {
80 std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE], false);
81}
82
83MoFEMErrorCode HookeElement::OpCalculateEnergy::doWork(int row_side,
84 EntityType row_type,
85 EntData &row_data) {
87
88 // get number of integration points
89 const int nb_integration_pts = getGaussPts().size2();
90 auto t_strain = getFTensor2SymmetricFromMat<3, -1, CoeffsByGauss>(
91 *(dataAtPts->smallStrainMat));
92 auto t_cauchy_stress =
94 *(dataAtPts->cauchyStressMat));
95 dataAtPts->energyVec->resize(nb_integration_pts, false);
97 &*(dataAtPts->energyVec->data().begin()));
98
99 FTensor::Index<'i', 3> i;
100 FTensor::Index<'j', 3> j;
101
102 for (int gg = 0; gg != nb_integration_pts; ++gg) {
103 t_energy = (t_strain(i, j) * t_cauchy_stress(i, j)) / 2.;
104 ++t_strain;
105 ++t_cauchy_stress;
106 ++t_energy;
107 }
108
109 if (ghostVec.get()) {
110 // get element volume
111 double vol = getVolume();
112 // get intergrayion weights
113 auto t_w = getFTensor0IntegrationWeight();
114 auto &det_H = *dataAtPts->detHVec;
116 &*(dataAtPts->energyVec->data().begin()));
117 double energy = 0;
118 for (int gg = 0; gg != nb_integration_pts; ++gg) {
119 // calculate scalar weight times element volume
120 double a = t_w * vol;
121 if (det_H.size()) {
122 a *= det_H[gg];
123 }
124 energy += a * t_energy;
125 ++t_energy;
126 ++t_w;
127 }
128 CHKERR VecSetValue(ghostVec, 0, energy, ADD_VALUES);
129 }
130
132}
133
134HookeElement::OpCalculateEshelbyStress::OpCalculateEshelbyStress(
135 const std::string row_field, const std::string col_field,
136 boost::shared_ptr<DataAtIntegrationPts> data_at_pts)
137 : VolUserDataOperator(row_field, col_field, OPROW, true),
138 dataAtPts(data_at_pts) {
139 std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE], false);
140}
141
142MoFEMErrorCode HookeElement::OpCalculateEshelbyStress::doWork(
143 int row_side, EntityType row_type, EntData &row_data) {
145 // get number of integration points
146 const int nb_integration_pts = getGaussPts().size2();
148 &*(dataAtPts->energyVec->data().begin()));
149 auto t_cauchy_stress =
151 *(dataAtPts->cauchyStressMat));
152 auto t_F = getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(
153 *(dataAtPts->FMat));
154 dataAtPts->eshelbyStressMat->resize(9, nb_integration_pts, false);
155 auto t_eshelby_stress =
157 *(dataAtPts->eshelbyStressMat));
158
159 FTensor::Index<'i', 3> i;
160 FTensor::Index<'j', 3> j;
161 FTensor::Index<'k', 3> k;
162
163 for (int gg = 0; gg != nb_integration_pts; ++gg) {
164 t_eshelby_stress(i, j) = -t_F(k, i) * t_cauchy_stress(k, j);
165 t_eshelby_stress(0, 0) += t_energy;
166 t_eshelby_stress(1, 1) += t_energy;
167 t_eshelby_stress(2, 2) += t_energy;
168 ++t_cauchy_stress;
169 ++t_energy;
170 ++t_eshelby_stress;
171 ++t_F;
172 }
174}
175
176HookeElement::OpAssemble::OpAssemble(
177 const std::string row_field, const std::string col_field,
178 boost::shared_ptr<DataAtIntegrationPts> data_at_pts, const char type,
179 bool symm)
180 : VolUserDataOperator(row_field, col_field, type, symm),
181 dataAtPts(data_at_pts) {}
182
183MoFEMErrorCode HookeElement::OpAssemble::doWork(int row_side, int col_side,
184 EntityType row_type,
185 EntityType col_type,
186 EntData &row_data,
187 EntData &col_data) {
188
190
191 // get number of dofs on row
192 nbRows = row_data.getIndices().size();
193 // if no dofs on row, exit that work, nothing to do here
194 if (!nbRows)
196
197 // get number of dofs on column
198 nbCols = col_data.getIndices().size();
199 // if no dofs on Columbia, exit nothing to do here
200 if (!nbCols)
202
203 // K_ij matrix will have 3 times the number of degrees of freedom of the
204 // i-th entity set (nbRows)
205 // and 3 times the number of degrees of freedom of the j-th entity set
206 // (nbCols)
207 K.resize(nbRows, nbCols, false);
208 K.clear();
209
210 // get number of integration points
211 nbIntegrationPts = getGaussPts().size2();
212 // check if entity block is on matrix diagonal
213 if (row_side == col_side && row_type == col_type) {
214 isDiag = true;
215 } else {
216 isDiag = false;
217 }
218
219 // integrate local matrix for entity block
220 CHKERR iNtegrate(row_data, col_data);
221
222 // assemble local matrix
223 CHKERR aSsemble(row_data, col_data);
224
226}
227
228MoFEMErrorCode HookeElement::OpAssemble::doWork(int row_side,
229 EntityType row_type,
230 EntData &row_data) {
232
233 // get number of dofs on row
234 nbRows = row_data.getIndices().size();
235 // if no dofs on row, exit that work, nothing to do here
236 if (!nbRows)
238
239 nF.resize(nbRows, false);
240 nF.clear();
241
242 // get number of integration points
243 nbIntegrationPts = getGaussPts().size2();
244
245 // integrate local matrix for entity block
246 CHKERR iNtegrate(row_data);
247
248 // assemble local matrix
249 CHKERR aSsemble(row_data);
250
252}
253
254MoFEMErrorCode HookeElement::OpAssemble::iNtegrate(EntData &row_data,
255 EntData &col_data) {
257 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
259};
260
261MoFEMErrorCode HookeElement::OpAssemble::iNtegrate(EntData &row_data) {
263 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
265};
266
267MoFEMErrorCode HookeElement::OpAssemble::aSsemble(EntData &row_data,
268 EntData &col_data) {
270
271 // get pointer to first global index on row
272 const int *row_indices = &*row_data.getIndices().data().begin();
273 // get pointer to first global index on column
274 const int *col_indices = &*col_data.getIndices().data().begin();
275
276 auto &data = *dataAtPts;
277 if (!data.forcesOnlyOnEntitiesRow.empty()) {
278 rowIndices.resize(nbRows, false);
279 noalias(rowIndices) = row_data.getIndices();
280 row_indices = &rowIndices[0];
281 VectorDofs &dofs = row_data.getFieldDofs();
282 VectorDofs::iterator dit = dofs.begin();
283 for (int ii = 0; dit != dofs.end(); dit++, ii++) {
284 if (data.forcesOnlyOnEntitiesRow.find((*dit)->getEnt()) ==
285 data.forcesOnlyOnEntitiesRow.end()) {
286 rowIndices[ii] = -1;
287 }
288 }
289 }
290
291 if (!data.forcesOnlyOnEntitiesCol.empty()) {
292 colIndices.resize(nbCols, false);
293 noalias(colIndices) = col_data.getIndices();
294 col_indices = &colIndices[0];
295 VectorDofs &dofs = col_data.getFieldDofs();
296 VectorDofs::iterator dit = dofs.begin();
297 for (int ii = 0; dit != dofs.end(); dit++, ii++) {
298 if (data.forcesOnlyOnEntitiesCol.find((*dit)->getEnt()) ==
299 data.forcesOnlyOnEntitiesCol.end()) {
300 colIndices[ii] = -1;
301 }
302 }
303 }
304
305 Mat B = getFEMethod()->ksp_B != PETSC_NULLPTR ? getFEMethod()->ksp_B
306 : getFEMethod()->snes_B;
307 // assemble local matrix
308 CHKERR MatSetValues(B, nbRows, row_indices, nbCols, col_indices,
309 &*K.data().begin(), ADD_VALUES);
310
311 if (!isDiag && sYmm) {
312 // if not diagonal term and since global matrix is symmetric assemble
313 // transpose term.
314 transK.resize(K.size2(), K.size1(), false);
315 noalias(transK) = trans(K);
316 CHKERR MatSetValues(B, nbCols, col_indices, nbRows, row_indices,
317 &*transK.data().begin(), ADD_VALUES);
318 }
320}
321
322MoFEMErrorCode HookeElement::OpAssemble::aSsemble(EntData &row_data) {
324
325 // get pointer to first global index on row
326 const int *row_indices = &*row_data.getIndices().data().begin();
327
328 auto &data = *dataAtPts;
329 if (!data.forcesOnlyOnEntitiesRow.empty()) {
330 rowIndices.resize(nbRows, false);
331 noalias(rowIndices) = row_data.getIndices();
332 row_indices = &rowIndices[0];
333 VectorDofs &dofs = row_data.getFieldDofs();
334 VectorDofs::iterator dit = dofs.begin();
335 for (int ii = 0; dit != dofs.end(); dit++, ii++) {
336 if (data.forcesOnlyOnEntitiesRow.find((*dit)->getEnt()) ==
337 data.forcesOnlyOnEntitiesRow.end()) {
338 rowIndices[ii] = -1;
339 }
340 }
341 }
342
343 Vec F = getFEMethod()->snes_f;
344 // assemble local matrix
345 CHKERR VecSetValues(F, nbRows, row_indices, &*nF.data().begin(), ADD_VALUES);
347}
348
349HookeElement::OpRhs_dx::OpRhs_dx(
350 const std::string row_field, const std::string col_field,
351 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
352 : OpAssemble(row_field, col_field, data_at_pts, OPROW) {}
353
354MoFEMErrorCode HookeElement::OpRhs_dx::iNtegrate(EntData &row_data) {
356
357 auto get_tensor1 = [](VectorDouble &v, const int r) {
359 &v(r + 0), &v(r + 1), &v(r + 2));
360 };
361
362 FTensor::Index<'i', 3> i;
363 FTensor::Index<'j', 3> j;
364 FTensor::Index<'k', 3> k;
365 FTensor::Index<'l', 3> l;
366
367 // get element volume
368 double vol = getVolume();
369 // get intergrayion weights
370 auto t_w = getFTensor0IntegrationWeight();
371
372 // get derivatives of base functions on rows
373 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
374 const int row_nb_base_fun = row_data.getN().size2();
375 auto t_cauchy_stress =
377 *dataAtPts->cauchyStressMat);
378
379 // iterate over integration points
380 for (int gg = 0; gg != nbIntegrationPts; ++gg) {
381
382 // calculate scalar weight times element volume
383 double a = t_w * vol;
384 auto t_nf = get_tensor1(nF, 0);
385
386 int rr = 0;
387 for (; rr != nbRows / 3; ++rr) {
388 t_nf(i) += a * t_row_diff_base(j) * t_cauchy_stress(i, j);
389 ++t_row_diff_base;
390 ++t_nf;
391 }
392
393 for (; rr != row_nb_base_fun; ++rr)
394 ++t_row_diff_base;
395
396 ++t_w;
397 ++t_cauchy_stress;
398 }
399
401}
402
403HookeElement::OpAleRhs_dx::OpAleRhs_dx(
404 const std::string row_field, const std::string col_field,
405 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
406 : OpAssemble(row_field, col_field, data_at_pts, OPROW) {}
407
408MoFEMErrorCode HookeElement::OpAleRhs_dx::iNtegrate(EntData &row_data) {
410
411 auto get_tensor1 = [](VectorDouble &v, const int r) {
413 &v(r + 0), &v(r + 1), &v(r + 2));
414 };
415
416 FTensor::Index<'i', 3> i;
417 FTensor::Index<'j', 3> j;
418
419 // get element volume
420 double vol = getVolume();
421 // get intergrayion weights
422 auto t_w = getFTensor0IntegrationWeight();
423
424 // get derivatives of base functions on rows
425 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
426 const int row_nb_base_fun = row_data.getN().size2();
427 auto t_cauchy_stress =
429 *dataAtPts->cauchyStressMat);
430 auto &det_H = *dataAtPts->detHVec;
431 auto t_invH =
432 getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->invHMat);
433
434 // iterate over integration points
435 for (int gg = 0; gg != nbIntegrationPts; ++gg) {
436
437 // calculate scalar weight times element volume
438 double a = t_w * vol * det_H[gg];
439 auto t_nf = get_tensor1(nF, 0);
440
441 int rr = 0;
442 for (; rr != nbRows / 3; ++rr) {
443 FTensor::Tensor1<double, 3> t_row_diff_base_pulled;
444 t_row_diff_base_pulled(i) = t_row_diff_base(j) * t_invH(j, i);
445 t_nf(i) += a * t_row_diff_base_pulled(j) * t_cauchy_stress(i, j);
446 ++t_row_diff_base;
447 ++t_nf;
448 }
449
450 for (; rr != row_nb_base_fun; ++rr)
451 ++t_row_diff_base;
452
453 ++t_w;
454 ++t_cauchy_stress;
455 ++t_invH;
456 }
457
459}
460
461HookeElement::OpAleRhs_dX::OpAleRhs_dX(
462 const std::string row_field, const std::string col_field,
463 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts)
464 : OpAssemble(row_field, col_field, data_at_pts, OPROW) {}
465
466MoFEMErrorCode HookeElement::OpAleRhs_dX::iNtegrate(EntData &row_data) {
468
469 auto get_tensor1 = [](VectorDouble &v, const int r) {
471 &v(r + 0), &v(r + 1), &v(r + 2));
472 };
473
474 FTensor::Index<'i', 3> i;
475 FTensor::Index<'j', 3> j;
476
477 // get element volume
478 double vol = getVolume();
479 // get intergrayion weights
480 auto t_w = getFTensor0IntegrationWeight();
481
482 // get derivatives of base functions on rows
483 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
484 const int row_nb_base_fun = row_data.getN().size2();
485 auto t_eshelby_stress =
487 *dataAtPts->eshelbyStressMat);
488 auto &det_H = *dataAtPts->detHVec;
489 auto t_invH =
490 getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->invHMat);
491
492 // iterate over integration points
493 for (int gg = 0; gg != nbIntegrationPts; ++gg) {
494
495 // calculate scalar weight times element volume
496 double a = t_w * vol * det_H[gg];
497 auto t_nf = get_tensor1(nF, 0);
498
499 int rr = 0;
500 for (; rr != nbRows / 3; ++rr) {
501 FTensor::Tensor1<double, 3> t_row_diff_base_pulled;
502 t_row_diff_base_pulled(i) = t_row_diff_base(j) * t_invH(j, i);
503 t_nf(i) += a * t_row_diff_base_pulled(j) * t_eshelby_stress(i, j);
504 ++t_row_diff_base;
505 ++t_nf;
506 }
507
508 for (; rr != row_nb_base_fun; ++rr)
509 ++t_row_diff_base;
510
511 ++t_w;
512 ++t_eshelby_stress;
513 ++t_invH;
514 }
515
517}
518
519MoFEMErrorCode HookeElement::setBlocks(
520 MoFEM::Interface &m_field,
521 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr) {
523
524 if (!block_sets_ptr)
525 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
526 "Pointer to block of sets is null");
527
529 m_field, BLOCKSET | MAT_ELASTICSET, it)) {
530 Mat_Elastic mydata;
531 CHKERR it->getAttributeDataStructure(mydata);
532 int id = it->getMeshsetId();
533 auto &block_data = (*block_sets_ptr)[id];
534 EntityHandle meshset = it->getMeshset();
535 CHKERR m_field.get_moab().get_entities_by_dimension(meshset, 3,
536 block_data.tEts, true);
537 block_data.iD = id;
538 block_data.E = mydata.data.Young;
539 block_data.PoissonRatio = mydata.data.Poisson;
540 }
541
543}
544
545MoFEMErrorCode HookeElement::addElasticElement(
546 MoFEM::Interface &m_field,
547 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr,
548 const std::string element_name, const std::string x_field,
549 const std::string X_field, const bool ale) {
551
552 if (!block_sets_ptr)
553 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
554 "Pointer to block of sets is null");
555
556 CHKERR m_field.add_finite_element(element_name, MF_ZERO);
557 CHKERR m_field.modify_finite_element_add_field_row(element_name, x_field);
558 CHKERR m_field.modify_finite_element_add_field_col(element_name, x_field);
559 CHKERR m_field.modify_finite_element_add_field_data(element_name, x_field);
560 if (m_field.check_field(X_field)) {
561 if (ale) {
562 CHKERR m_field.modify_finite_element_add_field_row(element_name, X_field);
563 CHKERR m_field.modify_finite_element_add_field_col(element_name, X_field);
564 }
565 CHKERR m_field.modify_finite_element_add_field_data(element_name, X_field);
566 }
567
568 for (auto &m : (*block_sets_ptr)) {
569 CHKERR m_field.add_ents_to_finite_element_by_dim(m.second.tEts, 3,
570 element_name);
571 }
572
574}
575
576MoFEMErrorCode HookeElement::setOperators(
577 boost::shared_ptr<ForcesAndSourcesCore> fe_lhs_ptr,
578 boost::shared_ptr<ForcesAndSourcesCore> fe_rhs_ptr,
579 boost::shared_ptr<map<int, BlockData>> block_sets_ptr,
580 const std::string x_field, const std::string X_field, const bool ale,
581 const bool field_disp, const EntityType type,
582 boost::shared_ptr<DataAtIntegrationPts> data_at_pts) {
584
585 if (!block_sets_ptr)
586 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
587 "Pointer to block of sets is null");
588
589 if (!data_at_pts)
590 data_at_pts = boost::make_shared<DataAtIntegrationPts>();
591
592 if (fe_lhs_ptr) {
593 if (ale == PETSC_FALSE) {
594 if (type == MBPRISM) {
595 boost::shared_ptr<MatrixDouble> inv_jac_ptr(new MatrixDouble);
596 fe_lhs_ptr->getOpPtrVector().push_back(
597 new OpCalculateInvJacForFatPrism(inv_jac_ptr));
598 fe_lhs_ptr->getOpPtrVector().push_back(
599 new OpSetInvJacH1ForFatPrism(inv_jac_ptr));
600 }
601 fe_lhs_ptr->getOpPtrVector().push_back(
603 x_field, x_field, block_sets_ptr, data_at_pts));
604 fe_lhs_ptr->getOpPtrVector().push_back(
605 new OpLhs_dx_dx<0>(x_field, x_field, data_at_pts));
606 } else {
607 if (type == MBPRISM) {
608 boost::shared_ptr<MatrixDouble> inv_jac_ptr(new MatrixDouble);
609 fe_lhs_ptr->getOpPtrVector().push_back(
610 new OpCalculateInvJacForFatPrism(inv_jac_ptr));
611 fe_lhs_ptr->getOpPtrVector().push_back(
612 new OpSetInvJacH1ForFatPrism(inv_jac_ptr));
613 }
614 fe_lhs_ptr->getOpPtrVector().push_back(
615 new OpCalculateVectorFieldGradient<3, 3>(X_field, data_at_pts->HMat));
616 fe_lhs_ptr->getOpPtrVector().push_back(
618 x_field, x_field, block_sets_ptr, data_at_pts));
619 fe_lhs_ptr->getOpPtrVector().push_back(
620 new OpCalculateVectorFieldGradient<3, 3>(x_field, data_at_pts->hMat));
621 fe_lhs_ptr->getOpPtrVector().push_back(
622 new OpCalculateStrainAle(x_field, x_field, data_at_pts));
623 fe_lhs_ptr->getOpPtrVector().push_back(
624 new OpCalculateStress<0>(x_field, x_field, data_at_pts));
625 fe_lhs_ptr->getOpPtrVector().push_back(
626 new OpAleLhs_dx_dx<0>(x_field, x_field, data_at_pts));
627 fe_lhs_ptr->getOpPtrVector().push_back(
628 new OpAleLhs_dx_dX<0>(x_field, X_field, data_at_pts));
629 fe_lhs_ptr->getOpPtrVector().push_back(
630 new OpCalculateEnergy(X_field, X_field, data_at_pts));
631 fe_lhs_ptr->getOpPtrVector().push_back(
632 new OpCalculateEshelbyStress(X_field, X_field, data_at_pts));
633 fe_lhs_ptr->getOpPtrVector().push_back(
634 new OpAleLhs_dX_dX<0>(X_field, X_field, data_at_pts));
635 fe_lhs_ptr->getOpPtrVector().push_back(
636 new OpAleLhsPre_dX_dx<0>(X_field, x_field, data_at_pts));
637 fe_lhs_ptr->getOpPtrVector().push_back(
638 new OpAleLhs_dX_dx(X_field, x_field, data_at_pts));
639 }
640 }
641
642 if (fe_rhs_ptr) {
643
644 if (ale == PETSC_FALSE) {
645 if (type == MBPRISM) {
646 boost::shared_ptr<MatrixDouble> inv_jac_ptr(new MatrixDouble);
647 fe_rhs_ptr->getOpPtrVector().push_back(
648 new OpCalculateInvJacForFatPrism(inv_jac_ptr));
649 fe_rhs_ptr->getOpPtrVector().push_back(
650 new OpSetInvJacH1ForFatPrism(inv_jac_ptr));
651 }
652 fe_rhs_ptr->getOpPtrVector().push_back(
653 new OpCalculateVectorFieldGradient<3, 3>(x_field, data_at_pts->hMat));
654 fe_rhs_ptr->getOpPtrVector().push_back(
655 new OpCalculateHomogeneousStiffness<0>(x_field, x_field,
656 block_sets_ptr, data_at_pts));
657 if (field_disp) {
658 fe_rhs_ptr->getOpPtrVector().push_back(
659 new OpCalculateStrain<true>(x_field, x_field, data_at_pts));
660 } else {
661 fe_rhs_ptr->getOpPtrVector().push_back(
662 new OpCalculateStrain<false>(x_field, x_field, data_at_pts));
663 }
664 fe_rhs_ptr->getOpPtrVector().push_back(
665 new OpCalculateStress<0>(x_field, x_field, data_at_pts));
666 fe_rhs_ptr->getOpPtrVector().push_back(
667 new OpRhs_dx(x_field, x_field, data_at_pts));
668 } else {
669 if (type == MBPRISM) {
670 boost::shared_ptr<MatrixDouble> inv_jac_ptr(new MatrixDouble);
671 fe_rhs_ptr->getOpPtrVector().push_back(
672 new OpCalculateInvJacForFatPrism(inv_jac_ptr));
673 fe_rhs_ptr->getOpPtrVector().push_back(
674 new OpSetInvJacH1ForFatPrism(inv_jac_ptr));
675 }
676 fe_rhs_ptr->getOpPtrVector().push_back(
677 new OpCalculateVectorFieldGradient<3, 3>(X_field, data_at_pts->HMat));
678 fe_rhs_ptr->getOpPtrVector().push_back(
679 new OpCalculateHomogeneousStiffness<0>(x_field, x_field,
680 block_sets_ptr, data_at_pts));
681 fe_rhs_ptr->getOpPtrVector().push_back(
682 new OpCalculateVectorFieldGradient<3, 3>(x_field, data_at_pts->hMat));
683 fe_rhs_ptr->getOpPtrVector().push_back(
684 new OpCalculateStrainAle(x_field, x_field, data_at_pts));
685 fe_rhs_ptr->getOpPtrVector().push_back(
686 new OpCalculateStress<0>(x_field, x_field, data_at_pts));
687 fe_rhs_ptr->getOpPtrVector().push_back(
688 new OpAleRhs_dx(x_field, x_field, data_at_pts));
689 fe_rhs_ptr->getOpPtrVector().push_back(
690 new OpCalculateEnergy(X_field, X_field, data_at_pts));
691 fe_rhs_ptr->getOpPtrVector().push_back(
692 new OpCalculateEshelbyStress(X_field, X_field, data_at_pts));
693 fe_rhs_ptr->getOpPtrVector().push_back(
694 new OpAleRhs_dX(X_field, X_field, data_at_pts));
695 }
696 }
697
699}
700
701MoFEMErrorCode HookeElement::calculateEnergy(
702 DM dm, boost::shared_ptr<map<int, BlockData>> block_sets_ptr,
703 const std::string x_field, const std::string X_field, const bool ale,
704 const bool field_disp, SmartPetscObj<Vec> &v_energy) {
706
707 MoFEM::Interface *m_field_ptr;
708 CHKERR DMoFEMGetInterfacePtr(dm, &m_field_ptr);
709
710 v_energy = createVectorMPI(m_field_ptr->get_comm(), PETSC_DECIDE, 1);
711
712 boost::shared_ptr<DataAtIntegrationPts> data_at_pts(
714
715 auto fe_ptr =
716 boost::make_shared<VolumeElementForcesAndSourcesCore>(*m_field_ptr);
717 fe_ptr->getRuleHook = [](const double, const double, const double o) {
718 return 2 * o;
719 };
720
721 if (m_field_ptr->check_field("MESH_NODE_POSITIONS"))
722 CHKERR AddHOOps<3, 3, 3>::add(fe_ptr->getOpPtrVector(), {H1},
723 "MESH_NODE_POSITIONS");
724
726
728 FatPrismElementForcesAndSourcesCore;
729 int getRuleTrianglesOnly(int order) { return 2 * order; }
730 int getRuleThroughThickness(int order) { return 2 * order; }
731 };
732
733 boost::shared_ptr<ForcesAndSourcesCore> prism_fe_ptr(
734 new PrismFE(*m_field_ptr));
735
736 auto push_ops = [&](boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
737 EntityType type) {
739 boost::shared_ptr<MatrixDouble> inv_jac_ptr(new MatrixDouble);
740 if (ale == PETSC_FALSE) {
741 if (type == MBPRISM) {
742 fe_ptr->getOpPtrVector().push_back(
743 new OpCalculateInvJacForFatPrism(inv_jac_ptr));
744 fe_ptr->getOpPtrVector().push_back(
745 new OpSetInvJacH1ForFatPrism(inv_jac_ptr));
746 }
747 fe_ptr->getOpPtrVector().push_back(
748 new OpCalculateVectorFieldGradient<3, 3>(x_field, data_at_pts->hMat));
749 fe_ptr->getOpPtrVector().push_back(new OpCalculateHomogeneousStiffness<0>(
750 x_field, x_field, block_sets_ptr, data_at_pts));
751 if (field_disp) {
752 fe_ptr->getOpPtrVector().push_back(
753 new OpCalculateStrain<true>(x_field, x_field, data_at_pts));
754 } else {
755 fe_ptr->getOpPtrVector().push_back(
756 new OpCalculateStrain<false>(x_field, x_field, data_at_pts));
757 }
758 fe_ptr->getOpPtrVector().push_back(
759 new OpCalculateStress<0>(x_field, x_field, data_at_pts));
760 fe_ptr->getOpPtrVector().push_back(
761 new OpCalculateEnergy(X_field, X_field, data_at_pts, v_energy));
762 } else {
763 if (type == MBPRISM) {
764 fe_ptr->getOpPtrVector().push_back(
765 new OpCalculateInvJacForFatPrism(inv_jac_ptr));
766 fe_ptr->getOpPtrVector().push_back(
767 new OpSetInvJacH1ForFatPrism(inv_jac_ptr));
768 }
769 fe_ptr->getOpPtrVector().push_back(
770 new OpCalculateVectorFieldGradient<3, 3>(X_field, data_at_pts->HMat));
771 fe_ptr->getOpPtrVector().push_back(new OpCalculateHomogeneousStiffness<0>(
772 x_field, x_field, block_sets_ptr, data_at_pts));
773 fe_ptr->getOpPtrVector().push_back(
774 new OpCalculateVectorFieldGradient<3, 3>(x_field, data_at_pts->hMat));
775 fe_ptr->getOpPtrVector().push_back(
776 new OpCalculateStrainAle(x_field, x_field, data_at_pts));
777 fe_ptr->getOpPtrVector().push_back(
778 new OpCalculateStress<0>(x_field, x_field, data_at_pts));
779 fe_ptr->getOpPtrVector().push_back(
780 new OpCalculateEnergy(X_field, X_field, data_at_pts, v_energy));
781 }
783 };
784
785 CHKERR push_ops(fe_ptr, MBTET);
786 CHKERR push_ops(prism_fe_ptr, MBPRISM);
787
788 CHKERR VecZeroEntries(v_energy);
789
790 fe_ptr->snes_ctx = SnesMethod::CTX_SNESNONE;
791 CHKERR DMoFEMLoopFiniteElements(dm, "ELASTIC", fe_ptr);
792 CHKERR DMoFEMLoopFiniteElements(dm, "ELASTIC", prism_fe_ptr);
793
794 CHKERR VecAssemblyBegin(v_energy);
795 CHKERR VecAssemblyEnd(v_energy);
796
798}
799
800MoFEMErrorCode HookeElement::OpAleLhs_dX_dx::iNtegrate(EntData &row_data,
801 EntData &col_data) {
803
804 // get sub-block (3x3) of local stiffens matrix, here represented by
805 // second order tensor
806 auto get_tensor2 = [](MatrixDouble &m, const int r, const int c) {
808 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 1, c + 0),
809 &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 2, c + 0), &m(r + 2, c + 1),
810 &m(r + 2, c + 2));
811 };
812
813 FTensor::Index<'i', 3> i;
814 FTensor::Index<'j', 3> j;
815 FTensor::Index<'k', 3> k;
816 FTensor::Index<'l', 3> l;
817 FTensor::Index<'m', 3> m;
818 FTensor::Index<'n', 3> n;
819
820 // get element volume
821 double vol = getVolume();
822
823 // get intergrayion weights
824 auto t_w = getFTensor0IntegrationWeight();
825
826 // get derivatives of base functions on rows
827 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
828 const int row_nb_base_fun = row_data.getN().size2();
829
830 auto t_invH =
831 getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->invHMat);
832 auto &det_H = *dataAtPts->detHVec;
833
834 auto get_eshelby_stress_dx = [this]() {
836 t_eshelby_stress_dx;
837 int mm = 0;
838 for (int ii = 0; ii != 3; ++ii)
839 for (int jj = 0; jj != 3; ++jj)
840 for (int kk = 0; kk != 3; ++kk)
841 for (int ll = 0; ll != 3; ++ll)
842 t_eshelby_stress_dx.ptr(ii, jj, kk, ll) =
843 &(*dataAtPts->eshelbyStress_dx)(mm++, 0);
844 return t_eshelby_stress_dx;
845 };
846
847 auto t_eshelby_stress_dx = get_eshelby_stress_dx();
848
849 // iterate over integration points
850 for (int gg = 0; gg != nbIntegrationPts; ++gg) {
851
852 // calculate scalar weight times element volume
853 double a = t_w * vol * det_H[gg];
854
855 // iterate over row base functions
856 int rr = 0;
857 for (; rr != nbRows / 3; ++rr) {
858
859 // get sub matrix for the row
860 auto t_m = get_tensor2(K, 3 * rr, 0);
861
862 FTensor::Tensor1<double, 3> t_row_diff_base_pulled;
863 t_row_diff_base_pulled(i) = t_row_diff_base(j) * t_invH(j, i);
864
865 FTensor::Tensor3<double, 3, 3, 3> t_row_stress_dx;
866 t_row_stress_dx(i, k, l) =
867 a * t_row_diff_base_pulled(j) * t_eshelby_stress_dx(i, j, k, l);
868
869 // get derivatives of base functions for columns
870 auto t_col_diff_base = col_data.getFTensor1DiffN<3>(gg, 0);
871
872 // iterate column base functions
873 for (int cc = 0; cc != nbCols / 3; ++cc) {
874
875 t_m(i, k) += t_row_stress_dx(i, k, l) * t_col_diff_base(l);
876
877 // move to next column base function
878 ++t_col_diff_base;
879
880 // move to next block of local stiffens matrix
881 ++t_m;
882 }
883
884 // move to next row base function
885 ++t_row_diff_base;
886 }
887
888 for (; rr != row_nb_base_fun; ++rr)
889 ++t_row_diff_base;
890
891 ++t_w;
892 ++t_invH;
893 ++t_eshelby_stress_dx;
894 }
895
897}
898
899HookeElement::OpAleLhsWithDensity_dX_dX::OpAleLhsWithDensity_dX_dX(
900 const std::string row_field, const std::string col_field,
901 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
902 boost::shared_ptr<VectorDouble> rho_at_gauss_pts,
903 boost::shared_ptr<MatrixDouble> rho_grad_at_gauss_pts, const double rho_n,
904 const double rho_0)
905 : OpAssemble(row_field, col_field, data_at_pts, OPROWCOL, false),
906 rhoAtGaussPtsPtr(rho_at_gauss_pts),
907 rhoGradAtGaussPtsPtr(rho_grad_at_gauss_pts), rhoN(rho_n), rHo0(rho_0) {}
908
910HookeElement::OpAleLhsWithDensity_dX_dX::iNtegrate(EntData &row_data,
911 EntData &col_data) {
913
914 // get sub-block (3x3) of local stiffens matrix, here represented by
915 // second order tensor
916 auto get_tensor2 = [](MatrixDouble &m, const int r, const int c) {
918 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 1, c + 0),
919 &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 2, c + 0), &m(r + 2, c + 1),
920 &m(r + 2, c + 2));
921 };
922
923 FTensor::Index<'i', 3> i;
924 FTensor::Index<'j', 3> j;
925 FTensor::Index<'k', 3> k;
926 FTensor::Index<'l', 3> l;
927
928 // get element volume
929 double vol = getVolume();
930
931 // get intergrayion weights
932 auto t_w = getFTensor0IntegrationWeight();
933
934 // get derivatives of base functions on rows
935 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
936 const int row_nb_base_fun = row_data.getN().size2();
937
938 // Elastic stiffness tensor (4th rank tensor with minor and major
939 // symmetry)
940 auto rho = getFTensor0FromVec(*rhoAtGaussPtsPtr);
941 auto t_grad_rho =
942 getFTensor1FromMat<3, -1, CoeffsByGauss>(*rhoGradAtGaussPtsPtr);
943
944 auto t_eshelby_stress =
946 *dataAtPts->eshelbyStressMat);
947 // auto t_h = getFTensor2FromMat<3, 3>(*dataAtPts->hMat);
948 auto t_invH =
949 getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->invHMat);
950 auto &det_H = *dataAtPts->detHVec;
951
952 // iterate over integration points
953 for (int gg = 0; gg != nbIntegrationPts; ++gg) {
954
955 // calculate scalar weight times element volume
956 double a = t_w * vol * det_H[gg];
957
958 const double stress_dho_coef = (rhoN / rho);
959 // (rhoN / rHo0) * pow(rho / rHo0, rhoN - 1.) * (1. / pow(rho / rHo0,
960 // rhoN));
961
962 // iterate over row base functions
963 int rr = 0;
964 for (; rr != nbRows / 3; ++rr) {
965
966 // get sub matrix for the row
967 auto t_m = get_tensor2(K, 3 * rr, 0);
968
969 FTensor::Tensor1<double, 3> t_row_diff_base_pulled;
970 t_row_diff_base_pulled(i) = t_row_diff_base(j) * t_invH(j, i);
971
972 FTensor::Tensor1<double, 3> t_row_stress;
973 t_row_stress(i) = a * t_row_diff_base_pulled(j) * t_eshelby_stress(i, j);
974
975 // get derivatives of base functions for columns
976 // auto t_col_diff_base = col_data.getFTensor1DiffN<3>(gg, 0);
977 auto t_col_base = col_data.getFTensor0N(gg, 0);
978
979 // iterate column base functions
980 for (int cc = 0; cc != nbCols / 3; ++cc) {
981
982 t_m(i, k) +=
983 t_row_stress(i) * stress_dho_coef * t_grad_rho(k) * t_col_base;
984 // move to next column base function
985 ++t_col_base;
986
987 // move to next block of local stiffens matrix
988 ++t_m;
989 }
990
991 // move to next row base function
992 ++t_row_diff_base;
993 }
994
995 for (; rr != row_nb_base_fun; ++rr)
996 ++t_row_diff_base;
997
998 // move to next integration weight
999 ++t_w;
1000 ++t_eshelby_stress;
1001 ++t_invH;
1002 ++rho;
1003 ++t_grad_rho;
1004 }
1005
1007}
1008
1009HookeElement::OpAleLhsWithDensity_dx_dX::OpAleLhsWithDensity_dx_dX(
1010 const std::string row_field, const std::string col_field,
1011 boost::shared_ptr<DataAtIntegrationPts> &data_at_pts,
1012 boost::shared_ptr<VectorDouble> rho_at_gauss_pts,
1013 boost::shared_ptr<MatrixDouble> rho_grad_at_gauss_pts, const double rho_n,
1014 const double rho_0)
1015 : OpAssemble(row_field, col_field, data_at_pts, OPROWCOL, false),
1016 rhoAtGaussPtsPtr(rho_at_gauss_pts),
1017 rhoGradAtGaussPtsPtr(rho_grad_at_gauss_pts), rhoN(rho_n), rHo0(rho_0) {}
1018
1020HookeElement::OpAleLhsWithDensity_dx_dX::iNtegrate(EntData &row_data,
1021 EntData &col_data) {
1023
1024 // get sub-block (3x3) of local stiffens matrix, here represented by
1025 // second order tensor
1026 auto get_tensor2 = [](MatrixDouble &m, const int r, const int c) {
1028 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 1, c + 0),
1029 &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 2, c + 0), &m(r + 2, c + 1),
1030 &m(r + 2, c + 2));
1031 };
1032
1033 FTensor::Index<'i', 3> i;
1034 FTensor::Index<'j', 3> j;
1035 FTensor::Index<'k', 3> k;
1036 FTensor::Index<'l', 3> l;
1037
1038 // get element volume
1039 double vol = getVolume();
1040
1041 // get integration weights
1042 auto t_w = getFTensor0IntegrationWeight();
1043
1044 // get derivatives of base functions on rows
1045 auto t_row_diff_base = row_data.getFTensor1DiffN<3>();
1046 const int row_nb_base_fun = row_data.getN().size2();
1047
1048 auto rho = getFTensor0FromVec(*rhoAtGaussPtsPtr);
1049 auto t_grad_rho =
1050 getFTensor1FromMat<3, -1, CoeffsByGauss>(*rhoGradAtGaussPtsPtr);
1051 auto t_cauchy_stress =
1053 *(dataAtPts->cauchyStressMat));
1054 // auto t_h = getFTensor2FromMat<3, 3>(*dataAtPts->hMat);
1055 auto t_invH =
1056 getFTensor2FromMat<3, 3, -1, CoeffsByGauss>(*dataAtPts->invHMat);
1057 auto &det_H = *dataAtPts->detHVec;
1058
1059 // iterate over integration points
1060 for (int gg = 0; gg != nbIntegrationPts; ++gg) {
1061
1062 // calculate scalar weight times element volume
1063 double a = t_w * vol * det_H[gg];
1064
1065 const double stress_dho_coef = (rhoN / rho);
1066 // (rhoN / rHo0) * pow(rho / rHo0, rhoN - 1.) * (1. / pow(rho / rHo0,
1067 // rhoN)); iterate over row base functions
1068 int rr = 0;
1069 for (; rr != nbRows / 3; ++rr) {
1070
1071 // get sub matrix for the row
1072 auto t_m = get_tensor2(K, 3 * rr, 0);
1073
1074 FTensor::Tensor1<double, 3> t_row_diff_base_pulled;
1075 t_row_diff_base_pulled(i) = t_row_diff_base(j) * t_invH(j, i);
1076
1077 FTensor::Tensor1<double, 3> t_row_stress;
1078 t_row_stress(i) = a * t_row_diff_base_pulled(j) * t_cauchy_stress(i, j);
1079
1080 // get derivatives of base functions for columns
1081 auto t_col_base = col_data.getFTensor0N(gg, 0);
1082 // iterate column base functions
1083 for (int cc = 0; cc != nbCols / 3; ++cc) {
1084
1085 t_m(i, k) +=
1086 t_row_stress(i) * stress_dho_coef * t_grad_rho(k) * t_col_base;
1087
1088 ++t_col_base;
1089
1090 // move to next block of local stiffens matrix
1091 ++t_m;
1092 }
1093
1094 // move to next row base function
1095 ++t_row_diff_base;
1096 }
1097
1098 for (; rr != row_nb_base_fun; ++rr)
1099 ++t_row_diff_base;
1100
1101 // move to next integration weight
1102 ++t_w;
1103 // ++t_D;
1104 ++t_cauchy_stress;
1105 ++t_invH;
1106 // ++t_h;
1107 ++rho;
1108 ++t_grad_rho;
1109 }
1110
1112}
1113
1114HookeElement::OpCalculateStiffnessScaledByDensityField::
1115 OpCalculateStiffnessScaledByDensityField(
1116 const std::string row_field, const std::string col_field,
1117 boost::shared_ptr<map<int, BlockData>> &block_sets_ptr,
1118 boost::shared_ptr<DataAtIntegrationPts> data_at_pts,
1119 boost::shared_ptr<VectorDouble> rho_at_gauss_pts, const double rho_n,
1120 const double rho_0)
1121
1122 : VolUserDataOperator(row_field, col_field, OPROW, true),
1123 blockSetsPtr(block_sets_ptr), dataAtPts(data_at_pts),
1124 rhoAtGaussPtsPtr(rho_at_gauss_pts), rhoN(rho_n), rHo0(rho_0) {
1125 std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE], false);
1126}
1127
1128MoFEMErrorCode HookeElement::OpCalculateStiffnessScaledByDensityField::doWork(
1129 int row_side, EntityType row_type, EntData &row_data) {
1131
1132 if (!rhoAtGaussPtsPtr)
1133 SETERRQ(PETSC_COMM_SELF, 1, "Calculate density with MWLS first.");
1134
1135 for (auto &m : (*blockSetsPtr)) {
1136
1137 if (m.second.tEts.find(getNumeredEntFiniteElementPtr()->getEnt()) ==
1138 m.second.tEts.end()) {
1139 continue;
1140 }
1141
1142 const int nb_integration_pts = getGaussPts().size2();
1143 dataAtPts->stiffnessMat->resize(36, nb_integration_pts, false);
1144
1146 MAT_TO_DDG(dataAtPts->stiffnessMat));
1147 const double young = m.second.E;
1148 const double poisson = m.second.PoissonRatio;
1149
1150 auto rho = getFTensor0FromVec(*rhoAtGaussPtsPtr);
1151
1152 // coefficient used in intermediate calculation
1153 const double coefficient = young / ((1 + poisson) * (1 - 2 * poisson));
1154
1155 FTensor::Index<'i', 3> i;
1156 FTensor::Index<'j', 3> j;
1157 FTensor::Index<'k', 3> k;
1158 FTensor::Index<'l', 3> l;
1159
1160 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1161
1162 t_D(i, j, k, l) = 0.;
1163
1164 t_D(0, 0, 0, 0) = 1 - poisson;
1165 t_D(1, 1, 1, 1) = 1 - poisson;
1166 t_D(2, 2, 2, 2) = 1 - poisson;
1167
1168 t_D(0, 1, 0, 1) = 0.5 * (1 - 2 * poisson);
1169 t_D(0, 2, 0, 2) = 0.5 * (1 - 2 * poisson);
1170 t_D(1, 2, 1, 2) = 0.5 * (1 - 2 * poisson);
1171
1172 t_D(0, 0, 1, 1) = poisson;
1173 t_D(1, 1, 0, 0) = poisson;
1174 t_D(0, 0, 2, 2) = poisson;
1175 t_D(2, 2, 0, 0) = poisson;
1176 t_D(1, 1, 2, 2) = poisson;
1177 t_D(2, 2, 1, 1) = poisson;
1178 // here the coefficient is modified to take density into account for
1179 // porous materials: E(p) = E * (p / p_0)^n
1180 t_D(i, j, k, l) *= coefficient * pow(rho / rHo0, rhoN);
1181
1182 ++t_D;
1183 ++rho;
1184 }
1185 }
1186
1188}
#define MAT_TO_DDG(SM)
std::string type
constexpr double a
@ MF_ZERO
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ H1
continuous field
Definition definitions.h:85
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MAT_ELASTICSET
block name is "MAT_ELASTIC"
@ BLOCKSET
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
constexpr int order
@ F
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:576
PetscErrorCode DMoFEMGetInterfacePtr(DM dm, MoFEM::Interface **m_field_ptr)
Get pointer to MoFEM::Interface.
Definition DMMoFEM.cpp:410
virtual MoFEMErrorCode add_ents_to_finite_element_by_dim(const EntityHandle entities, const int dim, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
virtual bool check_field(const std::string &name) const =0
check if field is in database
#define _IT_CUBITMESHSETS_BY_BCDATA_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet in a moFEM field.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
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.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
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.
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
auto getFTensor1FromMat(M &data, int rr=0, int cc=0)
Get tensor rank 1 (vector) form data matrix.
MoFEMErrorCode MatSetValues(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const double *ptr, InsertMode iora)
Assemble PETSc matrix.
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
static auto determinantTensor3by3(T &t)
Calculate the determinant of a 3x3 matrix or a tensor of rank 2.
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
ublas::vector< FEDofEntity *, DofsAllocator > VectorDofs
FTensor::Index< 'm', 3 > m
Add operators pushing bases from local to physical configuration.
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
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 VectorDofs & getFieldDofs() const
Get DOF data structures (const version)
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
Elastic material data structure.
Calculate inverse of jacobian for face element.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Transform local reference derivatives of shape functions to global derivatives.
intrusive_ptr for managing petsc objects
@ CTX_SNESNONE
No specific SNES context.
int getRuleThroughThickness(int order)
int getRuleTrianglesOnly(int order)
double rho
Definition plastic.cpp:145