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_EDGE3_H 21 : #define LIBMESH_EDGE_EDGE3_H 22 : 23 : // Local includes 24 : #include "libmesh/libmesh_common.h" 25 : #include "libmesh/edge.h" 26 : 27 : namespace libMesh 28 : { 29 : 30 : /** 31 : * The \p Edge3 is an element in 1D composed of 3 nodes. It is numbered 32 : * like this: 33 : * 34 : * \verbatim 35 : * EDGE3: o----o----o o---> xi 36 : * 0 2 1 37 : * \endverbatim 38 : * 39 : * xi in [-1,1] is the reference element coordinate associated with 40 : * the given numbering. 41 : * 42 : * \author Benjamin S. Kirk 43 : * \date 2002 44 : * \brief A 1D geometric element with 3 nodes. 45 : */ 46 : class Edge3 : public Edge 47 : { 48 : public: 49 : 50 : /** 51 : * Constructor. By default this element has no parent. 52 : */ 53 : explicit 54 26530516 : Edge3 (Elem * p=nullptr) : 55 26530516 : Edge(num_nodes, p, _nodelinks_data) {} 56 : 57 : Edge3 (Edge3 &&) = delete; 58 : Edge3 (const Edge3 &) = delete; 59 : Edge3 & operator= (const Edge3 &) = delete; 60 : Edge3 & operator= (Edge3 &&) = delete; 61 32206949 : virtual ~Edge3() = default; 62 : 63 : /** 64 : * \returns The \p Point associated with local \p Node \p i, 65 : * in master element rather than physical coordinates. 66 : */ 67 15204 : virtual Point master_point (const unsigned int i) const override 68 : { 69 504 : libmesh_assert_less(i, this->n_nodes()); 70 15204 : if (i < 2) 71 9231 : return Point(2.0f*Real(i)-1.0f,0,0); 72 198 : return Point(0,0,0); 73 : } 74 : 75 : /** 76 : * \returns 3. 77 : */ 78 85002306 : virtual unsigned int n_nodes() const override { return num_nodes; } 79 : 80 : /** 81 : * \returns 2. 82 : */ 83 6984 : virtual unsigned int n_sub_elem() const override { return 2; } 84 : 85 : /** 86 : * \returns \p true if the specified (local) node number is a vertex. 87 : */ 88 : virtual bool is_vertex(const unsigned int i) const override; 89 : 90 : /** 91 : * \returns \p true if the specified (local) node number is an edge. 92 : */ 93 : virtual bool is_edge(const unsigned int i) const override; 94 : 95 : /** 96 : * \returns \p true if the specified (local) node number is a face. 97 : */ 98 : virtual bool is_face(const unsigned int i) const override; 99 : 100 : /** 101 : * \returns \p true if the specified (local) node number is on the 102 : * specified side. 103 : */ 104 : virtual bool is_node_on_side(const unsigned int n, 105 : const unsigned int s) const override; 106 : 107 : /** 108 : * \returns \p true if the specified (local) node number is on the 109 : * specified edge (always true in 1D). 110 : */ 111 : virtual bool is_node_on_edge(const unsigned int n, 112 : const unsigned int e) const override; 113 : 114 : /** 115 : * \returns \p true if the element map is definitely affine within 116 : * numerical tolerances. 117 : */ 118 : virtual bool has_affine_map () const override; 119 : 120 : /** 121 : * \returns \p true if the element map is everywhere invertible, 122 : * false otherwise. The user can pass a custom tol >= 0 to this 123 : * function if desired to make the check more stringent, i.e. 124 : * to also catch elements which are "almost" non-invertible. 125 : */ 126 : virtual bool has_invertible_map(Real tol) const override; 127 : 128 : /** 129 : * \returns \p EDGE3. 130 : */ 131 94448584 : virtual ElemType type() const override { return EDGE3; } 132 : 133 : /** 134 : * \returns SECOND. 135 : */ 136 : virtual Order default_order() const override; 137 : 138 : virtual void connectivity(const unsigned int sc, 139 : const IOPackage iop, 140 : std::vector<dof_id_type> & conn) const override; 141 : 142 : /** 143 : * \returns 2 for all \p n. 144 : */ 145 1491 : virtual unsigned int n_second_order_adjacent_vertices (const unsigned int) const override 146 1491 : { return 2; } 147 : 148 : /** 149 : * \returns The element-local number of the \f$ v^{th} \f$ vertex 150 : * that defines the \f$ n^{th} \f$ second-order node. 151 : */ 152 2982 : virtual unsigned short int second_order_adjacent_vertex (const unsigned int, 153 : const unsigned int v) const override 154 2982 : { return static_cast<unsigned short int>(v); } 155 : 156 : /** 157 : * \returns The child number \p c and element-local index \p v of the 158 : * \f$ n^{th} \f$ second-order node on the parent element. See 159 : * elem.h for further details. 160 : */ 161 : virtual std::pair<unsigned short int, unsigned short int> 162 : second_order_child_vertex (const unsigned int n) const override; 163 : 164 : /** 165 : * An optimized method for computing the length of a 3-node edge. 166 : */ 167 : virtual Real volume () const override; 168 : 169 : /** 170 : * \returns A bounding box (not necessarily the minimal bounding box) 171 : * containing the edge. 172 : */ 173 : virtual BoundingBox loose_bounding_box () const override; 174 : 175 : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 176 : 177 : /** 178 : * \returns \p false. This is a finite element. 179 : */ 180 6763799 : virtual bool infinite () const override { return false; } 181 : 182 : #endif 183 : 184 : /** 185 : * Don't hide Edge::key(side) defined in the base class. 186 : */ 187 : using Edge::key; 188 : 189 : /** 190 : * Compute a unique key for this element which is suitable for 191 : * hashing (not necessarily unique, but close). The key is based 192 : * solely on the mid-edge node's global id, to be consistent with 2D 193 : * elements that have Edge3 sides (Quad9, Quad8, etc.). 194 : */ 195 : virtual dof_id_type key () const override; 196 : 197 : /** 198 : * Geometric constants for Edge3. 199 : */ 200 : static const int num_nodes = 3; 201 : 202 : virtual void flip(BoundaryInfo *) override final; 203 : 204 : protected: 205 : 206 : /** 207 : * Data for links to nodes. 208 : */ 209 : Node * _nodelinks_data[num_nodes]; 210 : 211 : 212 : 213 : #ifdef LIBMESH_ENABLE_AMR 214 : 215 : /** 216 : * Matrix used to create the elements children. 217 : */ 218 93639 : virtual Real embedding_matrix (const unsigned int i, 219 : const unsigned int j, 220 : const unsigned int k) const override 221 93639 : { return _embedding_matrix[i][j][k]; } 222 : 223 : /** 224 : * Matrix that computes new nodal locations/solution values 225 : * from current nodes/solution. 226 : */ 227 : static const Real _embedding_matrix[num_children][num_nodes][num_nodes]; 228 : 229 366415 : LIBMESH_ENABLE_TOPOLOGY_CACHES; 230 : 231 : #endif // LIBMESH_ENABLE_AMR 232 : 233 : }; 234 : 235 : } // namespace libMesh 236 : 237 : 238 : #endif // LIBMESH_EDGE_EDGE3_H