12 #include "libmesh/int_range.h" 19 : _center(center), _normal(normal), _debug(false)
25 const Point e1 = secondary_nodes[0] - secondary_nodes[1];
26 const Point e2 = secondary_nodes[2] - secondary_nodes[1];
36 for (
const auto & node : secondary_nodes)
57 const Point dp = p2 - p1;
58 const Point dq = q2 - q1;
59 const Real cp1q1 = p1(0) * q1(1) - p1(1) * q1(0);
60 const Real cp1q2 = p1(0) * q2(1) - p1(1) * q2(0);
61 const Real cq1q2 = q1(0) * q2(1) - q1(1) * q2(0);
62 const Real alpha = 1. / (dp(0) * dq(1) - dp(1) * dq(0));
63 s = -alpha * (cp1q2 - cp1q1 - cq1q2);
80 const Point e1 = q2 - q1;
81 const Point e2 = pt - q1;
87 bool inside = (e1(0) * e2(1) - e1(1) * e2(0)) <
_area_tol;
102 const Point edg = q2 - q1;
103 const Real cp = q2(0) * q1(1) - q2(1) * q1(0);
107 auto is_inside = [&edg, cp](
Point & pt,
Real tol)
108 {
return pt(0) * edg(1) - pt(1) * edg(0) + cp < -tol; };
110 bool all_outside =
true;
125 const Point e1 = primary_nodes[0] - primary_nodes[1];
126 const Point e2 = primary_nodes[2] - primary_nodes[1];
133 std::vector<Point> primary_poly;
134 const int n_verts = primary_nodes.size();
137 Point pt = (orient > 0) ? primary_nodes[n] -
_center : primary_nodes[n_verts - 1 - n] -
_center;
138 primary_poly.emplace_back(pt *
_u, pt *
_v, 0.);
143 primary_poly.clear();
154 if (clipped_poly.size() < 3)
156 clipped_poly.clear();
161 std::vector<Point> input_poly(clipped_poly);
162 clipped_poly.clear();
165 const Point & clip_pt1 = primary_poly[i];
166 const Point & clip_pt2 = primary_poly[(i + 1) % primary_poly.size()];
167 const Point edg = clip_pt2 - clip_pt1;
168 const Real cp = clip_pt2(0) * clip_pt1(1) - clip_pt2(1) * clip_pt1(0);
176 auto is_inside = [&edg, cp](
const Point & pt,
Real tol)
177 {
return pt(0) * edg(1) - pt(1) * edg(0) + cp < tol; };
183 const Point curr_pt = input_poly[(j + 1) % input_poly.size()];
184 const Point prev_pt = input_poly[j];
187 const bool is_current_inside = is_inside(curr_pt,
_area_tol);
188 const bool is_previous_inside = is_inside(prev_pt,
_area_tol);
190 if (is_current_inside)
192 if (!is_previous_inside)
211 clipped_poly.push_back(intersect);
213 clipped_poly.push_back(curr_pt);
215 else if (is_previous_inside)
220 clipped_poly.push_back(intersect);
227 if (clipped_poly.size() < 3)
229 clipped_poly.clear();
234 std::vector<Point> cleaned_poly;
236 cleaned_poly.push_back(clipped_poly.back());
237 for (
auto i :
make_range(clipped_poly.size() - 1))
239 const Point prev_pt = cleaned_poly.back();
240 const Point curr_pt = clipped_poly[i];
244 cleaned_poly.push_back(curr_pt);
252 const unsigned int offset,
253 std::vector<std::vector<unsigned int>> & tri_map)
const 261 if (poly_nodes.size() < 3)
262 mooseError(
"Can't triangulate poly with fewer than 3 nodes");
264 else if (poly_nodes.size() == 3)
266 tri_map.push_back({0 + offset, 1 + offset, 2 + offset});
276 const unsigned int n_verts = poly_nodes.size();
279 for (
auto node : poly_nodes)
281 poly_center /= n_verts;
285 tri_map.push_back({i + offset, (i + 1) % n_verts + offset, n_verts + offset});
288 poly_nodes.push_back(poly_center);
295 std::vector<Point> & nodes,
296 std::vector<std::vector<unsigned int>> & elem_to_nodes)
299 std::vector<Point> clipped_poly =
clipPoly(primary_nodes);
300 if (clipped_poly.size() < 3)
304 for (
auto pt : clipped_poly)
306 mooseError(
"Clipped polygon not inside linearized secondary element");
315 for (
auto pt : clipped_poly)
316 nodes.emplace_back((pt(0) *
_u) + (pt(1) *
_v) +
_center);
324 poly_area += nodes[i](0) * nodes[(i + 1) % nodes.size()](1) -
325 nodes[i](1) * nodes[(i + 1) % nodes.size()](0);
Point _center
Geometric center of secondary element.
Real _area_tol
Tolerance times secondary area for dimensional consistency.
bool isInsideSecondary(const Point &pt) const
Check that a point is inside the secondary polygon (for verification only)
auto norm() const -> decltype(std::norm(Real()))
R poly(const C &c, const T x, const bool derivative=false)
Evaluate a polynomial with the coefficients c at x.
void getMortarSegments(const std::vector< Point > &primary_nodes, std::vector< Point > &nodes, std::vector< std::vector< unsigned int >> &elem_to_nodes)
Get mortar segments generated by a secondary and primary element pair.
Real _length_tol
Tolerance times secondary area for dimensional consistency.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
std::vector< Point > clipPoly(const std::vector< Point > &primary_nodes) const
Clip secondary element (defined in instantiation) against given primary polygon result is a set of 2D...
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
std::vector< Point > _secondary_poly
List of projected points on the linearized secondary element.
Real _tolerance
Tolerance for intersection and clipping.
Point _u
Vectors orthogonal to normal that span the plane projection will be performed on. ...
Real _secondary_area
Area of projected secondary element.
Point _normal
Normal at geometric center of secondary element.
bool isDisjoint(const std::vector< Point > &poly) const
Checks whether polygons are disjoint for an easy out.
const Point & center() const
Get center point of secondary element.
Real area(const std::vector< Point > &nodes) const
Compute area of polygon.
TypeVector< typename CompareTypes< Real, T2 >::supertype > cross(const TypeVector< T2 > &v) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
IntRange< T > make_range(T beg, T end)
Point getIntersection(const Point &p1, const Point &p2, const Point &q1, const Point &q2, Real &s) const
Computes the intersection between line segments defined by point pairs (p1,p2) and (q1...
MortarSegmentHelper(const std::vector< Point > secondary_nodes, const Point ¢er, const Point &normal)
Real _remaining_area_fraction
Fraction of area remaining after overlapping primary polygons clipped.
void triangulatePoly(std::vector< Point > &poly_nodes, const unsigned int offset, std::vector< std::vector< unsigned int >> &tri_map) const
Triangulate a polygon (currently uses center of polygon to define triangulation)
auto index_range(const T &sizable)