1#ifndef __SMOOTHER_HPP__
2#define __SMOOTHER_HPP__
5#error "MoFEM need to be compiled with ADOL-C"
12 Range &output_vertices) {
15 Range fineFeatureTris;
21 "no 3d entities found in the mesh");
24 Skinner skinner(&m_field.
get_moab());
26 CHKERR skinner.find_skin(0, vols,
false, skin_tris);
27 if (skin_tris.empty()) {
29 "no skin triangles found in the mesh");
40 const double fine_planar_cos = std::cos(1e-6);
43 CHKERR m_field.
get_moab().get_adjacencies(skin_tris, 1,
true, skin_edges,
44 moab::Interface::UNION);
46 for (
auto edge : skin_edges) {
48 CHKERR m_field.
get_moab().get_adjacencies(&edge, 1, 2,
false, adj_tris,
49 moab::Interface::UNION);
50 adj_tris = intersect(adj_tris, skin_tris);
51 if (adj_tris.size() != 2) {
57 CHKERR tri_normal(adj_tris[0], n0);
58 CHKERR tri_normal(adj_tris[1], n1);
59 const double dot = n0(
i) * n1(
i);
60 if (std::abs(dot) <= fine_planar_cos) {
61 fineFeatureTris.insert(adj_tris[0]);
62 fineFeatureTris.insert(adj_tris[1]);
63 output_edges.insert(edge);
67 std::map<EntityHandle, std::vector<EntityHandle>> vert_edges;
68 for (
auto edge : output_edges) {
71 CHKERR m_field.
get_moab().get_connectivity(edge, conn, nconn,
false);
74 vert_edges[conn[0]].push_back(edge);
75 vert_edges[conn[1]].push_back(edge);
79 for (
auto edge : output_edges) {
82 CHKERR m_field.
get_moab().get_connectivity(edge, conn, nconn,
false);
86 bool keep_edge =
true;
87 for (
int vv = 0; vv < 2; ++vv) {
88 const auto v = conn[vv];
89 const auto it = vert_edges.find(
v);
90 if (it == vert_edges.end()) {
94 const auto &inc_edges = it->second;
95 if (inc_edges.size() > 2) {
99 if (inc_edges.size() == 2) {
100 const auto other_edge =
101 (inc_edges[0] == edge) ? inc_edges[1] : inc_edges[0];
104 CHKERR m_field.
get_moab().get_connectivity(other_edge, conn_other,
106 if (nconn_other != 2) {
111 (conn_other[0] ==
v) ? conn_other[1] : conn_other[0];
113 double pv[3], pa[3], pb[3];
122 &pv[0], &pv[1], &pv[2]);
124 &pa[0], &pa[1], &pa[2]);
126 &pb[0], &pb[1], &pb[2]);
127 a(
i) = t_pa(
i) - t_pv(
i);
128 b(
i) = t_pb(
i) - t_pv(
i);
129 const double na =
a.l2();
130 const double nb = b.
l2();
131 if (na == 0 || nb == 0) {
135 const double dot = (
a(
i) * b(
i)) / (na * nb);
136 if (std::abs(dot) < fine_planar_cos) {
144 straight_edges.insert(edge);
148 output_edges = straight_edges;
149 output_vertices.clear();
150 if (!output_edges.empty()) {
151 std::map<EntityHandle, int> vert_count;
152 for (
auto edge : output_edges) {
155 CHKERR m_field.
get_moab().get_connectivity(edge, conn, nconn,
false);
158 vert_count[conn[0]]++;
159 vert_count[conn[1]]++;
161 Range filtered_edges;
162 for (
auto edge : output_edges) {
165 CHKERR m_field.
get_moab().get_connectivity(edge, conn, nconn,
false);
168 const int d0 = vert_count[conn[0]];
169 const int d1 = vert_count[conn[1]];
170 if (!(d0 == 1 && d1 == 1)) {
171 filtered_edges.insert(edge);
172 for (
int vv = 0; vv < 2; ++vv) {
173 const auto v = conn[vv];
174 auto it = vert_count.find(
v);
175 if (it != vert_count.end() && it->second == 1) {
176 output_vertices.insert(
v);
181 output_edges = filtered_edges;
184 if (!fineFeatureTris.empty())
186 "tri_features_test.vtk", fineFeatureTris);
187 if (!output_edges.empty())
189 "edges_test.vtk", output_edges);
190 if (!output_vertices.empty())
192 "vertices_test.vtk", output_vertices);
203 using OpKPiola = BiLinearForm::OpGradTensorGrad<1, 3, 3, 1>;
219 template <
typename TYPE>
224 boost::shared_ptr<CalculatePK1<adouble>>
226 boost::shared_ptr<CalculatePK1<double>>
234 template <
typename TYPE>
261 m.resize(3, 3,
false);
307 MoFEMErrorCode
doWork(
int side, EntityType type,
308 EntitiesFieldData::EntData &data) {
311 if (type != MBVERTEX)
316 if (mat_grad.size2() != nb_gauss_pts)
319 auto t_grad = getFTensor2FromMat<3, 3>(mat_grad);
328 mat_p.resize(9, nb_gauss_pts,
false);
330 auto t_p = getFTensor2FromMat<3, 3>(mat_p);
333 "Material pointer not set");
335 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
338 for (
int ii = 0; ii < 3; ++ii) {
339 for (
int jj = 0; jj < 3; ++jj) {
345 for (
int ii = 0; ii < 3; ++ii)
346 for (
int jj = 0; jj < 3; ++jj)
357 "AD material pointer not set");
361 mat_tangent.resize(81, nb_gauss_pts,
false);
363 auto t_dP_dF = getFTensor4FromMat<3, 3, 3, 3, 1>(mat_tangent);
367 jacMat.resize(9, 9,
false);
369 bool tag_recorded =
false;
370 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
372 for (
int ii = 0; ii < 3; ++ii) {
373 for (
int jj = 0; jj < 3; ++jj) {
383 for (
int ii = 0; ii < 3; ++ii) {
384 for (
int jj = 0; jj < 3; ++jj) {
390 for (
int ii = 0; ii < 3; ++ii) {
391 for (
int jj = 0; jj < 3; ++jj) {
400 for (
int rr = 0; rr < 9; ++rr)
401 jac_ptr[rr] = &
jacMat(rr, 0);
406 "ADOL-C function evaluation with error");
408 for (
int ii = 0; ii < 3; ++ii) {
409 for (
int jj = 0; jj < 3; ++jj) {
410 for (
int kk = 0; kk < 3; ++kk) {
411 for (
int ll = 0; ll < 3; ++ll) {
412 t_dP_dF(ii, jj, kk, ll) =
413 jacMat(ii * 3 + jj, kk * 3 + ll);
ForcesAndSourcesCore::UserDataOperator UserDataOperator
#define FTENSOR_INDEX(DIM, I)
#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_OPERATION_UNSUCCESSFUL
@ MOFEM_DATA_INCONSISTENCY
#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 ...
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
FTensor::Index< 'l', 3 > l
constexpr auto field_name
FTensor::Index< 'm', 3 > m
virtual moab::Interface & get_moab()=0
std::array< bool, MBMAXTYPE > doEntities
If true operator is executed for entity.
Deprecated interface functions.
@ OPROW
operator doWork function is executed on FE rows
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Volume finite element base.
FTensor::Index< 'k', 3 > k
FTensor::Index< 'j', 3 > j
FTensor::Index< 'i', 3 > i
boost::shared_ptr< CalculatePK1< double > > materialDoublePtr
boost::shared_ptr< CalculatePK1< adouble > > materialAdoublePtr
FTensor::Tensor2< FTensor::PackPtr< TYPE *, 0 >, 3, 3 > t_P
FTensor::Index< 'i', 3 > i
FTensor::Index< 'k', 3 > k
virtual MoFEMErrorCode calculateP_PiolaKirchhoffI()
MoFEM::VolumeElementForcesAndSourcesCore::UserDataOperator * opPtr
pointer to finite element tetrahedral operator
CalculatePK1(const std::string field_name)
FTensor::Index< 'j', 3 > j
MatrixBoundedArray< TYPE, 9 > F
int gG
Gauss point number.
CommonData * commonDataPtr
field values at Gauss pts.)
MatrixBoundedArray< TYPE, 9 > invF
static auto resizeAndSet(MatrixBoundedArray< TYPE, 9 > &m)
FTensor::Tensor2< FTensor::PackPtr< TYPE *, 0 >, 3, 3 > t_F
MatrixBoundedArray< TYPE, 9 > P
FTensor::Tensor2< FTensor::PackPtr< TYPE *, 0 >, 3, 3 > t_invF
boost::shared_ptr< MatrixDouble > matTangentPtr
std::string meshPositions
std::vector< MatrixDouble > sTress
std::string spatialPositions
boost::shared_ptr< MatrixDouble > matFirstPiolaStressPtr
boost::shared_ptr< MatrixDouble > matGradPtr
const bool computeJacobian
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
OpJacobianSmoother(const std::string field_name, BlockData &data, CommonData &common_data, int tag, bool jacobian)
MyVolumeFE & feLhs
calculate left hand side for tetrahedral elements
BiLinearForm::OpGradTensorGrad< 1, 3, 3, 1 > OpKPiola
MyVolumeFE & getLoopFeLhs()
get lhs volume element
std::map< int, BlockData > setOfBlocks
Smoother(MoFEM::Interface &m_field)
boost::shared_ptr< MyVolumeFE > feLhsPtr
static MoFEMErrorCode extractMeshEdges(MoFEM::Interface &m_field, Range &output_edges, Range &output_vertices)
MyVolumeFE & getLoopFeRhs()
get rhs volume element
LinearForm::OpGradTimesTensor< 1, 3, 3 > OpInternalForcePiola
boost::shared_ptr< MyVolumeFE > feRhsPtr
MyVolumeFE & feRhs
calculate right hand side for tetrahedral elements