https://mooseframework.inl.gov
Loading...
Searching...
No Matches
FunctorSmoother.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "FunctorSmoother.h"
11#include "MooseUtils.h"
12#include "RelationshipManager.h"
13
14#include "metaphysicl/raw_type.h"
15
17
18template <typename T>
21{
23 params.addClassDescription("Creates smoother functor(s) using various averaging techniques");
24 params.addParam<std::vector<MooseFunctorName>>("functors_in",
25 "The name(s) of the functors to smooth");
26 params.addParam<std::vector<MooseFunctorName>>("functors_out",
27 "The name(s) of the smooth output functors");
28 MooseEnum smoothing_techniques("face_average layered_elem_average remove_checkerboard");
29 params.addParam<MooseEnum>(
30 "smoothing_technique", smoothing_techniques, "How to smooth the functor");
31
32 return params;
33}
34
35template <typename T>
37 : FunctorMaterial(parameters),
38 _functors_in(getParam<std::vector<MooseFunctorName>>("functors_in")),
39 _functors_out(getParam<std::vector<MooseFunctorName>>("functors_out")),
40 _smoothing_technique(getParam<MooseEnum>("smoothing_technique"))
41{
42 if (_tid == 0)
43 {
44 // We need one layer of ghosting at least to get neighbor values
45 auto & factory = _app.getFactory();
46 auto rm_params = factory.getValidParams("ElementSideNeighborLayers");
47 rm_params.template set<std::string>("for_whom") = name();
48 rm_params.template set<MooseMesh *>("mesh") = &const_cast<MooseMesh &>(_mesh);
49 rm_params.template set<Moose::RelationshipManagerType>("rm_type") =
52 rm_params.template set<unsigned short>("layers") = 1;
53 rm_params.template set<bool>("use_point_neighbors") = false;
54 rm_params.template set<bool>("use_displaced_mesh") =
55 parameters.template get<bool>("use_displaced_mesh");
56 mooseAssert(rm_params.areAllRequiredParamsValid(),
57 "All relationship manager parameters should be valid.");
58 auto rm_obj = factory.template create<RelationshipManager>(
59 "ElementSideNeighborLayers", name() + "_functor_smoothing", rm_params);
60
61 // Delete the resources created on behalf of the RM if it ends up not being added to the
62 // App.
63 if (!_app.addRelationshipManager(rm_obj))
64 factory.releaseSharedObjects(*rm_obj);
65 }
66
67 const std::set<ExecFlagType> clearance_schedule(_execute_enum.begin(), _execute_enum.end());
68
69 for (const auto i : index_range(_functors_in))
70 {
71 // This potentially upcasts functors from non-AD to AD
72 const auto & functor_in = getFunctor<typename Moose::ADType<T>::type>(_functors_in[i]);
73
74 // We always add the AD type
75 addFunctorProperty<typename Moose::ADType<T>::type>(
77 [this, &functor_in](const auto & r, const auto & t) -> typename Moose::ADType<T>::type
78 {
79 typename Moose::ADType<T>::type base_value = functor_in(r, t);
80 typename Moose::ADType<T>::type average = 0;
81 using std::abs;
82
83 const Elem * r_elem = nullptr;
84 if constexpr (std::is_same_v<const Moose::ElemArg &, decltype(r)>)
85 r_elem = r.elem;
86
87 // Handle the single isolated element case
88 if (r_elem && r_elem->n_neighbors() == 0)
89 return base_value;
90
91 // If these techniques are of interest elsewhere, they should be moved to a
92 // FunctorAveragingUtils file and namespaced
94 {
95 if constexpr (std::is_same_v<const Moose::ElemArg &, decltype(r)>)
96 {
97 unsigned int n_faces = 0;
98 for (const auto side_index : r_elem->side_index_range())
99 {
100 auto fi = _mesh.faceInfo(r_elem, side_index);
101 if (!fi)
102 fi =
103 _mesh.faceInfo(r_elem->neighbor_ptr(side_index),
104 r_elem->neighbor_ptr(side_index)->which_neighbor_am_i(r_elem));
105 Moose::FaceArg face_arg{
106 fi, Moose::FV::LimiterType::CentralDifference, true, false, nullptr, nullptr};
107 if (face_arg.fi)
108 {
109 average += functor_in(face_arg, t);
110 n_faces++;
111 }
112 }
113 average /= n_faces;
114 }
115 else
116 // a conceptually simple option here would be to use the smoothed version of the
117 // ElemArg to compute all the other functor arguments. Maybe with the same smoothing
118 // on the gradient calls
119 mooseError("Face averaging smoothing has only been defined for the ElemArg functor "
120 "argument, not for ",
122 ". Please contact a MOOSE developer or implement it yourself.");
123 }
125 {
126 if constexpr (std::is_same_v<const Moose::ElemArg &, decltype(r)>)
127 {
128 unsigned int n_neighbors = 0;
129 for (const auto neighbor : r_elem->neighbor_ptr_range())
130 if (neighbor)
131 {
132 n_neighbors++;
133 average += functor_in(Moose::ElemArg{neighbor, false}, t);
134 }
135 average /= n_neighbors;
136 }
137 else
138 mooseError("Element layered averaging smoothing has only been defined for the "
139 "ElemArg functor argument, not for ",
141 ". Please contact a MOOSE developer or implement it yourself.");
142 }
143 else
144 {
145 if constexpr (std::is_same_v<const Moose::ElemArg &, decltype(r)>)
146 {
147 // We average the local value with the average of the two values furthest away
148 // among the neighbors. For a checkerboarding but overall linear evolution, this will
149 // compute the average of the "high" and "low" profiles
150 average += base_value / 2;
151
152 // Find the neighbor with the furthest value
153 typename Moose::ADType<T>::type extreme_value = 0;
154 typename Moose::ADType<T>::type delta = 0;
155
156 unsigned int furthest_one = 0;
157 unsigned int num_neighbors = 0;
158 for (const auto side_index : r_elem->side_index_range())
159 {
160 auto neighbor = r_elem->neighbor_ptr(side_index);
161 if (neighbor)
162 {
163 num_neighbors++;
164 auto neighbor_value = functor_in(Moose::ElemArg{neighbor, false}, t);
165 if (abs(neighbor_value - base_value) > delta)
166 {
167 furthest_one = side_index;
168 extreme_value = neighbor_value;
169 delta = abs(neighbor_value - base_value);
170 }
171 }
172 }
173
174 // We're on a boundary in 1D, or maybe an odd shape corner in 2D
175 if (num_neighbors == 1)
176 {
177 average += extreme_value / 2;
178 return average;
179 }
180 else
181 average += extreme_value / 4;
182
183 // Get the value from the neighbor opposite the furthest-value neighbor
184 try
185 {
186 auto opposite_side = r_elem->opposite_side(furthest_one);
187 auto neighbor = r_elem->neighbor_ptr(opposite_side);
188 if (neighbor)
189 {
190 average += functor_in(Moose::ElemArg{neighbor, false}, t) / 4;
191 }
192 else
193 // We're probably at a boundary
194 average += extreme_value / 4;
195 }
196 // if there is no opposite side (for example a triangle)
197 catch (libMesh::LogicError & e)
198 {
199 // find the second furthest
200 delta = 0;
201 typename Moose::ADType<T>::type second_extreme_value = 0;
202
203 for (const auto side_index : r_elem->side_index_range())
204 {
205 auto neighbor = r_elem->neighbor_ptr(side_index);
206 auto neighbor_value =
207 neighbor ? functor_in(Moose::ElemArg{neighbor, false}, t) : base_value;
208 if (abs(neighbor_value - base_value) > delta && side_index != furthest_one)
209 {
210 second_extreme_value = neighbor_value;
211 delta = abs(neighbor_value - base_value);
212 }
213 }
214 average += second_extreme_value / 4;
215 }
216 }
217 else
218 mooseError("Checkerboard removal smoothing has only been defined for the "
219 "ElemArg functor argument, not for ",
221 ". Please contact a MOOSE developer or implement it yourself.");
222 }
223 return average;
224 },
225 clearance_schedule);
226 }
227}
228
229template class FunctorSmootherTempl<Real>;
registerMooseObject("MooseApp", FunctorSmoother)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
Definition Factory.C:68
FunctorMaterials compute functor material properties.
static InputParameters validParams()
This functor material smooths a functor material property.
const std::vector< MooseFunctorName > _functors_in
Incoming functor(s) names.
const std::vector< MooseFunctorName > _functors_out
Smoothed functor(s) names.
static InputParameters validParams()
FunctorSmootherTempl(const InputParameters &parameters)
const MooseEnum _smoothing_technique
Smoothing technique to use.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
THREAD_ID _tid
MooseMesh & _mesh
bool addRelationshipManager(std::shared_ptr< RelationshipManager > relationship_manager)
Transfers ownership of a RelationshipManager to the application for lifetime management.
Definition MooseApp.C:2991
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
Definition MooseApp.h:407
const InputParameters & parameters() const
Get the parameters of the object.
Definition MooseBase.h:131
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition MooseMesh.h:95
const std::vector< const FaceInfo * > & faceInfo() const
Accessor for local FaceInfo objects.
Definition MooseMesh.h:2349
MooseApp & _app
The MOOSE application this is associated with.
Definition MooseBase.h:375
MooseEnumIterator end() const
MooseEnumIterator begin() const
Returns a begin/end iterator to all of the set values in the enum.
const ExecFlagEnum & _execute_enum
Execute settings for this object.
std::string prettyCppType(const std::string &cpp_type)
A structure that is used to evaluate Moose functors logically at an element/cell center.
A structure defining a "face" evaluation calling argument for Moose functors.