19#include "libmesh/parallel_eigen.h"
35 "Prepare patches for use in nodal patch recovery based on a material property for material "
36 "property states projected onto nodal variables.");
40 { rm_params.
set<
unsigned short>(
"layers") = 2; });
45template <
typename T,
bool is_ad>
50 MooseEnum orders(
"CONSTANT FIRST SECOND THIRD FOURTH");
52 "property",
"Name of the material property to perform nodal patch recovery on");
54 "patch_polynomial_order",
56 "Polynomial order used in least squares fitting of material property "
57 "over the local patch of elements connected to a given node");
62 { rm_params.
set<
unsigned short>(
"layers") = 2; });
69template <
typename T,
bool is_ad>
74 _n_components(
Moose::SerialAccess<T>::size()),
75 _patch_polynomial_order(
76 static_cast<unsigned
int>(getParam<
MooseEnum>(
"patch_polynomial_order"))),
77 _multi_index(
MathUtils::multiIndex(_mesh.dimension(), _patch_polynomial_order)),
78 _q(_multi_index.size()),
79 _prop(getGenericMaterialProperty<T, is_ad>(
"property")),
80 _current_subdomain_id(_assembly.currentSubdomainID())
84template <
typename T,
bool is_ad>
89 _required_materials = buildRequiredMaterials();
92template <
typename T,
bool is_ad>
95 const Point & x,
const std::vector<dof_id_type> & elem_ids, std::size_t component)
const
98 if (_q_point.size() * elem_ids.size() < _q)
99 mooseError(
"There are not enough sample points to recover the nodal value, try reducing the "
100 "polynomial order or using a higher-order quadrature scheme.");
103 RealEigenMatrix A = RealEigenMatrix::Zero(_q, _q);
104 RealEigenVector b = RealEigenVector::Zero(_q);
105 for (
const auto elem_id : elem_ids)
107 const auto abs = libmesh_map_find(_abs, elem_id);
109 b += abs.second[component];
113 const RealEigenVector coef = A.completeOrthogonalDecomposition().solve(b);
116 const RealEigenVector p = evaluateBasisFunctions(x);
120template <
typename T,
bool is_ad>
123 const Point & q_point)
const
125 RealEigenVector p(_q);
127 for (
const auto r : index_range(_multi_index))
130 mooseAssert(_multi_index[r].size() == _mesh.dimension(),
"Wrong multi-index size.");
131 for (
const auto c : index_range(_multi_index[r]))
138template <
typename T,
bool is_ad>
145template <
typename T,
bool is_ad>
150 for (
const auto & mat : _required_materials[_current_subdomain_id])
151 mat->initStatefulProperties(_qrule->size());
153 std::vector<RealEigenVector> bs(_n_components, RealEigenVector::Zero(_q));
154 RealEigenMatrix Ae = RealEigenMatrix::Zero(_q, _q);
156 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
158 RealEigenVector p = evaluateBasisFunctions(_q_point[_qp]);
159 Ae += p * p.transpose();
161 std::size_t index = 0;
166 const dof_id_type elem_id = _current_elem->id();
167 _abs[elem_id] = {Ae, bs};
170template <
typename T,
bool is_ad>
176 _abs.insert(npr._abs.begin(), npr._abs.end());
179template <
typename T,
bool is_ad>
188 std::unordered_map<processor_id_type, std::vector<dof_id_type>> query_ids;
189 const ConstElemRange evaluable_elem_range = _fe_problem.getEvaluableElementRange();
190 for (
const auto *
const elem : evaluable_elem_range)
191 if (elem->processor_id() != processor_id())
192 query_ids[elem->processor_id()].push_back(elem->id());
195 auto gather_data = [
this](
const processor_id_type ,
196 const std::vector<dof_id_type> & elem_ids,
197 std::vector<ElementData> & abs_data)
199 for (
const auto i : index_range(elem_ids))
200 abs_data.emplace_back(libmesh_map_find(_abs, elem_ids[i]));
204 auto act_on_data = [
this](
const processor_id_type ,
205 const std::vector<dof_id_type> & elem_ids,
206 const std::vector<ElementData> & abs_data)
208 for (
const auto i : index_range(elem_ids))
209 _abs[elem_ids[i]] = abs_data[i];
212 libMesh::Parallel::pull_parallel_vector_data<ElementData>(
213 _communicator, query_ids, gather_data, act_on_data, 0);
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
registerMooseObject("MooseApp", ProjectedStatefulMaterialNodalPatchRecoveryReal)
void ErrorVector unsigned int
static InputParameters validParams()
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
static InputParameters validParams()
virtual Real nodalPatchRecovery(const Point &p, const std::vector< dof_id_type > &elem_ids, std::size_t component) const override
Solve the least-squares problem.
ProjectedStatefulMaterialNodalPatchRecoveryTempl(const InputParameters ¶meters)
virtual void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job.
virtual void finalize() override
Finalize.
virtual void threadJoin(const UserObject &) override
Must override.
virtual void execute() override
Execute method.
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
static InputParameters validParams()
RealEigenVector evaluateBasisFunctions(const Point &q_point) const
Compute the P vector at a given point i.e.
Base class for user-specific data.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
SerialAccessRange< T > serialAccess(T &obj)