LCOV - code coverage report
Current view: top level - src/loops - ComputeMortarFunctor.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 75 86 87.2 %
Date: 2025-07-17 01:28:37 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             : #include "ComputeMortarFunctor.h"
      11             : #include "FEProblemBase.h"
      12             : #include "SubProblem.h"
      13             : #include "Assembly.h"
      14             : #include "ADMortarConstraint.h"
      15             : #include "AutomaticMortarGeneration.h"
      16             : #include "MooseMesh.h"
      17             : #include "Assembly.h"
      18             : #include "MortarUtils.h"
      19             : #include "MaterialBase.h"
      20             : 
      21             : #include "libmesh/fe_base.h"
      22             : #include "libmesh/quadrature.h"
      23             : #include "libmesh/elem.h"
      24             : #include "libmesh/point.h"
      25             : #include "libmesh/mesh_base.h"
      26             : 
      27         897 : ComputeMortarFunctor::ComputeMortarFunctor(
      28             :     const std::vector<std::shared_ptr<MortarConstraintBase>> & mortar_constraints,
      29             :     const AutomaticMortarGeneration & amg,
      30             :     SubProblem & subproblem,
      31             :     FEProblemBase & fe_problem,
      32             :     bool displaced,
      33         897 :     Assembly & assembly)
      34         897 :   : _amg(amg),
      35         897 :     _subproblem(subproblem),
      36         897 :     _fe_problem(fe_problem),
      37         897 :     _displaced(displaced),
      38         897 :     _assembly(assembly)
      39             : {
      40             :   // Construct the mortar constraints we will later loop over
      41        2121 :   for (auto mc : mortar_constraints)
      42        1224 :     _mortar_constraints.push_back(mc.get());
      43             : 
      44         897 :   Moose::Mortar::setupMortarMaterials(_mortar_constraints,
      45             :                                       _fe_problem,
      46             :                                       _amg,
      47             :                                       0,
      48         897 :                                       _secondary_ip_sub_to_mats,
      49         897 :                                       _primary_ip_sub_to_mats,
      50         897 :                                       _secondary_boundary_mats);
      51         897 : }
      52             : 
      53             : void
      54       13062 : ComputeMortarFunctor::operator()(const Moose::ComputeType compute_type,
      55             :                                  const std::set<TagID> & vector_tag_ids,
      56             :                                  const std::set<TagID> & /*matrix_tag_ids*/)
      57             : {
      58             :   libmesh_parallel_only(_fe_problem.comm());
      59             : 
      60       13062 :   unsigned int num_cached = 0;
      61       13062 :   const auto & vector_tags = _fe_problem.getVectorTags(vector_tag_ids);
      62             : 
      63       13062 :   const auto & secondary_elems_to_mortar_segments = _amg.secondariesToMortarSegments();
      64             :   typedef decltype(secondary_elems_to_mortar_segments.begin()) it_type;
      65             : 
      66       13062 :   std::vector<it_type> iterators;
      67       13062 :   for (auto it = secondary_elems_to_mortar_segments.begin();
      68       97825 :        it != secondary_elems_to_mortar_segments.end();
      69       84763 :        ++it)
      70             :   {
      71       84763 :     auto * const secondary_elem = _subproblem.mesh().getMesh().query_elem_ptr(it->first);
      72             : 
      73      150626 :     if (secondary_elem && secondary_elem->processor_id() == _subproblem.processor_id() &&
      74       65863 :         !it->second.empty())
      75             :     {
      76             :       // This is local and the mortar segment set isn't empty, so include
      77       65863 :       iterators.push_back(it);
      78             :       mooseAssert(secondary_elem->active(),
      79             :                   "We loop over active elements when building the mortar segment mesh, so we golly "
      80             :                   "well hope this is active.");
      81             :     }
      82             :   }
      83             : 
      84     1422907 :   auto act_functor = [this, &num_cached, compute_type, &vector_tags]()
      85             :   {
      86      261890 :     ++num_cached;
      87             : 
      88      261890 :     switch (compute_type)
      89             :     {
      90      177834 :       case Moose::ComputeType::Residual:
      91             :       {
      92      366432 :         for (auto * const mc : _mortar_constraints)
      93             :         {
      94      188598 :           mc->setNormals();
      95      188598 :           mc->computeResidual();
      96             :         }
      97             : 
      98      177834 :         _assembly.cacheResidual(Assembly::GlobalDataKey{}, vector_tags);
      99      177834 :         _assembly.cacheResidualNeighbor(Assembly::GlobalDataKey{}, vector_tags);
     100      177834 :         _assembly.cacheResidualLower(Assembly::GlobalDataKey{}, vector_tags);
     101             : 
     102      177834 :         if (num_cached % 20 == 0)
     103        6358 :           _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
     104             : 
     105      177834 :         break;
     106             :       }
     107             : 
     108       80796 :       case Moose::ComputeType::Jacobian:
     109             :       {
     110      167164 :         for (auto * const mc : _mortar_constraints)
     111             :         {
     112       86368 :           mc->setNormals();
     113       86368 :           mc->computeJacobian();
     114             :         }
     115             : 
     116       80796 :         _assembly.cacheJacobianMortar(Assembly::GlobalDataKey{});
     117             : 
     118       80796 :         if (num_cached % 20 == 0)
     119        3541 :           _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
     120       80796 :         break;
     121             :       }
     122             : 
     123        3260 :       case Moose::ComputeType::ResidualAndJacobian:
     124             :       {
     125        6520 :         for (auto * const mc : _mortar_constraints)
     126             :         {
     127        3260 :           mc->setNormals();
     128        3260 :           mc->computeResidualAndJacobian();
     129             :         }
     130             : 
     131        3260 :         _assembly.cacheResidual(Assembly::GlobalDataKey{}, vector_tags);
     132        3260 :         _assembly.cacheResidualNeighbor(Assembly::GlobalDataKey{}, vector_tags);
     133        3260 :         _assembly.cacheResidualLower(Assembly::GlobalDataKey{}, vector_tags);
     134        3260 :         _assembly.cacheJacobianMortar(Assembly::GlobalDataKey{});
     135             : 
     136        3260 :         if (num_cached % 20 == 0)
     137             :         {
     138           0 :           _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
     139           0 :           _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
     140             :         }
     141        3260 :         break;
     142             :       }
     143             :     }
     144      261890 :   };
     145             : 
     146             :   PARALLEL_TRY
     147             :   {
     148             :     try
     149             :     {
     150       13062 :       Moose::Mortar::loopOverMortarSegments(iterators,
     151             :                                             _assembly,
     152             :                                             _subproblem,
     153             :                                             _fe_problem,
     154             :                                             _amg,
     155       13062 :                                             _displaced,
     156       13062 :                                             _mortar_constraints,
     157             :                                             0,
     158       13062 :                                             _secondary_ip_sub_to_mats,
     159       13062 :                                             _primary_ip_sub_to_mats,
     160       13062 :                                             _secondary_boundary_mats,
     161             :                                             act_functor,
     162             :                                             /*reinit_mortar_user_objects=*/true);
     163             :     }
     164           0 :     catch (libMesh::LogicError & e)
     165             :     {
     166           0 :       _fe_problem.setException("We caught a libMesh::LogicError: " + std::string(e.what()));
     167           0 :     }
     168           0 :     catch (MooseException & e)
     169             :     {
     170           0 :       _fe_problem.setException(e.what());
     171           0 :     }
     172           0 :     catch (MetaPhysicL::LogicError & e)
     173             :     {
     174           0 :       moose::translateMetaPhysicLError(e);
     175           0 :     }
     176             :   }
     177       13062 :   PARALLEL_CATCH;
     178             : 
     179             :   // Call any post operations for our mortar constraints
     180       28803 :   for (auto * const mc : _mortar_constraints)
     181             :   {
     182       15741 :     if (_amg.incorrectEdgeDropping())
     183        6900 :       mc->incorrectEdgeDroppingPost(_amg.getInactiveLMNodes());
     184             :     else
     185        8841 :       mc->post();
     186             : 
     187       15741 :     mc->zeroInactiveLMDofs(_amg.getInactiveLMNodes(), _amg.getInactiveLMElems());
     188             :   }
     189             : 
     190             :   // Make sure any remaining cached residuals/Jacobians get added
     191       13062 :   if (_assembly.computingResidual())
     192       10799 :     _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
     193       13062 :   if (_assembly.computingJacobian())
     194        3423 :     _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
     195       13062 : }

Generated by: LCOV version 1.14