www.mooseframework.org
SlopeLimitingBase.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "SlopeLimitingBase.h"
11 #include <unistd.h>
12 #include "libmesh/parallel.h"
13 #include "libmesh/parallel_algebra.h"
14 
15 // Static mutex definition
16 Threads::spin_mutex SlopeLimitingBase::_mutex;
17 
20 {
23 
24  params.addClassDescription(
25  "Base class for slope limiting to limit the slopes of cell average variables.");
26 
27  params.addParam<bool>("include_bc", true, "Indicate whether to include bc, default = true");
28 
29  return params;
30 }
31 
33  : ElementLoopUserObject(parameters),
34  _lslope(
35  declareRestartableData<std::map<dof_id_type, std::vector<RealGradient>>>("limited_slope")),
36  _include_bc(getParam<bool>("include_bc")),
37  _q_point_face(_assembly.qPointsFace()),
38  _qrule_face(_assembly.qRuleFace()),
39  _JxW_face(_assembly.JxWFace()),
40  _normals_face(_assembly.normals()),
41  _side(_assembly.side()),
42  _side_elem(_assembly.sideElem()),
43  _side_volume(_assembly.sideElemVolume()),
44  _neighbor_elem(_assembly.neighbor())
45 {
46 }
47 
48 void
50 {
52 
53  _lslope.clear();
54 }
55 
56 const std::vector<RealGradient> &
58 {
59  Threads::spin_mutex::scoped_lock lock(_mutex);
60  std::map<dof_id_type, std::vector<RealGradient>>::const_iterator pos = _lslope.find(elementid);
61 
62  if (pos == _lslope.end())
63  mooseError("Limited slope is not cached for element id '", elementid, "' in ", __FUNCTION__);
64 
65  return pos->second;
66 }
67 
68 void
70 {
71  dof_id_type _elementID = _current_elem->id();
72 
73  _lslope[_elementID] = limitElementSlope();
74 }
75 
76 void
77 SlopeLimitingBase::serialize(std::string & serialized_buffer)
78 {
79  std::ostringstream oss;
80 
81  // First store the number of elements to send
82  unsigned int size = _interface_elem_ids.size();
83  oss.write((char *)&size, sizeof(size));
84 
85  for (auto it = _interface_elem_ids.begin(); it != _interface_elem_ids.end(); ++it)
86  {
87  storeHelper(oss, *it, this);
88  storeHelper(oss, _lslope[*it], this);
89  }
90 
91  // Populate the passed in string pointer with the string stream's buffer contents
92  serialized_buffer.assign(oss.str());
93 }
94 
95 void
96 SlopeLimitingBase::deserialize(std::vector<std::string> & serialized_buffers)
97 {
98  // The input string stream used for deserialization
99  std::istringstream iss;
100 
101  mooseAssert(serialized_buffers.size() == _app.n_processors(),
102  "Unexpected size of serialized_buffers: " << serialized_buffers.size());
103 
104  for (auto rank = decltype(_app.n_processors())(0); rank < serialized_buffers.size(); ++rank)
105  {
106  if (rank == processor_id())
107  continue;
108 
109  iss.str(serialized_buffers[rank]); // populate the stream with a new buffer
110  iss.clear(); // reset the string stream state
111 
112  // Load the communicated data into all of the other processors' slots
113 
114  unsigned int size = 0;
115  iss.read((char *)&size, sizeof(size));
116 
117  for (unsigned int i = 0; i < size; i++)
118  {
119  dof_id_type key;
120  loadHelper(iss, key, this);
121 
122  std::vector<RealGradient> value;
123  loadHelper(iss, value, this);
124 
125  // merge the data we received from other procs
126  _lslope.insert(std::pair<dof_id_type, std::vector<RealGradient>>(key, value));
127  }
128  }
129 }
130 
131 void
133 {
135 
136  if (_app.n_processors() > 1)
137  {
138  std::vector<std::string> send_buffers(1);
139  std::vector<std::string> recv_buffers;
140 
141  recv_buffers.reserve(_app.n_processors());
142  serialize(send_buffers[0]);
143  comm().allgather_packed_range((void *)(nullptr),
144  send_buffers.begin(),
145  send_buffers.end(),
146  std::back_inserter(recv_buffers));
147  deserialize(recv_buffers);
148  }
149 }
virtual const std::vector< RealGradient > & getElementSlope(dof_id_type elementid) const
accessor function call
virtual void serialize(std::string &serialized_buffer)
A base class that loops over elements and do things.
static InputParameters validParams()
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
std::map< dof_id_type, std::vector< RealGradient > > & _lslope
store the updated slopes into this map indexed by element ID
virtual void finalize()
const Parallel::Communicator & comm() const
void allgather_packed_range(Context *context, Iter range_begin, const Iter range_end, OutputIter out, std::size_t approx_buffer_size=1000000) const
static InputParameters validParams()
static InputParameters validParams()
virtual void computeElement()
void storeHelper(std::ostream &stream, P &data, void *context)
processor_id_type n_processors() const
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
static Threads::spin_mutex _mutex
SlopeLimitingBase(const InputParameters &parameters)
virtual void deserialize(std::vector< std::string > &serialized_buffers)
std::set< dof_id_type > _interface_elem_ids
List of element IDs that are on the processor boundary and need to be send to other processors...
virtual void initialize()
virtual std::vector< RealGradient > limitElementSlope() const =0
compute the slope of the cell
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
processor_id_type processor_id() const
void loadHelper(std::istream &stream, P &data, void *context)
uint8_t dof_id_type