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