Line data Source code
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 "SlopeReconstructionBase.h"
11 :
12 : // Static mutex definition
13 : Threads::spin_mutex SlopeReconstructionBase::_mutex;
14 :
15 : InputParameters
16 0 : SlopeReconstructionBase::validParams()
17 : {
18 0 : InputParameters params = ElementLoopUserObject::validParams();
19 0 : params.addClassDescription("Base class for piecewise linear slope reconstruction to get the "
20 : "slopes of element average variables.");
21 0 : return params;
22 0 : }
23 :
24 0 : SlopeReconstructionBase::SlopeReconstructionBase(const InputParameters & parameters)
25 : : ElementLoopUserObject(parameters),
26 0 : _rslope(declareRestartableData<std::map<dof_id_type, std::vector<RealGradient>>>(
27 : "reconstructed_slopes")),
28 0 : _avars(declareRestartableData<std::map<dof_id_type, std::vector<Real>>>("avg_var_values")),
29 0 : _bnd_avars(
30 0 : declareRestartableData<std::map<std::pair<dof_id_type, unsigned int>, std::vector<Real>>>(
31 : "avg_bnd_var_values")),
32 0 : _side_centroid(declareRestartableData<std::map<std::pair<dof_id_type, dof_id_type>, Point>>(
33 : "side_centroid")),
34 0 : _bnd_side_centroid(
35 0 : declareRestartableData<std::map<std::pair<dof_id_type, unsigned int>, Point>>(
36 : "bnd_side_centroid")),
37 0 : _side_area(
38 0 : declareRestartableData<std::map<std::pair<dof_id_type, dof_id_type>, Real>>("side_area")),
39 0 : _bnd_side_area(declareRestartableData<std::map<std::pair<dof_id_type, unsigned int>, Real>>(
40 : "bnd_side_area")),
41 0 : _side_normal(declareRestartableData<std::map<std::pair<dof_id_type, dof_id_type>, Point>>(
42 : "side_normal")),
43 0 : _bnd_side_normal(declareRestartableData<std::map<std::pair<dof_id_type, unsigned int>, Point>>(
44 : "bnd_side_normal")),
45 0 : _q_point_face(_assembly.qPointsFace()),
46 0 : _qrule_face(_assembly.qRuleFace()),
47 0 : _JxW_face(_assembly.JxWFace()),
48 0 : _normals_face(_assembly.normals()),
49 0 : _side(_assembly.side()),
50 0 : _side_elem(_assembly.sideElem()),
51 0 : _side_volume(_assembly.sideElemVolume()),
52 0 : _neighbor_elem(_assembly.neighbor()),
53 0 : _side_geoinfo_cached(false)
54 : {
55 0 : }
56 :
57 : void
58 0 : SlopeReconstructionBase::initialize()
59 : {
60 0 : ElementLoopUserObject::initialize();
61 :
62 0 : _rslope.clear();
63 0 : _avars.clear();
64 0 : }
65 :
66 : void
67 0 : SlopeReconstructionBase::finalize()
68 : {
69 0 : ElementLoopUserObject::finalize();
70 :
71 0 : if (_app.n_processors() > 1)
72 : {
73 0 : _side_geoinfo_cached = true;
74 :
75 0 : std::vector<std::string> send_buffers(1);
76 : std::vector<std::string> recv_buffers;
77 :
78 0 : recv_buffers.reserve(_app.n_processors());
79 0 : serialize(send_buffers[0]);
80 0 : comm().allgather_packed_range((void *)(nullptr),
81 : send_buffers.begin(),
82 : send_buffers.end(),
83 : std::back_inserter(recv_buffers));
84 0 : deserialize(recv_buffers);
85 0 : }
86 0 : }
87 :
88 : void
89 0 : SlopeReconstructionBase::meshChanged()
90 : {
91 0 : ElementLoopUserObject::meshChanged();
92 :
93 0 : _side_geoinfo_cached = false;
94 0 : _side_centroid.clear();
95 0 : _bnd_side_centroid.clear();
96 0 : _side_normal.clear();
97 0 : _bnd_side_normal.clear();
98 0 : _side_area.clear();
99 0 : _bnd_side_area.clear();
100 0 : }
101 :
102 : const std::vector<RealGradient> &
103 0 : SlopeReconstructionBase::getElementSlope(dof_id_type elementid) const
104 : {
105 : Threads::spin_mutex::scoped_lock lock(_mutex);
106 0 : std::map<dof_id_type, std::vector<RealGradient>>::const_iterator pos = _rslope.find(elementid);
107 :
108 0 : if (pos == _rslope.end())
109 0 : mooseError(
110 : "Reconstructed slope is not cached for element id '", elementid, "' in ", __FUNCTION__);
111 :
112 0 : return pos->second;
113 : }
114 :
115 : const std::vector<Real> &
116 0 : SlopeReconstructionBase::getElementAverageValue(dof_id_type elementid) const
117 : {
118 : Threads::spin_mutex::scoped_lock lock(_mutex);
119 0 : std::map<dof_id_type, std::vector<Real>>::const_iterator pos = _avars.find(elementid);
120 :
121 0 : if (pos == _avars.end())
122 0 : mooseError("Average variable values are not cached for element id '",
123 : elementid,
124 : "' in ",
125 : __FUNCTION__);
126 :
127 0 : return pos->second;
128 : }
129 :
130 : const std::vector<Real> &
131 0 : SlopeReconstructionBase::getBoundaryAverageValue(dof_id_type elementid, unsigned int side) const
132 : {
133 : Threads::spin_mutex::scoped_lock lock(_mutex);
134 : std::map<std::pair<dof_id_type, unsigned int>, std::vector<Real>>::const_iterator pos =
135 0 : _bnd_avars.find(std::pair<dof_id_type, unsigned int>(elementid, side));
136 :
137 0 : if (pos == _bnd_avars.end())
138 0 : mooseError("Average variable values are not cached for element id '",
139 : elementid,
140 : "' and side '",
141 : side,
142 : "' in ",
143 : __FUNCTION__);
144 :
145 0 : return pos->second;
146 : }
147 :
148 : const Point &
149 0 : SlopeReconstructionBase::getSideCentroid(dof_id_type elementid, dof_id_type neighborid) const
150 : {
151 : Threads::spin_mutex::scoped_lock lock(_mutex);
152 : std::map<std::pair<dof_id_type, dof_id_type>, Point>::const_iterator pos =
153 0 : _side_centroid.find(std::pair<dof_id_type, dof_id_type>(elementid, neighborid));
154 :
155 0 : if (pos == _side_centroid.end())
156 0 : mooseError("Side centroid values are not cached for element id '",
157 : elementid,
158 : "' and neighbor id '",
159 : neighborid,
160 : "' in ",
161 : __FUNCTION__);
162 :
163 0 : return pos->second;
164 : }
165 :
166 : const Point &
167 0 : SlopeReconstructionBase::getBoundarySideCentroid(dof_id_type elementid, unsigned int side) const
168 : {
169 : Threads::spin_mutex::scoped_lock lock(_mutex);
170 : std::map<std::pair<dof_id_type, unsigned int>, Point>::const_iterator pos =
171 0 : _bnd_side_centroid.find(std::pair<dof_id_type, unsigned int>(elementid, side));
172 :
173 0 : if (pos == _bnd_side_centroid.end())
174 0 : mooseError("Boundary side centroid values are not cached for element id '",
175 : elementid,
176 : "' and side '",
177 : side,
178 : "' in ",
179 : __FUNCTION__);
180 :
181 0 : return pos->second;
182 : }
183 :
184 : const Point &
185 0 : SlopeReconstructionBase::getSideNormal(dof_id_type elementid, dof_id_type neighborid) const
186 : {
187 : Threads::spin_mutex::scoped_lock lock(_mutex);
188 : std::map<std::pair<dof_id_type, dof_id_type>, Point>::const_iterator pos =
189 0 : _side_normal.find(std::pair<dof_id_type, dof_id_type>(elementid, neighborid));
190 :
191 0 : if (pos == _side_normal.end())
192 0 : mooseError("Side normal values are not cached for element id '",
193 : elementid,
194 : "' and neighbor id '",
195 : neighborid,
196 : "' in ",
197 : __FUNCTION__);
198 :
199 0 : return pos->second;
200 : }
201 :
202 : const Point &
203 0 : SlopeReconstructionBase::getBoundarySideNormal(dof_id_type elementid, unsigned int side) const
204 : {
205 : Threads::spin_mutex::scoped_lock lock(_mutex);
206 : std::map<std::pair<dof_id_type, unsigned int>, Point>::const_iterator pos =
207 0 : _bnd_side_normal.find(std::pair<dof_id_type, unsigned int>(elementid, side));
208 :
209 0 : if (pos == _bnd_side_normal.end())
210 0 : mooseError("Boundary side normal values are not cached for element id '",
211 : elementid,
212 : "' and side '",
213 : side,
214 : "' in ",
215 : __FUNCTION__);
216 :
217 0 : return pos->second;
218 : }
219 :
220 : const Real &
221 0 : SlopeReconstructionBase::getSideArea(dof_id_type elementid, dof_id_type neighborid) const
222 : {
223 : Threads::spin_mutex::scoped_lock lock(_mutex);
224 : std::map<std::pair<dof_id_type, dof_id_type>, Real>::const_iterator pos =
225 0 : _side_area.find(std::pair<dof_id_type, dof_id_type>(elementid, neighborid));
226 :
227 0 : if (pos == _side_area.end())
228 0 : mooseError("Side area values are not cached for element id '",
229 : elementid,
230 : "' and neighbor id '",
231 : neighborid,
232 : "' in ",
233 : __FUNCTION__);
234 :
235 0 : return pos->second;
236 : }
237 :
238 : const Real &
239 0 : SlopeReconstructionBase::getBoundarySideArea(dof_id_type elementid, unsigned int side) const
240 : {
241 : Threads::spin_mutex::scoped_lock lock(_mutex);
242 : std::map<std::pair<dof_id_type, unsigned int>, Real>::const_iterator pos =
243 0 : _bnd_side_area.find(std::pair<dof_id_type, unsigned int>(elementid, side));
244 :
245 0 : if (pos == _bnd_side_area.end())
246 0 : mooseError("Boundary side area values are not cached for element id '",
247 : elementid,
248 : "' and side '",
249 : side,
250 : "' in ",
251 : __FUNCTION__);
252 :
253 0 : return pos->second;
254 : }
255 :
256 : void
257 0 : SlopeReconstructionBase::computeElement()
258 : {
259 0 : reconstructElementSlope();
260 0 : }
261 :
262 : void
263 0 : SlopeReconstructionBase::serialize(std::string & serialized_buffer)
264 : {
265 0 : std::ostringstream oss;
266 :
267 : // First store the number of elements to send
268 0 : unsigned int size = _interface_elem_ids.size();
269 0 : oss.write((char *)&size, sizeof(size));
270 :
271 0 : for (auto it = _interface_elem_ids.begin(); it != _interface_elem_ids.end(); ++it)
272 : {
273 : storeHelper(oss, *it, this);
274 0 : storeHelper(oss, _rslope[*it], this);
275 : }
276 :
277 : // Populate the passed in string pointer with the string stream's buffer contents
278 0 : serialized_buffer.assign(oss.str());
279 0 : }
280 :
281 : void
282 0 : SlopeReconstructionBase::deserialize(std::vector<std::string> & serialized_buffers)
283 : {
284 : // The input string stream used for deserialization
285 0 : std::istringstream iss;
286 :
287 : mooseAssert(serialized_buffers.size() == _app.n_processors(),
288 : "Unexpected size of serialized_buffers: " << serialized_buffers.size());
289 :
290 0 : for (auto rank = decltype(_app.n_processors())(0); rank < serialized_buffers.size(); ++rank)
291 : {
292 0 : if (rank == processor_id())
293 0 : continue;
294 :
295 : iss.str(serialized_buffers[rank]); // populate the stream with a new buffer
296 0 : iss.clear(); // reset the string stream state
297 :
298 : // Load the communicated data into all of the other processors' slots
299 :
300 0 : unsigned int size = 0;
301 0 : iss.read((char *)&size, sizeof(size));
302 :
303 0 : for (unsigned int i = 0; i < size; i++)
304 : {
305 : dof_id_type key;
306 : loadHelper(iss, key, this);
307 :
308 : std::vector<RealGradient> value;
309 : loadHelper(iss, value, this);
310 :
311 : // merge the data we received from other procs
312 0 : _rslope.insert(std::pair<dof_id_type, std::vector<RealGradient>>(key, value));
313 0 : }
314 : }
315 0 : }
|