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);
101 const std::unordered_map<SubdomainID, C> & functors)
const;
133template <
typename PolymorphicLambda>
135 const std::string & name,
136 PolymorphicLambda my_lammy,
137 const std::set<ExecFlagType> & clearance_schedule,
139 const std::set<SubdomainID> & block_ids)
140 :
Moose::FunctorBase<T>(name, clearance_schedule), _mesh(
mesh)
146template <
typename PolymorphicLambda>
149 const std::set<SubdomainID> & block_ids,
150 PolymorphicLambda my_lammy)
152 mooseAssert(&
mesh == &_mesh,
153 "We should always be setting this functor with the same mesh. We may relax this "
156 auto add_lammy = [
this, my_lammy](
const SubdomainID block_id)
158 auto pr = _elem_functor.emplace(block_id, my_lammy);
160 mooseError(
"No insertion for the functor material property '",
164 ". Another material must already declare this property on that block.");
165 _face_functor.emplace(block_id, my_lammy);
166 _elem_qp_functor.emplace(block_id, my_lammy);
167 _elem_side_qp_functor.emplace(block_id, my_lammy);
168 _elem_point_functor.emplace(block_id, my_lammy);
169 _node_functor.emplace(block_id, my_lammy);
172 for (
const auto block_id : block_ids)
178 block_ids ==
mesh.meshSubdomains())
191 const bool defined_on_elem = _elem_functor.count(fi.
elem().subdomain_id());
192 const bool defined_on_neighbor = _elem_functor.count(fi.
neighbor().subdomain_id());
193 const bool extrapolated = (defined_on_elem + defined_on_neighbor) == 1;
195 mooseAssert(defined_on_elem || defined_on_neighbor,
196 "This shouldn't be called if we aren't defined on either side.");
205 const bool has_blocks = _elem_functor.count(
id);
206 mooseAssert(has_blocks == _face_functor.count(
id),
207 "All functor sets should agree on whether we have this sub id");
208 mooseAssert(has_blocks == _elem_qp_functor.count(
id),
209 "All functor sets should agree on whether we have this sub id");
210 mooseAssert(has_blocks == _elem_side_qp_functor.count(
id),
211 "All functor sets should agree on whether we have this sub id");
219 const auto & name = _mesh.getSubdomainName(sub_id);
229 const SubdomainID sub_id,
const std::unordered_map<SubdomainID, C> & functors)
const
231 std::vector<std::string> block_names_and_ids;
232 block_names_and_ids.reserve(functors.size());
233 for (
const auto & [available_sub_id, functor] : functors)
235 libmesh_ignore(functor);
236 block_names_and_ids.push_back(subdomainNameAndID(available_sub_id));
239 subdomainNameAndID(sub_id),
240 " doesn't exist in the map for lambda functor '",
242 "'! This is likely because you did not provide a functor material "
243 "definition on that subdomain.\nSubdomains in the map: ",
252 const Elem *
const elem = elem_arg.
elem;
254 "The element must be non-null and non-remote in functor material properties");
255 auto it = _elem_functor.find(elem->subdomain_id());
256 if (it == _elem_functor.end())
257 subdomainErrorMessage(elem->subdomain_id(), _elem_functor);
259 return it->second(elem_arg, time);
272 auto it = _face_functor.find(sub_id);
273 if (it == _face_functor.end())
274 subdomainErrorMessage(sub_id, _face_functor);
276 return it->second(face, time);
279 mooseAssert(this->isInternalFace(*face.
fi),
280 "If we did not have a face side, then we must be an internal face");
281 return interpolate(*
this, face, time);
290 auto it = _elem_qp_functor.find(sub_id);
291 if (it == _elem_qp_functor.end())
292 subdomainErrorMessage(sub_id, _elem_qp_functor);
294 return it->second(elem_qp, time);
303 auto it = _elem_side_qp_functor.find(sub_id);
304 if (it == _elem_side_qp_functor.end())
305 subdomainErrorMessage(sub_id, _elem_side_qp_functor);
307 return it->second(elem_side_qp, time);
315 const Elem *
const elem = elem_point_arg.
elem;
317 "The element must be non-null and non-remote in functor material properties");
318 auto it = _elem_point_functor.find(elem->subdomain_id());
319 if (it == _elem_point_functor.end())
320 subdomainErrorMessage(elem->subdomain_id(), _elem_point_functor);
322 return it->second(elem_point_arg, time);
330 mooseAssert(node_arg.
node,
"The node must be non-null in functor material properties");
332 mooseError(
"We do not currently support multi-subdomain evaluation of nodal arguments");
334 auto it = _node_functor.find(sub_id);
335 if (it == _node_functor.end())
336 subdomainErrorMessage(sub_id, _node_functor);
338 return it->second(node_arg, time);
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, 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::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.
State argument for evaluating functors.