Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : 19 : 20 : #ifndef LIBMESH_REMOTE_ELEM_H 21 : #define LIBMESH_REMOTE_ELEM_H 22 : 23 : // Local includes 24 : #include "libmesh/elem.h" 25 : #include "libmesh/libmesh_singleton.h" 26 : 27 : // C++ includes 28 : #include <limits> 29 : 30 : #define remote_elem_error(func_name) \ 31 : do { \ 32 : std::stringstream message_stream; \ 33 : message_stream << "RemoteElem::" << func_name << " was called. A RemoteElem is not a\n" << \ 34 : "real Elem, merely a shim accessible on distributed meshes via\n" << \ 35 : "Elem::neighbor_ptr(), to indicate when a neighbor exists but is not\n" << \ 36 : "local or ghosted on this processor. Calling this method was an\n" << \ 37 : "application or library error. Investigate a stack trace for details.\n"; \ 38 : libMesh::Threads::lock_singleton_spin_mutex(); \ 39 : libMesh::MacroFunctions::report_error(__FILE__, __LINE__, LIBMESH_DATE, LIBMESH_TIME, message_stream); \ 40 : libMesh::Threads::unlock_singleton_spin_mutex(); \ 41 : LIBMESH_THROW(libMesh::LogicError(message_stream.str())); \ 42 : } while (0) 43 : 44 : 45 : namespace libMesh 46 : { 47 : 48 : /** 49 : * In parallel meshes where a ghost element has neighbors which do 50 : * not exist on the local processor, the ghost element's neighbors 51 : * are set to point to the singleton RemoteElement instead. 52 : * Library code can then distinguish between such elements and 53 : * boundary elements (with nullptr neighbors). 54 : * 55 : * \author Roy H. Stogner 56 : * \date 2007 57 : * \brief Used by ParallelMesh to represent an Elem owned by another processor. 58 : */ 59 : class RemoteElem : public Elem, 60 : public Singleton 61 : { 62 : public: 63 : 64 : /** 65 : * A unique \p id to distinguish remote element links 66 : */ 67 : static const dof_id_type remote_elem_id = static_cast<dof_id_type>(-2); 68 : 69 : /** 70 : * Constructor. Private to force use of the \p create() member. 71 : */ 72 : private: 73 16381 : RemoteElem () : Elem(0, 74 : 0, 75 : nullptr, 76 16381 : _elemlinks_data, 77 16381 : nullptr) 78 16381 : { this->set_id(remote_elem_id); } 79 : 80 : public: 81 : 82 : RemoteElem (RemoteElem &&) = delete; 83 : RemoteElem (const RemoteElem &) = delete; 84 : RemoteElem & operator= (const RemoteElem &) = delete; 85 : RemoteElem & operator= (RemoteElem &&) = delete; 86 : 87 : /** 88 : * Sets remote_elem to nullptr. 89 : */ 90 : virtual ~RemoteElem(); 91 : 92 : /** 93 : * Return a reference to the global \p RemoteElem 94 : * singleton object. 95 : */ 96 : static const Elem & create (); 97 : 98 0 : virtual Point master_point (const unsigned int /*i*/) const override 99 0 : { remote_elem_error("master_point"); return Point(); } 100 : 101 : #ifdef LIBMESH_ENABLE_DEPRECATED 102 0 : virtual Node * & set_node (const unsigned int i) override 103 0 : { remote_elem_error("set_node"); return Elem::set_node(i); } 104 : #endif // LIBMESH_ENABLE_DEPRECATED 105 : 106 0 : virtual void set_node (const unsigned int /*i*/, Node * /*node*/) override 107 0 : { remote_elem_error("set_node"); } 108 : 109 : /** 110 : * Don't hide Elem::key() defined in the base class. 111 : */ 112 : using Elem::key; 113 : 114 0 : virtual dof_id_type key (const unsigned int) const override 115 0 : { remote_elem_error("key"); return 0; } 116 : 117 0 : virtual dof_id_type low_order_key (const unsigned int) const override 118 0 : { remote_elem_error("low_order_key"); return 0; } 119 : 120 0 : virtual unsigned int local_side_node(unsigned int /*side*/, 121 : unsigned int /*side_node*/) const override 122 0 : { remote_elem_error("local_side_node"); return 0; } 123 : 124 0 : virtual unsigned int local_edge_node(unsigned int /*side*/, 125 : unsigned int /*side_node*/) const override 126 0 : { remote_elem_error("local_edge_node"); return 0; } 127 : 128 79825197 : virtual bool is_remote () const override 129 79825197 : { return true; } 130 : 131 0 : virtual void connectivity(const unsigned int, 132 : const IOPackage, 133 : std::vector<dof_id_type> &) const override 134 0 : { remote_elem_error("connectivity"); } 135 : 136 0 : virtual ElemType type () const override 137 0 : { return REMOTEELEM; } 138 : 139 0 : virtual unsigned short dim () const override 140 0 : { remote_elem_error("dim"); return 0; } 141 : 142 0 : virtual unsigned int n_nodes () const override 143 0 : { remote_elem_error("n_nodes"); return 0; } 144 : 145 37 : virtual unsigned int n_sides () const override 146 74 : { remote_elem_error("n_sides"); return 0; } 147 : 148 0 : virtual unsigned int n_vertices () const override 149 0 : { remote_elem_error("n_vertices"); return 0; } 150 : 151 0 : virtual unsigned int n_edges () const override 152 0 : { remote_elem_error("n_edges"); return 0; } 153 : 154 0 : virtual unsigned int n_faces () const override 155 0 : { remote_elem_error("n_faces"); return 0; } 156 : 157 0 : virtual unsigned int n_children () const override 158 0 : { remote_elem_error("n_children"); return 0; } 159 : 160 0 : virtual bool is_vertex(const unsigned int) const override 161 0 : { remote_elem_error("is_vertex"); return false; } 162 : 163 0 : virtual bool is_edge(const unsigned int) const override 164 0 : { remote_elem_error("is_edge"); return false; } 165 : 166 0 : virtual bool is_face(const unsigned int) const override 167 0 : { remote_elem_error("is_face"); return false; } 168 : 169 0 : virtual bool is_node_on_side(const unsigned int, 170 : const unsigned int) const override 171 0 : { remote_elem_error("is_node_on_side"); return false; } 172 : 173 0 : virtual std::vector<unsigned int> nodes_on_side(const unsigned int) const override 174 0 : { remote_elem_error("nodes_on_side"); return {0}; } 175 : 176 0 : virtual std::vector<unsigned int> nodes_on_edge(const unsigned int) const override 177 0 : { remote_elem_error("nodes_on_edge"); return {0}; } 178 : 179 0 : virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int) const override 180 0 : { remote_elem_error("edges_adjacent_to_node"); return {0};} 181 : 182 0 : virtual std::vector<unsigned int> sides_on_edge(const unsigned int) const override 183 0 : { remote_elem_error("sides_on_edge"); return {0}; } 184 : 185 0 : virtual bool is_child_on_side(const unsigned int, 186 : const unsigned int) const override 187 0 : { remote_elem_error("is_child_on_side"); return false; } 188 : 189 0 : virtual bool is_edge_on_side(const unsigned int, 190 : const unsigned int) const override 191 0 : { remote_elem_error("is_edge_on_side"); return false; } 192 : 193 0 : virtual bool is_node_on_edge(const unsigned int, 194 : const unsigned int) const override 195 0 : { remote_elem_error("is_node_on_edge"); return false; } 196 : 197 0 : virtual unsigned int n_sub_elem () const override 198 0 : { remote_elem_error("n_sub_elem"); return 0; } 199 : 200 0 : virtual std::unique_ptr<Elem> side_ptr (const unsigned int) override 201 0 : { remote_elem_error("side_ptr"); return std::unique_ptr<Elem>(); } 202 : 203 0 : virtual void side_ptr (std::unique_ptr<Elem> &, 204 : const unsigned int) override 205 0 : { remote_elem_error("side_ptr"); } 206 : 207 0 : virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int) override 208 0 : { remote_elem_error("build_side_ptr"); return std::unique_ptr<Elem>(); } 209 : 210 0 : virtual void build_side_ptr (std::unique_ptr<Elem> &, 211 : const unsigned int) override 212 0 : { remote_elem_error("build_side_ptr"); } 213 : 214 : // Avoid hiding deprecated version with different signature 215 : using Elem::build_side_ptr; 216 : 217 0 : virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int) override 218 0 : { remote_elem_error("build_edge_ptr"); return std::unique_ptr<Elem>(); } 219 : 220 0 : virtual void build_edge_ptr (std::unique_ptr<Elem> &, const unsigned int) override 221 0 : { remote_elem_error("build_edge_ptr"); } 222 : 223 0 : virtual Order default_order () const override 224 0 : { remote_elem_error("default_order"); return static_cast<Order>(1); } 225 : 226 : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 227 : 228 0 : virtual bool infinite () const override 229 0 : { remote_elem_error("infinite"); return false; } 230 : 231 : #endif 232 : 233 : #ifdef LIBMESH_ENABLE_AMR 234 : 235 : /** 236 : * Matrix that transforms the parents nodes into the children's 237 : * nodes. 238 : */ 239 0 : virtual Real embedding_matrix (const unsigned int, 240 : const unsigned int, 241 : const unsigned int) const override 242 0 : { remote_elem_error("embedding_matrix"); return 0.; } 243 : 244 0 : LIBMESH_ENABLE_TOPOLOGY_CACHES; 245 : 246 : #endif // LIBMESH_ENABLE_AMR 247 : 248 0 : virtual unsigned int n_permutations() const override 249 0 : { remote_elem_error("n_permutations"); return 0; } 250 : 251 0 : virtual void permute(unsigned int) override 252 0 : { remote_elem_error("permute"); } 253 : 254 0 : virtual void flip(BoundaryInfo *) override final 255 0 : { remote_elem_error("flip"); } 256 : 257 0 : virtual bool is_flipped() const override final 258 0 : { remote_elem_error("is_flipped"); return false; } 259 : 260 0 : virtual unsigned int center_node_on_side(const unsigned short) const override 261 0 : { remote_elem_error("center_node_on_side"); return invalid_uint; } 262 : 263 0 : virtual ElemType side_type (const unsigned int) const override 264 0 : { remote_elem_error("side_type"); return INVALID_ELEM; } 265 : 266 0 : virtual bool on_reference_element(const Point & /*p*/, 267 : const Real /*eps*/ = TOLERANCE) const override 268 0 : { remote_elem_error("on_reference_element"); return false; } 269 : 270 : protected: 271 : 272 : /** 273 : * Data for link to (nullptr!) parent. 274 : */ 275 : Elem * _elemlinks_data[1]; 276 : }; 277 : 278 : // Singleton RemoteElem 279 : extern const RemoteElem * remote_elem; 280 : 281 : } // namespace libMesh 282 : 283 : #endif // LIBMESH_REMOTE_ELEM_H