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 "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 : 18 : InputParameters 19 98 : SlopeLimitingBase::validParams() 20 : { 21 98 : InputParameters params = ElementLoopUserObject::validParams(); 22 98 : params += TransientInterface::validParams(); 23 : 24 98 : params.addClassDescription( 25 : "Base class for slope limiting to limit the slopes of cell average variables."); 26 : 27 196 : params.addParam<bool>("include_bc", true, "Indicate whether to include bc, default = true"); 28 : 29 98 : return params; 30 0 : } 31 : 32 49 : SlopeLimitingBase::SlopeLimitingBase(const InputParameters & parameters) 33 : : ElementLoopUserObject(parameters), 34 49 : _lslope( 35 98 : declareRestartableData<std::map<dof_id_type, std::vector<RealGradient>>>("limited_slope")), 36 98 : _include_bc(getParam<bool>("include_bc")), 37 49 : _q_point_face(_assembly.qPointsFace()), 38 49 : _qrule_face(_assembly.qRuleFace()), 39 49 : _JxW_face(_assembly.JxWFace()), 40 49 : _normals_face(_assembly.normals()), 41 49 : _side(_assembly.side()), 42 49 : _side_elem(_assembly.sideElem()), 43 49 : _side_volume(_assembly.sideElemVolume()), 44 49 : _neighbor_elem(_assembly.neighbor()) 45 : { 46 49 : } 47 : 48 : void 49 744 : SlopeLimitingBase::initialize() 50 : { 51 744 : ElementLoopUserObject::initialize(); 52 : 53 744 : _lslope.clear(); 54 744 : } 55 : 56 : const std::vector<RealGradient> & 57 107545 : SlopeLimitingBase::getElementSlope(dof_id_type elementid) const 58 : { 59 : Threads::spin_mutex::scoped_lock lock(_mutex); 60 107545 : std::map<dof_id_type, std::vector<RealGradient>>::const_iterator pos = _lslope.find(elementid); 61 : 62 107545 : if (pos == _lslope.end()) 63 0 : mooseError("Limited slope is not cached for element id '", elementid, "' in ", __FUNCTION__); 64 : 65 107545 : return pos->second; 66 : } 67 : 68 : void 69 45400 : SlopeLimitingBase::computeElement() 70 : { 71 45400 : dof_id_type _elementID = _current_elem->id(); 72 : 73 90800 : _lslope[_elementID] = limitElementSlope(); 74 45400 : } 75 : 76 : void 77 540 : SlopeLimitingBase::serialize(std::string & serialized_buffer) 78 : { 79 540 : std::ostringstream oss; 80 : 81 : // First store the number of elements to send 82 540 : unsigned int size = _interface_elem_ids.size(); 83 540 : oss.write((char *)&size, sizeof(size)); 84 : 85 1056 : for (auto it = _interface_elem_ids.begin(); it != _interface_elem_ids.end(); ++it) 86 : { 87 : storeHelper(oss, *it, this); 88 516 : storeHelper(oss, _lslope[*it], this); 89 : } 90 : 91 : // Populate the passed in string pointer with the string stream's buffer contents 92 540 : serialized_buffer.assign(oss.str()); 93 540 : } 94 : 95 : void 96 540 : SlopeLimitingBase::deserialize(std::vector<std::string> & serialized_buffers) 97 : { 98 : // The input string stream used for deserialization 99 540 : std::istringstream iss; 100 : 101 : mooseAssert(serialized_buffers.size() == _app.n_processors(), 102 : "Unexpected size of serialized_buffers: " << serialized_buffers.size()); 103 : 104 1620 : for (auto rank = decltype(_app.n_processors())(0); rank < serialized_buffers.size(); ++rank) 105 : { 106 1080 : if (rank == processor_id()) 107 540 : continue; 108 : 109 : iss.str(serialized_buffers[rank]); // populate the stream with a new buffer 110 540 : iss.clear(); // reset the string stream state 111 : 112 : // Load the communicated data into all of the other processors' slots 113 : 114 540 : unsigned int size = 0; 115 540 : iss.read((char *)&size, sizeof(size)); 116 : 117 1056 : 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 1032 : _lslope.insert(std::pair<dof_id_type, std::vector<RealGradient>>(key, value)); 127 516 : } 128 : } 129 540 : } 130 : 131 : void 132 744 : SlopeLimitingBase::finalize() 133 : { 134 744 : ElementLoopUserObject::finalize(); 135 : 136 744 : if (_app.n_processors() > 1) 137 : { 138 540 : std::vector<std::string> send_buffers(1); 139 : std::vector<std::string> recv_buffers; 140 : 141 540 : recv_buffers.reserve(_app.n_processors()); 142 540 : serialize(send_buffers[0]); 143 540 : comm().allgather_packed_range((void *)(nullptr), 144 : send_buffers.begin(), 145 : send_buffers.end(), 146 : std::back_inserter(recv_buffers)); 147 540 : deserialize(recv_buffers); 148 540 : } 149 744 : }