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_EDGE_H 21 : #define LIBMESH_EDGE_H 22 : 23 : // Local includes 24 : #include "libmesh/elem.h" 25 : 26 : namespace libMesh 27 : { 28 : 29 : /** 30 : * The \p Edge is an element in 1D. It can be thought of as a 31 : * line segment. 32 : * 33 : * \author Benjamin S. Kirk 34 : * \date 2002 35 : * \brief The base class for all 1D geometric element types. 36 : */ 37 : class Edge : public Elem 38 : { 39 : public: 40 : 41 : /** 42 : * Default line element, takes number of nodes and 43 : * parent. Derived classes implement 'true' elements. 44 : */ 45 65582908 : Edge (const unsigned int nn, 46 : Elem * p, 47 65582908 : Node ** nodelinkdata) : 48 65582908 : Elem(nn, num_sides, p, _elemlinks_data, nodelinkdata) 49 : { 50 : // Make sure the interior parent isn't undefined 51 : if (LIBMESH_DIM > 1) 52 65582908 : this->set_interior_parent(nullptr); 53 65582908 : } 54 : 55 : Edge (Edge &&) = delete; 56 : Edge (const Edge &) = delete; 57 : Edge & operator= (const Edge &) = delete; 58 : Edge & operator= (Edge &&) = delete; 59 65582908 : virtual ~Edge() = default; 60 : 61 : /** 62 : * Geometric constants for all Edges. 63 : */ 64 : static const int num_sides = 2; 65 : static const int num_edges = 0; 66 : static const int num_children = 2; 67 : static const int nodes_per_side = 1; 68 : static const int nodes_per_edge = invalid_int; 69 : 70 : /** 71 : * \returns 1, the dimensionality of the object. 72 : */ 73 722967888 : virtual unsigned short dim () const override final { return 1; } 74 : 75 : /** 76 : * \returns 2. Every edge is guaranteed to have at least 2 nodes. 77 : */ 78 740121867 : virtual unsigned int n_nodes() const override { return 2; } 79 : 80 : /** 81 : * \returns 2. 82 : */ 83 171421284 : virtual unsigned int n_sides() const override final { return 2; } 84 : 85 : /** 86 : * \returns 2. Every edge has exactly two vertices. 87 : */ 88 8592145 : virtual unsigned int n_vertices() const override final { return 2; } 89 : 90 : /** 91 : * \returns 0. All 1D elements have no edges. 92 : */ 93 357479 : virtual unsigned int n_edges() const override final { return 0; } 94 : 95 : /** 96 : * \returns 0. All 1D elements have no faces. 97 : */ 98 19744 : virtual unsigned int n_faces() const override final { return 0; } 99 : 100 : /** 101 : * \returns 2. 102 : */ 103 1965149 : virtual unsigned int n_children() const override final { return 2; } 104 : 105 : /** 106 : * \returns \p true if the specified child is on the specified side. 107 : */ 108 : virtual bool is_child_on_side(const unsigned int c, 109 : const unsigned int s) const override final; 110 : 111 : /** 112 : * \returns \p true if the specified edge is on the specified side. 113 : */ 114 0 : virtual bool is_edge_on_side(const unsigned int, 115 : const unsigned int) const override final 116 0 : { return false; } 117 : 118 : /** 119 : * \returns The side number opposite to \p s (for a tensor product 120 : * element), or throws an error otherwise. 121 : */ 122 : virtual unsigned int opposite_side(const unsigned int s) const override final; 123 : 124 : /** 125 : * \returns The local node number for the node opposite to node n 126 : * on side \p opposite_side(s) (for a tensor product element), or 127 : * throws an error otherwise. 128 : */ 129 : virtual unsigned int opposite_node(const unsigned int n, 130 : const unsigned int s) const override final; 131 : 132 : /** 133 : * Don't hide Elem::key() defined in the base class. 134 : */ 135 : using Elem::key; 136 : 137 : /** 138 : * \returns An id associated with the \p s side of this element. 139 : * The id is not necessarily unique, but should be close. 140 : */ 141 0 : virtual dof_id_type key (const unsigned int s) const override final 142 0 : { return this->compute_key(this->node_id(s)); } 143 : 144 : /** 145 : * \returns An id associated with the \p s side of this element, as 146 : * defined solely by element vertices. The id is not necessarily 147 : * unique, but should be close. This is particularly useful in the 148 : * \p MeshBase::find_neighbors() routine. 149 : */ 150 1282724 : virtual dof_id_type low_order_key (const unsigned int s) const override final 151 1326276 : { return this->compute_key(this->node_id(s)); } 152 : 153 : /** 154 : * \returns \p side after doing some range checking. \p side_node is ignored. 155 : */ 156 : virtual unsigned int local_side_node(unsigned int side, 157 : unsigned int /*side_node*/) const override final; 158 : 159 : /** 160 : * Throws an error. Edge elems have n_edges() == 0, so it does not 161 : * make sense to call local_edge_node(). 162 : */ 163 : virtual unsigned int local_edge_node(unsigned int edge, 164 : unsigned int edge_node) const override final; 165 : 166 : /** 167 : * \returns A pointer to a NodeElem for the specified node. 168 : */ 169 : virtual std::unique_ptr<Elem> side_ptr (const unsigned int i) override final; 170 : 171 : /** 172 : * Rebuilds a pointer to a NodeElem for the specified node. 173 : */ 174 : virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) override final; 175 : 176 : /** 177 : * \returns A pointer to a NodeElem for the specified node. 178 : */ 179 : virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) override final; 180 : 181 : /** 182 : * Rebuilds a NODEELEM for the specified node. 183 : */ 184 : virtual void build_side_ptr (std::unique_ptr<Elem> & elem, 185 : const unsigned int i) override final; 186 : 187 : // Avoid hiding deprecated version with different signature 188 : using Elem::build_side_ptr; 189 : 190 : /** 191 : * The \p Elem::build_edge_ptr() member makes no sense for edges. 192 : */ 193 0 : virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int) override final 194 0 : { libmesh_not_implemented(); return std::unique_ptr<Elem>(); } 195 : 196 : /** 197 : * The \p Elem::build_edge_ptr() member makes no sense for edges. 198 : */ 199 0 : virtual void build_edge_ptr (std::unique_ptr<Elem> &, const unsigned int) override final 200 0 : { libmesh_not_implemented(); } 201 : 202 : virtual std::vector<unsigned int> nodes_on_side(const unsigned int s) const override; 203 : 204 : virtual std::vector<unsigned int> nodes_on_edge(const unsigned int e) const override; 205 : 206 0 : virtual std::vector<unsigned int> sides_on_edge(const unsigned int) const override final 207 0 : { return {}; } 208 : 209 : /** 210 : * 1D elements don't have any edges, but they are *themselves* 211 : * edges, so I guess an argument could be made for returning "this" 212 : * somehow. Since I don't know exactly how that should be done, 213 : * return an empty vector for now. 214 : */ 215 216 : virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int /*n*/) const override final 216 216 : { return {}; } 217 : 218 : /** 219 : * \returns The "circumcenter of mass" (area-weighted average of 220 : * triangulation circumcenters) of the element. 221 : * 222 : * Currently ignores curvature of element edges, which makes this 223 : * trivial in 1D. 224 : */ 225 72 : virtual Point quasicircumcenter () const override 226 78 : { return (this->point(0) + this->point(1)) / 2; } 227 : 228 : // Any edge permutation flips the mapping Jacobian negative 229 5357 : virtual unsigned int n_permutations() const override final { return 0; } 230 : 231 0 : virtual void permute(unsigned int) override final { libmesh_error(); } 232 : 233 : virtual bool is_flipped() const override final; 234 : 235 : unsigned int center_node_on_side(const unsigned short side) const override final; 236 : 237 : ElemType side_type (const unsigned int s) const override final; 238 : 239 : virtual bool on_reference_element(const Point & p, 240 : const Real eps = TOLERANCE) const override final; 241 : 242 : protected: 243 : 244 : /** 245 : * Data for links to parent/neighbor/interior_parent elements. 246 : */ 247 : Elem * _elemlinks_data[3+(LIBMESH_DIM>1)]; 248 : 249 : #ifdef LIBMESH_ENABLE_AMR 250 : 251 : /** 252 : * Matrix that allows children to inherit boundary conditions. 253 : */ 254 : unsigned int side_children_matrix (const unsigned int, 255 : const unsigned int) const 256 : { libmesh_not_implemented(); return 0; } 257 : 258 : #endif 259 : 260 : }; 261 : 262 : } // namespace libMesh 263 : 264 : #endif // LIBMESH_EDGE_H