LCOV - code coverage report
Current view: top level - src/loops - ComputeIndicatorThread.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 39a256 Lines: 111 112 99.1 %
Date: 2026-07-14 14:36:17 Functions: 13 13 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 "ComputeIndicatorThread.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "AuxiliarySystem.h"
      14             : #include "FEProblem.h"
      15             : #include "Indicator.h"
      16             : #include "InternalSideIndicatorBase.h"
      17             : #include "MooseVariableFE.h"
      18             : #include "Problem.h"
      19             : #include "SwapBackSentinel.h"
      20             : // For dynamic casting to Coupleable
      21             : #include "Material.h"
      22             : #include "InterfaceMaterial.h"
      23             : 
      24             : #include "libmesh/threads.h"
      25             : 
      26        4750 : ComputeIndicatorThread::ComputeIndicatorThread(FEProblemBase & fe_problem, bool finalize)
      27             :   : ThreadedElementLoop<ConstElemRange>(fe_problem),
      28        4750 :     _fe_problem(fe_problem),
      29        9500 :     _aux_sys(fe_problem.getAuxiliarySystem()),
      30        4750 :     _indicator_whs(_fe_problem.getIndicatorWarehouse()),
      31        4750 :     _internal_side_indicators(_fe_problem.getInternalSideIndicatorWarehouse()),
      32        4750 :     _finalize(finalize)
      33             : {
      34        4750 : }
      35             : 
      36             : // Splitting Constructor
      37          14 : ComputeIndicatorThread::ComputeIndicatorThread(ComputeIndicatorThread & x, Threads::split split)
      38             :   : ThreadedElementLoop<ConstElemRange>(x, split),
      39          14 :     _fe_problem(x._fe_problem),
      40          14 :     _aux_sys(x._aux_sys),
      41          14 :     _indicator_whs(x._indicator_whs),
      42          14 :     _internal_side_indicators(x._internal_side_indicators),
      43          14 :     _finalize(x._finalize)
      44             : {
      45          14 : }
      46             : 
      47        4778 : ComputeIndicatorThread::~ComputeIndicatorThread() {}
      48             : 
      49             : void
      50       25062 : ComputeIndicatorThread::subdomainChanged()
      51             : {
      52       25062 :   _fe_problem.subdomainSetup(_subdomain, _tid);
      53             : 
      54       25062 :   _indicator_whs.subdomainSetup(_tid);
      55       25062 :   _internal_side_indicators.subdomainSetup(_tid);
      56             : 
      57       25062 :   std::set<MooseVariableFEBase *> needed_moose_vars;
      58       25062 :   _indicator_whs.updateVariableDependency(needed_moose_vars, _tid);
      59       25062 :   _internal_side_indicators.updateVariableDependency(needed_moose_vars, _tid);
      60       25062 :   _fe_problem.setActiveElementalMooseVariables(needed_moose_vars, _tid);
      61             : 
      62             :   // Update variable coupleable vector tags
      63       25062 :   std::set<TagID> needed_var_vector_tags;
      64       25062 :   _indicator_whs.updateBlockFEVariableCoupledVectorTagDependency(
      65       25062 :       _subdomain, needed_var_vector_tags, _tid);
      66       25062 :   _internal_side_indicators.updateBlockFEVariableCoupledVectorTagDependency(
      67       25062 :       _subdomain, needed_var_vector_tags, _tid);
      68       25062 :   _fe_problem.getMaterialWarehouse().updateBlockFEVariableCoupledVectorTagDependency(
      69       25062 :       _subdomain, needed_var_vector_tags, _tid);
      70       25062 :   _fe_problem.setActiveFEVariableCoupleableVectorTags(needed_var_vector_tags, _tid);
      71             : 
      72       25062 :   std::unordered_set<unsigned int> needed_mat_props;
      73       25062 :   _indicator_whs.updateMatPropDependency(needed_mat_props, _tid);
      74       25062 :   _internal_side_indicators.updateMatPropDependency(needed_mat_props, _tid);
      75             : 
      76             :   // Only prepare (and therefore reinit) materials if an indicator actually consumes a material
      77             :   // property. Otherwise skip the material system entirely to avoid recomputing the whole stack.
      78       25062 :   if (!needed_mat_props.empty())
      79           0 :     _fe_problem.prepareMaterials(needed_mat_props, _subdomain, _tid);
      80             :   else
      81       25062 :     _fe_problem.clearActiveMaterialProperties(_tid);
      82       25062 : }
      83             : 
      84             : void
      85     1523446 : ComputeIndicatorThread::onElement(const Elem * elem)
      86             : {
      87     5442852 :   for (auto * var : _aux_sys._elem_vars[_tid])
      88     3919406 :     var->prepareAux();
      89             : 
      90     1523446 :   _fe_problem.prepare(elem, _tid);
      91     1523446 :   _fe_problem.reinitElem(elem, _tid);
      92             : 
      93             :   // Set up Sentinel class so that, even if reinitMaterials() throws, we
      94             :   // still remember to swap back during stack unwinding.
      95     1523446 :   SwapBackSentinel sentinel(_fe_problem, &FEProblemBase::swapBackMaterials, _tid);
      96             : 
      97     1523446 :   _fe_problem.reinitMaterials(_subdomain, _tid);
      98             : 
      99             :   // Compute
     100     1523446 :   if (!_finalize)
     101             :   {
     102      761723 :     if (_indicator_whs.hasActiveBlockObjects(_subdomain, _tid))
     103             :     {
     104             :       const std::vector<std::shared_ptr<Indicator>> & indicators =
     105       33256 :           _indicator_whs.getActiveBlockObjects(_subdomain, _tid);
     106       66512 :       for (const auto & indicator : indicators)
     107       33256 :         indicator->computeIndicator();
     108             :     }
     109             :   }
     110             : 
     111             :   // Finalize
     112             :   else
     113             :   {
     114      761723 :     if (_indicator_whs.hasActiveBlockObjects(_subdomain, _tid))
     115             :     {
     116             :       const std::vector<std::shared_ptr<Indicator>> & indicators =
     117       33256 :           _indicator_whs.getActiveBlockObjects(_subdomain, _tid);
     118       66512 :       for (const auto & indicator : indicators)
     119       33256 :         indicator->finalize();
     120             :     }
     121             : 
     122      761723 :     if (_internal_side_indicators.hasActiveBlockObjects(_subdomain, _tid))
     123             :     {
     124             :       const std::vector<std::shared_ptr<InternalSideIndicatorBase>> & internal_indicators =
     125      749115 :           _internal_side_indicators.getActiveBlockObjects(_subdomain, _tid);
     126     1503222 :       for (const auto & internal_indicator : internal_indicators)
     127      754107 :         internal_indicator->finalize();
     128             :     }
     129             :   }
     130             : 
     131     1523446 :   if (!_finalize) // During finalize the Indicators should be setting values in the vectors manually
     132     2721426 :     for (auto * var : _aux_sys._elem_vars[_tid])
     133     1959703 :       var->add(_aux_sys.solution());
     134     1523446 : }
     135             : 
     136             : void
     137      248646 : ComputeIndicatorThread::onBoundary(const Elem * /*elem*/,
     138             :                                    unsigned int /*side*/,
     139             :                                    BoundaryID /*bnd_id*/,
     140             :                                    const Elem * /*lower_d_elem = nullptr*/)
     141             : {
     142      248646 : }
     143             : 
     144             : void
     145     3051382 : ComputeIndicatorThread::onInternalSide(const Elem * elem, unsigned int side)
     146             : {
     147     3051382 :   if (_finalize) // If finalizing we only do something on the elements
     148     1525691 :     return;
     149             : 
     150             :   // Pointer to the neighbor we are currently working on.
     151     1525691 :   const Elem * neighbor = elem->neighbor_ptr(side);
     152             : 
     153     5467115 :   for (auto * var : _aux_sys._elem_vars[_tid])
     154     3941424 :     var->prepareAux();
     155             : 
     156     1525691 :   SubdomainID block_id = elem->subdomain_id();
     157     1525691 :   if (_internal_side_indicators.hasActiveBlockObjects(block_id, _tid))
     158             :   {
     159     1502606 :     _fe_problem.reinitNeighbor(elem, side, _tid);
     160             : 
     161             :     // Set up Sentinels so that, even if one of the reinitMaterialsXXX() calls throws, we
     162             :     // still remember to swap back during stack unwinding.
     163     1502606 :     SwapBackSentinel face_sentinel(_fe_problem, &FEProblemBase::swapBackMaterialsFace, _tid);
     164     1502606 :     _fe_problem.reinitMaterialsFace(block_id, _tid);
     165             : 
     166             :     SwapBackSentinel neighbor_sentinel(
     167     1502606 :         _fe_problem, &FEProblemBase::swapBackMaterialsNeighbor, _tid);
     168     1502606 :     _fe_problem.reinitMaterialsNeighbor(neighbor->subdomain_id(), _tid);
     169             : 
     170             :     const std::vector<std::shared_ptr<InternalSideIndicatorBase>> & indicators =
     171     1502606 :         _internal_side_indicators.getActiveBlockObjects(block_id, _tid);
     172     3014492 :     for (const auto & indicator : indicators)
     173     1511886 :       indicator->computeIndicator();
     174     1502606 :   }
     175             : }
     176             : 
     177             : void
     178     1523446 : ComputeIndicatorThread::postElement(const Elem * /*elem*/)
     179             : {
     180     1523446 : }
     181             : 
     182             : void
     183        4764 : ComputeIndicatorThread::post()
     184             : {
     185        4764 :   _fe_problem.clearActiveElementalMooseVariables(_tid);
     186        4764 :   _fe_problem.clearActiveMaterialProperties(_tid);
     187        4764 : }
     188             : 
     189             : void
     190          14 : ComputeIndicatorThread::join(const ComputeIndicatorThread & /*y*/)
     191             : {
     192          14 : }
     193             : 
     194             : void
     195        4764 : ComputeIndicatorThread::printGeneralExecutionInformation() const
     196             : {
     197        4764 :   if (!_fe_problem.shouldPrintExecution(_tid))
     198        4638 :     return;
     199             : 
     200         126 :   const auto & console = _fe_problem.console();
     201         126 :   const auto & execute_on = _fe_problem.getCurrentExecuteOnFlag();
     202         126 :   if (!_finalize)
     203          63 :     console << "[DBG] Executing indicators on elements then on internal sides on " << execute_on
     204          63 :             << std::endl;
     205             :   else
     206          63 :     console << "[DBG] Finalizing indicator loop" << std::endl;
     207             : }
     208             : 
     209             : void
     210       25062 : ComputeIndicatorThread::printBlockExecutionInformation() const
     211             : {
     212       25062 :   if (!_fe_problem.shouldPrintExecution(_tid) || _blocks_exec_printed.count(_subdomain))
     213       24936 :     return;
     214             : 
     215         126 :   const auto & console = _fe_problem.console();
     216         126 :   if (_indicator_whs.hasActiveBlockObjects(_subdomain, _tid))
     217             :   {
     218          72 :     const auto & indicators = _indicator_whs.getActiveBlockObjects(_subdomain, _tid);
     219          72 :     console << "[DBG] Ordering of element indicators on block " << _subdomain << std::endl;
     220         216 :     printExecutionOrdering<Indicator>(indicators, false);
     221             :   }
     222         126 :   if (_internal_side_indicators.hasActiveBlockObjects(_subdomain, _tid))
     223             :   {
     224         126 :     const auto & indicators = _internal_side_indicators.getActiveBlockObjects(_subdomain, _tid);
     225         126 :     console << "[DBG] Ordering of element internal sides indicators on block " << _subdomain
     226         126 :             << std::endl;
     227         378 :     printExecutionOrdering<InternalSideIndicatorBase>(indicators, false);
     228             :   }
     229         126 :   _blocks_exec_printed.insert(_subdomain);
     230             : }

Generated by: LCOV version 1.14