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 : // App includes 11 : #include "GhostBoundary.h" 12 : #include "Executioner.h" 13 : #include "FEProblemBase.h" 14 : #include "MooseApp.h" 15 : 16 : // libMesh includes 17 : #include "libmesh/elem.h" 18 : #include "libmesh/mesh_base.h" 19 : #include "libmesh/boundary_info.h" 20 : 21 : registerMooseObject("MooseApp", GhostBoundary); 22 : 23 : using namespace libMesh; 24 : 25 : InputParameters 26 14421 : GhostBoundary::validParams() 27 : { 28 14421 : InputParameters params = RelationshipManager::validParams(); 29 14421 : params.addRequiredParam<std::vector<BoundaryName>>("boundary", 30 : "The name of the primary boundary sideset."); 31 14421 : params.addClassDescription("This class constructs a relationship manager system' " 32 : "to communicate ghost elements on a boundary."); 33 14421 : return params; 34 0 : } 35 : 36 72 : GhostBoundary::GhostBoundary(const InputParameters & params) 37 72 : : RelationshipManager(params), _boundary_name(getParam<std::vector<BoundaryName>>("boundary")) 38 : { 39 72 : } 40 : 41 12 : GhostBoundary::GhostBoundary(const GhostBoundary & other) 42 12 : : RelationshipManager(other), _boundary_name(other._boundary_name) 43 : { 44 12 : } 45 : 46 : void 47 12 : GhostBoundary::internalInitWithMesh(const MeshBase &) 48 : { 49 12 : } 50 : 51 : std::string 52 12 : GhostBoundary::getInfo() const 53 : { 54 12 : std::ostringstream oss; 55 12 : oss << "GhostBoundary"; 56 24 : return oss.str(); 57 12 : } 58 : 59 : void 60 4 : GhostBoundary::operator()(const MeshBase::const_element_iterator & /*range_begin*/, 61 : const MeshBase::const_element_iterator & /*range_end*/, 62 : const processor_id_type p, 63 : map_type & coupled_elements) 64 : { 65 : // We ask the user to pass boundary names instead of ids to our constraint object. However, We 66 : // are unable to get the boundary ids from boundary names until we've attached the MeshBase object 67 : // to the MooseMesh 68 4 : const bool generating_mesh = !_moose_mesh->getMeshPtr(); 69 4 : const auto boundary_ids = generating_mesh ? std::vector<BoundaryID>{Moose::INVALID_BOUNDARY_ID} 70 4 : : _moose_mesh->getBoundaryIDs(_boundary_name); 71 : 72 204 : for (const Elem * const elem : _mesh->active_element_ptr_range()) 73 : { 74 100 : if (generating_mesh) 75 : { // We are still generating the mesh, so it's possible we don't even have the right boundary 76 : // ids created yet! So we actually ghost all boundary elements and all lower dimensional 77 : // elements who have parents on a boundary 78 0 : if (elem->on_boundary()) 79 0 : coupled_elements.insert(std::make_pair(elem, _null_mat)); 80 : } 81 : else 82 : { 83 : // We've finished generating our mesh so we can be selective and only ghost elements lying on 84 : // our boundary 85 100 : const BoundaryInfo & binfo = _mesh->get_boundary_info(); 86 371 : for (auto side : elem->side_index_range()) 87 1484 : for (auto boundary_id : boundary_ids) 88 1213 : if ((elem->processor_id() != p) && (binfo.has_boundary_id(elem, side, boundary_id))) 89 : { 90 48 : coupled_elements.insert(std::make_pair(elem, _null_mat)); 91 48 : goto countBreak; 92 : } 93 100 : countBreak:; 94 : } 95 4 : } 96 4 : } 97 : 98 : bool 99 132 : GhostBoundary::operator>=(const RelationshipManager & other) const 100 : { 101 132 : if (auto asoi = dynamic_cast<const GhostBoundary *>(&other); asoi && baseGreaterEqual(*asoi)) 102 : { 103 60 : std::set<BoundaryName> our_set(_boundary_name.begin(), _boundary_name.end()); 104 60 : std::set<BoundaryName> their_set(asoi->_boundary_name.begin(), asoi->_boundary_name.end()); 105 60 : std::set<BoundaryName> difference; 106 60 : std::set_difference(their_set.begin(), 107 : their_set.end(), 108 : our_set.begin(), 109 : our_set.end(), 110 : std::inserter(difference, difference.end())); 111 60 : if (difference.empty()) 112 60 : return true; 113 180 : } 114 72 : return false; 115 : } 116 : 117 : std::unique_ptr<GhostingFunctor> 118 12 : GhostBoundary::clone() const 119 : { 120 12 : return _app.getFactory().copyConstruct(*this); 121 : }