https://mooseframework.inl.gov
ComputeLinearFVGreenGaussGradientVolumeThread.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 #include "LinearSystem.h"
13 #include "PetscVectorReader.h"
14 #include "FEProblemBase.h"
15 
17  FEProblemBase & fe_problem, const unsigned int linear_system_num)
18  : _fe_problem(fe_problem),
19  _dim(_fe_problem.mesh().dimension()),
20  _linear_system_number(linear_system_num),
21  _linear_system(libMesh::cast_ref<libMesh::LinearImplicitSystem &>(
22  _fe_problem.getLinearSystem(_linear_system_number).system())),
23  _system_number(_linear_system.number())
24 {
25 }
26 
29  : _fe_problem(x._fe_problem),
30  _dim(x._dim),
31  _linear_system_number(x._linear_system_number),
32  _linear_system(x._linear_system),
33  _system_number(x._system_number)
34 {
35 }
36 
37 void
39 {
40  ParallelUniqueId puid;
41  _tid = puid.id;
42 
43  auto & linear_system = _fe_problem.getLinearSystem(_linear_system_number);
44 
45  // This will be the vector we work on since the old gradient might still be needed
46  // to compute extrapolated boundary conditions for example.
47  auto & grad_container = linear_system.newGradientContainer();
48 
49  // Computing this size can be very expensive so we only want to do it once
50  unsigned int size = 0;
51 
52  for (const auto & variable : linear_system.getVariables(_tid))
53  {
54  _current_var = dynamic_cast<MooseLinearVariableFV<Real> *>(variable);
55  mooseAssert(_current_var,
56  "This should be a linear FV variable, did we somehow add a nonlinear variable to "
57  "the linear system?");
59  {
60  if (!size)
61  size = range.size();
62 
63  const auto rz_radial_coord = _fe_problem.mesh().getAxisymmetricRadialCoord();
64  const auto state = Moose::currentState();
65 
66  std::vector<std::vector<Real>> new_values(grad_container.size(),
67  std::vector<Real>(size, 0.0));
68  std::vector<dof_id_type> dof_indices(size, 0);
69  {
70  std::vector<PetscVectorReader> grad_reader;
71  for (const auto dim_index : index_range(grad_container))
72  grad_reader.emplace_back(*grad_container[dim_index]);
73 
74  // Iterate over all the elements in the range
75  auto elem_iterator = range.begin();
76  for (const auto elem_i : make_range(size))
77  {
78  const auto & elem_info = *elem_iterator;
79  if (_current_var->hasBlocks(elem_info->subdomain_id()))
80  {
81  const auto coord_type = _fe_problem.mesh().getCoordSystem(elem_info->subdomain_id());
82 
83  mooseAssert(coord_type != Moose::CoordinateSystemType::COORD_RSPHERICAL,
84  "We have not yet implemented the correct translation from gradient to "
85  "divergence for "
86  "spherical coordinates yet.");
87 
88  dof_indices[elem_i] = elem_info->dofIndices()[_system_number][_current_var->number()];
89  const auto volume = elem_info->volume() * elem_info->coordFactor();
90 
91  for (const auto dim_index : index_range(grad_container))
92  new_values[dim_index][elem_i] = grad_reader[dim_index](dof_indices[elem_i]) / volume;
93 
94  if (coord_type == Moose::CoordinateSystemType::COORD_RZ)
95  {
96  const auto radial_contrib = _current_var->getElemValue(*elem_info, state) /
97  elem_info->centroid()(rz_radial_coord);
98  new_values[rz_radial_coord][elem_i] += radial_contrib;
99  }
100  }
101  elem_iterator++;
102  }
103  }
104  for (const auto dim_index : index_range(grad_container))
105  {
106  grad_container[dim_index]->zero();
107  grad_container[dim_index]->add_vector(new_values[dim_index].data(), dof_indices);
108  }
109  }
110  }
111 }
112 
113 void
116 {
117 }
StoredRange< MooseMesh::const_elem_info_iterator, const ElemInfo * > ElemInfoRange
unsigned int number() const
Get variable number coming from libMesh.
The gradient in a volume using Green Gauss theorem and a cell-centered finite-volume approximation ca...
std::vector< std::unique_ptr< NumericVector< Number > > > & newGradientContainer()
Return a reference to the new (temporary) gradient container vectors.
Definition: LinearSystem.h:137
Tnew cast_ref(Told &oldvar)
MeshBase & mesh
const unsigned int _linear_system_number
The number of the linear system on which this thread is acting.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
unsigned int getAxisymmetricRadialCoord() const
Returns the desired radial direction for RZ coordinate transformation.
Definition: MooseMesh.C:4263
void operator()(const ElemInfoRange &range)
Operator which is used to execute the thread over a certain iterator range.
MooseLinearVariableFV< Real > * _current_var
Pointer to the current variable.
Moose::CoordinateSystemType getCoordSystem(SubdomainID sid) const
Get the coordinate system type, e.g.
Definition: MooseMesh.C:4144
Real volume(const MeshBase &mesh, unsigned int dim=libMesh::invalid_uint)
LinearSystem & getLinearSystem(unsigned int sys_num)
Get non-constant reference to a linear system.
ComputeLinearFVGreenGaussGradientVolumeThread(FEProblemBase &fe_problem, const unsigned int linear_system_num)
Class constructor.
bool hasBlocks(const SubdomainID id) const override
Returns whether the functor is defined on this block.
Real getElemValue(const ElemInfo &elem_info, const StateArg &state) const
Get the solution value for the provided element and seed the derivative for the corresponding dof ind...
void join(const ComputeLinearFVGreenGaussGradientVolumeThread &y)
Join threads at the end of the execution.
IntRange< T > make_range(T beg, T end)
virtual MooseMesh & mesh() override
virtual bool needsGradientVectorStorage() const override
Check if cell gradient computations were requested for this variable.
StateArg currentState()
auto index_range(const T &sizable)