#define SINGULARITY
#include <boost/math/constants/constants.hpp>
#ifdef PYTHON_SDF
#include <boost/python.hpp>
#include <boost/python/def.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
#pragma message "With PYTHON_SDF"
#else
#pragma message "Without PYTHON_SDF"
#endif
extern "C" {
}
struct VolUserDataOperatorStabAssembly
};
struct FaceUserDataOperatorStabAssembly
};
}
const std::string block_name, int dim) {
std::regex((boost::format("%s(.*)") % block_name).str())
);
for (auto bc : bcs) {
faces, true),
"get meshset ents");
}
};
CHKERR moab.add_entities(*out_meshset,
r);
CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1);
} else {
MOFEM_LOG(
"SELF", Sev::warning) <<
"Empty range for " << name;
}
};
template <>
return MatSetValues<AssemblyTypeSelector<SCHUR>>(
op_ptr->
getKSPB(), row_data, col_data,
m, ADD_VALUES);
};
struct SetIntegrationAtFrontVolume {
SetIntegrationAtFrontVolume() = default;
int order_col, int order_data) {
auto &m_field = fe_raw_ptr->
mField;
auto vol_fe_ptr = dynamic_cast<VolFe *>(fe_raw_ptr);
auto fe_handle = vol_fe_ptr->getFEEntityHandle();
auto set_base_quadrature = [&]() {
int rule = 2 * order_data + 1;
"wrong dimension");
}
}
auto &gauss_pts = vol_fe_ptr->gaussPts;
gauss_pts.resize(4, nb_gauss_pts, false);
&gauss_pts(0, 0), 1);
&gauss_pts(1, 0), 1);
&gauss_pts(2, 0), 1);
&gauss_pts(3, 0), 1);
auto &data = vol_fe_ptr->dataOnElement[
H1];
data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
false);
double *shape_ptr =
&*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
shape_ptr, 1);
} else {
"rule > quadrature order %d < %d", rule,
}
};
if (frontNodes->size() && EshelbianCore::setSingularity) {
auto get_singular_nodes = [&]() {
int num_nodes;
CHKERR m_field.
get_moab().get_connectivity(fe_handle, conn, num_nodes,
true);
std::bitset<numNodes> singular_nodes;
for (auto nn = 0; nn != numNodes; ++nn) {
if (frontNodes->find(conn[nn]) != frontNodes->end()) {
singular_nodes.set(nn);
} else {
singular_nodes.reset(nn);
}
}
return singular_nodes;
};
auto get_singular_edges = [&]() {
std::bitset<numEdges> singular_edges;
for (int ee = 0; ee != numEdges; ee++) {
if (frontEdges->find(edge) != frontEdges->end()) {
singular_edges.set(ee);
} else {
singular_edges.reset(ee);
}
}
return singular_edges;
};
auto set_gauss_pts = [&](auto &ref_gauss_pts) {
vol_fe_ptr->gaussPts.swap(ref_gauss_pts);
const size_t nb_gauss_pts = vol_fe_ptr->gaussPts.size2();
};
auto singular_nodes = get_singular_nodes();
if (singular_nodes.count()) {
auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
CHKERR set_gauss_pts(it_map_ref_coords->second);
} else {
auto refine_quadrature = [&]() {
const int max_level = refinementLevels;
double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
for (int nn = 0; nn != 4; nn++)
CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
CHKERR moab_ref.create_element(MBTET, nodes, 4, tet);
for (int nn = 0; nn != numNodes; nn++) {
if (singular_nodes[nn]) {
CHKERR moab_ref.side_element(tet, 0, nn, ent);
nodes_at_front.insert(ent);
}
}
auto singular_edges = get_singular_edges();
CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
for (int ee = 0; ee != 6; ee++) {
if (singular_edges[ee]) {
CHKERR moab_ref.side_element(tet, 1, ee, ent);
CHKERR moab_ref.add_entities(meshset, &ent, 1);
}
}
for (int ll = 0; ll != max_level; ll++) {
edges);
CHKERR moab_ref.get_adjacencies(
nodes_at_front, 1, true, ref_edges, moab::Interface::UNION);
ref_edges = intersect(ref_edges, edges);
CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
ref_edges = intersect(ref_edges, ents);
->getEntitiesByTypeAndRefLevel(
CHKERR m_ref->addVerticesInTheMiddleOfEdges(
->updateMeshsetByEntitiesChildren(meshset,
meshset, MBEDGE, true);
}
->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
tets);
int tt = 0;
for (Range::iterator tit = tets.begin(); tit != tets.end();
tit++, tt++) {
int num_nodes;
CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
}
auto &data = vol_fe_ptr->dataOnElement[
H1];
const size_t nb_gauss_pts = vol_fe_ptr->gaussPts.size2();
MatrixDouble ref_gauss_pts(4, nb_gauss_pts * ref_coords.size1());
data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
int gg = 0;
for (size_t tt = 0; tt != ref_coords.size1(); tt++) {
double *tet_coords = &ref_coords(tt, 0);
det *= 6;
for (size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
for (
int dd = 0;
dd != 3;
dd++) {
shape_n(ggg, 0) * tet_coords[3 * 0 +
dd] +
shape_n(ggg, 1) * tet_coords[3 * 1 +
dd] +
shape_n(ggg, 2) * tet_coords[3 * 2 +
dd] +
shape_n(ggg, 3) * tet_coords[3 * 3 +
dd];
}
ref_gauss_pts(3, gg) = vol_fe_ptr->gaussPts(3, ggg) * det;
}
}
mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
};
}
}
}
}
};
static inline constexpr int numNodes = 4;
static inline constexpr int numEdges = 6;
static inline constexpr int refinementLevels = 3;
static inline boost::shared_ptr<Range> frontNodes;
static inline boost::shared_ptr<Range> frontEdges;
static inline std::map<long int, MatrixDouble>
mapRefCoords;
};
double EshelbianCore::exponentBase = exp(1);
EshelbianCore::d_f_log_e;
EshelbianCore::dd_f_log_e;
boost::function<
double(
const double)> EshelbianCore::inv_f =
EshelbianCore::inv_f_log;
boost::function<
double(
const double)> EshelbianCore::inv_d_f =
EshelbianCore::inv_d_f_log;
boost::function<
double(
const double)> EshelbianCore::inv_dd_f =
EshelbianCore::inv_dd_f_log;
EshelbianCore::query_interface(boost::typeindex::type_index type_index,
*iface = const_cast<EshelbianCore *>(this);
return 0;
}
if (evalRhs)
if (evalLhs)
}
}
EshelbianCore::~EshelbianCore() = default;
const char *list_rots[] = {"small", "moderate", "large", "no_h1"};
PetscInt choice_rot = EshelbianCore::rotSelector;
PetscInt choice_grad = EshelbianCore::gradApproximator;
const char *list_stretches[] = {"linear", "log"};
CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Eshelbian plasticity",
"none");
CHKERR PetscOptionsInt(
"-space_order",
"approximation oder for space",
"",
spaceOrder, &spaceOrder, PETSC_NULL);
CHKERR PetscOptionsInt(
"-space_h1_order",
"approximation oder for space",
"",
spaceH1Order, &spaceH1Order, PETSC_NULL);
CHKERR PetscOptionsInt(
"-material_order",
"approximation oder for material",
"", materialOrder, &materialOrder, PETSC_NULL);
CHKERR PetscOptionsScalar(
"-viscosity_alpha_u",
"viscosity",
"", alphaU,
&alphaU, PETSC_NULL);
CHKERR PetscOptionsScalar(
"-viscosity_alpha_w",
"viscosity",
"", alphaW,
&alphaW, PETSC_NULL);
CHKERR PetscOptionsScalar(
"-density_alpha_rho",
"density",
"", alphaRho,
&alphaRho, PETSC_NULL);
CHKERR PetscOptionsEList(
"-rotations",
"rotations",
"", list_rots,
LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
PETSC_NULL);
CHKERR PetscOptionsEList(
"-grad",
"gradient of defamation approximate",
"",
list_rots[choice_grad], &choice_grad, PETSC_NULL);
CHKERR PetscOptionsScalar(
"-exponent_base",
"exponent_base",
"", exponentBase,
&EshelbianCore::exponentBase, PETSC_NULL);
list_stretches[choice_stretch], &choice_stretch, PETSC_NULL);
CHKERR PetscOptionsBool(
"-no_stretch",
"do not solve for stretch",
"",
noStretch, &noStretch, PETSC_NULL);
CHKERR PetscOptionsBool(
"-set_singularity",
"set singularity",
"",
setSingularity, &setSingularity, PETSC_NULL);
CHKERR PetscOptionsInt(
"-contact_max_post_proc_ref_level",
"refinement level",
"", contactRefinementLevels, &contactRefinementLevels,
PETSC_NULL);
ierr = PetscOptionsEnd();
EshelbianCore::rotSelector =
static_cast<RotSelector>(choice_rot);
EshelbianCore::gradApproximator =
static_cast<RotSelector>(choice_grad);
EshelbianCore::stretchSelector =
static_cast<StretchSelector>(choice_stretch);
switch (EshelbianCore::stretchSelector) {
EshelbianCore::inv_f = inv_f_linear;
EshelbianCore::inv_d_f = inv_d_f_linear;
EshelbianCore::inv_dd_f = inv_dd_f_linear;
break;
if (EshelbianCore::exponentBase != exp(1)) {
EshelbianCore::inv_f = inv_f_log;
EshelbianCore::inv_d_f = inv_d_f_log;
EshelbianCore::inv_dd_f = inv_dd_f_log;
} else {
EshelbianCore::inv_f = inv_f_log;
EshelbianCore::inv_d_f = inv_d_f_log;
EshelbianCore::inv_dd_f = inv_dd_f_log;
}
break;
default:
break;
};
MOFEM_LOG(
"EP", Sev::inform) <<
"spaceOrder " << spaceOrder;
MOFEM_LOG(
"EP", Sev::inform) <<
"spaceH1Order " << spaceH1Order;
MOFEM_LOG(
"EP", Sev::inform) <<
"materialOrder " << materialOrder;
MOFEM_LOG(
"EP", Sev::inform) <<
"alphaU " << alphaU;
MOFEM_LOG(
"EP", Sev::inform) <<
"alphaW " << alphaW;
MOFEM_LOG(
"EP", Sev::inform) <<
"alphaRho " << alphaRho;
<< "Rotations " << list_rots[EshelbianCore::rotSelector];
MOFEM_LOG(
"EP", Sev::inform) <<
"Gradient of deformation "
<< list_rots[EshelbianCore::gradApproximator];
if (exponentBase != exp(1))
<< "Base exponent " << EshelbianCore::exponentBase;
else
MOFEM_LOG(
"EP", Sev::inform) <<
"Base exponent e";
MOFEM_LOG(
"EP", Sev::inform) <<
"Stretch " << list_stretches[choice_stretch];
if (spaceH1Order == -1)
spaceH1Order = spaceOrder;
}
auto get_tets = [&]() {
CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
return tets;
};
auto get_tets_skin = [&]() {
Skinner skin(&mField.get_moab());
CHKERR skin.find_skin(0, get_tets(),
false, tets_skin_part);
ParallelComm *pcomm =
CHKERR pcomm->filter_pstatus(tets_skin_part,
PSTATUS_SHARED | PSTATUS_MULTISHARED,
PSTATUS_NOT, -1, &tets_skin);
return tets_skin;
};
auto subtract_boundary_conditions = [&](auto &&tets_skin) {
if (bcSpatialTraction)
for (
auto &
v : *bcSpatialTraction) {
tets_skin = subtract(tets_skin,
v.faces);
}
return tets_skin;
};
auto add_blockset = [&](auto block_name, auto &&tets_skin) {
auto crack_faces =
tets_skin.merge(crack_faces);
return tets_skin;
};
auto subtract_blockset = [&](auto block_name, auto &&tets_skin) {
auto contact_range =
tets_skin = subtract(tets_skin, contact_range);
return tets_skin;
};
auto get_stress_trace_faces = [&](auto &&tets_skin) {
faces, moab::Interface::UNION);
Range trace_faces = subtract(faces, tets_skin);
return trace_faces;
};
auto tets = get_tets();
auto trace_faces = get_stress_trace_faces(
subtract_blockset("CONTACT",
subtract_boundary_conditions(get_tets_skin()))
);
contactFaces = boost::make_shared<Range>(intersect(
skeletonFaces =
boost::make_shared<Range>(subtract(trace_faces, *contactFaces));
materialSkeletonFaces =
boost::make_shared<Range>(get_stress_trace_faces(
Range()));
#ifndef NDEBUG
if (contactFaces->size())
if (skeletonFaces->size())
if (skeletonFaces->size())
*materialSkeletonFaces);
#endif
auto add_broken_hdiv_field = [
this, meshset](
const std::string
field_name,
auto get_side_map_hdiv = [&]() {
return std::vector<
std::pair<EntityType,
>>{
{MBTET,
dofs_side_map);
}}
};
};
get_side_map_hdiv(), MB_TAG_DENSE,
MF_ZERO);
};
auto add_l2_field = [
this, meshset](
const std::string
field_name,
const int order,
const int dim) {
};
auto add_h1_field = [
this, meshset](
const std::string
field_name,
const int order,
const int dim) {
};
auto add_l2_field_by_range = [
this](
const std::string
field_name,
const int order,
const int dim,
const int field_dim,
Range &&
r) {
};
auto add_bubble_field = [
this, meshset](
const std::string
field_name,
const int order,
const int dim) {
auto field_ptr = mField.get_field_structure(
field_name);
auto field_order_table =
const_cast<Field *
>(field_ptr)->getFieldOrderTable();
auto get_cgg_bubble_order_zero = [](int p) { return 0; };
auto get_cgg_bubble_order_tet = [](int p) {
};
field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
field_order_table[MBTRI] = get_cgg_bubble_order_zero;
field_order_table[MBTET] = get_cgg_bubble_order_tet;
};
auto add_user_l2_field = [
this, meshset](
const std::string
field_name,
const int order,
const int dim) {
auto field_ptr = mField.get_field_structure(
field_name);
auto field_order_table =
const_cast<Field *
>(field_ptr)->getFieldOrderTable();
auto zero_dofs = [](int p) { return 0; };
field_order_table[MBVERTEX] = zero_dofs;
field_order_table[MBEDGE] = zero_dofs;
field_order_table[MBTRI] = zero_dofs;
field_order_table[MBTET] = dof_l2_tet;
};
CHKERR add_broken_hdiv_field(piolaStress, spaceOrder);
CHKERR add_bubble_field(bubbleField, spaceOrder, 1);
CHKERR add_l2_field(spatialL2Disp, spaceOrder - 1, 3);
CHKERR add_user_l2_field(rotAxis, spaceOrder - 1, 3);
CHKERR add_user_l2_field(stretchTensor, noStretch ? -1 : spaceOrder, 6);
if (!skeletonFaces)
if (!contactFaces)
CHKERR add_l2_field_by_range(hybridSpatialDisp, spaceOrder - 1, 2, 3,
CHKERR add_l2_field_by_range(contactDisp, spaceOrder - 1, 2, 3,
CHKERR add_h1_field(spatialH1Disp, spaceH1Order, 3);
CHKERR add_h1_field(materialH1Positions, 2, 3);
CHKERR add_broken_hdiv_field(eshelbyStress, spaceOrder);
CHKERR add_l2_field(materialL2Disp, spaceOrder - 1, 3);
CHKERR add_l2_field_by_range(hybridMaterialDisp, spaceOrder - 1, 2, 3,
Range(*materialSkeletonFaces));
}
auto project_ho_geometry = [&]() {
return mField.loop_dofs(materialH1Positions, ent_method);
};
auto get_skin = [&](auto &body_ents) {
Skinner skin(&mField.get_moab());
CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
return skin_ents;
};
auto filter_true_skin = [&](auto &&skin) {
ParallelComm *pcomm =
CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
PSTATUS_NOT, -1, &boundary_ents);
return boundary_ents;
};
auto get_crack_front_edges = [&]() {
auto &moab = mField.get_moab();
auto crack_skin = get_skin(*crackFaces);
CHKERR mField.get_moab().get_entities_by_dimension(0,
SPACE_DIM, body_ents);
auto body_skin = filter_true_skin(get_skin(body_ents));
CHKERR moab.get_adjacencies(body_skin,
SPACE_DIM - 2,
true, body_skin_edges,
moab::Interface::UNION);
crack_skin = subtract(crack_skin, body_skin_edges);
std::map<int, Range> received_ents;
crack_skin, &received_ents);
for (
auto &
m : received_ents) {
if (
m.first != mField.get_comm_rank()) {
to_remove.merge(intersect(crack_skin,
m.second));
}
}
crack_skin = subtract(crack_skin, to_remove);
crack_skin);
return boost::make_shared<Range>(crack_skin);
};
auto get_adj_front_edges = [&](auto &front_edges) {
auto &moab = mField.get_moab();
CHKERR moab.get_connectivity(front_edges, front_crack_nodes,
true);
front_crack_nodes);
crack_front_edges, moab::Interface::UNION);
crack_front_edges = subtract(crack_front_edges, front_edges);
crack_front_edges);
Range crack_front_edges_nodes;
CHKERR moab.get_connectivity(crack_front_edges, crack_front_edges_nodes,
true);
crack_front_edges_nodes =
subtract(crack_front_edges_nodes, front_crack_nodes);
Range crack_front_edges_with_both_nodes_not_at_front;
crack_front_edges_with_both_nodes_not_at_front,
moab::Interface::UNION);
crack_front_edges_with_both_nodes_not_at_front = intersect(
crack_front_edges_with_both_nodes_not_at_front, crack_front_edges);
return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
boost::make_shared<Range>(
crack_front_edges_with_both_nodes_not_at_front));
};
crackFaces = boost::make_shared<Range>(
frontEdges = get_crack_front_edges();
auto [front_vertices, front_adj_edges] = get_adj_front_edges(*frontEdges);
frontVertices = front_vertices;
frontAdjEdges = front_adj_edges;
auto set_singular_dofs = [&](auto &front_adj_edges, auto &front_vertices) {
auto &moab = mField.get_moab();
double beta = 0;
PETSC_NULL);
MOFEM_LOG(
"EP", Sev::inform) <<
"Singularity eps " << beta;
for (auto edge : front_adj_edges) {
int num_nodes;
CHKERR moab.get_connectivity(edge, conn, num_nodes,
false);
double coords[6];
CHKERR moab.get_coords(conn, num_nodes, coords);
const double dir[3] = {coords[3] - coords[0], coords[4] - coords[1],
coords[5] - coords[2]};
double dof[3] = {0, 0, 0};
if (front_vertices.find(conn[0]) != front_vertices.end()) {
for (
int dd = 0;
dd != 3;
dd++) {
}
} else if (front_vertices.find(conn[1]) != front_vertices.end()) {
for (
int dd = 0;
dd != 3;
dd++) {
}
}
mField, materialH1Positions, edge, dit)) {
const int idx = dit->get()->getEntDofIdx();
if (idx > 2) {
dit->get()->getFieldData() = 0;
} else {
dit->get()->getFieldData() = dof[idx];
}
}
}
};
if (setSingularity)
CHKERR set_singular_dofs(*frontAdjEdges, *frontVertices);
}
EshelbianCore::addVolumeFiniteElement(
const EntityHandle meshset) {
auto add_field_to_fe = [this](const std::string fe,
};
if (!mField.check_finite_element(elementVolumeName)) {
CHKERR mField.add_ents_to_finite_element_by_type(meshset, MBTET,
elementVolumeName);
CHKERR add_field_to_fe(elementVolumeName, piolaStress);
CHKERR add_field_to_fe(elementVolumeName, bubbleField);
if (!noStretch)
CHKERR add_field_to_fe(elementVolumeName, stretchTensor);
CHKERR add_field_to_fe(elementVolumeName, rotAxis);
CHKERR add_field_to_fe(elementVolumeName, spatialL2Disp);
CHKERR add_field_to_fe(elementVolumeName, spatialH1Disp);
CHKERR add_field_to_fe(elementVolumeName, contactDisp);
CHKERR mField.modify_finite_element_add_field_data(elementVolumeName,
materialH1Positions);
CHKERR mField.build_finite_elements(elementVolumeName);
}
if (!mField.check_finite_element(materialVolumeElement)) {
for (
auto l = 0;
l != frontLayers; ++
l) {
Range front_elements_layer;
front_elements_layer,
moab::Interface::UNION);
front_elements.merge(front_elements_layer);
front_edges.clear();
CHKERR mField.get_moab().get_adjacencies(front_elements_layer,
moab::Interface::UNION);
}
CHKERR mField.add_finite_element(materialVolumeElement,
MF_ZERO);
CHKERR mField.add_ents_to_finite_element_by_type(front_elements, MBTET,
materialVolumeElement);
CHKERR add_field_to_fe(materialVolumeElement, eshelbyStress);
CHKERR add_field_to_fe(materialVolumeElement, materialL2Disp);
CHKERR mField.build_finite_elements(materialVolumeElement);
}
}
EshelbianCore::addBoundaryFiniteElement(
const EntityHandle meshset) {
auto set_fe_adjacency = [&](auto fe_name) {
parentAdjSkeletonFunctionDim2 =
boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
bitAdjParent, bitAdjParentMask, bitAdjEnt, bitAdjEntMask);
CHKERR mField.modify_finite_element_adjacency_table(
fe_name, MBTRI, *parentAdjSkeletonFunctionDim2);
};
auto add_field_to_fe = [this](const std::string fe,
CHKERR mField.modify_finite_element_add_field_data(fe, materialH1Positions);
};
if (!mField.check_finite_element(naturalBcElement)) {
Range natural_bc_elements;
if (bcSpatialDispVecPtr) {
for (
auto &
v : *bcSpatialDispVecPtr) {
natural_bc_elements.merge(
v.faces);
}
}
if (bcSpatialRotationVecPtr) {
for (
auto &
v : *bcSpatialRotationVecPtr) {
natural_bc_elements.merge(
v.faces);
}
}
if (bcSpatialTraction) {
for (
auto &
v : *bcSpatialTraction) {
natural_bc_elements.merge(
v.faces);
}
}
CHKERR mField.add_ents_to_finite_element_by_type(natural_bc_elements, MBTRI,
naturalBcElement);
CHKERR add_field_to_fe(naturalBcElement, hybridSpatialDisp);
CHKERR mField.build_finite_elements(naturalBcElement);
}
auto get_skin = [&](auto &body_ents) {
Skinner skin(&mField.get_moab());
CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
return skin_ents;
};
auto filter_true_skin = [&](auto &&skin) {
ParallelComm *pcomm =
CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
PSTATUS_NOT, -1, &boundary_ents);
return boundary_ents;
};
if (!mField.check_finite_element(skinElement)) {
CHKERR mField.get_moab().get_entities_by_dimension(0,
SPACE_DIM, body_ents);
auto skin = filter_true_skin(get_skin(body_ents));
CHKERR mField.add_ents_to_finite_element_by_type(skin, MBTRI, skinElement);
CHKERR mField.modify_finite_element_add_field_data(skinElement,
spatialH1Disp);
CHKERR mField.modify_finite_element_add_field_data(skinElement,
materialH1Positions);
CHKERR mField.modify_finite_element_add_field_data(skinElement,
hybridSpatialDisp);
CHKERR mField.modify_finite_element_add_field_data(skinElement,
hybridMaterialDisp);
CHKERR mField.modify_finite_element_add_field_data(skinElement,
contactDisp);
CHKERR mField.build_finite_elements(skinElement);
}
if (!mField.check_finite_element(contactElement)) {
if (contactFaces) {
<< "Contact elements " << contactFaces->size();
CHKERR mField.add_ents_to_finite_element_by_type(*contactFaces, MBTRI,
contactElement);
CHKERR add_field_to_fe(contactElement, piolaStress);
CHKERR add_field_to_fe(contactElement, spatialH1Disp);
CHKERR add_field_to_fe(contactElement, hybridSpatialDisp);
CHKERR add_field_to_fe(contactElement, contactDisp);
CHKERR set_fe_adjacency(contactElement);
CHKERR mField.build_finite_elements(contactElement);
}
}
if (!mField.check_finite_element(skeletonElement)) {
if (!skeletonFaces)
<< "Skeleton elements " << skeletonFaces->size();
CHKERR mField.add_ents_to_finite_element_by_type(*skeletonFaces, MBTRI,
skeletonElement);
CHKERR add_field_to_fe(skeletonElement, piolaStress);
CHKERR add_field_to_fe(skeletonElement, hybridSpatialDisp);
CHKERR add_field_to_fe(contactElement, contactDisp);
CHKERR set_fe_adjacency(skeletonElement);
CHKERR mField.build_finite_elements(skeletonElement);
}
if (!mField.check_finite_element(materialSkeletonElement)) {
for (
auto l = 0;
l != frontLayers; ++
l) {
Range front_elements_layer;
front_elements_layer,
moab::Interface::UNION);
front_elements.merge(front_elements_layer);
front_edges.clear();
CHKERR mField.get_moab().get_adjacencies(front_elements_layer,
moab::Interface::UNION);
}
CHKERR mField.get_moab().get_entities_by_dimension(0,
SPACE_DIM, body_ents);
Range front_elements_faces;
true, front_elements_faces,
moab::Interface::UNION);
auto body_skin = filter_true_skin(get_skin(body_ents));
auto front_elements_skin = filter_true_skin(get_skin(front_elements));
Range material_skeleton_faces =
subtract(front_elements_faces, front_elements_skin);
material_skeleton_faces.merge(intersect(front_elements_skin, body_skin));
#ifndef NDEBUG
front_elements_skin);
material_skeleton_faces);
#endif
CHKERR mField.add_finite_element(materialSkeletonElement,
MF_ZERO);
CHKERR mField.add_ents_to_finite_element_by_type(
material_skeleton_faces, MBTRI, materialSkeletonElement);
CHKERR add_field_to_fe(materialSkeletonElement, eshelbyStress);
CHKERR add_field_to_fe(materialSkeletonElement, hybridMaterialDisp);
CHKERR set_fe_adjacency(materialSkeletonElement);
CHKERR mField.build_finite_elements(materialSkeletonElement);
}
if (!mField.check_finite_element(crackElement)) {
CHKERR mField.add_ents_to_finite_element_by_type(crack_faces, MBTRI,
crackElement);
CHKERR add_field_to_fe(crackElement, eshelbyStress);
CHKERR add_field_to_fe(crackElement, hybridMaterialDisp);
CHKERR mField.modify_finite_element_add_field_data(crackElement,
spatialH1Disp);
CHKERR mField.modify_finite_element_add_field_data(crackElement,
materialH1Positions);
CHKERR mField.modify_finite_element_add_field_data(crackElement,
hybridSpatialDisp);
CHKERR mField.modify_finite_element_add_field_data(crackElement,
hybridMaterialDisp);
CHKERR mField.modify_finite_element_add_field_data(crackElement,
contactDisp);
CHKERR set_fe_adjacency(crackElement);
CHKERR mField.build_finite_elements(crackElement);
}
}
dM =
createDM(mField.get_comm(),
"DMMOFEM");
mField.getInterface<
ProblemsManager>()->buildProblemFromFields = PETSC_TRUE;
mField.getInterface<
ProblemsManager>()->buildProblemFromFields = PETSC_FALSE;
auto remove_dofs_on_broken_skin = [&](const std::string prb_name) {
for (
int d : {0, 1, 2}) {
std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
->getSideDofsOnBrokenSpaceEntities(
dofs_to_remove, prb_name,
ROW, piolaStress,
dofs_to_remove);
dofs_to_remove);
}
};
CHKERR remove_dofs_on_broken_skin(
"ESHELBY_PLASTICITY");
dmElastic =
createDM(mField.get_comm(),
"DMMOFEM");
if (!noStretch) {
}
auto set_zero_block = [&]() {
if (!noStretch) {
"ELASTIC_PROBLEM", spatialL2Disp, stretchTensor);
"ELASTIC_PROBLEM", stretchTensor, spatialL2Disp);
}
"ELASTIC_PROBLEM", spatialL2Disp, rotAxis);
"ELASTIC_PROBLEM", rotAxis, spatialL2Disp);
"ELASTIC_PROBLEM", spatialL2Disp, bubbleField);
"ELASTIC_PROBLEM", bubbleField, spatialL2Disp);
if (!noStretch) {
"ELASTIC_PROBLEM", bubbleField, bubbleField);
"ELASTIC_PROBLEM", piolaStress, piolaStress);
"ELASTIC_PROBLEM", bubbleField, piolaStress);
"ELASTIC_PROBLEM", piolaStress, bubbleField);
}
};
auto set_section = [&]() {
PetscSection section;
§ion);
CHKERR DMSetSection(dmElastic, section);
CHKERR DMSetGlobalSection(dmElastic, section);
CHKERR PetscSectionDestroy(§ion);
};
dmPrjSpatial =
createDM(mField.get_comm(),
"DMMOFEM");
->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
"PROJECT_SPATIAL", spatialH1Disp, true, false);
}
BcDisp::BcDisp(std::string name, std::vector<double> &attr,
Range &faces)
: blockName(name), faces(faces) {
vals.resize(3, false);
flags.resize(3, false);
for (int ii = 0; ii != 3; ++ii) {
vals[ii] = attr[ii];
flags[ii] = static_cast<int>(attr[ii + 3]);
}
MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp " << name;
<< "Add BCDisp vals " << vals[0] << " " << vals[1] << " " << vals[2];
<< "Add BCDisp flags " << flags[0] << " " << flags[1] << " " << flags[2];
MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp nb. of faces " << faces.size();
}
BcRot::BcRot(std::string name, std::vector<double> &attr,
Range &faces)
: blockName(name), faces(faces) {
vals.resize(3, false);
for (int ii = 0; ii != 3; ++ii) {
vals[ii] = attr[ii];
}
theta = attr[3];
}
TractionBc::TractionBc(std::string name, std::vector<double> &attr,
: blockName(name), faces(faces) {
vals.resize(3, false);
flags.resize(3, false);
for (int ii = 0; ii != 3; ++ii) {
vals[ii] = attr[ii];
flags[ii] = static_cast<int>(attr[ii + 3]);
}
MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce " << name;
<< "Add BCForce vals " << vals[0] << " " << vals[1] << " " << vals[2];
<< "Add BCForce flags " << flags[0] << " " << flags[1] << " " << flags[2];
MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce nb. of faces " << faces.size();
}
EshelbianCore::getTractionFreeBc(
const EntityHandle meshset,
boost::shared_ptr<TractionFreeBc> &bc_ptr,
const std::string contact_set_name) {
CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
Skinner skin(&mField.get_moab());
CHKERR skin.find_skin(0, tets,
false, tets_skin_part);
ParallelComm *pcomm =
CHKERR pcomm->filter_pstatus(tets_skin_part,
PSTATUS_SHARED | PSTATUS_MULTISHARED,
PSTATUS_NOT, -1, &tets_skin);
bc_ptr->resize(3);
for (
int dd = 0;
dd != 3; ++
dd)
(*bc_ptr)[
dd] = tets_skin;
if (bcSpatialDispVecPtr)
for (
auto &
v : *bcSpatialDispVecPtr) {
(*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
(*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
(*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
}
if (bcSpatialRotationVecPtr)
for (
auto &
v : *bcSpatialRotationVecPtr) {
(*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
(*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
(*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
}
if (bcSpatialTraction)
for (
auto &
v : *bcSpatialTraction) {
(*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
(*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
(*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
}
std::regex((boost::format("%s(.*)") % contact_set_name).str()))) {
CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
true);
(*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
(*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
(*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
}
}
int operator()(
int p_row,
int p_col,
int p_data)
const {
return 2 * p_data + 1;
}
};
int operator()(
int p_row,
int p_col,
int p_data)
const {
return 2 * (p_data + 1);
}
};
CGGUserPolynomialBase::CGGUserPolynomialBase(
boost::shared_ptr<CachePhi> cache_phi_otr)
boost::typeindex::type_index type_index,
*iface = const_cast<CGGUserPolynomialBase *>(this);
return 0;
}
boost::shared_ptr<BaseFunctionCtx> ctx_ptr) {
int nb_gauss_pts = pts.size2();
if (!nb_gauss_pts) {
}
if (pts.size1() < 3) {
"Wrong dimension of pts, should be at least 3 rows with "
"coordinates");
}
const auto base = this->cTx->bAse;
switch (this->cTx->sPace) {
CHKERR getValueHdivForCGGBubble(pts);
break;
data.
dataOnEntities[MBVERTEX][0].getN(base).resize(nb_gauss_pts, 4,
false);
&pts(0, 0), &pts(1, 0), &pts(2, 0), nb_gauss_pts);
std::copy(Tools::diffShapeFunMBTET.begin(), Tools::diffShapeFunMBTET.end(),
CHKERR getValueL2AinsworthBase(pts);
break;
default:
}
}
CGGUserPolynomialBase::getValueHdivForCGGBubble(
MatrixDouble &pts) {
"Wrong base, should be USER_BASE");
}
const int nb_gauss_pts = pts.size2();
auto check_cache = [
this](
int order,
int nb_gauss_pts) ->
bool {
if (cachePhiPtr) {
return cachePhiPtr->get<0>() ==
order &&
cachePhiPtr->get<1>() == nb_gauss_pts;
} else {
return false;
}
};
if (check_cache(
order, nb_gauss_pts)) {
auto &mat = cachePhiPtr->get<2>();
phi.resize(mat.size1(), mat.size2(),
false);
} else {
shapeFun.resize(nb_gauss_pts, 4, false);
&pts(2, 0), nb_gauss_pts);
double diff_shape_fun[12];
phi.resize(nb_gauss_pts, 9 * nb_base_functions,
false);
nb_gauss_pts);
if (cachePhiPtr) {
cachePhiPtr->get<0>() =
order;
cachePhiPtr->get<1>() = nb_gauss_pts;
cachePhiPtr->get<2>().resize(
phi.size1(),
phi.size2(),
false);
noalias(cachePhiPtr->get<2>()) =
phi;
}
}
}
const int tag, const bool do_rhs, const bool do_lhs,
boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe) {
fe = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
auto bubble_cache =
boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
fe->getUserPolynomialBase() =
boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
if (!dataAtPts) {
dataAtPts =
boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
dataAtPts->physicsPtr = physicalEquations;
}
piolaStress, dataAtPts->getApproxPAtPts()));
bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
piolaStress, dataAtPts->getDivPAtPts()));
if (noStretch) {
fe->getOpPtrVector().push_back(
physicalEquations->returnOpCalculateStretchFromStress(
dataAtPts, physicalEquations));
} else {
fe->getOpPtrVector().push_back(
stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
}
rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
if (noStretch) {
} else {
fe->getOpPtrVector().push_back(
stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
}
rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
}
spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
fe->getOpPtrVector().push_back(
new OpCalculateRotationAndSpatialGradient(dataAtPts));
if (noStretch) {
} else {
fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
tag, do_rhs, do_lhs, dataAtPts, physicalEquations));
}
}
const int tag, const bool add_elastic, const bool add_material,
boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_rhs,
boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_lhs) {
auto get_body_range = [this](auto name, int dim) {
std::map<int, Range> map;
for (auto m_ptr :
(boost::format("%s(.*)") % name).str()
))
) {
CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
dim, ents, true),
"by dim");
map[m_ptr->getMeshsetId()] = ents;
}
return map;
};
auto rule_contact = [](
int,
int,
int o) {
return -1; };
auto refine = Tools::refineTriangle(contactRefinementLevels);
auto set_rule_contact = [refine](
int order_col, int order_data
) {
auto rule = 2 * order_data;
fe_raw_ptr->
gaussPts = Tools::refineTriangleIntegrationPts(rule, refine);
};
auto time_scale = boost::make_shared<TimeScale>();
CHKERR setBaseVolumeElementOps(tag,
true,
false, fe_rhs);
if (add_elastic) {
fe_rhs->getOpPtrVector().push_back(
new OpSpatialEquilibrium(spatialL2Disp, dataAtPts, alphaW, alphaRho));
fe_rhs->getOpPtrVector().push_back(
new OpSpatialRotation(rotAxis, dataAtPts));
if (noStretch) {
} else {
fe_rhs->getOpPtrVector().push_back(
physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
alphaU));
}
fe_rhs->getOpPtrVector().push_back(
new OpSpatialConsistencyP(piolaStress, dataAtPts));
fe_rhs->getOpPtrVector().push_back(
new OpSpatialConsistencyBubble(bubbleField, dataAtPts));
fe_rhs->getOpPtrVector().push_back(
new OpSpatialConsistencyDivTerm(piolaStress, dataAtPts));
auto set_hybridisation = [&](auto &pip) {
mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
op_loop_skeleton_side->getSideFEPtr()->getRuleHook =
FaceRule();
AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
op_loop_skeleton_side->getOpPtrVector(), {L2},
materialH1Positions, frontAdjEdges);
auto broken_data_ptr =
boost::make_shared<std::vector<BrokenBaseSideData>>();
mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
boost::make_shared<CGGUserPolynomialBase>();
op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
materialH1Positions, frontAdjEdges);
op_loop_domain_side->getOpPtrVector().push_back(
auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
op_loop_domain_side->getOpPtrVector().push_back(
flux_mat_ptr));
op_loop_domain_side->getOpPtrVector().push_back(
op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dHybrid(hybridSpatialDisp, broken_data_ptr, 1.));
auto hybrid_ptr = boost::make_shared<MatrixDouble>();
op_loop_skeleton_side->getOpPtrVector().push_back(
hybrid_ptr));
op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dBroken(broken_data_ptr, hybrid_ptr, 1.));
pip.push_back(op_loop_skeleton_side);
};
auto set_contact = [&](auto &pip) {
mField, contactElement,
SPACE_DIM - 1, Sev::noisy);
op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
op_loop_skeleton_side->getOpPtrVector(), {L2},
materialH1Positions, frontAdjEdges);
auto broken_data_ptr =
boost::make_shared<std::vector<BrokenBaseSideData>>();
auto contact_common_data_ptr =
boost::make_shared<ContactOps::CommonData>();
auto add_ops_domain_side = [&](auto &pip) {
mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
boost::make_shared<CGGUserPolynomialBase>();
op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
materialH1Positions, frontAdjEdges);
op_loop_domain_side->getOpPtrVector().push_back(
broken_data_ptr));
op_loop_domain_side->getOpPtrVector().push_back(
piolaStress, contact_common_data_ptr->contactTractionPtr()));
pip.push_back(op_loop_domain_side);
};
auto add_ops_contact_rhs = [&](auto &pip) {
auto contact_sfd_map_range_ptr =
boost::make_shared<std::map<int, Range>>(
get_body_range(
"CONTACT_SDF",
SPACE_DIM - 1));
contactDisp, contact_common_data_ptr->contactDispPtr()));
auto u_h1_ptr = boost::make_shared<MatrixDouble>();
pip.push_back(
pip.push_back(new OpTreeSearch(
contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
nullptr));
contactDisp, contact_common_data_ptr, contactTreeRhs,
contact_sfd_map_range_ptr));
pip.push_back(
broken_data_ptr, contact_common_data_ptr, contactTreeRhs));
};
CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
CHKERR add_ops_contact_rhs(op_loop_skeleton_side->getOpPtrVector());
pip.push_back(op_loop_skeleton_side);
};
CHKERR set_hybridisation(fe_rhs->getOpPtrVector());
CHKERR set_contact(fe_rhs->getOpPtrVector());
using BodyNaturalBC =
Assembly<PETSC>::LinearForm<
GAUSS>;
BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {time_scale},
"BODY_FORCE", Sev::inform);
}
CHKERR setBaseVolumeElementOps(tag,
true,
true, fe_lhs);
if (add_elastic) {
const bool symmetric_system =
if (noStretch) {
fe_lhs->getOpPtrVector().push_back(
new OpSpatialConsistency_dP_dP(piolaStress, piolaStress, dataAtPts));
fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_dP(
bubbleField, piolaStress, dataAtPts));
fe_lhs->getOpPtrVector().push_back(
new OpSpatialConsistency_dBubble_dBubble(bubbleField, bubbleField,
dataAtPts));
} else {
fe_lhs->getOpPtrVector().push_back(
physicalEquations->returnOpSpatialPhysical_du_du(
stretchTensor, stretchTensor, dataAtPts, alphaU));
fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dP(
stretchTensor, piolaStress, dataAtPts, true));
fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dBubble(
stretchTensor, bubbleField, dataAtPts, true));
if (!symmetric_system) {
fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_domega(
stretchTensor, rotAxis, dataAtPts, false));
}
}
fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dP(
spatialL2Disp, piolaStress, dataAtPts, true));
fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dw(
spatialL2Disp, spatialL2Disp, dataAtPts, alphaW, alphaRho));
fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dP_domega(
piolaStress, rotAxis, dataAtPts, symmetric_system));
fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_domega(
bubbleField, rotAxis, dataAtPts, symmetric_system));
if (!symmetric_system) {
fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dP(
rotAxis, piolaStress, dataAtPts, false));
fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dBubble(
rotAxis, bubbleField, dataAtPts, false));
fe_lhs->getOpPtrVector().push_back(
new OpSpatialRotation_domega_domega(rotAxis, rotAxis, dataAtPts));
}
auto set_hybridisation = [&](auto &pip) {
mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
op_loop_skeleton_side->getSideFEPtr()->getRuleHook =
FaceRule();
AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
op_loop_skeleton_side->getOpPtrVector(), {L2},
materialH1Positions, frontAdjEdges);
auto broken_data_ptr =
boost::make_shared<std::vector<BrokenBaseSideData>>();
mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
boost::make_shared<CGGUserPolynomialBase>();
op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
materialH1Positions, frontAdjEdges);
op_loop_domain_side->getOpPtrVector().push_back(
op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC(hybridSpatialDisp, broken_data_ptr, 1., true, false));
pip.push_back(op_loop_skeleton_side);
};
auto set_contact = [&](auto &pip) {
mField, contactElement,
SPACE_DIM - 1, Sev::noisy);
op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
op_loop_skeleton_side->getOpPtrVector(), {L2},
materialH1Positions, frontAdjEdges);
auto broken_data_ptr =
boost::make_shared<std::vector<BrokenBaseSideData>>();
auto contact_common_data_ptr =
boost::make_shared<ContactOps::CommonData>();
auto add_ops_domain_side = [&](auto &pip) {
mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
boost::make_shared<CGGUserPolynomialBase>();
op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
materialH1Positions, frontAdjEdges);
op_loop_domain_side->getOpPtrVector().push_back(
broken_data_ptr));
op_loop_domain_side->getOpPtrVector().push_back(
piolaStress, contact_common_data_ptr->contactTractionPtr()));
pip.push_back(op_loop_domain_side);
};
auto add_ops_contact_lhs = [&](auto &pip) {
contactDisp, contact_common_data_ptr->contactDispPtr()));
auto u_h1_ptr = boost::make_shared<MatrixDouble>();
pip.push_back(
pip.push_back(new OpTreeSearch(
contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
nullptr));
auto contact_sfd_map_range_ptr =
boost::make_shared<std::map<int, Range>>(
get_body_range(
"CONTACT_SDF",
SPACE_DIM - 1));
contactDisp, contactDisp, contact_common_data_ptr, contactTreeRhs,
contact_sfd_map_range_ptr));
pip.push_back(
contactDisp, broken_data_ptr, contact_common_data_ptr,
contactTreeRhs, contact_sfd_map_range_ptr));
pip.push_back(
broken_data_ptr, contactDisp, contact_common_data_ptr,
contactTreeRhs));
};
CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
CHKERR add_ops_contact_lhs(op_loop_skeleton_side->getOpPtrVector());
pip.push_back(op_loop_skeleton_side);
};
CHKERR set_hybridisation(fe_lhs->getOpPtrVector());
CHKERR set_contact(fe_lhs->getOpPtrVector());
}
if (add_material) {
}
}
const bool add_elastic, const bool add_material,
boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
fe_rhs->getRuleHook = [](
int,
int,
int p) {
return 2 * (p + 1); };
fe_lhs->getRuleHook = [](
int,
int,
int p) {
return 2 * (p + 1); };
fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
if (add_elastic) {
auto get_broken_op_side = [this](auto &pip) {
auto broken_data_ptr =
boost::make_shared<std::vector<BrokenBaseSideData>>();
mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
boost::make_shared<CGGUserPolynomialBase>();
op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
materialH1Positions, frontAdjEdges);
op_loop_domain_side->getOpPtrVector().push_back(
pip.push_back(op_loop_domain_side);
return broken_data_ptr;
};
auto broken_data_ptr = get_broken_op_side(fe_rhs->getOpPtrVector());
fe_rhs->getOpPtrVector().push_back(
new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr,
{
boost::make_shared<TimeScale>("disp_history.txt")
}));
fe_rhs->getOpPtrVector().push_back(new OpRotationBc(
broken_data_ptr, bcSpatialRotationVecPtr,
{
boost::make_shared<TimeScale>("rotation_history.txt")
}));
fe_rhs->getOpPtrVector().push_back(
new OpBrokenTractionBc(hybridSpatialDisp, bcSpatialTraction));
}
}
boost::shared_ptr<ContactTree> &fe_contact_tree
) {
auto get_body_range = [this](auto name, int dim) {
std::map<int, Range> map;
for (auto m_ptr :
(boost::format("%s(.*)") % name).str()
))
) {
CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
dim, ents, true),
"by dim");
map[m_ptr->getMeshsetId()] = ents;
}
return map;
};
auto get_map_skin = [this](auto &&map) {
ParallelComm *pcomm =
Skinner skin(&mField.get_moab());
CHKERR skin.find_skin(0,
m.second,
false, skin_faces);
PSTATUS_SHARED | PSTATUS_MULTISHARED,
PSTATUS_NOT, -1, nullptr),
"filter");
m.second.swap(skin_faces);
}
return map;
};
auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
auto calcs_side_traction = [&](auto &pip) {
mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
boost::make_shared<CGGUserPolynomialBase>();
op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
materialH1Positions, frontAdjEdges);
op_loop_domain_side->getOpPtrVector().push_back(
piolaStress, contact_common_data_ptr->contactTractionPtr()));
pip.push_back(op_loop_domain_side);
};
auto add_contact_three = [&]() {
auto tree_moab_ptr = boost::make_shared<moab::Core>();
fe_contact_tree = boost::make_shared<ContactTree>(
mField, tree_moab_ptr, spaceOrder,
get_map_skin(get_body_range("BODY", 3)));
fe_contact_tree->getOpPtrVector().push_back(
contactDisp, contact_common_data_ptr->contactDispPtr()));
CHKERR calcs_side_traction(fe_contact_tree->getOpPtrVector());
auto u_h1_ptr = boost::make_shared<MatrixDouble>();
fe_contact_tree->getOpPtrVector().push_back(
fe_contact_tree->getOpPtrVector().push_back(
new OpMoveNode(fe_contact_tree, contact_common_data_ptr, u_h1_ptr));
};
}
CHKERR setContactElementRhsOps(contactTreeRhs);
CHKERR setVolumeElementOps(tag,
true,
false, elasticFeRhs, elasticFeLhs);
CHKERR setFaceElementOps(
true,
false, elasticBcRhs, elasticBcLhs);
auto adj_cache =
boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
auto get_op_contact_bc = [&]() {
mField, contactElement,
SPACE_DIM - 1, Sev::noisy, adj_cache);
return op_loop_side;
};
}
boost::shared_ptr<FEMethod> null;
if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
null);
null);
null);
} else {
null);
null);
null);
}
}
#ifdef PYTHON_SDF
boost::shared_ptr<ContactOps::SDFPython> sdf_python_ptr;
auto file_exists = [](std::string myfile) {
std::ifstream file(myfile.c_str());
if (file) {
return true;
}
return false;
};
char sdf_file_name[255] = "sdf.py";
sdf_file_name, 255, PETSC_NULL);
if (file_exists(sdf_file_name)) {
MOFEM_LOG(
"EP", Sev::inform) << sdf_file_name <<
" file found";
sdf_python_ptr = boost::make_shared<ContactOps::SDFPython>();
CHKERR sdf_python_ptr->sdfInit(sdf_file_name);
ContactOps::sdfPythonWeakPtr = sdf_python_ptr;
} else {
MOFEM_LOG(
"EP", Sev::warning) << sdf_file_name <<
" file NOT found";
}
#else
#endif
boost::shared_ptr<TsCtx>
ts_ctx;
CHKERR TSAppendOptionsPrefix(ts,
"elastic_");
CHKERR TSSetDM(ts, dmElastic);
SNES snes;
PetscViewerAndFormat *vf;
CHKERR PetscViewerAndFormatCreate(PETSC_VIEWER_STDOUT_WORLD,
PETSC_VIEWER_DEFAULT, &vf);
snes,
(
MoFEMErrorCode(*)(SNES, PetscInt, PetscReal,
void *))SNESMonitorFields,
PetscSection section;
CHKERR DMGetSection(dmElastic, §ion);
int num_fields;
CHKERR PetscSectionGetNumFields(section, &num_fields);
for (int ff = 0; ff != num_fields; ff++) {
}
CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
boost::shared_ptr<SetUpSchur> schur_ptr;
}
if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
CHKERR TS2SetSolution(ts, x, xx);
} else {
}
TetPolynomialBase::switchCacheBaseOn<HDIV>(
{elasticFeLhs.get(), elasticFeRhs.get()});
CHKERR TSSolve(ts, PETSC_NULL);
TetPolynomialBase::switchCacheBaseOff<HDIV>(
{elasticFeLhs.get(), elasticFeRhs.get()});
int lin_solver_iterations;
CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
<< "Number of linear solver iterations " << lin_solver_iterations;
PetscBool test_cook_flg = PETSC_FALSE;
PETSC_NULL);
if (test_cook_flg) {
constexpr int expected_lin_solver_iterations = 11;
if (lin_solver_iterations > expected_lin_solver_iterations)
SETERRQ2(
"Expected number of iterations is different than expected %d > %d",
lin_solver_iterations, expected_lin_solver_iterations);
}
}
const std::string file) {
if (!dataAtPts) {
dataAtPts =
boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
}
auto post_proc_mesh = boost::make_shared<moab::Core>();
auto post_proc_begin =
auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
auto get_post_proc = [&](auto sense) {
auto post_proc_ptr =
boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
mField, post_proc_mesh);
post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
frontAdjEdges);
auto domain_ops = [&](auto &fe, int sense) {
fe.getUserPolynomialBase() =
boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
frontAdjEdges);
piolaStress, dataAtPts->getApproxPAtPts()));
bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
if (noStretch) {
fe.getOpPtrVector().push_back(
physicalEquations->returnOpCalculateStretchFromStress(
dataAtPts, physicalEquations));
} else {
fe.getOpPtrVector().push_back(
stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
}
rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
fe.getOpPtrVector().push_back(
new OpCalculateRotationAndSpatialGradient(dataAtPts));
fe.getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
tag, true, false, dataAtPts, physicalEquations));
if (auto op =
physicalEquations->returnOpCalculateEnergy(dataAtPts, nullptr)) {
fe.getOpPtrVector().push_back(op);
}
spatialL2Disp, contact_common_data_ptr->contactDispPtr()));
fe.getOpPtrVector().push_back(new OpPostProcDataStructure(
post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
dataAtPts, sense));
};
post_proc_ptr->getOpPtrVector().push_back(
dataAtPts->getContactL2AtPts()));
auto X_h1_ptr = boost::make_shared<MatrixDouble>();
post_proc_ptr->getOpPtrVector().push_back(
dataAtPts->getLargeXH1AtPts()));
domain_ops(*(op_loop_side->getSideFEPtr()), sense);
post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
return post_proc_ptr;
};
auto post_proc_ptr = get_post_proc(1);
auto post_proc_negative_sense_ptr = get_post_proc(-1);
auto u_h1_ptr = boost::make_shared<MatrixDouble>();
auto lambda_h1_ptr = boost::make_shared<MatrixDouble>();
post_proc_ptr->getOpPtrVector().push_back(
auto calcs_side_traction = [&](auto &pip) {
mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
materialH1Positions, frontAdjEdges);
op_loop_domain_side->getOpPtrVector().push_back(
piolaStress, contact_common_data_ptr->contactTractionPtr()));
pip.push_back(op_loop_domain_side);
};
CHKERR calcs_side_traction(post_proc_ptr->getOpPtrVector());
post_proc_ptr->getOpPtrVector().push_back(new OpTreeSearch(
contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
&post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
0, mField.get_comm_size());
post_proc_negative_sense_ptr, 0,
mField.get_comm_size());
CHKERR post_proc_end.writeFile(file.c_str());
}
auto post_proc_norm_fe =
boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
auto post_proc_norm_rule_hook = [](
int,
int,
int p) ->
int {
return 2 * (p);
};
post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
post_proc_norm_fe->getUserPolynomialBase() =
boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
post_proc_norm_fe->getOpPtrVector(), {L2, H1, HDIV}, materialH1Positions,
frontAdjEdges);
enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
auto norms_vec =
CHKERR VecZeroEntries(norms_vec);
auto u_l2_ptr = boost::make_shared<MatrixDouble>();
auto u_h1_ptr = boost::make_shared<MatrixDouble>();
post_proc_norm_fe->getOpPtrVector().push_back(
post_proc_norm_fe->getOpPtrVector().push_back(
post_proc_norm_fe->getOpPtrVector().push_back(
post_proc_norm_fe->getOpPtrVector().push_back(
post_proc_norm_fe->getOpPtrVector().push_back(
u_h1_ptr));
auto piola_ptr = boost::make_shared<MatrixDouble>();
post_proc_norm_fe->getOpPtrVector().push_back(
post_proc_norm_fe->getOpPtrVector().push_back(
TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
CHKERR mField.loop_finite_elements(
"ELASTIC_PROBLEM", elementVolumeName,
*post_proc_norm_fe);
TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
CHKERR VecAssemblyBegin(norms_vec);
CHKERR VecAssemblyEnd(norms_vec);
const double *norms;
CHKERR VecGetArrayRead(norms_vec, &norms);
MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u: " << std::sqrt(norms[U_NORM_L2]);
MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
<< "norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
<< "norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
CHKERR VecRestoreArrayRead(norms_vec, &norms);
}
auto bc_mng = mField.getInterface<
BcManager>();
"", piolaStress, false, false);
bcSpatialDispVecPtr = boost::make_shared<BcDispVec>();
for (auto bc : bc_mng->getBcMapByBlockName()) {
if (auto disp_bc = bc.second->dispBcPtr) {
std::vector<double> block_attributes(6, 0.);
if (disp_bc->data.flag1 == 1) {
block_attributes[0] = disp_bc->data.value1;
block_attributes[3] = 1;
}
if (disp_bc->data.flag2 == 1) {
block_attributes[1] = disp_bc->data.value2;
block_attributes[4] = 1;
}
if (disp_bc->data.flag3 == 1) {
block_attributes[2] = disp_bc->data.value3;
block_attributes[5] = 1;
}
auto faces = bc.second->bcEnts.subset_by_dimension(2);
bcSpatialDispVecPtr->emplace_back(bc.first, block_attributes, faces);
}
}
CHKERR getBc(bcSpatialDispVecPtr,
"SPATIAL_DISP_BC", 6);
}
auto bc_mng = mField.getInterface<
BcManager>();
false, false);
bcSpatialTraction = boost::make_shared<TractionBcVec>();
for (auto bc : bc_mng->getBcMapByBlockName()) {
if (auto force_bc = bc.second->forceBcPtr) {
std::vector<double> block_attributes(6, 0.);
block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
block_attributes[3] = 1;
block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
block_attributes[4] = 1;
block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
block_attributes[5] = 1;
auto faces = bc.second->bcEnts.subset_by_dimension(2);
bcSpatialTraction->emplace_back(bc.first, block_attributes, faces);
}
}
CHKERR getBc(bcSpatialTraction,
"SPATIAL_TRACTION_BC", 6);
}
}