LCOV - code coverage report
Current view: top level - include/userobjects - UserObjectBase.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 31 31 100.0 %
Date: 2026-05-29 20:35:17 Functions: 23 24 95.8 %
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             : // MOOSE includes
      13             : #include "DistributionInterface.h"
      14             : #include "FunctionInterface.h"
      15             : #include "UserObjectInterface.h"
      16             : #include "PostprocessorInterface.h"
      17             : #include "VectorPostprocessorInterface.h"
      18             : #include "ReporterInterface.h"
      19             : #include "MeshChangedInterface.h"
      20             : #include "MeshDisplacedInterface.h"
      21             : #include "MooseObject.h"
      22             : #include "MooseTypes.h"
      23             : #include "Restartable.h"
      24             : #include "MeshMetaDataInterface.h"
      25             : #include "ScalarCoupleable.h"
      26             : #include "SetupInterface.h"
      27             : #include "PerfGraphInterface.h"
      28             : #include "SamplerInterface.h"
      29             : 
      30             : #include "libmesh/parallel.h"
      31             : 
      32             : class FEProblemBase;
      33             : class SubProblem;
      34             : class Assembly;
      35             : class SystemBase;
      36             : 
      37             : class UserObjectBase : public MooseObject,
      38             :                        public SetupInterface,
      39             :                        protected FunctionInterface,
      40             :                        public UserObjectInterface,
      41             :                        protected PostprocessorInterface,
      42             :                        protected VectorPostprocessorInterface,
      43             :                        protected ReporterInterface,
      44             :                        protected DistributionInterface,
      45             :                        protected SamplerInterface,
      46             :                        protected Restartable,
      47             :                        protected MeshMetaDataInterface,
      48             :                        protected MeshChangedInterface,
      49             :                        protected MeshDisplacedInterface,
      50             :                        protected PerfGraphInterface,
      51             :                        public DependencyResolverInterface
      52             : {
      53             : public:
      54             :   static InputParameters validParams();
      55             : 
      56             :   UserObjectBase(const InputParameters & params);
      57       79920 :   virtual ~UserObjectBase() = default;
      58             : 
      59             : #ifdef MOOSE_KOKKOS_ENABLED
      60             :   /**
      61             :    * Special constructor used for Kokkos functor copy during parallel dispatch
      62             :    */
      63             :   UserObjectBase(const UserObjectBase & object, const Moose::Kokkos::FunctorCopy & key);
      64             : #endif
      65             : 
      66             :   /**
      67             :    * Called before execute() is ever called so that data can be cleared.
      68             :    */
      69             :   virtual void initialize() = 0;
      70             : 
      71             :   /**
      72             :    * Finalize.  This is called _after_ execute() and _after_ threadJoin()!  This is probably where
      73             :    * you want to do MPI communication!
      74             :    */
      75             :   virtual void finalize() = 0;
      76             : 
      77             :   /**
      78             :    * Returns a reference to the subproblem that
      79             :    * this postprocessor is tied to
      80             :    */
      81          22 :   SubProblem & getSubProblem() const { return _subproblem; }
      82             : 
      83             :   /**
      84             :    * Returns whether or not this user object should be executed twice during the initial condition
      85             :    * when depended upon by an IC.
      86             :    */
      87             :   bool shouldDuplicateInitialExecution() const { return _duplicate_initial_execution; }
      88             : 
      89             :   /**
      90             :    * Gather the parallel sum of the variable passed in. It takes care of values across all threads
      91             :    * and CPUs (we DO hybrid parallelism!)
      92             :    *
      93             :    * After calling this, the variable that was passed in will hold the gathered value.
      94             :    */
      95             :   template <typename T>
      96      493826 :   void gatherSum(T & value)
      97             :   {
      98      493826 :     _communicator.sum(value);
      99      493826 :   }
     100             : 
     101             :   /**
     102             :    * Gather the parallel max of the variable passed in. It takes care of values across all threads
     103             :    * and CPUs (we DO hybrid parallelism!)
     104             :    *
     105             :    * After calling this, the variable that was passed in will hold the gathered value.
     106             :    */
     107             :   template <typename T>
     108         521 :   void gatherMax(T & value)
     109             :   {
     110         521 :     _communicator.max(value);
     111         521 :   }
     112             : 
     113             :   /**
     114             :    * Gather the parallel min of the variable passed in. It takes care of values across all threads
     115             :    * and CPUs (we DO hybrid parallelism!)
     116             :    *
     117             :    * After calling this, the variable that was passed in will hold the gathered value.
     118             :    */
     119             :   template <typename T>
     120        1559 :   void gatherMin(T & value)
     121             :   {
     122        1559 :     _communicator.min(value);
     123        1559 :   }
     124             : 
     125             :   /**
     126             :    * Deteremine the value of a variable according to the parallel
     127             :    * maximum of the provided proxy.
     128             :    * @param[in] proxy maximum proxy will be selected
     129             :    * @param[in] value value to be obtained corresponding to the location of maximum proxy
     130             :    */
     131             :   template <typename T1, typename T2>
     132             :   void gatherProxyValueMax(T1 & proxy, T2 & value);
     133             : 
     134             :   /**
     135             :    * Determine the value of a variable according to which process has the parallel
     136             :    * minimum of the provided proxy.
     137             :    * @param[in] proxy minimum proxy will be selected
     138             :    * @param[in] value value to be obtained corresponding to the location of minimum proxy
     139             :    */
     140             :   template <typename T1, typename T2>
     141             :   void gatherProxyValueMin(T1 & proxy, T2 & value);
     142             : 
     143             :   /**
     144             :    * Recursively return a set of user objects this user object depends on
     145             :    * Note: this can be called only after all user objects are constructed.
     146             :    */
     147             :   std::set<UserObjectName> getDependObjects() const;
     148             : 
     149      328881 :   const std::set<std::string> & getRequestedItems() override { return _depend_uo; }
     150             : 
     151      328881 :   const std::set<std::string> & getSuppliedItems() override { return _supplied_uo; }
     152             : 
     153             :   /**
     154             :    * @returns the number of the system associated with this object
     155             :    */
     156         735 :   unsigned int systemNumber() const { return _sys.number(); }
     157             : 
     158             :   /**
     159             :    * Whether or not a threaded copy of this object is needed when obtaining it in
     160             :    * another object, like via the UserObjectInterface.
     161             :    *
     162             :    * Derived classes should override this as needed.
     163             :    */
     164       81563 :   virtual bool needThreadedCopy() const { return false; }
     165             : 
     166             : protected:
     167             :   virtual void addPostprocessorDependencyHelper(const PostprocessorName & name) const override;
     168             :   virtual void
     169             :   addVectorPostprocessorDependencyHelper(const VectorPostprocessorName & name) const override;
     170             :   virtual void addUserObjectDependencyHelper(const UserObjectBase & uo) const override;
     171             :   void addReporterDependencyHelper(const ReporterName & reporter_name) override;
     172             : 
     173             :   /// Thread ID of this postprocessor
     174             :   const THREAD_ID _tid;
     175             : 
     176             :   /// Reference to the Subproblem for this user object
     177             :   SubProblem & _subproblem;
     178             : 
     179             :   /// Reference to the FEProblemBase for this user object
     180             :   FEProblemBase & _fe_problem;
     181             : 
     182             :   /// Reference to the system object for this user object. This should correspond to a nonlinear
     183             :   /// system (either through the FEProblemBase or the DisplacedProblem)
     184             :   SystemBase & _sys;
     185             : 
     186             :   /// Reference to the assembly object for this user object
     187             :   Assembly & _assembly;
     188             : 
     189             :   /// Whether to execute this object twice on initial
     190             :   const bool _duplicate_initial_execution;
     191             : 
     192             :   /// Depend UserObjects that to be used both for determining user object sorting and by AuxKernel
     193             :   /// for finding the full UO dependency
     194             :   mutable std::set<std::string> _depend_uo;
     195             : 
     196             : private:
     197             :   /// A name of the "supplied" user objects, which is just this object
     198             :   std::set<std::string> _supplied_uo;
     199             : };
     200             : 
     201             : template <typename T1, typename T2>
     202             : void
     203        2733 : UserObjectBase::gatherProxyValueMax(T1 & proxy, T2 & value)
     204             : {
     205             :   // Get all proxy, value pairs. _communicator.maxloc would be faster but leads to
     206             :   // partitioning dependent results if the maximum proxy is not unique.
     207        2733 :   std::vector<std::pair<T1, T2>> all(n_processors());
     208        2733 :   const auto pair = std::make_pair(proxy, value);
     209        2733 :   _communicator.allgather(pair, all);
     210             : 
     211             :   // find maximum, disambiguated by the value
     212        2733 :   const auto it = std::max_element(all.begin(), all.end());
     213        2733 :   proxy = it->first;
     214        2733 :   value = it->second;
     215        2733 : }
     216             : 
     217             : template <typename T1, typename T2>
     218             : void
     219        1002 : UserObjectBase::gatherProxyValueMin(T1 & proxy, T2 & value)
     220             : {
     221             :   // get all proxy, value pairs
     222        1002 :   std::vector<std::pair<T1, T2>> all(n_processors());
     223        1002 :   const auto pair = std::make_pair(proxy, value);
     224        1002 :   _communicator.allgather(pair, all);
     225             : 
     226             :   // find minimum, disambiguated by the value
     227        1002 :   const auto it = std::min_element(all.begin(), all.end());
     228        1002 :   proxy = it->first;
     229        1002 :   value = it->second;
     230        1002 : }

Generated by: LCOV version 1.14