12 : mField(m_field), fieldName(
field_name), vErbose(verb) {}
19 <<
"Only working well for first order AINSWORTH_BERNSTEIN_BEZIER_BASE!";
33 if (
dofPtr->getEntType() == MBVERTEX) {
40 "val = %6.7e\n",
dofPtr->getFieldData());
46 if (
dofPtr->getEntType() != MBEDGE) {
49 if (
dofPtr->getEntDofIdx() !=
dofPtr->getDofCoeffIdx()) {
55 "this method works only elements which are type of MBEDGE");
61 if ((num_nodes != 2) && (num_nodes != 3)) {
63 "this method works only 4 node and 10 node tets");
65 coords.resize(num_nodes * 3);
69 for (
int dd = 0; dd < 3; dd++) {
78 const auto base =
dofPtr->getApproxBase();
79 double edge_shape_function_val;
82 edge_shape_function_val = 0.25;
100 if (
dofPtr->getNbOfCoeffs() > 3) {
102 "this method works only fields which are rank 3 or lower");
117 const int free_edge_threshold = 1) {
125 CHKERR moab.get_adjacencies(tris, 1,
true, edges, moab::Interface::UNION);
127 std::unordered_map<EntityHandle, int> edge_adj_count;
128 edge_adj_count.reserve(edges.size());
130 for (
auto edge : edges) {
132 CHKERR moab.get_adjacencies(&edge, 1, 2,
false, adj_tris,
133 moab::Interface::UNION);
134 adj_tris = intersect(adj_tris, tris);
135 edge_adj_count[edge] =
static_cast<int>(adj_tris.size());
139 for (
auto tri : tris) {
141 CHKERR moab.get_adjacencies(&tri, 1, 1,
false, tri_edges,
142 moab::Interface::UNION);
144 for (
auto edge : tri_edges) {
145 auto it = edge_adj_count.find(edge);
146 if (it != edge_adj_count.end() && it->second == 1) {
147 if (++free_edges >= free_edge_threshold) {
148 remove_tris.insert(tri);
155 if (!remove_tris.empty()) {
156 tris = subtract(tris, remove_tris);
172 for (
auto tri : tris) {
175 CHKERR moab.get_adjacencies(&tri, 1, 1,
false, adj_edges,
176 moab::Interface::UNION);
178 CHKERR moab.get_adjacencies(adj_edges, 2,
false, adj_tris,
179 moab::Interface::UNION);
180 adj_tris = intersect(adj_tris, tris);
182 if (adj_tris.size() <= 1) {
183 remove_tris.insert(tri);
187 if (!remove_tris.empty()) {
188 tris = subtract(tris, remove_tris);
196 moab::Interface &fine_moab,
197 const Range &fine_tris,
199 double planar_angle_deg,
200 double max_disp_factor,
203 : mField(m_field), fineMoab(fine_moab), fineTris(fine_tris),
204 fieldName(
field_name), vErbose(verb), fineTree(&fine_moab), fineRoot(0),
205 fineFeatureTree(&fine_moab), fineFeatureRoot(0),
206 planarAngleCos(
std::cos(planar_angle_deg * 0.017453292519943295)),
207 maxDispFactor(max_disp_factor), debugSurfaces(debug_surfaces) {}
215 if (coarse_vols.empty()) {
217 "no 3d entities found in coarse mesh");
225 "no skin triangles found in coarse mesh");
231 moab::Interface::UNION);
235 "no surface triangles found in fine mesh");
252 const double fine_planar_cos =
257 moab::Interface::UNION);
264 for (
auto edge : fine_edges) {
267 moab::Interface::UNION);
268 adj_tris = intersect(adj_tris,
fineTris);
269 if (adj_tris.size() != 2) {
275 CHKERR tri_normal(adj_tris[0], n0);
276 CHKERR tri_normal(adj_tris[1], n1);
277 const double dot = n0(
i) * n1(
i);
278 if (std::abs(dot) < fine_planar_cos) {
310 if (
entPtr->getEntType() != MBEDGE)
320 moab::Interface::UNION);
322 if (adj_tris.size() != 2) {
324 "skin edge does not have exactly two adjacent triangles");
332 "edge connectivity has fewer than 2 nodes");
335 const auto base =
entPtr->getApproxBase();
336 double edge_shape_function_val = 0.0;
339 edge_shape_function_val = 0.25;
353 auto ent_data =
entPtr->getEntFieldData();
354 auto t_ent_data = getFTensor1FromPtr<3>(&ent_data(0));
355 if (ent_data.size() != 3) {
357 "edge data size mismatch");
359 coords.resize(num_nodes * 3);
366 edge_vec(
i) = t_n1(
i) - t_n0(
i);
367 const double h = edge_vec.
l2();
373 auto t_ave_mid_coord = getFTensor1FromPtr<3>(&
aveMidCoord(0));
374 auto t_mid_node_coord = getFTensor1FromPtr<3>(&
midNodeCoord(0));
375 t_ave_mid_coord(
i) = 0.5 * (t_n0(
i) + t_n1(
i));
376 t_mid_node_coord(
i) =
377 t_ave_mid_coord(
i) + edge_shape_function_val * t_ent_data(
i);
383 t_normal.normalize();
389 CHKERR tri_normal(adj_tris[0], n0);
390 CHKERR tri_normal(adj_tris[1], n1);
391 const double dot = n0(
i) * n1(
i);
397 double closest_point[3] = {0.0, 0.0, 0.0};
404 "no closest triangle found on fine mesh");
407 auto get_disp = [&](
double _closest_point[3]) {
409 for (
int ii = 0; ii < 3; ii++)
414 double disp = get_disp(closest_point);
422 disp = get_disp(closest_point);
428 "The displacement for edge " << edge
429 <<
" is too large: " << disp <<
" (max allowed (-max_midnode_disp_factor * h) "
439 auto t_diff_node_coord = getFTensor1FromPtr<3>(&
diffNodeCoord(0));
440 t_diff_node_coord(
i) = t_mid_node_coord(
i) - t_ave_mid_coord(
i);
442 auto t_dof = getFTensor1FromPtr<3>(&
dOf(0));
443 t_dof(
i) = t_diff_node_coord(
i) / edge_shape_function_val;
444 if (
entPtr->getNbOfCoeffs() > 3) {
446 "this method works only fields which are rank 3 or lower");
448 ent_data[0] =
dOf[0];
449 ent_data[1] =
dOf[1];
450 ent_data[2] =
dOf[2];
461 std::string _fieldName,
466 onCoords(on_coords), onTag(on_tag), maxApproximationOrder(20) {}
469Field_multiIndex::index<FieldName_mi_tag>::type::iterator
field_it;
476 if (
onTag ==
"NoNE") {
478 "tag name not specified");
485 int field_rank = (*field_it)->getNbOfCoeffs();
486 VectorDouble def_VAL = ublas::zero_vector<double>(field_rank);
488 onTag.c_str(), field_rank, MB_TYPE_DOUBLE,
th,
489 MB_TAG_CREAT | MB_TAG_SPARSE, &*def_VAL.data().begin());
495 &*
L.data().begin(), NULL, 3);
507 if (
dofPtr->getEntType() == MBVERTEX) {
515 int field_rank = (*field_it)->getNbOfCoeffs();
516 if (field_rank !=
dofPtr->getNbOfCoeffs()) {
518 "data inconsistency");
523 th, &node, 1, (
const void **)&tag_value, &tag_size);
524 if (tag_size !=
dofPtr->getNbOfCoeffs()) {
525 SETERRQ(PETSC_COMM_SELF, 1,
"data inconsistency");
527 tag_value[
dofPtr->getDofCoeffIdx()] =
dofPtr->getFieldData();
532 if (
dofPtr->getEntType() != MBEDGE) {
538 "this method works only elements which are type of MBEDGE");
544 if ((num_nodes != 2) && (num_nodes != 3)) {
546 "this method works only 4 node and 10 node tets");
548 if (num_nodes == 2) {
554 "too big approximation order, increase constant "
555 "max_ApproximationOrder");
557 double approx_val = 0;
561 approx_val = 0.25 *
L[
dofPtr->getDofOrder() - 2] *
dofPtr->getFieldData();
564 approx_val = 0.25 *
K[
dofPtr->getDofOrder() - 2] *
dofPtr->getFieldData();
571 coords.resize(num_nodes * 3);
574 if (
dofPtr->getEntDofIdx() ==
dofPtr->getDofCoeffIdx()) {
576 double ave_mid = (
coords[3 * 0 +
dofPtr->getDofCoeffIdx()] +
585 double *tag_value[num_nodes];
587 th, conn, num_nodes, (
const void **)tag_value, &tag_size);
588 if (tag_size !=
dofPtr->getNbOfCoeffs()) {
591 if (
dofPtr->getEntDofIdx() ==
dofPtr->getDofCoeffIdx()) {
593 double ave_mid = (tag_value[0][
dofPtr->getDofCoeffIdx()] +
594 tag_value[1][
dofPtr->getDofCoeffIdx()]) *
596 tag_value[2][
dofPtr->getDofCoeffIdx()] = ave_mid;
598 tag_value[2][
dofPtr->getDofCoeffIdx()] += approx_val;
#define MOFEM_TAG_AND_LOG_C(channel, severity, tag, format,...)
Tag and log in channel.
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define LOBATTO_PHI0(x)
Definitions taken from Hermes2d code.
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
@ AINSWORTH_BERNSTEIN_BEZIER_BASE
#define MOAB_THROW(err)
Check error code of MoAB function and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ MOFEM_DATA_INCONSISTENCY
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
PetscErrorCode Legendre_polynomials(int p, double s, double *diff_s, double *L, double *diffL, int dim)
Calculate Legendre approximation basis.
PetscErrorCode LobattoKernel_polynomials(int p, double s, double *diff_s, double *L, double *diffL, const int dim)
Calculate Kernel Lobatto base functions.
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
FTensor::Index< 'i', SPACE_DIM > i
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasVector< double > VectorDouble
implementation of Data Operators for Forces and Sources
auto type_from_handle(const EntityHandle h)
get type from entity handle
static MoFEMErrorCode filterOuterTrisByTris(moab::Interface &moab, Range &tris)
static MoFEMErrorCode filterOuterTrisByEdges(moab::Interface &moab, Range &tris, const int free_edge_threshold=1)
Field_multiIndex::index< FieldName_mi_tag >::type::iterator field_it
constexpr auto field_name
static constexpr double delta
const Field_multiIndex * fieldsPtr
Raw pointer to fields multi-index container.
virtual moab::Interface & get_moab()=0
Deprecated interface functions.
boost::shared_ptr< DofEntity > dofPtr
Shared pointer to DOF entity data.
boost::shared_ptr< FieldEntity > entPtr
Shared pointer to field entity data.
MultiIndex Tag for field name.
VectorDouble3 aveMidCoord
AdaptiveKDTree fineFeatureTree
moab::Interface & fineMoab
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
MoFEMErrorCode operator()()
Main operator function executed for each loop iteration.
VectorDouble3 midNodeCoord
EntityHandle fineFeatureRoot
VectorDouble3 diffNodeCoord
MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
Projection10NodeCoordsFromFineSurfaceOnField(Interface &m_field, moab::Interface &fine_moab, const Range &fine_tris, std::string field_name, double planar_angle_deg=5.0, double max_disp_factor=0.5, bool debug_surfaces=false, int verb=0)
Projection of edge entities with one mid-node on hierarchical basis.
VectorDouble3 diffNodeCoord
VectorDouble3 midNodeCoord
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
VectorDouble3 aveMidCoord
MoFEMErrorCode operator()()
Main operator function executed for each loop iteration.
Projection10NodeCoordsOnField(Interface &m_field, std::string field_name, int verb=0)
MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
ProjectionFieldOn10NodeTet(Interface &m_field, std::string _fieldName, bool set_nodes, bool on_coords, std::string on_tag="NoNE")
MoFEMErrorCode operator()()
Main operator function executed for each loop iteration.
const int maxApproximationOrder
Field_multiIndex::index< FieldName_mi_tag >::type::iterator field_it
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.