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);
102 template <
typename C>
104 const std::unordered_map<SubdomainID, C> & functors)
const;
139template <
typename PolymorphicLambda>
141 const std::string & name,
142 PolymorphicLambda my_lammy,
143 const std::set<ExecFlagType> & clearance_schedule,
145 const std::set<SubdomainID> & block_ids)
146 :
Moose::FunctorBase<T>(name, clearance_schedule), _mesh(
mesh)
152template <
typename PolymorphicLambda>
155 const std::set<SubdomainID> & block_ids,
156 PolymorphicLambda my_lammy)
158 mooseAssert(&
mesh == &_mesh,
159 "We should always be setting this functor with the same mesh. We may relax this "
162 auto add_lammy = [
this, my_lammy](
const SubdomainID block_id)
164 auto pr = _elem_functor.emplace(block_id, my_lammy);
166 mooseError(
"No insertion for the functor material property '",
170 ". Another material must already declare this property on that block.");
171 _face_functor.emplace(block_id, my_lammy);
172 _elem_qp_functor.emplace(block_id, my_lammy);
173 _elem_side_qp_functor.emplace(block_id, my_lammy);
174 _elem_point_functor.emplace(block_id, my_lammy);
175 _node_functor.emplace(block_id, my_lammy);
176 _point_functor.emplace(block_id, my_lammy);
179 for (
const auto block_id : block_ids)
185 block_ids ==
mesh.meshSubdomains())
198 const bool defined_on_elem = _elem_functor.count(fi.
elem().subdomain_id());
199 const bool defined_on_neighbor = _elem_functor.count(fi.
neighbor().subdomain_id());
200 const bool extrapolated = (defined_on_elem + defined_on_neighbor) == 1;
202 mooseAssert(defined_on_elem || defined_on_neighbor,
203 "This shouldn't be called if we aren't defined on either side.");
212 const bool has_blocks = _elem_functor.count(
id);
213 mooseAssert(has_blocks == _face_functor.count(
id),
214 "All functor sets should agree on whether we have this sub id");
215 mooseAssert(has_blocks == _elem_qp_functor.count(
id),
216 "All functor sets should agree on whether we have this sub id");
217 mooseAssert(has_blocks == _elem_side_qp_functor.count(
id),
218 "All functor sets should agree on whether we have this sub id");
226 const auto & name = _mesh.getSubdomainName(sub_id);
236 const SubdomainID sub_id,
const std::unordered_map<SubdomainID, C> & functors)
const
238 std::vector<std::string> block_names_and_ids;
239 block_names_and_ids.reserve(functors.size());
240 for (
const auto & [available_sub_id, functor] : functors)
242 libmesh_ignore(functor);
243 block_names_and_ids.push_back(subdomainNameAndID(available_sub_id));
246 subdomainNameAndID(sub_id),
247 " doesn't exist in the map for lambda functor '",
249 "'! This is likely because you did not provide a functor material "
250 "definition on that subdomain.\nSubdomains in the map: ",
259 const Elem *
const elem = elem_arg.
elem;
261 "The element must be non-null and non-remote in functor material properties");
262 auto it = _elem_functor.find(elem->subdomain_id());
263 if (it == _elem_functor.end())
264 subdomainErrorMessage(elem->subdomain_id(), _elem_functor);
266 return it->second(elem_arg, time);
279 auto it = _face_functor.find(sub_id);
280 if (it == _face_functor.end())
281 subdomainErrorMessage(sub_id, _face_functor);
283 return it->second(face, time);
286 mooseAssert(this->isInternalFace(*face.
fi),
287 "If we did not have a face side, then we must be an internal face");
288 return interpolate(*
this, face, time);
297 auto it = _elem_qp_functor.find(sub_id);
298 if (it == _elem_qp_functor.end())
299 subdomainErrorMessage(sub_id, _elem_qp_functor);
301 return it->second(elem_qp, time);
310 auto it = _elem_side_qp_functor.find(sub_id);
311 if (it == _elem_side_qp_functor.end())
312 subdomainErrorMessage(sub_id, _elem_side_qp_functor);
314 return it->second(elem_side_qp, time);
322 const Elem *
const elem = elem_point_arg.
elem;
324 "The element must be non-null and non-remote in functor material properties");
325 auto it = _elem_point_functor.find(elem->subdomain_id());
326 if (it == _elem_point_functor.end())
327 subdomainErrorMessage(elem->subdomain_id(), _elem_point_functor);
329 return it->second(elem_point_arg, time);
337 mooseAssert(node_arg.
node,
"The node must be non-null in functor material properties");
339 mooseError(
"We do not currently support multi-subdomain evaluation of nodal arguments");
341 auto it = _node_functor.find(sub_id);
342 if (it == _node_functor.end())
343 subdomainErrorMessage(sub_id, _node_functor);
345 return it->second(node_arg, time);
355 if (it == _point_functor.end())
358 return it->second(point_arg, time);
subdomain_id_type SubdomainID
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
This data structure is used to store geometric and variable related metadata about each cell face in ...
const Elem & elem() const
const Elem * neighborPtr() const
const Elem & neighbor() const
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Base class template for functor objects.
typename FunctorReturnType< T, FunctorEvaluationKind::Gradient >::type GradientType
This rigmarole makes it so that a user can create functors that return containers (std::vector,...
A material property that is evaluated on-the-fly via calls to various overloads of operator()
virtual ~PiecewiseByBlockLambdaFunctor()=default
std::function< T(const Moose::ElemSideQpArg &, const Moose::StateArg &)> ElemSideQpFn
ValueType evaluate(const Moose::ElemArg &elem_arg, const Moose::StateArg &time) const override
Evaluate the functor with a given element.
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.
GradientType evaluateGradient(const Moose::ElemArg &elem_arg, const Moose::StateArg &) const override
Evaluate the functor gradient with a given element.
std::unordered_map< SubdomainID, FaceFn > _face_functor
Functors that return the property value on the requested side of the face (e.g.
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_...
std::unordered_map< SubdomainID, ElemSideQpFn > _elem_side_qp_functor
Functors that will evaluate elements at side quadrature points.
std::unordered_map< SubdomainID, PointFn > _point_functor
Functors that return evaluations at an arbitrary physical point without mesh information.
std::unordered_map< SubdomainID, NodeFn > _node_functor
Functors that return nodal values.
std::string subdomainNameAndID(SubdomainID sub_id) const
Format a subdomain ID with its name, when available.
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.
std::function< T(const Moose::FaceArg &, const Moose::StateArg &)> FaceFn
PiecewiseByBlockLambdaFunctor(const std::string &name, PolymorphicLambda my_lammy, const std::set< ExecFlagType > &clearance_schedule, const MooseMesh &mesh, const std::set< SubdomainID > &block_ids)
bool supportsElemSideQpArg() const override final
Whether this functor supports evaluation with ElemSideQpArg.
const MooseMesh & _mesh
The mesh that this functor operates on.
std::function< T(const Moose::NodeArg &, const Moose::StateArg &)> NodeFn
bool hasBlocks(SubdomainID id) const override
Returns whether the functor is defined on this block.
std::function< T(const Moose::ElemArg &, const Moose::StateArg &)> ElemFn
std::unordered_map< SubdomainID, ElemFn > _elem_functor
Functors that return element average values (or cell centroid values or whatever the implementer want...
bool supportsFaceArg() const override final
Whether this functor supports evaluation with FaceArg.
std::function< T(const Moose::ElemQpArg &, const Moose::StateArg &)> ElemQpFn
std::unordered_map< SubdomainID, ElemQpFn > _elem_qp_functor
Functors that will evaluate elements at quadrature points.
std::function< T(const Moose::ElemPointArg &, const Moose::StateArg &)> ElemPointFn
std::function< T(const Moose::PointArg &, const Moose::StateArg &)> PointFn
std::unordered_map< SubdomainID, ElemPointFn > _elem_point_functor
Functors that return evaluations at an arbitrary physical point in an element.
subdomain_id_type subdomain_id() 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.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
const SubdomainID ANY_BLOCK_ID
std::string stringify(const T &t)
conversion to string
const SubdomainID INVALID_BLOCK_ID
const RemoteElem * remote_elem
A structure that is used to evaluate Moose functors logically at an element/cell center.
const libMesh::Elem * elem
A structure that is used to evaluate Moose functors at an arbitrary physical point contained within a...
const libMesh::Elem * elem
Argument for requesting functor evaluation at a quadrature point location in an element.
const libMesh::Elem * elem
The element.
Argument for requesting functor evaluation at quadrature point locations on an element side.
const libMesh::Elem * elem
The element.
A structure defining a "face" evaluation calling argument for Moose functors.
const libMesh::Elem * face_side
A member that can be used to indicate whether there is a sidedness to this face.
const FaceInfo * fi
a face information object which defines our location in space
const libMesh::Node * node
The node which defines our location in space.
const std::set< SubdomainID > * subdomain_ids
Indicates what subdomains this argument should be associated with.
A structure that is used to evaluate Moose functors at an arbitrary physical point,...
State argument for evaluating functors.