LCOV - code coverage report
Current view: top level - src/loops - ComputeMortarFunctor.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 75 86 87.2 %
Date: 2025-08-08 20:01:16 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         955 : 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         955 :     Assembly & assembly)
      34         955 :   : _amg(amg),
      35         955 :     _subproblem(subproblem),
      36         955 :     _fe_problem(fe_problem),
      37         955 :     _displaced(displaced),
      38         955 :     _assembly(assembly)
      39             : {
      40             :   // Construct the mortar constraints we will later loop over
      41        2259 :   for (auto mc : mortar_constraints)
      42        1304 :     _mortar_constraints.push_back(mc.get());
      43             : 
      44         955 :   Moose::Mortar::setupMortarMaterials(_mortar_constraints,
      45             :                                       _fe_problem,
      46             :                                       _amg,
      47             :                                       0,
      48         955 :                                       _secondary_ip_sub_to_mats,
      49         955 :                                       _primary_ip_sub_to_mats,
      50         955 :                                       _secondary_boundary_mats);
      51         955 : }
      52             : 
      53             : void
      54       13633 : 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       13633 :   unsigned int num_cached = 0;
      61       13633 :   const auto & vector_tags = _fe_problem.getVectorTags(vector_tag_ids);
      62             : 
      63       13633 :   const auto & secondary_elems_to_mortar_segments = _amg.secondariesToMortarSegments();
      64             :   typedef decltype(secondary_elems_to_mortar_segments.begin()) it_type;
      65             : 
      66       13633 :   std::vector<it_type> iterators;
      67       13633 :   for (auto it = secondary_elems_to_mortar_segments.begin();
      68      101981 :        it != secondary_elems_to_mortar_segments.end();
      69       88348 :        ++it)
      70             :   {
      71       88348 :     auto * const secondary_elem = _subproblem.mesh().getMesh().query_elem_ptr(it->first);
      72             : 
      73      157796 :     if (secondary_elem && secondary_elem->processor_id() == _subproblem.processor_id() &&
      74       69448 :         !it->second.empty())
      75             :     {
      76             :       // This is local and the mortar segment set isn't empty, so include
      77       69448 :       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     1533849 :   auto act_functor = [this, &num_cached, compute_type, &vector_tags]()
      85             :   {
      86      282725 :     ++num_cached;
      87             : 
      88      282725 :     switch (compute_type)
      89             :     {
      90      191110 :       case Moose::ComputeType::Residual:
      91             :       {
      92      393512 :         for (auto * const mc : _mortar_constraints)
      93             :         {
      94      202402 :           mc->setNormals();
      95      202402 :           mc->computeResidual();
      96             :         }
      97             : 
      98      191110 :         _assembly.cacheResidual(Assembly::GlobalDataKey{}, vector_tags);
      99      191110 :         _assembly.cacheResidualNeighbor(Assembly::GlobalDataKey{}, vector_tags);
     100      191110 :         _assembly.cacheResidualLower(Assembly::GlobalDataKey{}, vector_tags);
     101             : 
     102      191110 :         if (num_cached % 20 == 0)
     103        6937 :           _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
     104             : 
     105      191110 :         break;
     106             :       }
     107             : 
     108       88307 :       case Moose::ComputeType::Jacobian:
     109             :       {
     110      182374 :         for (auto * const mc : _mortar_constraints)
     111             :         {
     112       94067 :           mc->setNormals();
     113       94067 :           mc->computeJacobian();
     114             :         }
     115             : 
     116       88307 :         _assembly.cacheJacobianMortar(Assembly::GlobalDataKey{});
     117             : 
     118       88307 :         if (num_cached % 20 == 0)
     119        3868 :           _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
     120       88307 :         break;
     121             :       }
     122             : 
     123        3308 :       case Moose::ComputeType::ResidualAndJacobian:
     124             :       {
     125        6616 :         for (auto * const mc : _mortar_constraints)
     126             :         {
     127        3308 :           mc->setNormals();
     128        3308 :           mc->computeResidualAndJacobian();
     129             :         }
     130             : 
     131        3308 :         _assembly.cacheResidual(Assembly::GlobalDataKey{}, vector_tags);
     132        3308 :         _assembly.cacheResidualNeighbor(Assembly::GlobalDataKey{}, vector_tags);
     133        3308 :         _assembly.cacheResidualLower(Assembly::GlobalDataKey{}, vector_tags);
     134        3308 :         _assembly.cacheJacobianMortar(Assembly::GlobalDataKey{});
     135             : 
     136        3308 :         if (num_cached % 20 == 0)
     137             :         {
     138           0 :           _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
     139           0 :           _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
     140             :         }
     141        3308 :         break;
     142             :       }
     143             :     }
     144      282725 :   };
     145             : 
     146             :   PARALLEL_TRY
     147             :   {
     148             :     try
     149             :     {
     150       13633 :       Moose::Mortar::loopOverMortarSegments(iterators,
     151             :                                             _assembly,
     152             :                                             _subproblem,
     153             :                                             _fe_problem,
     154             :                                             _amg,
     155       13633 :                                             _displaced,
     156       13633 :                                             _mortar_constraints,
     157             :                                             0,
     158       13633 :                                             _secondary_ip_sub_to_mats,
     159       13633 :                                             _primary_ip_sub_to_mats,
     160       13633 :                                             _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       13633 :   PARALLEL_CATCH;
     178             : 
     179             :   // Call any post operations for our mortar constraints
     180       30146 :   for (auto * const mc : _mortar_constraints)
     181             :   {
     182       16513 :     if (_amg.incorrectEdgeDropping())
     183        7084 :       mc->incorrectEdgeDroppingPost(_amg.getInactiveLMNodes());
     184             :     else
     185        9429 :       mc->post();
     186             : 
     187       16513 :     mc->zeroInactiveLMDofs(_amg.getInactiveLMNodes(), _amg.getInactiveLMElems());
     188             :   }
     189             : 
     190             :   // Make sure any remaining cached residuals/Jacobians get added
     191       13633 :   if (_assembly.computingResidual())
     192       11183 :     _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
     193       13633 :   if (_assembly.computingJacobian())
     194        3622 :     _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
     195       13633 : }

Generated by: LCOV version 1.14