LCOV - code coverage report
Current view: top level - include/constraints - MortarSegmentHelper.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #33390 (250e9c) with base 846a5c Lines: 3 3 100.0 %
Date: 2026-07-31 18:15:22 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          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             : };

Generated by: LCOV version 1.14