13#include "libmesh/compare_types.h"
14#include "libmesh/type_tensor.h"
15#include "libmesh/tensor_tools.h"
16#include "libmesh/dense_matrix.h"
17#include "libmesh/elem.h"
18#include "libmesh/point.h"
22template <typename T, typename T2, typename std::enable_if<ScalarTraits<T>::value,
int>::type = 0>
23inline TypeVector<typename libMesh::CompareTypes<T, T2>::supertype>
26 TypeVector<typename libMesh::CompareTypes<T, T2>::supertype> ret;
33template <
typename T,
typename T2>
34inline TypeTensor<typename libMesh::CompareTypes<T, T2>::supertype>
41template <
typename T,
typename Map>
67 using PrimitiveType =
typename MetaPhysicL::ReplaceAlgebraicType<
69 typename TensorTools::DecrementRank<typename MetaPhysicL::ValueType<T>::type>::type>::type;
73 const auto dim = _mesh.dimension();
76 DenseMatrix<PrimitiveType> n_x_Sf(
dim,
dim);
77 DenseVector<PrimitiveType> sum_normal_flux(
dim);
79 const Elem *
const elem = elem_arg.
elem;
81 for (
const auto side : make_range(elem->n_sides()))
88 const FaceInfo *
const fi = _mesh.faceInfo(
89 elem_has_fi ? elem : neighbor, elem_has_fi ? side : neighbor->which_neighbor_am_i(elem));
90 const Point & normal = elem_has_fi ? fi->
normal() : Point(-fi->
normal());
92 const Point area_vector = normal * fi->
faceArea();
97 const auto flux_contrib = normal * (face_value * area_vector);
98 for (
const auto i : make_range(
dim))
100 sum_normal_flux(i) += flux_contrib(i);
101 for (
const auto j : make_range(
dim))
102 n_x_Sf(i, j) += product(i, j);
108 DenseVector<PrimitiveType> dense_result(
dim);
109 n_x_Sf.cholesky_solve(sum_normal_flux, dense_result);
112 for (
const auto i : make_range(
dim))
113 result(i) = dense_result(i);
121 mooseError(
"Cell center reconstruction is not implemented!");
125template <
typename T,
typename Map>
132template <
typename T,
typename Map>
136 auto it = this->find(fi->
id());
137 if (it == this->end())
139 if (!_sub_ids.empty() && !_sub_ids.count(fi->
elem().subdomain_id()))
142 mooseError(
"Attempted to evaluate FaceCenteredMapFunctor '",
144 "' with an element subdomain id of '",
145 fi->
elem().subdomain_id(),
146 fi->
neighborPtr() ?
" or neighbor subdomain id of '" +
147 std::to_string(fi->
neighborPtr()->subdomain_id()) +
"'"
149 "' but that subdomain id is not one of the subdomain ids the functor is "
153 mooseError(
"Attempted access into FaceCenteredMapFunctor '",
155 "' with a key that does not yet exist in the map. Make sure to fill your "
156 "FaceCenteredMapFunctor for all elements you will attempt to access later.");
165 std::unordered_map<dof_id_type, ADRealVectorValue>>;
167 std::unordered_map<dof_id_type, RealVectorValue>>;
void mooseError(Args &&... args)
T evaluate(Real, const Point &)
A functor whose evaluation relies on querying a map where the keys are face info ids and the values c...
ValueType evaluate(const FaceInfo *const fi) const
Evaluate the face functor using a FaceInfo argument.
const Point & normal() const
const Elem & elem() const
const Elem * neighborPtr() const
const Elem * neighbor_ptr(unsigned int i) const
bool elemHasFaceInfo(const Elem &elem, const Elem *const neighbor)
static constexpr std::size_t dim
TypeVector< typename libMesh::CompareTypes< T, T2 >::supertype > outer_product(const T &a, const TypeVector< T2 > &b)
TypeTensor< typename CompareTypes< T, T2 >::supertype > outer_product(const TypeVector< T > &a, const TypeVector< T2 > &b)
const libMesh::Elem * elem