https://mooseframework.inl.gov
AutomaticMortarGeneration.h
Go to the documentation of this file.
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 #include "Mortar3DSubpatchPlane.h"
14 #include "MooseHashing.h"
15 #include "ConsoleStreamInterface.h"
16 #include "MooseError.h"
17 #include "MooseUtils.h"
18 
19 // libMesh includes
20 #include "libmesh/id_types.h"
21 #include "libmesh/equation_systems.h"
22 #include "libmesh/elem.h"
23 #include "libmesh/int_range.h"
24 
25 // C++ includes
26 #include <array>
27 #include <optional>
28 #include <set>
29 #include <memory>
30 #include <vector>
31 #include <unordered_map>
32 
33 // Forward declarations
34 namespace libMesh
35 {
36 class MeshBase;
37 class System;
38 }
39 class GetPot;
40 
41 // Using statements
45 using libMesh::Elem;
46 using libMesh::MeshBase;
47 using libMesh::Node;
48 using libMesh::Point;
49 using libMesh::Real;
51 
54 
59 {
60  std::array<Point, 3> secondary_reference_points;
61  std::array<Point, 3> primary_reference_points;
62 };
63 
69 {
70 public:
75  const static std::string system_name;
76 
82  MeshBase & mesh_in,
83  const std::pair<BoundaryID, BoundaryID> & boundary_key,
84  const std::pair<SubdomainID, SubdomainID> & subdomain_key,
85  bool on_displaced,
86  bool periodic,
87  const bool debug,
88  const bool correct_edge_dropping,
89  const Real minimum_projection_angle,
90  const Mortar3DSubpatchPlane mortar_3d_subpatch_plane,
91  const MortarSegmentTriangulationMode triangulation_mode,
92  const bool triangulate_triangles,
93  const Mortar3DQuadraturePointMapping mortar_3d_qp_mapping =
94  Mortar3DQuadraturePointMapping::NORMAL_PROJECTION);
95 
102  void buildNodeToElemMaps();
103 
111  void computeNodalGeometry();
112 
126  void projectSecondaryNodes();
127 
142  void projectPrimaryNodes();
143 
160  void buildMortarSegmentMesh();
161 
174 
180  {
191  std::size_t msm_n_elems;
195  };
196 
201  std::vector<MsmSubdomainStats> computeMsmStatistics();
202 
206  void msmStatistics();
207 
211  void clear();
212 
217  void meshChanged() { _msm_node_id_start = std::nullopt; }
218 
222  bool onDisplaced() const { return _on_displaced; }
223 
227  std::vector<Point> getNodalNormals(const Elem & secondary_elem) const;
228 
233  std::array<MooseUtils::SemidynamicVector<Point, 9>, 2>
234  getNodalTangents(const Elem & secondary_elem) const;
235 
240  std::map<unsigned int, unsigned int>
241  getSecondaryIpToLowerElementMap(const Elem & lower_secondary_elem) const;
242 
249  std::map<unsigned int, unsigned int>
250  getPrimaryIpToLowerElementMap(const Elem & primary_elem,
251  const Elem & primary_elem_ip,
252  const Elem & lower_secondary_elem) const;
253 
262  std::vector<Point> getNormals(const Elem & secondary_elem,
263  const std::vector<Point> & xi1_pts) const;
264 
273  std::vector<Point> getNormals(const Elem & secondary_elem,
274  const std::vector<Real> & oned_xi1_pts) const;
275 
283  const Elem * getSecondaryLowerdElemFromSecondaryElem(dof_id_type secondary_elem_id) const;
284 
289  void computeInactiveLMNodes();
290 
296 
301  void computeInactiveLMElems();
302 
306  const std::unordered_map<dof_id_type, std::unordered_set<dof_id_type>> &
308  {
310  }
311 
315  const std::pair<BoundaryID, BoundaryID> & primarySecondaryBoundaryIDPair() const;
316 
320  const MeshBase & mortarSegmentMesh() const { return *_mortar_segment_mesh; }
321 
325  const std::unordered_map<const Elem *, MortarSegmentInfo> & mortarSegmentMeshElemToInfo() const
326  {
327  return _msm_elem_to_info;
328  }
329 
330  int dim() const { return _mesh.mesh_dimension(); }
331 
333  Mortar3DQuadraturePointMapping mortar3DQpMapping() const { return _mortar_3d_qp_mapping; }
334 
337  mortarSegmentReferencePoints(const Elem & mortar_segment_elem) const;
338 
342  const std::unordered_set<const Node *> & getInactiveLMNodes() const
343  {
345  }
346 
350  const std::unordered_set<const Elem *> & getInactiveLMElems() const
351  {
353  }
354 
356 
357  using MortarFilterIter =
358  std::unordered_map<dof_id_type, std::set<Elem *, CompareDofObjectsByID>>::const_iterator;
359 
366  std::vector<MortarFilterIter> secondariesToMortarSegments(const Node & node) const;
367 
372  const std::unordered_map<dof_id_type, std::set<Elem *, CompareDofObjectsByID>> &
374  {
376  }
377 
381  const std::set<SubdomainID> & secondaryIPSubIDs() const { return _secondary_ip_sub_ids; }
382 
386  const std::set<SubdomainID> & primaryIPSubIDs() const { return _primary_ip_sub_ids; }
387 
391  const std::unordered_map<dof_id_type, std::vector<const Elem *>> & nodesToSecondaryElem() const
392  {
394  }
395 
399  void initOutput();
400 
401 private:
405  void outputMortarMesh();
406 
410  std::string mortarInterfaceName() const;
411 
416 
419 
422 
424  std::set<BoundaryID> _secondary_requested_boundary_ids;
425 
427  std::set<BoundaryID> _primary_requested_boundary_ids;
428 
431  std::vector<std::pair<BoundaryID, BoundaryID>> _primary_secondary_boundary_id_pairs;
432 
434  std::unordered_map<dof_id_type, std::vector<const Elem *>> _nodes_to_secondary_elem_map;
435  std::unordered_map<dof_id_type, std::vector<const Elem *>> _nodes_to_primary_elem_map;
436 
454  std::unordered_map<std::pair<const Node *, const Elem *>, std::pair<Real, const Elem *>>
456 
462  std::map<std::tuple<dof_id_type, const Node *, const Elem *>, std::pair<Real, const Elem *>>
464 
467  std::unique_ptr<MeshBase> _mortar_segment_mesh;
468 
472  std::unordered_map<const Elem *, MortarSegmentInfo> _msm_elem_to_info;
473 
476  std::unordered_map<const Elem *, unsigned int> _lower_elem_to_side_id;
477 
480  std::vector<std::pair<SubdomainID, SubdomainID>> _primary_secondary_subdomain_id_pairs;
481 
484  std::set<SubdomainID> _secondary_boundary_subdomain_ids;
485  std::set<SubdomainID> _primary_boundary_subdomain_ids;
486 
495  std::unordered_map<dof_id_type, std::unordered_set<dof_id_type>> _mortar_interface_coupling;
496 
498  std::unordered_map<const Node *, Point> _secondary_node_to_nodal_normal;
499 
502  std::unordered_map<const Node *, std::array<Point, 2>> _secondary_node_to_hh_nodal_tangents;
503 
505  std::unordered_map<dof_id_type, const Elem *> _secondary_element_to_secondary_lowerd_element;
506 
507  // List of inactive lagrange multiplier nodes (for nodal variables)
508  std::unordered_set<const Node *> _inactive_local_lm_nodes;
509 
511  std::unordered_set<const Elem *> _inactive_local_lm_elems;
512 
516  std::unordered_map<dof_id_type, std::set<Elem *, CompareDofObjectsByID>>
518 
520  std::set<SubdomainID> _secondary_ip_sub_ids;
521 
523  std::set<SubdomainID> _primary_ip_sub_ids;
524 
530  void projectSecondaryNodesSinglePair(SubdomainID lower_dimensional_primary_subdomain_id,
531  SubdomainID lower_dimensional_secondary_subdomain_id);
532 
536  void projectPrimaryNodesSinglePair(SubdomainID lower_dimensional_primary_subdomain_id,
537  SubdomainID lower_dimensional_secondary_subdomain_id);
538 
542  void
543  householderOrthogolization(const Point & normal, Point & tangent_one, Point & tangent_two) const;
544 
549  bool processAlignedNodes(const Node & secondary_node,
550  const Node & primary_node,
551  const std::vector<const Elem *> * secondary_node_neighbors,
552  const std::vector<const Elem *> * primary_node_neighbors,
553  const VectorValue<Real> & nodal_normal,
554  const Elem & candidate_element,
555  std::set<const Elem *> & rejected_element_candidates);
556 
558  const bool _debug;
559 
561  const bool _on_displaced;
562 
564  const bool _periodic;
565 
567  const bool _distributed;
568 
571 
576 
580 
586 
588  const Mortar3DSubpatchPlane _mortar_3d_subpatch_plane;
589 
592 
595 
597  const Mortar3DQuadraturePointMapping _mortar_3d_qp_mapping;
598 
600  std::unordered_map<const Elem *, MortarSegmentReferencePoints> _msm_elem_to_reference_points;
601 
603  std::unique_ptr<InputParameters> _output_params;
604 
608  std::optional<dof_id_type> _msm_node_id_start;
609 
612  std::unordered_set<dof_id_type> _projected_secondary_nodes;
613 
615  std::unordered_set<dof_id_type> _failed_secondary_node_projections;
616 
619 };
620 
621 inline const std::pair<BoundaryID, BoundaryID> &
623 {
624  mooseAssert(_primary_secondary_boundary_id_pairs.size() == 1,
625  "We currently only support a single boundary pair per mortar generation object");
626 
628 }
std::set< SubdomainID > _primary_boundary_subdomain_ids
const std::pair< BoundaryID, BoundaryID > & primarySecondaryBoundaryIDPair() const
const Elem * getSecondaryLowerdElemFromSecondaryElem(dof_id_type secondary_elem_id) const
Return lower dimensional secondary element given its interior parent.
std::unordered_set< const Elem * > _inactive_local_lm_elems
List of inactive lagrange multiplier nodes (for elemental variables)
std::unordered_map< dof_id_type, std::set< Elem *, CompareDofObjectsByID > >::const_iterator MortarFilterIter
void computeInactiveLMNodes()
Get list of secondary nodes that don&#39;t contribute to interaction with any primary element...
std::vector< std::pair< BoundaryID, BoundaryID > > _primary_secondary_boundary_id_pairs
A list of primary/secondary boundary id pairs corresponding to each side of the mortar interface...
void clear()
Clears the mortar segment mesh and accompanying data structures.
std::set< SubdomainID > _secondary_boundary_subdomain_ids
The secondary/primary lower-dimensional boundary subdomain ids are the secondary/primary boundary ids...
std::unordered_map< dof_id_type, std::set< Elem *, CompareDofObjectsByID > > _secondary_elems_to_mortar_segments
We maintain a mapping from lower-dimensional secondary elements in the original mesh to (sets of) ele...
std::map< unsigned int, unsigned int > getPrimaryIpToLowerElementMap(const Elem &primary_elem, const Elem &primary_elem_ip, const Elem &lower_secondary_elem) const
Compute on-the-fly mapping from primary interior parent nodes to its corresponding lower dimensional ...
const bool _periodic
Whether this object will be generating a mortar segment mesh for periodic constraints.
void outputMortarMesh()
Write the mortar segment mesh to exodus.
Real _newton_tolerance
Newton solve tolerance for node projections.
TestClass subdomain_id_type
std::unordered_map< const Elem *, MortarSegmentInfo > _msm_elem_to_info
Map between Elems in the mortar segment mesh and their info structs.
const bool _distributed
Whether the mortar segment mesh is distributed.
Base class for MOOSE-based applications.
Definition: MooseApp.h:109
void buildMortarSegmentMesh()
Builds the mortar segment mesh once the secondary and primary node projections have been completed...
const std::set< SubdomainID > & primaryIPSubIDs() const
void msmStatistics()
Prints mortar segment mesh statistics to console (calls computeMsmStatistics internally) ...
std::array< Point, 3 > secondary_reference_points
const std::unordered_set< const Elem * > & getInactiveLMElems() const
void buildCouplingInformation()
build the _mortar_interface_coupling data
std::vector< Point > getNodalNormals(const Elem &secondary_elem) const
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
static const std::string system_name
The name of the nodal normals system.
void projectSecondaryNodes()
Project secondary nodes (find xi^(2) values) to the closest points on the primary surface...
const std::unordered_map< dof_id_type, std::set< Elem *, CompareDofObjectsByID > > & secondariesToMortarSegments() const
std::unordered_set< dof_id_type > _projected_secondary_nodes
Debugging container for printing information about fraction of successful projections for secondary n...
const std::set< SubdomainID > & secondaryIPSubIDs() const
This class is a container/interface for the objects involved in automatic generation of mortar spaces...
const bool _debug
Whether to print debug output.
std::array< Point, 3 > primary_reference_points
MortarSegmentTriangulationMode
Statistics for one primary-secondary subdomain pair.
const bool _triangulate_triangles
Whether already-triangular clipped polygons should still be centroid-subdivided.
std::set< SubdomainID > _secondary_ip_sub_ids
All the secondary interior parent subdomain IDs associated with the mortar mesh.
std::optional< dof_id_type > _msm_node_id_start
Cached per-rank starting ID for 3D MSM nodes/elements.
void projectPrimaryNodes()
(Inverse) project primary nodes to the points on the secondary surface where they would have come fro...
int8_t boundary_id_type
void meshChanged()
Invalidates the cached MSM node/element ID starting offset so that the next call to buildMortarSegmen...
void buildNodeToElemMaps()
Once the secondary_requested_boundary_ids and primary_requested_boundary_ids containers have been fil...
std::unordered_map< dof_id_type, const Elem * > _secondary_element_to_secondary_lowerd_element
Map from full dimensional secondary element id to lower dimensional secondary element.
std::map< std::tuple< dof_id_type, const Node *, const Elem * >, std::pair< Real, const Elem * > > _primary_node_and_elem_to_xi1_secondary_elem
Same type of container, but for mapping (Primary Node ID, Primary Node, Primary Elem) -> (xi^(1)...
boundary_id_type BoundaryID
void projectPrimaryNodesSinglePair(SubdomainID lower_dimensional_primary_subdomain_id, SubdomainID lower_dimensional_secondary_subdomain_id)
Helper function used internally by AutomaticMortarGeneration::project_primary_nodes().
std::unordered_map< dof_id_type, std::vector< const Elem * > > _nodes_to_primary_elem_map
const bool _correct_edge_dropping
Flag to enable regressed treatment of edge dropping where all LM DoFs on edge dropping element are st...
bool processAlignedNodes(const Node &secondary_node, const Node &primary_node, const std::vector< const Elem *> *secondary_node_neighbors, const std::vector< const Elem *> *primary_node_neighbors, const VectorValue< Real > &nodal_normal, const Elem &candidate_element, std::set< const Elem *> &rejected_element_candidates)
Process aligned nodes.
An inteface for the _console for outputting to the Console object.
const MortarSegmentReferencePoints & mortarSegmentReferencePoints(const Elem &mortar_segment_elem) const
Return the parent-face reference coordinates for a mortar segment.
std::array< MooseUtils::SemidynamicVector< Point, 9 >, 2 > getNodalTangents(const Elem &secondary_elem) const
Compute the two nodal tangents, which are built on-the-fly.
std::unique_ptr< InputParameters > _output_params
Storage for the input parameters used by the mortar nodal geometry output.
const std::unordered_map< dof_id_type, std::unordered_set< dof_id_type > > & mortarInterfaceCoupling() const
std::set< BoundaryID > _primary_requested_boundary_ids
The boundary ids corresponding to all the primary surfaces.
std::map< unsigned int, unsigned int > getSecondaryIpToLowerElementMap(const Elem &lower_secondary_elem) const
Compute on-the-fly mapping from secondary interior parent nodes to lower dimensional nodes...
subdomain_id_type SubdomainID
std::unordered_map< const Elem *, MortarSegmentReferencePoints > _msm_elem_to_reference_points
Reference-coordinate data used only by the reference-interpolation mapping mode.
void computeNodalGeometry()
Computes and stores the nodal normal/tangent vectors in a local data structure instead of using the E...
Real _xi_tolerance
Tolerance for checking projection xi values.
void computeIncorrectEdgeDroppingInactiveLMNodes()
Computes inactive secondary nodes when incorrect edge dropping behavior is enabled (any node touching...
std::unordered_set< dof_id_type > _failed_secondary_node_projections
Secondary nodes that failed to project.
void buildMortarSegmentMesh3d()
Builds the mortar segment mesh once the secondary and primary node projections have been completed...
const std::unordered_map< dof_id_type, std::vector< const Elem * > > & nodesToSecondaryElem() const
bool onDisplaced() const
returns whether this object is on the displaced mesh
void projectSecondaryNodesSinglePair(SubdomainID lower_dimensional_primary_subdomain_id, SubdomainID lower_dimensional_secondary_subdomain_id)
Helper function responsible for projecting secondary nodes onto primary elements for a single primary...
const MortarSegmentTriangulationMode _triangulation_mode
Triangulation mode used for clipped 3D mortar polygons.
Mortar3DQuadraturePointMapping mortar3DQpMapping() const
Return the 3D mortar quadrature-point mapping method.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::unordered_map< std::pair< const Node *, const Elem * >, std::pair< Real, const Elem * > > _secondary_node_and_elem_to_xi2_primary_elem
Similar to the map above, but associates a (Secondary Node, Secondary Elem) pair to a (xi^(2)...
Parent-face reference coordinates associated with the vertices of one triangular mortar segment...
const bool _on_displaced
Whether this object is on the displaced mesh.
AutomaticMortarGeneration(MooseApp &app, MeshBase &mesh_in, const std::pair< BoundaryID, BoundaryID > &boundary_key, const std::pair< SubdomainID, SubdomainID > &subdomain_key, bool on_displaced, bool periodic, const bool debug, const bool correct_edge_dropping, const Real minimum_projection_angle, const Mortar3DSubpatchPlane mortar_3d_subpatch_plane, const MortarSegmentTriangulationMode triangulation_mode, const bool triangulate_triangles, const Mortar3DQuadraturePointMapping mortar_3d_qp_mapping=Mortar3DQuadraturePointMapping::NORMAL_PROJECTION)
Must be constructed with a reference to the Mesh we are generating mortar spaces for.
std::vector< MsmSubdomainStats > computeMsmStatistics()
Computes mortar segment mesh statistics and returns one entry per subdomain pair. ...
const Mortar3DSubpatchPlane _mortar_3d_subpatch_plane
Method used to define the local projection planes for 3D secondary subpatches.
void initOutput()
initialize mortar-mesh based output
const std::unordered_map< const Elem *, MortarSegmentInfo > & mortarSegmentMeshElemToInfo() const
std::unordered_map< const Node *, std::array< Point, 2 > > _secondary_node_to_hh_nodal_tangents
Container for storing the nodal tangent/binormal vectors associated with each secondary node (Househo...
unsigned int mesh_dimension() const
const Real _minimum_projection_angle
Parameter to control which angle (in degrees) is admissible for the creation of mortar segments...
MeshBase & _mesh
Reference to the mesh stored in equation_systems.
const MeshBase & mortarSegmentMesh() const
std::vector< std::pair< SubdomainID, SubdomainID > > _primary_secondary_subdomain_id_pairs
A list of primary/secondary subdomain id pairs corresponding to each side of the mortar interface...
const std::unordered_set< const Node * > & getInactiveLMNodes() const
std::set< BoundaryID > _secondary_requested_boundary_ids
The boundary ids corresponding to all the secondary surfaces.
std::unordered_map< const Node *, Point > _secondary_node_to_nodal_normal
Container for storing the nodal normal vector associated with each secondary node.
std::unordered_set< const Node * > _inactive_local_lm_nodes
std::unordered_map< dof_id_type, std::unordered_set< dof_id_type > > _mortar_interface_coupling
Used by the AugmentSparsityOnInterface functor to determine whether a given Elem is coupled to any ot...
std::set< SubdomainID > _primary_ip_sub_ids
All the primary interior parent subdomain IDs associated with the mortar mesh.
void householderOrthogolization(const Point &normal, Point &tangent_one, Point &tangent_two) const
Householder orthogonalization procedure to obtain proper basis for tangent and binormal vectors...
std::vector< Point > getNormals(const Elem &secondary_elem, const std::vector< Point > &xi1_pts) const
Compute the normals at given reference points on a secondary element.
const Mortar3DQuadraturePointMapping _mortar_3d_qp_mapping
Method used to map 3D mortar segment quadrature points to primary and secondary faces.
MooseApp & _app
The Moose app.
std::unique_ptr< MeshBase > _mortar_segment_mesh
1D Mesh of mortar segment elements which gets built by the call to build_mortar_segment_mesh().
uint8_t dof_id_type
std::unordered_map< dof_id_type, std::vector< const Elem * > > _nodes_to_secondary_elem_map
Map from nodes to connected lower-dimensional elements on the secondary/primary subdomains.
std::unordered_map< const Elem *, unsigned int > _lower_elem_to_side_id
Keeps track of the mapping between lower-dimensional elements and the side_id of the interior_parent ...
void computeInactiveLMElems()
Get list of secondary elems without any corresponding primary elements.