1410 {
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) {
1432 MB_TAG_CREAT | MB_TAG_SPARSE,
1433 def_val.data());
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
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);
1453
1454 EntityHandle ent = this->getFEEntityHandle();
1456 EntityHandle ent_3d = ent;
1457 if (
type == MBTRI ||
type == MBQUAD) {
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())
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;
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)
1493 "Element not found in any of material blocksets");
1494
1495 int def_val_int = 0;
1498 MB_TAG_CREAT | MB_TAG_SPARSE, &def_val_int);
1499 double detH = 0.;
1506
1507 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1508
1510 t_h(0, 0) += 1;
1511 t_h(1, 1) += 1;
1512 t_h(2, 2) += 1;
1513 }
1514
1516 t_small_strain_symm(
i,
j) = (t_h(
i,
j) || t_h(
j,
i)) / 2.;
1517 } else {
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
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
1537 &t_stress(0, 0));
1539 &block_id);
1540
1541 ++t_h;
1542 }
1543
1545}
#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
#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
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
auto type_from_handle(const EntityHandle h)
get type from entity handle
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.
static auto determinantTensor3by3(T &t)
Calculate the determinant of a 3x3 matrix or a tensor of rank 2.
FTensor::Index< 'm', 3 > m