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 : }