LCOV - code coverage report
Current view: top level - src/loops - ComputeElemAuxBcsThread.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 88 88 100.0 %
Date: 2026-05-29 20:35:17 Functions: 6 18 33.3 %
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             : // MOOSE includes
      11             : #include "ComputeElemAuxBcsThread.h"
      12             : #include "AuxiliarySystem.h"
      13             : #include "FEProblem.h"
      14             : #include "DisplacedProblem.h"
      15             : #include "Assembly.h"
      16             : #include "AuxKernel.h"
      17             : #include "SwapBackSentinel.h"
      18             : 
      19             : #include "libmesh/threads.h"
      20             : 
      21             : template <typename AuxKernelType>
      22       24876 : ComputeElemAuxBcsThread<AuxKernelType>::ComputeElemAuxBcsThread(
      23             :     FEProblemBase & fe_problem,
      24             :     const MooseObjectWarehouse<AuxKernelType> & storage,
      25             :     bool need_materials)
      26       24876 :   : _fe_problem(fe_problem),
      27       24876 :     _aux_sys(fe_problem.getAuxiliarySystem()),
      28       24876 :     _storage(storage),
      29       24876 :     _need_materials(need_materials)
      30             : {
      31       24876 : }
      32             : 
      33             : // Splitting Constructor
      34             : template <typename AuxKernelType>
      35        2420 : ComputeElemAuxBcsThread<AuxKernelType>::ComputeElemAuxBcsThread(ComputeElemAuxBcsThread & x,
      36             :                                                                 Threads::split /*split*/)
      37        2420 :   : _fe_problem(x._fe_problem),
      38        2420 :     _aux_sys(x._aux_sys),
      39        2420 :     _storage(x._storage),
      40        2420 :     _need_materials(x._need_materials)
      41             : {
      42        2420 : }
      43             : 
      44             : template <typename AuxKernelType>
      45             : void
      46       27296 : ComputeElemAuxBcsThread<AuxKernelType>::operator()(const ConstBndElemRange & range)
      47             : {
      48       27296 :   ParallelUniqueId puid;
      49       27296 :   _tid = puid.id;
      50             : 
      51             :   // Reference to all boundary restricted AuxKernels for the current thread
      52       27296 :   const auto & boundary_kernels = _storage.getActiveBoundaryObjects(_tid);
      53             : 
      54       27296 :   printGeneralExecutionInformation();
      55             : 
      56     3831035 :   for (const auto & belem : range)
      57             :   {
      58     3803747 :     const Elem * elem = belem->_elem;
      59     3803747 :     unsigned short int side = belem->_side;
      60     3803747 :     BoundaryID boundary_id = belem->_bnd_id;
      61     3803747 :     SubdomainID last_sub_id = Elem::invalid_subdomain_id;
      62             : 
      63             :     // need to update the boundary ID in assembly
      64     3803747 :     _fe_problem.setCurrentBoundaryID(boundary_id, _tid);
      65             : 
      66     3803747 :     if (elem->processor_id() == _fe_problem.processor_id())
      67             :     {
      68             :       // Locate the AuxKernel objects for the current BoundaryID
      69     2947405 :       const auto iter = boundary_kernels.find(boundary_id);
      70             : 
      71     2947405 :       if (iter != boundary_kernels.end() && !(iter->second.empty()))
      72             :       {
      73      111834 :         printBoundaryExecutionInformation(boundary_id, iter->second);
      74      111834 :         const auto sub_id = elem->subdomain_id();
      75      111834 :         if (sub_id != last_sub_id)
      76             :         {
      77      111834 :           _fe_problem.subdomainSetup(sub_id, _tid);
      78      111834 :           last_sub_id = sub_id;
      79             :         }
      80      111834 :         _fe_problem.setCurrentSubdomainID(elem, _tid);
      81      111834 :         _fe_problem.prepare(elem, _tid);
      82      111834 :         _fe_problem.reinitElemFace(elem, side, _tid);
      83             : 
      84      111834 :         const Elem * lower_d_elem = _fe_problem.mesh().getLowerDElem(elem, side);
      85      111834 :         _fe_problem.setCurrentLowerDElem(lower_d_elem, _tid);
      86      111834 :         if (lower_d_elem)
      87         826 :           _fe_problem.reinitLowerDElem(lower_d_elem, _tid);
      88             : 
      89      111834 :         const Elem * neighbor = elem->neighbor_ptr(side);
      90             : 
      91             :         // The last check here is absolutely necessary otherwise we will attempt to evaluate
      92             :         // neighbor materials on neighbor elements that aren't evaluable, e.g. don't have algebraic
      93             :         // ghosting
      94      111834 :         bool compute_interface =
      95      113436 :             neighbor && neighbor->active() &&
      96        1602 :             _fe_problem.getInterfaceMaterialsWarehouse().hasActiveBoundaryObjects(boundary_id,
      97             :                                                                                   _tid);
      98             : 
      99             :         // Set up Sentinel class so that, even if reinitMaterialsFace() throws, we
     100             :         // still remember to swap back during stack unwinding.
     101      111834 :         SwapBackSentinel sentinel(_fe_problem, &FEProblem::swapBackMaterialsFace, _tid);
     102      111834 :         SwapBackSentinel neighbor_sentinel(
     103             :             _fe_problem, &FEProblem::swapBackMaterialsNeighbor, _tid, compute_interface);
     104             : 
     105      111834 :         if (_need_materials)
     106             :         {
     107      111834 :           std::unordered_set<unsigned int> needed_mat_props;
     108      234366 :           for (const auto & aux : iter->second)
     109             :           {
     110      122532 :             const auto & mp_deps = aux->getMatPropDependencies();
     111      122532 :             needed_mat_props.insert(mp_deps.begin(), mp_deps.end());
     112             :           }
     113      111834 :           _fe_problem.setActiveMaterialProperties(needed_mat_props, _tid);
     114             : 
     115      111834 :           _fe_problem.reinitMaterialsFaceOnBoundary(boundary_id, sub_id, _tid);
     116             : 
     117      111834 :           _fe_problem.reinitMaterialsBoundary(boundary_id, _tid);
     118             : 
     119      111834 :           if (compute_interface)
     120             :           {
     121         416 :             _fe_problem.reinitNeighbor(elem, side, _tid);
     122         416 :             _fe_problem.reinitMaterialsNeighbor(neighbor->subdomain_id(), _tid);
     123         416 :             _fe_problem.reinitMaterialsInterface(boundary_id, _tid);
     124             :           }
     125      111834 :         }
     126             : 
     127      234350 :         for (const auto & aux : iter->second)
     128             :         {
     129      122524 :           aux->determineWhetherCoincidentLowerDCalc();
     130      122516 :           aux->compute();
     131      122516 :           aux->insert();
     132             :         }
     133             : 
     134      111826 :         if (_need_materials)
     135      111826 :           _fe_problem.clearActiveMaterialProperties(_tid);
     136      111826 :       }
     137             :     }
     138             :   }
     139       27288 : }
     140             : 
     141             : template <typename AuxKernelType>
     142             : void
     143        2418 : ComputeElemAuxBcsThread<AuxKernelType>::join(const ComputeElemAuxBcsThread & /*y*/)
     144             : {
     145        2418 : }
     146             : 
     147             : template <typename AuxKernelType>
     148             : void
     149       27296 : ComputeElemAuxBcsThread<AuxKernelType>::printGeneralExecutionInformation() const
     150             : {
     151       27296 :   if (_fe_problem.shouldPrintExecution(_tid) && _storage.hasActiveObjects())
     152             :   {
     153         420 :     const auto & console = _fe_problem.console();
     154         420 :     const auto & execute_on = _fe_problem.getCurrentExecuteOnFlag();
     155         420 :     console << "[DBG] Executing boundary restricted auxkernels on boundary elements on "
     156         420 :             << execute_on << std::endl;
     157             :   }
     158       27296 : }
     159             : 
     160             : template <typename AuxKernelType>
     161             : void
     162      111834 : ComputeElemAuxBcsThread<AuxKernelType>::printBoundaryExecutionInformation(
     163             :     unsigned int boundary_id, const std::vector<std::shared_ptr<AuxKernelType>> & kernels) const
     164             : {
     165      116754 :   if (!_fe_problem.shouldPrintExecution(_tid) || !_storage.hasActiveObjects() ||
     166      116754 :       _boundaries_exec_printed.count(boundary_id))
     167      111030 :     return;
     168             : 
     169         804 :   const auto & console = _fe_problem.console();
     170         804 :   console << "[DBG] Ordering on boundary " << boundary_id << std::endl;
     171         804 :   std::vector<MooseObject *> objs_ptrs;
     172        1608 :   for (auto & kernel_ptr : kernels)
     173         804 :     if (kernel_ptr->hasBoundary(boundary_id))
     174         804 :       objs_ptrs.push_back(dynamic_cast<MooseObject *>(kernel_ptr.get()));
     175        1608 :   std::string list_kernels = ConsoleUtils::mooseObjectVectorToString(objs_ptrs);
     176         804 :   console << ConsoleUtils::formatString(list_kernels, "[DBG]") << std::endl;
     177         804 :   _boundaries_exec_printed.insert(boundary_id);
     178         804 : }
     179             : 
     180             : template class ComputeElemAuxBcsThread<AuxKernel>;
     181             : template class ComputeElemAuxBcsThread<VectorAuxKernel>;
     182             : template class ComputeElemAuxBcsThread<ArrayAuxKernel>;

Generated by: LCOV version 1.14