LCOV - code coverage report
Current view: top level - src/loops - ComputeMortarFunctor.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: fef103 Lines: 81 92 88.0 %
Date: 2025-09-03 20:01:23 Functions: 4 4 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         981 : 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         981 :     Assembly & assembly)
      34         981 :   : _amg(amg),
      35         981 :     _subproblem(subproblem),
      36         981 :     _fe_problem(fe_problem),
      37         981 :     _displaced(displaced),
      38         981 :     _assembly(assembly)
      39             : {
      40             :   // Construct the mortar constraints we will later loop over
      41        2311 :   for (auto mc : mortar_constraints)
      42        1330 :     _mortar_constraints.push_back(mc.get());
      43             : 
      44         981 :   Moose::Mortar::setupMortarMaterials(_mortar_constraints,
      45             :                                       _fe_problem,
      46             :                                       _amg,
      47             :                                       0,
      48         981 :                                       _secondary_ip_sub_to_mats,
      49         981 :                                       _primary_ip_sub_to_mats,
      50         981 :                                       _secondary_boundary_mats);
      51         981 : }
      52             : 
      53             : void
      54         192 : ComputeMortarFunctor::setupMortarMaterials()
      55             : {
      56         192 :   Moose::Mortar::setupMortarMaterials(_mortar_constraints,
      57             :                                       _fe_problem,
      58             :                                       _amg,
      59             :                                       /*thread id*/ 0,
      60         192 :                                       _secondary_ip_sub_to_mats,
      61         192 :                                       _primary_ip_sub_to_mats,
      62         192 :                                       _secondary_boundary_mats);
      63         192 : }
      64             : 
      65             : void
      66       13807 : ComputeMortarFunctor::operator()(const Moose::ComputeType compute_type,
      67             :                                  const std::set<TagID> & vector_tag_ids,
      68             :                                  const std::set<TagID> & /*matrix_tag_ids*/)
      69             : {
      70             :   libmesh_parallel_only(_fe_problem.comm());
      71             : 
      72       13807 :   unsigned int num_cached = 0;
      73       13807 :   const auto & vector_tags = _fe_problem.getVectorTags(vector_tag_ids);
      74             : 
      75       13807 :   const auto & secondary_elems_to_mortar_segments = _amg.secondariesToMortarSegments();
      76             :   typedef decltype(secondary_elems_to_mortar_segments.begin()) it_type;
      77             : 
      78       13807 :   std::vector<it_type> iterators;
      79       13807 :   for (auto it = secondary_elems_to_mortar_segments.begin();
      80      102551 :        it != secondary_elems_to_mortar_segments.end();
      81       88744 :        ++it)
      82             :   {
      83       88744 :     auto * const secondary_elem = _subproblem.mesh().getMesh().query_elem_ptr(it->first);
      84             : 
      85      158492 :     if (secondary_elem && secondary_elem->processor_id() == _subproblem.processor_id() &&
      86       69748 :         !it->second.empty())
      87             :     {
      88             :       // This is local and the mortar segment set isn't empty, so include
      89       69748 :       iterators.push_back(it);
      90             :       mooseAssert(secondary_elem->active(),
      91             :                   "We loop over active elements when building the mortar segment mesh, so we golly "
      92             :                   "well hope this is active.");
      93             :     }
      94             :   }
      95             : 
      96      283025 :   auto act_functor = [this, &num_cached, compute_type, &vector_tags]()
      97             :   {
      98      283025 :     ++num_cached;
      99             : 
     100      283025 :     switch (compute_type)
     101             :     {
     102      191316 :       case Moose::ComputeType::Residual:
     103             :       {
     104      393924 :         for (auto * const mc : _mortar_constraints)
     105             :         {
     106      202608 :           mc->setNormals();
     107      202608 :           mc->computeResidual();
     108             :         }
     109             : 
     110      191316 :         _assembly.cacheResidual(Assembly::GlobalDataKey{}, vector_tags);
     111      191316 :         _assembly.cacheResidualNeighbor(Assembly::GlobalDataKey{}, vector_tags);
     112      191316 :         _assembly.cacheResidualLower(Assembly::GlobalDataKey{}, vector_tags);
     113             : 
     114      191316 :         if (num_cached % 20 == 0)
     115        6937 :           _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
     116             : 
     117      191316 :         break;
     118             :       }
     119             : 
     120       88401 :       case Moose::ComputeType::Jacobian:
     121             :       {
     122      182562 :         for (auto * const mc : _mortar_constraints)
     123             :         {
     124       94161 :           mc->setNormals();
     125       94161 :           mc->computeJacobian();
     126             :         }
     127             : 
     128       88401 :         _assembly.cacheJacobianMortar(Assembly::GlobalDataKey{});
     129             : 
     130       88401 :         if (num_cached % 20 == 0)
     131        3868 :           _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
     132       88401 :         break;
     133             :       }
     134             : 
     135        3308 :       case Moose::ComputeType::ResidualAndJacobian:
     136             :       {
     137        6616 :         for (auto * const mc : _mortar_constraints)
     138             :         {
     139        3308 :           mc->setNormals();
     140        3308 :           mc->computeResidualAndJacobian();
     141             :         }
     142             : 
     143        3308 :         _assembly.cacheResidual(Assembly::GlobalDataKey{}, vector_tags);
     144        3308 :         _assembly.cacheResidualNeighbor(Assembly::GlobalDataKey{}, vector_tags);
     145        3308 :         _assembly.cacheResidualLower(Assembly::GlobalDataKey{}, vector_tags);
     146        3308 :         _assembly.cacheJacobianMortar(Assembly::GlobalDataKey{});
     147             : 
     148        3308 :         if (num_cached % 20 == 0)
     149             :         {
     150           0 :           _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
     151           0 :           _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
     152             :         }
     153        3308 :         break;
     154             :       }
     155             :     }
     156      283025 :   };
     157             : 
     158             :   PARALLEL_TRY
     159             :   {
     160             :     try
     161             :     {
     162       13807 :       Moose::Mortar::loopOverMortarSegments(iterators,
     163             :                                             _assembly,
     164             :                                             _subproblem,
     165             :                                             _fe_problem,
     166             :                                             _amg,
     167       13807 :                                             _displaced,
     168       13807 :                                             _mortar_constraints,
     169             :                                             0,
     170       13807 :                                             _secondary_ip_sub_to_mats,
     171       13807 :                                             _primary_ip_sub_to_mats,
     172       13807 :                                             _secondary_boundary_mats,
     173             :                                             act_functor,
     174             :                                             /*reinit_mortar_user_objects=*/true);
     175             :     }
     176           0 :     catch (libMesh::LogicError & e)
     177             :     {
     178           0 :       _fe_problem.setException("We caught a libMesh::LogicError: " + std::string(e.what()));
     179           0 :     }
     180           0 :     catch (MooseException & e)
     181             :     {
     182           0 :       _fe_problem.setException(e.what());
     183           0 :     }
     184           0 :     catch (MetaPhysicL::LogicError & e)
     185             :     {
     186           0 :       moose::translateMetaPhysicLError(e);
     187           0 :     }
     188             :   }
     189       13807 :   PARALLEL_CATCH;
     190             : 
     191             :   // Call any post operations for our mortar constraints
     192       30494 :   for (auto * const mc : _mortar_constraints)
     193             :   {
     194       16687 :     if (_amg.incorrectEdgeDropping())
     195        7258 :       mc->incorrectEdgeDroppingPost(_amg.getInactiveLMNodes());
     196             :     else
     197        9429 :       mc->post();
     198             : 
     199       16687 :     mc->zeroInactiveLMDofs(_amg.getInactiveLMNodes(), _amg.getInactiveLMElems());
     200             :   }
     201             : 
     202             :   // Make sure any remaining cached residuals/Jacobians get added
     203       13807 :   if (_assembly.computingResidual())
     204       11307 :     _assembly.addCachedResiduals(Assembly::GlobalDataKey{}, vector_tags);
     205       13807 :   if (_assembly.computingJacobian())
     206        3672 :     _assembly.addCachedJacobian(Assembly::GlobalDataKey{});
     207       13807 : }

Generated by: LCOV version 1.14