721 {
723 Tag th0, th1, th2, th3;
725 if (number_pathes) {
727 }
728 for (auto edge : edges) {
730 CHKERR moab.get_adjacencies(&edge, 1, 2,
false, adj_faces);
731 adj_faces = intersect(adj_faces, tris);
732 if (adj_faces.size() != 2) {
734 "Should be 2 faces adjacent to edge but is %d",
735 adj_faces.size());
736 }
740 &
v[0], &
v[1], &
v[2]);
741 };
742
746
747 std::array<double, 3> areas;
748 auto calculate_normals = [&, get_tensor_from_vec]() {
749 int ff = 0;
750 for (auto face : adj_faces) {
751 double &x = (
v[ff])[0];
752 double &y = (
v[ff])[1];
753 double &z = (
v[ff])[2];
754 moab::Util::normal(&moab, face, x, y, z);
755 auto t_n = get_tensor_from_vec(
v[ff]);
756 areas[ff] = sqrt(t_n(
i) * t_n(
i));
758 int orientation;
759
760 CHKERR moab.tag_get_data(th3, &face, 1, &orientation);
761 if (orientation == -1) {
763 }
764 if (surface_orientation && m_field_ptr) {
765 CHKERR surface_orientation->getElementOrientation(*m_field_ptr,
766 face);
767 int eo = surface_orientation->elementOrientation;
768 if (eo == -1) {
770 }
771 }
772 ++ff;
773 }
774 };
775 calculate_normals();
776
777 auto get_patch_number = [&]() {
778 std::vector<int>
p = {0, 0};
779 CHKERR moab.tag_get_data(th2, adj_faces, &*
p.begin());
781 };
782
783 std::array<EntityHandle, 2> faces_handles = {adj_faces[0],
784 adj_faces[1]};
785 auto order_normals = [&, get_patch_number]() {
786 auto p = get_patch_number();
789 faces_handles[0] = adj_faces[1];
790 faces_handles[1] = adj_faces[0];
791 }
792 };
793 order_normals();
794
796 auto t_n0 = get_tensor_from_vec(
v[0]);
797 auto t_n1 = get_tensor_from_vec(
v[1]);
799
800 auto get_base_for_coplanar_faces = [&]() {
802
803 std::vector<EntityHandle> face_conn;
804 CHKERR moab.get_connectivity(&faces_handles[1], 1, face_conn,
true);
805 std::vector<EntityHandle> edge_conn;
806 CHKERR moab.get_connectivity(&edge, 1, edge_conn,
true);
807 std::sort(face_conn.begin(), face_conn.end());
808 std::sort(edge_conn.begin(), edge_conn.end());
811 if (face_conn[
n] != edge_conn[
n])
812 break;
814 CHKERR moab.get_coords(&face_conn[
n], 1,
815 &*coords_face.data().begin());
817 CHKERR moab.get_coords(&edge_conn[0], 2,
818 &*coords_edge.data().begin());
820 coords_edge[0], coords_edge[1], coords_edge[2]);
822 coords_edge[3], coords_edge[4], coords_edge[5]);
823 auto t_face_n = get_tensor_from_vec(coords_face);
824 t_face_n(
i) -= t_edge_n0(
i);
826 t_delta(
i) = t_edge_n1(
i) - t_edge_n0(
i);
827 t_delta(
i) /= sqrt(t_delta(
i) * t_delta(
i));
829 if (t_n1(
i) * t_face_n(
i) < 0)
831
833 };
834
835 auto get_base_for_not_planar_faces = [&]() {
838 t_n1(
i) /= sqrt(t_n1(
i) * t_n1(
i));
840 };
841
842
843 constexpr double tol = 1e-6;
844 if ((t_cross(
i) * t_cross(
i)) <
tol)
845 CHKERR get_base_for_coplanar_faces();
846 else
847 CHKERR get_base_for_not_planar_faces();
848
851 CHKERR moab.tag_set_data(th0, &edge, 1, &v0[0]);
852 CHKERR moab.tag_set_data(th1, &edge, 1, &v1[0]);
853 }
855 }
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
FTensor::Index< 'n', SPACE_DIM > n
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
auto cross(const Tensor1_Expr< A, T, 3, i > &a, const Tensor1_Expr< B, U, 3, j > &b, const Index< k, 3 > &)
VectorBoundedArray< double, 3 > VectorDouble3
VectorBoundedArray< double, 6 > VectorDouble6
static MoFEMErrorCode numberSurfaces(moab::Interface &moab, Range edges, Range tris)