https://mooseframework.inl.gov
ComputeLinearFVLimitedGradientThread.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 
11 
12 #include "GradientLimiterType.h"
13 #include "SystemBase.h"
14 #include "PetscVectorReader.h"
15 #include "FEProblemBase.h"
16 #include "FVUtils.h"
17 
18 #include "libmesh/dof_object.h"
19 
20 #include <algorithm>
21 #include <cmath>
22 #include <limits>
23 
25  FEProblemBase & fe_problem,
26  SystemBase & system,
27  const std::vector<std::unique_ptr<NumericVector<Number>>> & raw_gradient,
28  std::vector<std::unique_ptr<NumericVector<Number>>> & temporary_limited_gradient,
29  const Moose::FV::GradientLimiterType limiter_type,
30  const std::unordered_set<unsigned int> & requested_variables)
31  : _fe_problem(fe_problem),
32  _dim(_fe_problem.mesh().dimension()),
33  _system(system),
34  _libmesh_system(system.system()),
35  _system_number(_libmesh_system.number()),
36  _raw_gradient(raw_gradient),
37  _limiter_type(limiter_type),
38  _requested_variables(requested_variables),
39  _temporary_limited_gradient(temporary_limited_gradient)
40 {
41 }
42 
45  : _fe_problem(x._fe_problem),
46  _dim(x._dim),
47  _system(x._system),
48  _libmesh_system(x._libmesh_system),
49  _system_number(x._system_number),
50  _raw_gradient(x._raw_gradient),
51  _limiter_type(x._limiter_type),
52  _requested_variables(x._requested_variables),
53  _temporary_limited_gradient(x._temporary_limited_gradient)
54 {
55 }
56 
57 void
59 {
60  ParallelUniqueId puid;
61  _tid = puid.id;
62 
63  const auto & raw_grad_container = _raw_gradient;
64 
66  mooseError("ComputeLinearFVLimitedGradientThread currently supports only the Venkatakrishnan "
67  "limiter.");
68 
69  unsigned int size = 0;
70 
71  for (const auto & variable : _system.getVariables(_tid))
72  {
73  _current_var = dynamic_cast<MooseLinearVariableFV<Real> *>(variable);
74  if (!_current_var)
75  continue;
76 
78  continue;
79 
81  continue;
82 
83  if (!size)
84  size = range.size();
85 
86  std::vector<std::vector<Real>> temporary_values(_temporary_limited_gradient.size(),
87  std::vector<Real>(size, 0.0));
88  std::vector<dof_id_type> dof_indices(size, 0);
89 
91  std::vector<PetscVectorReader> grad_reader;
92  grad_reader.reserve(raw_grad_container.size());
93  for (const auto dim_index : index_range(raw_grad_container))
94  grad_reader.emplace_back(*raw_grad_container[dim_index]);
95 
96  mooseAssert(raw_grad_container.size() >= _dim,
97  "Raw gradient container has fewer components than mesh dimension.");
98  mooseAssert(_temporary_limited_gradient.size() >= _dim,
99  "Limited gradient container has fewer components than mesh dimension.");
100 
101  auto elem_iterator = range.begin();
102  for (const auto elem_i : make_range(size))
103  {
104  const auto & elem_info = *elem_iterator;
105  elem_iterator++;
106 
107  if (!_current_var->hasBlocks(elem_info->subdomain_id()))
108  continue;
109 
110  const dof_id_type dof = elem_info->dofIndices()[_system_number][_current_var->number()];
112  continue;
113 
114  dof_indices[elem_i] = dof;
115 
116  const Real phi_elem = solution_reader(dof);
117  Real max_value = phi_elem;
118  Real min_value = phi_elem;
119 
120  // Gather one-ring min/max values.
121  const Elem * const elem = elem_info->elem();
122  for (const auto side : make_range(elem->n_sides()))
123  {
124  const Elem * const neighbor = elem->neighbor_ptr(side);
125  if (!neighbor)
126  continue;
127 
128  const auto & neighbor_info = _fe_problem.mesh().elemInfo(neighbor->id());
129  if (!_current_var->hasBlocks(neighbor_info.subdomain_id()))
130  continue;
131 
132  const dof_id_type neighbor_dof =
133  neighbor_info.dofIndices()[_system_number][_current_var->number()];
134  if (neighbor_dof == libMesh::DofObject::invalid_id)
135  continue;
136 
137  const Real phi_neighbor = solution_reader(neighbor_dof);
138  max_value = std::max(max_value, phi_neighbor);
139  min_value = std::min(min_value, phi_neighbor);
140  }
141 
142  // Read the raw cell gradient.
143  VectorValue<Real> raw_grad;
144  raw_grad.zero();
145  for (const auto dim_index : make_range(_dim))
146  raw_grad(dim_index) = grad_reader[dim_index](dof);
147 
148  // If the stencil is constant (or nearly constant), don't attempt to limit.
149  if (std::abs(max_value - min_value) < 1e-14)
150  {
151  for (const auto dim_index : make_range(_dim))
152  temporary_values[dim_index][elem_i] = raw_grad(dim_index);
153  continue;
154  }
155 
156  Real alpha = 1.0;
157  const Point & elem_centroid = elem_info->centroid();
158 
159  for (const auto side : make_range(elem->n_sides()))
160  {
161  const Elem * const neighbor = elem->neighbor_ptr(side);
162  if (!neighbor)
163  continue;
164 
165  const auto & neighbor_info = _fe_problem.mesh().elemInfo(neighbor->id());
166  if (!_current_var->hasBlocks(neighbor_info.subdomain_id()))
167  continue;
168 
169  const dof_id_type neighbor_dof =
170  neighbor_info.dofIndices()[_system_number][_current_var->number()];
171  if (neighbor_dof == libMesh::DofObject::invalid_id)
172  continue;
173 
174  const bool elem_has_face_info = Moose::FV::elemHasFaceInfo(*elem, neighbor);
175  const Elem * const fi_elem = elem_has_face_info ? elem : neighbor;
176  const unsigned int fi_side =
177  elem_has_face_info ? side : neighbor->which_neighbor_am_i(elem);
178  const auto * fi = _fe_problem.mesh().faceInfo(fi_elem, fi_side);
179  mooseAssert(fi,
180  "Missing FaceInfo for neighboring elements with centroid " +
181  Moose::stringify(elem_info->centroid()) + " and " +
182  Moose::stringify(neighbor->vertex_average()) +
183  " while computing limited gradients.");
184 
185  const Point face_point = fi->faceCentroid();
186 
187  const Real delta_face = raw_grad * (face_point - elem_centroid);
188 
189  Real h = elem->hmin();
190  Real grad_mag = raw_grad.norm();
191 
192  Real eps = 0.1 * (grad_mag * h) * (grad_mag * h) + 1e-20;
193 
194  const Real delta_max = std::abs(max_value - phi_elem) + eps;
195  const Real delta_min = std::abs(min_value - phi_elem) + eps;
196 
197  const Real rf = (delta_face >= 0.0) ? std::abs(delta_face) / delta_max
198  : std::abs(delta_face) / delta_min;
199 
200  const Real beta = (2.0 * rf + 1.0) / (rf * (2.0 * rf + 1.0) + 1.0);
201  alpha = std::min(alpha, beta);
202  }
203 
204  const VectorValue<Real> limited_grad = alpha * raw_grad;
205  for (const auto dim_index : make_range(_dim))
206  temporary_values[dim_index][elem_i] = limited_grad(dim_index);
207  }
208 
209  for (const auto dim_index : make_range(_dim))
210  {
211  _temporary_limited_gradient[dim_index]->add_vector(temporary_values[dim_index].data(),
212  dof_indices);
213  }
214  }
215 }
216 
217 void
219 {
220 }
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:50
const std::vector< MooseVariableFieldBase * > & getVariables(THREAD_ID tid)
Definition: SystemBase.h:752
GradientLimiterType
Cell-gradient limiter variants used for MUSCL-style reconstructions.
bool elemHasFaceInfo(const Elem &elem, const Elem *const neighbor)
This function infers based on elements if the faceinfo between them belongs to the element or not...
Definition: FVUtils.C:21
int eps(unsigned int i, unsigned int j)
2D version
auto norm() const
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
unsigned int number() const
Get variable number coming from libMesh.
const libMesh::System & _libmesh_system
Reference to the libMesh system backing the wrapper system.
MeshBase & mesh
ComputeLinearFVLimitedGradientThread(FEProblemBase &fe_problem, SystemBase &system, const std::vector< std::unique_ptr< NumericVector< Number >>> &raw_gradient, std::vector< std::unique_ptr< NumericVector< Number >>> &temporary_limited_gradient, const Moose::FV::GradientLimiterType limiter_type, const std::unordered_set< unsigned int > &requested_variables)
Class constructor.
Compute limited cell gradients for linear FV variables.
Base class for a system (of equations)
Definition: SystemBase.h:85
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
const std::unordered_set< unsigned int > & _requested_variables
Variable numbers that requested the current limiter.
auto max(const L &left, const R &right)
void join(const ComputeLinearFVLimitedGradientThread &y)
Join threads at the end of the execution.
const unsigned int _system_number
Global system number in the libMesh equation system.
const std::vector< const FaceInfo * > & faceInfo() const
Accessor for local FaceInfo objects.
Definition: MooseMesh.h:2332
FEProblemBase & _fe_problem
Reference to the problem.
std::vector< std::unique_ptr< NumericVector< Number > > > & _temporary_limited_gradient
Reference to the temporary limited gradient storage.
static constexpr dof_id_type invalid_id
A class which helps with repeated reading from a petsc vector.
const Moose::FV::GradientLimiterType _limiter_type
The type of the limiter we requested.
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
void operator()(const ElemInfoRange &range)
Operator which is used to execute the thread over a certain iterator range.
const std::vector< std::vector< dof_id_type > > & dofIndices() const
Definition: ElemInfo.h:39
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool hasBlocks(const SubdomainID id) const override
Returns whether the functor is defined on this block.
SystemBase & _system
The system wrapper this thread operates on.
IntRange< T > make_range(T beg, T end)
virtual MooseMesh & mesh() override
std::unique_ptr< NumericVector< Number > > current_local_solution
Venkatakrishnan limiter (smooth, multidimensional).
virtual bool needsGradientVectorStorage() const override
Check if cell gradient computations were requested for this variable.
const unsigned int _dim
The dimension of the domain.
StoredRange< MooseMesh::const_elem_info_iterator, const ElemInfo * > ElemInfoRange
MooseLinearVariableFV< Real > * _current_var
Pointer to the current variable we are operating on.
auto min(const L &left, const R &right)
auto index_range(const T &sizable)
const ElemInfo & elemInfo(const dof_id_type id) const
Accessor for the elemInfo object for a given element ID.
Definition: MooseMesh.C:4018
uint8_t dof_id_type
const std::vector< std::unique_ptr< NumericVector< Number > > > & _raw_gradient
Reference to the raw gradient storage used as input for limiting.