21 #include "libmesh/elem.h" 22 #include "libmesh/remote_elem.h" 23 #include "libmesh/tensor_tools.h" 25 #include <unordered_map> 35 template <
typename PolymorphicLambda>
37 PolymorphicLambda my_lammy,
38 const std::set<ExecFlagType> & clearance_schedule,
40 const std::set<SubdomainID> & block_ids);
48 template <
typename PolymorphicLambda>
50 const std::set<SubdomainID> & block_ids,
51 PolymorphicLambda my_lammy);
70 using ElemFn = std::function<T(const Moose::ElemArg &, const Moose::StateArg &)>;
71 using FaceFn = std::function<T(const Moose::FaceArg &, const Moose::StateArg &)>;
72 using ElemQpFn = std::function<T(const Moose::ElemQpArg &, const Moose::StateArg &)>;
73 using ElemSideQpFn = std::function<T(const Moose::ElemSideQpArg &, const Moose::StateArg &)>;
74 using ElemPointFn = std::function<T(const Moose::ElemPointArg &, const Moose::StateArg &)>;
75 using NodeFn = std::function<T(const Moose::NodeArg &, const Moose::StateArg &)>;
101 const std::unordered_map<SubdomainID, C> & functors)
const;
127 template <
typename T>
128 template <
typename PolymorphicLambda>
130 const std::string & name,
131 PolymorphicLambda my_lammy,
132 const std::set<ExecFlagType> & clearance_schedule,
134 const std::set<SubdomainID> & block_ids)
135 :
Moose::FunctorBase<T>(
name, clearance_schedule), _mesh(
mesh)
140 template <
typename T>
141 template <
typename PolymorphicLambda>
144 const std::set<SubdomainID> & block_ids,
145 PolymorphicLambda my_lammy)
147 mooseAssert(&
mesh == &_mesh,
148 "We should always be setting this functor with the same mesh. We may relax this " 151 auto add_lammy = [
this, my_lammy](
const SubdomainID block_id)
153 auto pr = _elem_functor.emplace(block_id, my_lammy);
155 mooseError(
"No insertion for the functor material property '",
159 ". Another material must already declare this property on that block.");
160 _face_functor.emplace(block_id, my_lammy);
161 _elem_qp_functor.emplace(block_id, my_lammy);
162 _elem_side_qp_functor.emplace(block_id, my_lammy);
163 _elem_point_functor.emplace(block_id, my_lammy);
164 _node_functor.emplace(block_id, my_lammy);
167 for (
const auto block_id : block_ids)
173 block_ids ==
mesh.meshSubdomains())
177 template <
typename T>
186 const bool defined_on_elem = _elem_functor.count(fi.
elem().subdomain_id());
187 const bool defined_on_neighbor = _elem_functor.count(fi.
neighbor().subdomain_id());
188 const bool extrapolated = (defined_on_elem + defined_on_neighbor) == 1;
190 mooseAssert(defined_on_elem || defined_on_neighbor,
191 "This shouldn't be called if we aren't defined on either side.");
195 template <
typename T>
200 const bool has_blocks = _elem_functor.count(
id);
201 mooseAssert(has_blocks == _face_functor.count(
id),
202 "All functor sets should agree on whether we have this sub id");
203 mooseAssert(has_blocks == _elem_qp_functor.count(
id),
204 "All functor sets should agree on whether we have this sub id");
205 mooseAssert(has_blocks == _elem_side_qp_functor.count(
id),
206 "All functor sets should agree on whether we have this sub id");
210 template <
typename T>
211 template <
typename C>
214 const SubdomainID sub_id,
const std::unordered_map<SubdomainID, C> & functors)
const 216 std::vector<SubdomainID> block_ids;
217 block_ids.reserve(functors.size());
218 for (
const auto & [available_sub_id, functor] : functors)
221 block_ids.push_back(available_sub_id);
224 std::to_string(sub_id),
225 " doesn't exist in the map for lambda functor '",
227 "'! This is likely because you did not provide a functor material " 228 "definition on that subdomain.\nSubdomain IDs in the map: ",
232 template <
typename T>
237 const Elem *
const elem = elem_arg.
elem;
239 "The element must be non-null and non-remote in functor material properties");
240 auto it = _elem_functor.find(elem->subdomain_id());
241 if (it == _elem_functor.end())
242 subdomainErrorMessage(elem->subdomain_id(), _elem_functor);
244 return it->second(elem_arg, time);
247 template <
typename T>
257 auto it = _face_functor.find(sub_id);
258 if (it == _face_functor.end())
259 subdomainErrorMessage(sub_id, _face_functor);
261 return it->second(face, time);
264 mooseAssert(this->isInternalFace(*face.
fi),
265 "If we did not have a face side, then we must be an internal face");
269 template <
typename T>
275 auto it = _elem_qp_functor.find(sub_id);
276 if (it == _elem_qp_functor.end())
277 subdomainErrorMessage(sub_id, _elem_qp_functor);
279 return it->second(elem_qp, time);
282 template <
typename T>
288 auto it = _elem_side_qp_functor.find(sub_id);
289 if (it == _elem_side_qp_functor.end())
290 subdomainErrorMessage(sub_id, _elem_side_qp_functor);
292 return it->second(elem_side_qp, time);
295 template <
typename T>
300 const Elem *
const elem = elem_point_arg.
elem;
302 "The element must be non-null and non-remote in functor material properties");
303 auto it = _elem_point_functor.find(elem->subdomain_id());
304 if (it == _elem_point_functor.end())
305 subdomainErrorMessage(elem->subdomain_id(), _elem_point_functor);
307 return it->second(elem_point_arg, time);
310 template <
typename T>
315 mooseAssert(node_arg.
node,
"The node must be non-null in functor material properties");
317 mooseError(
"We do not currently support multi-subdomain evaluation of nodal arguments");
319 auto it = _node_functor.find(sub_id);
320 if (it == _node_functor.end())
321 subdomainErrorMessage(sub_id, _node_functor);
323 return it->second(node_arg, time);
326 template <
typename T>
334 template <
typename T>
std::string name(const ElemQuality q)
ValueType evaluate(const Moose::ElemArg &elem_arg, const Moose::StateArg &time) const override
Evaluate the functor with a given element.
A material property that is evaluated on-the-fly via calls to various overloads of operator() ...
std::function< T(const Moose::NodeArg &, const Moose::StateArg &)> NodeFn
bool supportsFaceArg() const override final
Whether this functor supports evaluation with FaceArg.
Base class template for functor objects.
std::unordered_map< SubdomainID, ElemFn > _elem_functor
Functors that return element average values (or cell centroid values or whatever the implementer want...
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
std::unordered_map< SubdomainID, ElemPointFn > _elem_point_functor
Functors that return evaluations at an arbitrary physical point in an element.
const libMesh::Elem * face_side
A member that can be used to indicate whether there is a sidedness to this face.
std::function< T(const Moose::ElemPointArg &, const Moose::StateArg &)> ElemPointFn
const Elem & elem() const
libMesh::VectorValue< T > greenGaussGradient(const ElemArg &elem_arg, const StateArg &state_arg, const FunctorBase< T > &functor, const bool two_term_boundary_expansion, const MooseMesh &mesh, const bool force_green_gauss=false)
Compute a cell gradient using the method of Green-Gauss.
std::unordered_map< SubdomainID, ElemSideQpFn > _elem_side_qp_functor
Functors that will evaluate elements at side quadrature points.
void subdomainErrorMessage(SubdomainID sub_id, const std::unordered_map< SubdomainID, C > &functors) const
Provide a useful error message about lack of functor material property on the provided subdomain sub_...
GradientType evaluateGradient(const Moose::ElemArg &elem_arg, const Moose::StateArg &) const override
Evaluate the functor gradient with a given element.
A structure that is used to evaluate Moose functors at an arbitrary physical point contained within a...
const libMesh::Node * node
The node which defines our location in space.
typename FunctorReturnType< T, FunctorEvaluationKind::Gradient >::type GradientType
This rigmarole makes it so that a user can create functors that return containers (std::vector...
virtual ~PiecewiseByBlockLambdaFunctor()=default
const SubdomainID INVALID_BLOCK_ID
This data structure is used to store geometric and variable related metadata about each cell face in ...
void libmesh_ignore(const Args &...)
std::unordered_map< SubdomainID, ElemQpFn > _elem_qp_functor
Functors that will evaluate elements at quadrature points.
const std::set< SubdomainID > * subdomain_ids
Indicates what subdomains this argument should be associated with.
std::unordered_map< SubdomainID, NodeFn > _node_functor
Functors that return nodal values.
const Elem * neighborPtr() const
std::unordered_map< SubdomainID, FaceFn > _face_functor
Functors that return the property value on the requested side of the face (e.g.
A structure defining a "face" evaluation calling argument for Moose functors.
PiecewiseByBlockLambdaFunctor(const std::string &name, PolymorphicLambda my_lammy, const std::set< ExecFlagType > &clearance_schedule, const MooseMesh &mesh, const std::set< SubdomainID > &block_ids)
void setFunctor(const MooseMesh &mesh, const std::set< SubdomainID > &block_ids, PolymorphicLambda my_lammy)
Set the functor that will be used in calls to evaluate overloads.
const FaceInfo * fi
a face information object which defines our location in space
const MooseMesh & _mesh
The mesh that this functor operates on.
std::function< T(const Moose::ElemArg &, const Moose::StateArg &)> ElemFn
const libMesh::Elem * elem
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
const Elem & neighbor() const
const libMesh::Elem * elem
A structure that is used to evaluate Moose functors logically at an element/cell center.
Argument for requesting functor evaluation at a quadrature point location in an element.
const libMesh::Elem * elem
The element.
std::string stringify(const T &t)
conversion to string
std::function< T(const Moose::ElemSideQpArg &, const Moose::StateArg &)> ElemSideQpFn
bool supportsElemSideQpArg() const override final
Whether this functor supports evaluation with ElemSideQpArg.
std::function< T(const Moose::FaceArg &, const Moose::StateArg &)> FaceFn
const SubdomainID ANY_BLOCK_ID
subdomain_id_type subdomain_id() const
std::function< T(const Moose::ElemQpArg &, const Moose::StateArg &)> ElemQpFn
bool hasBlocks(SubdomainID id) const override
Returns whether the functor is defined on this block.
State argument for evaluating functors.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
bool isExtrapolatedBoundaryFace(const FaceInfo &fi, const Elem *elem, const Moose::StateArg &time) const override
Returns whether this (sided) face is an extrapolated boundary face for this functor.
const libMesh::Elem * elem
The element.
void interpolate(InterpMethod m, T &result, const T2 &value1, const T3 &value2, const FaceInfo &fi, const bool one_is_elem)
Provides interpolation of face values for non-advection-specific purposes (although it can/will still...
Argument for requesting functor evaluation at quadrature point locations on an element side...
const RemoteElem * remote_elem