LCOV - code coverage report
Current view: top level - include/interfaces - MortarConsumerInterface.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 39a256 Lines: 22 22 100.0 %
Date: 2026-07-14 14:36:17 Functions: 8 8 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 "MooseTypes.h"
      13             : 
      14             : #include <set>
      15             : 
      16             : class InputParameters;
      17             : class MooseObject;
      18             : class MooseMesh;
      19             : class MortarInterfaceWarehouse;
      20             : class AutomaticMortarGeneration;
      21             : class SubProblem;
      22             : class Assembly;
      23             : 
      24             : namespace libMesh
      25             : {
      26             : class QBase;
      27             : }
      28             : 
      29             : /**
      30             :  * An interface for accessing mortar mesh data
      31             :  *
      32             :  * \note mci is shorthand for mortar consumer interface, so \p _mci_problem indicates
      33             :  *       the mortar consumer interface's problem
      34             :  */
      35             : class MortarConsumerInterface
      36             : {
      37             : public:
      38             :   MortarConsumerInterface(const MooseObject * moose_object);
      39             : 
      40             :   static InputParameters validParams();
      41             : 
      42             :   /**
      43             :    * @return An InputParameters object containing just the parameters that control 3D mortar
      44             :    * polygon triangulation (\p triangulation, \p triangulate_triangles). Provided so that
      45             :    * downstream actions / objects which need to expose the same controls (e.g. ContactAction)
      46             :    * can pull these definitions in via \p params += rather than duplicating them.
      47             :    */
      48             :   static InputParameters triangulationParams();
      49             : 
      50             :   /**
      51             :    * @return The primary lower dimensional subdomain id
      52             :    */
      53         500 :   SubdomainID primarySubdomain() const { return _primary_subdomain_id; }
      54             : 
      55             :   /**
      56             :    * @return The secondary lower dimensional subdomain id
      57             :    */
      58         500 :   SubdomainID secondarySubdomain() const { return _secondary_subdomain_id; }
      59             : 
      60             :   /**
      61             :    * @return Whether this object lies on the given primary-secondary boundary pair
      62             :    */
      63             :   bool onInterface(BoundaryID primary_boundary_id, BoundaryID secondary_boundary_id) const;
      64             : 
      65             : protected:
      66             :   const std::set<SubdomainID> & getHigherDimSubdomainIDs() const
      67             :   {
      68             :     return _higher_dim_subdomain_ids;
      69             :   }
      70        1312 :   const std::set<BoundaryID> & getBoundaryIDs() const { return _boundary_ids; }
      71             : 
      72             :   /**
      73             :    * Retrieve the automatic mortar generation object associated with this constraint
      74             :    */
      75             :   const AutomaticMortarGeneration & amg() const;
      76             : 
      77             :   /**
      78             :    * Whether to interpolate the nodal normals (e.g. classic idea of evaluating field at quadrature
      79             :    * points). If this is set to false, then non-interpolated nodal normals will be used, and then
      80             :    * the _normals member should be indexed with _i instead of _qp
      81             :    */
      82      492178 :   bool interpolateNormals() const { return _interpolate_normals; }
      83             : 
      84             :   /**
      85             :    * Get rid of AD derivative entries by dof index
      86             :    */
      87             :   static void trimDerivative(dof_id_type remove_derivative_index, ADReal & dual_number);
      88             : 
      89             :   /**
      90             :    * Get rid of interior node variable's derivatives
      91             :    */
      92             :   template <typename Variables, typename DualNumbers>
      93             :   static void
      94             :   trimInteriorNodeDerivatives(const std::map<unsigned int, unsigned int> & primary_ip_lowerd_map,
      95             :                               const Variables & moose_var,
      96             :                               DualNumbers & ad_vars,
      97             :                               const bool is_secondary);
      98             : 
      99             :   FEProblemBase & _mci_fe_problem;
     100             :   SubProblem & _mci_subproblem;
     101             :   const THREAD_ID _mci_tid;
     102             : 
     103             :   /// Mesh to query for boundary and subdomain ID information
     104             :   MooseMesh & _mci_mesh;
     105             : 
     106             :   Assembly & _mci_assembly;
     107             : 
     108             :   /// A reference to the mortar data object that holds all the mortar
     109             :   /// mesh information
     110             :   const MortarInterfaceWarehouse & _mortar_data;
     111             : 
     112             :   /// Boundary ID for the secondary surface
     113             :   const BoundaryID _secondary_id;
     114             : 
     115             :   /// Boundary ID for the primary surface
     116             :   const BoundaryID _primary_id;
     117             : 
     118             :   /// Subdomain ID for the secondary surface
     119             :   const SubdomainID _secondary_subdomain_id;
     120             : 
     121             :   /// Subdomain ID for the primary surface
     122             :   const SubdomainID _primary_subdomain_id;
     123             : 
     124             :   /// the secondaryid set
     125             :   std::set<BoundaryID> _secondary_set;
     126             : 
     127             :   /// the union of the secondary and primary boundary ids
     128             :   std::set<BoundaryID> _boundary_ids;
     129             : 
     130             :   /// the higher dimensional subdomain ids corresponding to the interior parents
     131             :   std::set<SubdomainID> _higher_dim_subdomain_ids;
     132             : 
     133             :   /// Whether to interpolate the nodal normals
     134             :   const bool _interpolate_normals;
     135             : 
     136             :   /// The locations of the quadrature points on the interior secondary elements
     137             :   const MooseArray<Point> & _phys_points_secondary;
     138             : 
     139             :   /// The locations of the quadrature points on the interior primary elements
     140             :   const MooseArray<Point> & _phys_points_primary;
     141             : 
     142             :   /// The quadrature rule on the mortar segment element
     143             :   const libMesh::QBase * const & _qrule_msm;
     144             : 
     145             :   /// The arbitrary quadrature rule on the lower dimensional secondary face
     146             :   const libMesh::QBase * const & _qrule_face;
     147             : 
     148             :   /// The secondary face lower dimensional element (not the mortar element!). The mortar element
     149             :   /// lives on the secondary side of the mortar interface and *may* correspond to \p
     150             :   /// _lower_secondary_elem under the very specific circumstance that the nodes on the primary side
     151             :   /// of the mortar interface exactly project onto the secondary side of the mortar interface. In
     152             :   /// general projection of primary nodes will split the face elements on the secondary side of the
     153             :   /// interface. It is these split elements that are the mortar segment mesh elements
     154             :   Elem const * const & _lower_secondary_elem;
     155             : 
     156             :   /// The primary face lower dimensional element (not the mortar element!). The mortar element
     157             :   /// lives on the secondary side of the mortar interface and *may* correspond to \p
     158             :   /// _lower_secondary_elem under the very specific circumstance that the nodes on the primary side
     159             :   /// of the mortar interface exactly project onto the secondary side of the mortar interface. In
     160             :   /// general projection of primary nodes will split the face elements on the secondary side of the
     161             :   /// interface. It is these split elements that are the mortar segment mesh elements
     162             :   Elem const * const & _lower_primary_elem;
     163             : 
     164             :   /// The element Jacobian times weights
     165             :   const std::vector<Real> & _JxW_msm;
     166             : 
     167             :   /// The current mortar segment element
     168             :   const Elem * const & _msm_elem;
     169             : 
     170             :   /// the normals
     171             :   std::vector<Point> _normals;
     172             : 
     173             : private:
     174             :   /**
     175             :    * Set the normals vector
     176             :    */
     177             :   void setNormals();
     178             : 
     179             :   // Pointer to automatic mortar generation object to give constraints access to mortar geometry
     180             :   const AutomaticMortarGeneration * _amg;
     181             : 
     182             :   friend class ComputeMortarFunctor;
     183             :   friend class FEProblemBase;
     184             : 
     185             :   template <typename>
     186             :   friend class MortarNodalAuxKernelTempl;
     187             :   friend class MortarUserObjectThread;
     188             : 
     189             :   /**
     190             :    * Calls the reinitialization of mortar user objects
     191             :    * @see FEProblemBase::reinitMortarUserObjects
     192             :    */
     193             :   friend void reinitMortarUserObjects(BoundaryID, BoundaryID, bool);
     194             : };
     195             : 
     196             : inline const AutomaticMortarGeneration &
     197      541698 : MortarConsumerInterface::amg() const
     198             : {
     199             :   mooseAssert(_amg, "this should have been set in the constructor");
     200      541698 :   return *_amg;
     201             : }
     202             : 
     203             : template <typename Variables, typename DualNumbers>
     204             : void
     205       39252 : MortarConsumerInterface::trimInteriorNodeDerivatives(
     206             :     const std::map<unsigned int, unsigned int> & domain_ip_lowerd_map,
     207             :     const Variables & moose_vars,
     208             :     DualNumbers & dual_numbers,
     209             :     const bool is_secondary)
     210             : {
     211             :   //
     212             :   // Remove interior node variable's derivatives from AD objects.
     213             :   //
     214             : 
     215             :   mooseAssert(moose_vars.size(), "Should have passed at least one variable");
     216       39252 :   const auto num_indices = is_secondary ? moose_vars[0]->dofIndices().size()
     217       19626 :                                         : moose_vars[0]->dofIndicesNeighbor().size();
     218             : #ifdef DEBUG
     219             :   for (const auto i : make_range(std::size_t(1), moose_vars.size()))
     220             :     if (auto * moose_var = moose_vars[i])
     221             :       mooseAssert(is_secondary ? moose_var->dofIndices().size()
     222             :                                : moose_var->dofIndicesNeighbor().size() == num_indices,
     223             :                   "These must be the same for all passed in variables");
     224             : #endif
     225             : 
     226      186198 :   for (const auto dof_index : make_range(num_indices))
     227      146946 :     if (!domain_ip_lowerd_map.count(dof_index))
     228             :     {
     229      205326 :       for (const auto * const moose_var : moose_vars)
     230             :       {
     231             :         // It's valid for a user to pass a container that represents a LIBMESH_DIM vector of
     232             :         // component variables for which one or two of the variables may be null depending on the
     233             :         // mesh dimension in the simulation
     234      136884 :         if (!moose_var)
     235       68442 :           continue;
     236             : 
     237             :         mooseAssert(moose_var->isNodal(),
     238             :                     "Trimming of interior node's derivatives is only supported for Lagrange "
     239             :                     "elements in mortar objects");
     240             : 
     241       68442 :         const auto remove_derivative_index = is_secondary
     242      107694 :                                                  ? moose_var->dofIndices()[dof_index]
     243       39252 :                                                  : moose_var->dofIndicesNeighbor()[dof_index];
     244      264890 :         for (auto & dual_number : dual_numbers)
     245      196448 :           trimDerivative(remove_derivative_index, dual_number);
     246             :       }
     247             :     }
     248       39252 : }
     249             : 
     250             : inline bool
     251          22 : MortarConsumerInterface::onInterface(const BoundaryID primary_boundary_id,
     252             :                                      const BoundaryID secondary_boundary_id) const
     253             : {
     254          22 :   return (primary_boundary_id == _primary_id) && (secondary_boundary_id == _secondary_id);
     255             : }

Generated by: LCOV version 1.14