Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "MortarSegmentInfo.h" 13 : 14 : #include "libmesh/point.h" 15 : #include "libmesh/int_range.h" 16 : 17 : #include <array> 18 : #include <optional> 19 : #include <string> 20 : #include <vector> 21 : 22 : using libMesh::Point; 23 : using libMesh::Real; 24 : 25 : #ifdef MOOSE_UNIT_TEST 26 : class MortarSegmentHelperTest; 27 : #endif 28 : 29 : /** 30 : * This class supports defining mortar segment mesh elements in 3D by projecting secondary and 31 : * primary elements onto a linearized plane, computing the overlapping polygon formed by their 32 : * projections, and triangulating the resulting nodes. 33 : */ 34 : 35 : class MortarSegmentHelper 36 : { 37 : public: 38 : /** 39 : * Construct a helper that generates mortar segment geometry only. 40 : */ 41 : MortarSegmentHelper(std::vector<Point> secondary_nodes, 42 : const Point & center, 43 : const Point & normal, 44 : const MortarSegmentTriangulationMode triangulation_mode, 45 : const bool triangulate_triangles); 46 : 47 : /** 48 : * Construct a helper that also tracks secondary parent-reference coordinates. 49 : */ 50 : MortarSegmentHelper(std::vector<Point> secondary_nodes, 51 : std::vector<Point> secondary_reference_points, 52 : const Point & center, 53 : const Point & normal, 54 : const MortarSegmentTriangulationMode triangulation_mode, 55 : const bool triangulate_triangles); 56 : 57 : /** 58 : * Computes the intersection between line segments defined by point pairs (p1,p2) and (q1,q2) 59 : * Also computes s, the ratio of distance between (p1,p2) that the intersection falls, 60 : * quantity s is useful in avoiding adding nearly degenerate nodes 61 : */ 62 : Point getIntersection( 63 : const Point & p1, const Point & p2, const Point & q1, const Point & q2, Real & s) const; 64 : 65 : /** 66 : * Check that a point is inside the secondary polygon (for verification only) 67 : */ 68 : bool isInsideSecondary(const Point & pt) const; 69 : 70 : /** 71 : * Checks whether polygons are disjoint for an easy out 72 : */ 73 : bool isDisjoint(const std::vector<Point> & poly) const; 74 : 75 : /** 76 : * Project a primary polygon into the helper plane while preserving the clipping orientation. 77 : */ 78 : std::vector<Point> projectPrimaryPoly(const std::vector<Point> & primary_nodes) const; 79 : 80 : /** 81 : * Clip secondary element (defined in instantiation) against given primary polygon 82 : * result is a set of 2D nodes defining clipped polygon 83 : */ 84 : std::vector<Point> clipPoly(const std::vector<Point> & primary_nodes) const; 85 : 86 : /** 87 : * Triangulate a polygon according to the configured mortar-segment triangulation mode. 88 : * @param poly_nodes List of 2D nodes defining polygon. May be augmented with extra interior 89 : * nodes (e.g. centroid) by triangulation modes that require them; callers 90 : * should append the result to their nodes list before applying the offset 91 : * to \p tri_map. 92 : * @param tri_map Output triangle list expressed in indices local to \p poly_nodes (i.e. starting 93 : * at 0). Callers are responsible for shifting these indices into the global node 94 : * numbering. 95 : */ 96 : void triangulatePoly(std::vector<Point> & poly_nodes, 97 : std::vector<std::vector<unsigned int>> & tri_map) const; 98 : 99 : /** 100 : * Get mortar segments generated by a secondary and primary element pair 101 : * @param primary_nodes List of primary element 3D nodes 102 : * @return nodes List of 3D mortar segment nodes 103 : * @return tri_map List of integer arrays defining which nodes belong to each mortar segment 104 : */ 105 : void getMortarSegments(const std::vector<Point> & primary_nodes, 106 : std::vector<Point> & nodes, 107 : std::vector<std::vector<unsigned int>> & elem_to_nodes); 108 : 109 : /** 110 : * Get mortar segments and aligned parent-reference coordinates by appending to the output 111 : * containers. Segments below \p minimum_segment_area are removed before mapping; retained 112 : * vertices must map uniquely. 113 : */ 114 : void getMortarSegments(const std::vector<Point> & primary_nodes, 115 : const std::vector<Point> & primary_reference_points, 116 : std::vector<Point> & nodes, 117 : std::vector<std::vector<unsigned int>> & elem_to_nodes, 118 : std::vector<std::array<Point, 3>> & elem_to_secondary_reference_points, 119 : std::vector<std::array<Point, 3>> & elem_to_primary_reference_points, 120 : Real minimum_segment_area = 0.); 121 : 122 : /** 123 : * Compute area of polygon 124 : */ 125 : Real area(const std::vector<Point> & nodes) const; 126 : 127 : /** 128 : * Get center point of secondary element 129 : */ 130 5909 : const Point & center() const { return _center; } 131 : 132 : /** 133 : * Get the unit normal of the projection plane. 134 : */ 135 387672 : const Point & normal() const { return _normal; } 136 : 137 : /** 138 : * Get area fraction remaining after clipping against primary elements 139 : */ 140 480 : Real remainder() const { return _remaining_area_fraction; } 141 : 142 : /** 143 : * Get 3D position of node of linearized secondary element 144 : */ 145 : Point point(unsigned int i) const 146 : { 147 : return (_secondary_poly[i](0) * _u) + (_secondary_poly[i](1) * _v) + _center; 148 : } 149 : 150 : private: 151 : /** 152 : * Output containers and filtering data used while generating reference-coordinate mappings. 153 : */ 154 : struct ReferenceMappingData 155 : { 156 : const std::vector<Point> & primary_reference_points; 157 : std::vector<std::array<Point, 3>> & elem_to_secondary_reference_points; 158 : std::vector<std::array<Point, 3>> & elem_to_primary_reference_points; 159 : Real minimum_segment_area; 160 : }; 161 : 162 : void getMortarSegmentsImpl(const std::vector<Point> & primary_nodes, 163 : std::vector<Point> & nodes, 164 : std::vector<std::vector<unsigned int>> & elem_to_nodes, 165 : ReferenceMappingData * reference_mapping); 166 : 167 : /** 168 : * Clip an already projected primary polygon against the secondary polygon. Keeping projection 169 : * separate preserves the ordering shared with primary reference points. 170 : */ 171 : std::vector<Point> clipProjectedPoly(const std::vector<Point> & primary_poly) const; 172 : 173 : /** 174 : * Recover a parent-reference point from a projected sub-element map. 175 : * @return No value for invalid or out-of-tolerance maps. 176 : */ 177 : std::optional<Point> referencePoint(const Point & point, 178 : const std::vector<Point> & poly, 179 : const std::vector<Point> & reference_points, 180 : std::string * failure_reason = nullptr) const; 181 : 182 : #ifdef MOOSE_UNIT_TEST 183 : friend class MortarSegmentHelperTest; 184 : #endif 185 : 186 : /** 187 : * Geometric center of secondary element 188 : */ 189 : Point _center; 190 : 191 : /** 192 : * Unit normal of the plane used to project and clip the linearized secondary subpatch. 193 : */ 194 : Point _normal; 195 : 196 : /** 197 : * Vectors orthogonal to normal that span the plane projection will be performed on. 198 : * These vectors are used to project the polygon clipping problem on a 2D plane, 199 : * they are defined so the nodes of the projected polygon are listed with positive orientation 200 : */ 201 : Point _u, _v; 202 : 203 : /** 204 : * Area of projected secondary element 205 : */ 206 : Real _secondary_area; 207 : 208 : /** 209 : * Fraction of area remaining after overlapping primary polygons clipped 210 : */ 211 : Real _remaining_area_fraction; 212 : 213 : bool _debug; 214 : 215 : /** 216 : * Tolerance for intersection and clipping 217 : */ 218 : Real _tolerance = 1e-8; 219 : 220 : /** 221 : * Triangulation mode used for clipped polygons. 222 : */ 223 : const MortarSegmentTriangulationMode _triangulation_mode; 224 : 225 : /** 226 : * Whether already-triangular polygons should still be centroid-subdivided. 227 : */ 228 : const bool _triangulate_triangles; 229 : 230 : /** 231 : * Tolerance times secondary area for dimensional consistency 232 : */ 233 : Real _area_tol; 234 : 235 : /** 236 : * Tolerance times secondary area for dimensional consistency 237 : */ 238 : Real _length_tol; 239 : 240 : /** 241 : * List of projected points on the linearized secondary element 242 : */ 243 : std::vector<Point> _secondary_poly; 244 : 245 : /// Parent reference points corresponding to _secondary_poly. 246 : std::vector<Point> _secondary_reference_points; 247 : };