| Base 739e36 | Head #4283 f95625 | ||||
|---|---|---|---|---|---|
| Total | Total | +/- | New | ||
| Rate | 65.00% | 65.04% | +0.03% | 90.91% | |
| Hits | 76957 | 77039 | +82 | 60 | |
| Misses | 41434 | 41417 | -17 | 6 | |
| Filename | Stmts | Miss | Cover | 
|---|---|---|---|
| include/ghosting/disconnected_neighbor_coupling.h | +6 | +3 | +50.00% | 
| src/base/dof_map.C | 0 | -6 | +0.47% | 
| src/ghosting/disconnected_neighbor_coupling.C | +22 | +3 | +86.36% | 
| src/mesh/boundary_info.C | 0 | -13 | +0.82% | 
| src/mesh/distributed_mesh.C | 0 | -2 | +0.25% | 
| src/mesh/mesh_base.C | +16 | 0 | +0.22% | 
| src/mesh/mesh_refinement.C | +2 | -2 | +0.33% | 
| src/mesh/unstructured_mesh.C | +19 | 0 | +0.46% | 
| TOTAL | +65 | -17 | +0.03% | 
codecodecode+| 17 18 19 20 + 21 22 23 24 25 + 26 27 + 28 + 29 30 + 31 + 32 33 34 | * user-defined disconnected interfaces, * such as cohesive zone boundaries. */ class DisconnectedNeighborCoupling : public GhostingFunctor { public: using DisconnectedMap = std::unordered_map<const Elem *, const Elem *>; DisconnectedNeighborCoupling(const MeshBase & mesh) : GhostingFunctor(mesh), _dof_coupling(nullptr) {} virtual std::unique_ptr<GhostingFunctor> clone () const override { return std::make_unique<DisconnectedNeighborCoupling>(*this); } virtual void operator() (const MeshBase::const_element_iterator & range_begin, const MeshBase::const_element_iterator & range_end, | 
| 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 | this->prepare_send_list(); } void DofMap::set_implicit_neighbor_dofs(bool implicit_neighbor_dofs) { _implicit_neighbor_dofs_initialized = true; _implicit_neighbor_dofs = implicit_neighbor_dofs; } void DofMap::set_verify_dirichlet_bc_consistency(bool val) { | 
| 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 | // has been called. if (_implicit_neighbor_dofs_initialized) { implicit_neighbor_dofs = _implicit_neighbor_dofs; // Again, if the user explicitly says implicit_neighbor_dofs = false, // then we return here. if (!implicit_neighbor_dofs) return false; } | 
| 8 9 10 11 + 12 13 14 15 16 17 + 18 + 19 + 20 + 21 22 + 23 24 25 + 26 + 27 + 28 29 30 + 31 + 32 33 + 34 35 + 36 + 37 38 + 39 40 + 41 42 + 43 + 44 45 + 46 + 47 48 + 49 + 50 51 52 | namespace libMesh { void DisconnectedNeighborCoupling::operator()( const MeshBase::const_element_iterator & range_begin, const MeshBase::const_element_iterator & range_end, processor_id_type p, map_type & coupled_elements) { libmesh_assert(_mesh); auto * db = _mesh->get_disconnected_boundaries(); if (!db) return; std::unique_ptr<PointLocatorBase> point_locator = _mesh->sub_point_locator(); // Primary ghosting: elements in range_begin...range_end for (const auto & elem : as_range(range_begin, range_end)) if (elem->processor_id() != p) coupled_elements.emplace(elem, _dof_coupling); // Also ghost their disconnected neighbors for (const auto & elem : as_range(range_begin, range_end)) for (auto s : elem->side_index_range()) { for (const auto & [id, boundary_ptr] : *db) { if (!_mesh->get_boundary_info().has_boundary_id(elem, s, id)) continue; unsigned int neigh_side = invalid_uint; const Elem * neigh = db->neighbor(id, *point_locator, elem, s, &neigh_side); if (!neigh || neigh == remote_elem) continue; if (neigh->processor_id() != p) coupled_elements.emplace(neigh, _dof_coupling); } } } } // namespace libMesh | 
| 2322 2323 2324 2325 2326 2327 2328 2329 + 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 | { // If we're on this external boundary then we share this // external boundary id if (elem->neighbor_ptr(side) == nullptr) return side; // Internal boundary case const Elem * p = elem; #ifdef LIBMESH_ENABLE_AMR // If we're on an internal boundary then we need to be sure // it's the same internal boundary as our top_parent while (p != nullptr) { const Elem * parent = p->parent(); if (parent && !parent->is_child_on_side(parent->which_child_am_i(p), side)) break; p = parent; } #else // do not forget to return the internal boundary when AMR is disabled return side; #endif // We're on that side of our top_parent; return it if (!p) return side; } // Otherwise we need to check if the child's ancestors have something on // the side of the child | 
| 2388 2389 2390 2391 2392 2393 2394 | // if we get here, we found elem in the data structure but not // the requested boundary id, so return the default value return libMesh::invalid_uint; } | 
| 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 | #ifdef LIBMESH_ENABLE_AMR while (p != nullptr) { const Elem * parent = p->parent(); if (parent && !parent->is_child_on_side(parent->which_child_am_i(p), side)) break; p = parent; } #endif // We're on that side of our top_parent; return it if (!p) returnval.push_back(side); } // Otherwise we trust what we got and return the side else | 
| 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 | sender_could_become_owner) { if (it != repartitioned_node_pids.end() && pid < it->second) it->second = pid; else repartitioned_node_pids[n] = pid; } else if (it == repartitioned_node_pids.end()) repartitioned_node_pids[n] = DofObject::invalid_processor_id; repartitioned_node_sets_to_push[pid].insert(n); | 
| 1960 1961 1962 1963 + 1964 1965 1966 1967 1968 + 1969 + 1970 1971 1972 + 1973 + 1974 1975 + 1976 + 1977 + 1978 + 1979 1980 1981 + 1982 + 1983 + 1984 1985 + 1986 1987 + 1988 1989 1990 + 1991 1992 + 1993 1994 1995 | /** * Register a pair of boundaries as disconnected boundaries. */ void MeshBase::add_disconnected_boundaries(const boundary_id_type b1, const boundary_id_type b2, const RealVectorValue & translation) { // Lazily allocate the container the first time it’s needed if (!_disconnected_boundary_pairs) _disconnected_boundary_pairs = std::make_unique<PeriodicBoundaries>(); // Create forward and inverse boundary mappings PeriodicBoundary forward(translation); PeriodicBoundary inverse(translation * -1.0); forward.myboundary = b1; forward.pairedboundary = b2; inverse.myboundary = b2; inverse.pairedboundary = b1; // Add both directions into the container _disconnected_boundary_pairs->emplace(b1, forward.clone()); _disconnected_boundary_pairs->emplace(b2, inverse.clone()); } PeriodicBoundaries * MeshBase::get_disconnected_boundaries() { return _disconnected_boundary_pairs.get(); } const PeriodicBoundaries * MeshBase::get_disconnected_boundaries() const { return _disconnected_boundary_pairs.get(); } #endif | 
| 694 695 696 697 + 698 699 + 700 701 702 | // // For safety, refinement is disabled while disconnected boundaries are // present. if (_mesh.get_disconnected_boundaries()) { libmesh_error_msg( "Mesh contains disconnected boundary interfaces; refinement is disabled.\n" "MeshRefinement::refine_elements() cannot proceed because disconnected\n" "boundaries may produce invalid neighbor relations. Please remove or\n" | 
| 1291 1292 1293 1294 1295 1296 1297 1298 | if (neighbor->p_level() < my_p_level && neighbor->p_refinement_flag() != Elem::REFINE) { neighbor->set_p_refinement_flag(Elem::REFINE); level_one_satisfied = false; compatible_with_coarsening = false; } if (neighbor->p_level() == my_p_level && | 
| 1001 1002 1003 1004 + 1005 1006 + 1007 1008 1009 + 1010 1011 + 1012 1013 + 1014 1015 1016 + 1017 + 1018 + 1019 1020 + 1021 1022 + 1023 + 1024 1025 1026 1027 + 1028 1029 + 1030 1031 + 1032 + 1033 + 1034 1035 1036 1037 + 1038 1039 1040 + 1041 + 1042 1043 1044 | #ifdef LIBMESH_ENABLE_PERIODIC // Get the disconnected boundaries object (from periodic BCs) auto * db = this->get_disconnected_boundaries(); if (db) { // Obtain a point locator std::unique_ptr<PointLocatorBase> point_locator = this->sub_point_locator(); for (const auto & element : this->element_ptr_range()) { for (auto ms : element->side_index_range()) { // Skip if this side already has a valid neighbor (including remote neighbors) if (element->neighbor_ptr(ms) != nullptr && element->neighbor_ptr(ms) != remote_elem) continue; for (const auto & [id, boundary_ptr] : *db) { if (!this->get_boundary_info().has_boundary_id(element, ms, id)) continue; unsigned int neigh_side; const Elem * neigh = db->neighbor(id, *point_locator, element, ms, &neigh_side); if (neigh && neigh != remote_elem && neigh != element) { auto neigh_changeable = this->elem_ptr(neigh->id()); element->set_neighbor(ms, neigh_changeable); neigh_changeable->set_neighbor(neigh_side, element); } } } } // Ghost the disconnected elements this->add_ghosting_functor(std::make_unique<DisconnectedNeighborCoupling>(*this)); } #endif // LIBMESH_ENABLE_PERIODIC #ifdef LIBMESH_ENABLE_AMR |