LCOV - code coverage report
Current view: top level - include/loops - ThreadedElementLoop.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 55 55 100.0 %
Date: 2025-07-17 01:28:37 Functions: 41 53 77.4 %
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             : #pragma once
      11             : 
      12             : #include "ParallelUniqueId.h"
      13             : #include "FEProblemBase.h"
      14             : #include "ThreadedElementLoopBase.h"
      15             : #include "ConsoleUtils.h"
      16             : #include "SwapBackSentinel.h"
      17             : 
      18             : // Forward declarations
      19             : class SystemBase;
      20             : 
      21             : /**
      22             :  * This mutex is used by all derived classes of the ThreadedElementLoop. It
      23             :  * is necessary to protect the creation of the strings used in the propagation
      24             :  * of the error messages.  It's possible for a thread to have acquired the
      25             :  * commonly used mutex in the Threads namespace so this one is here to
      26             :  * avoid any deadlocking.
      27             :  */
      28             : static Threads::spin_mutex threaded_element_mutex;
      29             : 
      30             : /**
      31             :  * Base class for assembly-like calculations.
      32             :  */
      33             : template <typename RangeType>
      34             : class ThreadedElementLoop : public ThreadedElementLoopBase<RangeType>
      35             : {
      36             : public:
      37             :   ThreadedElementLoop(FEProblemBase & feproblem);
      38             : 
      39             :   ThreadedElementLoop(ThreadedElementLoop & x, Threads::split split);
      40             : 
      41             :   virtual ~ThreadedElementLoop();
      42             : 
      43             :   virtual void caughtMooseException(MooseException & e) override;
      44             : 
      45   388188137 :   virtual bool keepGoing() override { return !_fe_problem.hasException(); }
      46             : 
      47             :   virtual void preElement(const Elem * elem) override;
      48             : 
      49             :   virtual void preInternalSide(const Elem * elem, unsigned int side) override;
      50             : 
      51             :   virtual void preBoundary(const Elem * elem,
      52             :                            unsigned int side,
      53             :                            BoundaryID bnd_id,
      54             :                            const Elem * lower_d_elem = nullptr) override;
      55             : 
      56             :   virtual void neighborSubdomainChanged() override;
      57             : 
      58             : protected:
      59             :   void prepareElement(const Elem * elem);
      60             :   void clearVarsAndMaterials();
      61             : 
      62             :   FEProblemBase & _fe_problem;
      63             : 
      64             :   /**
      65             :    * Routine to output the ordering of objects within a vector of pointers to these objects.
      66             :    * These objects must implement the name() routine, and it must return a string or compatible
      67             :    * type.
      68             :    *
      69             :    * @tparam T the object type
      70             :    * @param objs the vector with all the objects (should be pointers)
      71             :    * @param objects_type the name of the type of objects. Defaults to the CPP object name
      72             :    * @param print_header whether to print a header about the timing of execution and the type of
      73             :    * objects
      74             :    */
      75             :   template <typename T>
      76             :   void printExecutionOrdering(const std::vector<T *> & objs,
      77             :                               const bool print_header = true,
      78             :                               const std::string & line_prefix = "[DBG]") const;
      79             :   template <typename T>
      80             :   void printExecutionOrdering(const std::vector<std::shared_ptr<T>> & objs_ptrs,
      81             :                               const bool print_header = true,
      82             :                               const std::string & line_prefix = "[DBG]") const;
      83             : };
      84             : 
      85             : template <typename RangeType>
      86     3918882 : ThreadedElementLoop<RangeType>::ThreadedElementLoop(FEProblemBase & fe_problem)
      87     3918882 :   : ThreadedElementLoopBase<RangeType>(fe_problem.mesh()), _fe_problem(fe_problem)
      88             : {
      89     3918882 : }
      90             : 
      91             : template <typename RangeType>
      92      342439 : ThreadedElementLoop<RangeType>::ThreadedElementLoop(ThreadedElementLoop & x,
      93             :                                                     Threads::split /*split*/)
      94      342439 :   : ThreadedElementLoopBase<RangeType>(x), _fe_problem(x._fe_problem)
      95             : {
      96      342439 : }
      97             : 
      98             : template <typename RangeType>
      99     4261239 : ThreadedElementLoop<RangeType>::~ThreadedElementLoop()
     100             : {
     101     4261239 : }
     102             : 
     103             : template <typename RangeType>
     104             : void
     105         165 : ThreadedElementLoop<RangeType>::caughtMooseException(MooseException & e)
     106             : {
     107         165 :   Threads::spin_mutex::scoped_lock lock(threaded_element_mutex);
     108             : 
     109         165 :   std::string what(e.what());
     110         165 :   _fe_problem.setException(what);
     111         165 : }
     112             : 
     113             : template <typename RangeType>
     114             : void
     115   388188132 : ThreadedElementLoop<RangeType>::preElement(const Elem * el)
     116             : {
     117   388188132 :   _fe_problem.setCurrentSubdomainID(el, ThreadedElementLoopBase<RangeType>::_tid);
     118   388188132 : }
     119             : 
     120             : template <typename RangeType>
     121             : void
     122  1476509705 : ThreadedElementLoop<RangeType>::preInternalSide(const Elem * el, unsigned int side)
     123             : {
     124  1476509705 :   _fe_problem.setNeighborSubdomainID(el, side, ThreadedElementLoopBase<RangeType>::_tid);
     125  1476509705 : }
     126             : 
     127             : template <typename RangeType>
     128             : void
     129   116160485 : ThreadedElementLoop<RangeType>::preBoundary(const Elem * /*elem*/,
     130             :                                             unsigned int /*side*/,
     131             :                                             BoundaryID bnd_id,
     132             :                                             const Elem * /*=nullptr*/)
     133             : {
     134   116160485 :   _fe_problem.setCurrentBoundaryID(bnd_id, ThreadedElementLoopBase<RangeType>::_tid);
     135   116160485 : }
     136             : 
     137             : template <typename RangeType>
     138             : void
     139    12810469 : ThreadedElementLoop<RangeType>::neighborSubdomainChanged()
     140             : {
     141    12810469 :   _fe_problem.neighborSubdomainSetup(ThreadedElementLoopBase<RangeType>::_neighbor_subdomain,
     142             :                                      ThreadedElementLoopBase<RangeType>::_tid);
     143    12810469 : }
     144             : 
     145             : template <typename RangeType>
     146             : template <typename T>
     147             : void
     148       13276 : ThreadedElementLoop<RangeType>::printExecutionOrdering(const std::vector<T *> & objs,
     149             :                                                        const bool print_header,
     150             :                                                        const std::string & line_prefix) const
     151             : {
     152       13276 :   if (!objs.size())
     153        1460 :     return;
     154             : 
     155       11816 :   auto & console = _fe_problem.console();
     156       11816 :   const auto objects_type = MooseUtils::prettyCppType(objs[0]);
     157       11816 :   std::vector<MooseObject *> moose_objs;
     158       34830 :   for (auto obj_ptr : objs)
     159       23014 :     moose_objs.push_back(dynamic_cast<MooseObject *>(obj_ptr));
     160       11816 :   const auto names = ConsoleUtils::mooseObjectVectorToString(moose_objs);
     161             : 
     162             :   // Print string with a DBG prefix and with sufficient line breaks
     163       12806 :   std::string message = print_header ? "Executing " + objects_type + " on " +
     164         990 :                                            _fe_problem.getCurrentExecuteOnFlag().name() + "\n"
     165             :                                      : "";
     166       11816 :   message += (print_header ? "Order of execution:\n" : "") + names;
     167       11816 :   console << ConsoleUtils::formatString(message, line_prefix) << std::endl;
     168       11816 : }
     169             : 
     170             : template <typename RangeType>
     171             : template <typename T>
     172             : void
     173       10826 : ThreadedElementLoop<RangeType>::printExecutionOrdering(
     174             :     const std::vector<std::shared_ptr<T>> & objs_ptrs,
     175             :     const bool print_header,
     176             :     const std::string & line_prefix) const
     177             : {
     178       10826 :   std::vector<T *> regular_ptrs;
     179       31320 :   for (auto shared_ptr : objs_ptrs)
     180       20494 :     regular_ptrs.push_back(shared_ptr.get());
     181       10826 :   printExecutionOrdering<T>(regular_ptrs, print_header, line_prefix);
     182       10826 : }
     183             : 
     184             : template <typename RangeType>
     185             : void
     186   344434215 : ThreadedElementLoop<RangeType>::prepareElement(const Elem * const elem)
     187             : {
     188   344434215 :   _fe_problem.prepare(elem, this->_tid);
     189   344434187 :   _fe_problem.reinitElem(elem, this->_tid);
     190   344434187 :   _fe_problem.reinitMaterials(this->_subdomain, this->_tid);
     191   344434129 : }
     192             : 
     193             : template <typename RangeType>
     194             : void
     195     3797293 : ThreadedElementLoop<RangeType>::clearVarsAndMaterials()
     196             : {
     197     3797293 :   _fe_problem.clearActiveElementalMooseVariables(this->_tid);
     198     3797293 :   _fe_problem.clearActiveMaterialProperties(this->_tid);
     199     3797293 : }

Generated by: LCOV version 1.14