1 // The libMesh Finite Element Library. 2 // Copyright (C) 2002-2020 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_CELL_INF_HEX_H 21 #define LIBMESH_CELL_INF_HEX_H 22 23 #include "libmesh/libmesh_config.h" 24 25 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 26 27 // Local includes 28 #include "libmesh/cell_inf.h" 29 30 namespace libMesh 31 { 32 33 /** 34 * The \p InfHex is an element in 3D with 5 sides. 35 * The \f$ 6^{th} \f$ side is theoretically located at infinity, 36 * and therefore not accounted for. 37 * However, one could say that the \f$ 6^{th} \f$ side actually 38 * does exist in the mesh, since the outer nodes are located 39 * at a specific distance from the mesh origin (and therefore 40 * define a side). Still, this face is not to be used! 41 * 42 * \author Daniel Dreyer 43 * \date 2003 44 * \brief The base class for all 3D infinite hexahedral element types. 45 */ 46 class InfHex : public InfCell 47 { 48 public: 49 50 /** 51 * Default infinite brick element, takes number of nodes and 52 * parent. Derived classes implement 'true' elements. 53 */ InfHex(const unsigned int nn,Elem * p,Node ** nodelinkdata)54 InfHex(const unsigned int nn, Elem * p, Node ** nodelinkdata) : 55 InfCell(nn, InfHex::n_sides(), p, _elemlinks_data, nodelinkdata) 56 { 57 // Make sure the interior parent isn't undefined 58 if (LIBMESH_DIM > 3) 59 this->set_interior_parent(nullptr); 60 } 61 62 InfHex (InfHex &&) = delete; 63 InfHex (const InfHex &) = delete; 64 InfHex & operator= (const InfHex &) = delete; 65 InfHex & operator= (InfHex &&) = delete; 66 virtual ~InfHex() = default; 67 68 /** 69 * \returns The \p Point associated with local \p Node \p i, 70 * in master element rather than physical coordinates. 71 */ master_point(const unsigned int i)72 virtual Point master_point (const unsigned int i) const override final 73 { 74 libmesh_assert_less(i, this->n_nodes()); 75 return Point(_master_points[i][0], 76 _master_points[i][1], 77 _master_points[i][2]); 78 } 79 80 /** 81 * \returns 5. Infinite elements have one side less 82 * than their conventional counterparts, since one 83 * side is supposed to be located at infinity. 84 */ n_sides()85 virtual unsigned int n_sides() const override final { return 5; } 86 87 /** 88 * \returns 8. All infinite hexahedra (in our 89 * setting) have 8 vertices. 90 */ n_vertices()91 virtual unsigned int n_vertices() const override final { return 8; } 92 93 /** 94 * \returns \p true if the specified (local) node number is a 95 * "mid-edge" node on an infinite element edge. 96 */ is_mid_infinite_edge_node(const unsigned int i)97 virtual bool is_mid_infinite_edge_node(const unsigned int i) const 98 override final { return (i > 3 && i < 8); } 99 100 /** 101 * \returns 8. All infinite hexahedra have 8 edges, 102 * 4 lying in the base, and 4 perpendicular to the base. 103 */ n_edges()104 virtual unsigned int n_edges() const override final { return 8; } 105 106 /** 107 * \returns 5. All infinite hexahedra have 5 faces. 108 */ n_faces()109 virtual unsigned int n_faces() const override final { return 5; } 110 111 /** 112 * \returns 4. 113 */ n_children()114 virtual unsigned int n_children() const override final { return 4; } 115 116 /** 117 * \returns \p true if the specified child is on the 118 * specified side. 119 */ 120 virtual bool is_child_on_side(const unsigned int c, 121 const unsigned int s) const override final; 122 123 /** 124 * \returns \p true if the specified edge is on the specified side. 125 */ 126 virtual bool is_edge_on_side(const unsigned int e, 127 const unsigned int s) const override final; 128 129 virtual std::vector<unsigned int> sides_on_edge(const unsigned int e) const override final; 130 131 /** 132 * Don't hide Elem::key() defined in the base class. 133 */ 134 using Elem::key; 135 136 /** 137 * \returns An id associated with the \p s side of this element. 138 * The id is not necessarily unique, but should be close. This is 139 * particularly useful in the \p MeshBase::find_neighbors() routine. 140 */ 141 virtual dof_id_type key (const unsigned int s) const override; 142 143 /** 144 * \returns \p InfHex8::side_nodes_map[side][side_node] after doing some range checking. 145 */ 146 virtual unsigned int local_side_node(unsigned int side, 147 unsigned int side_node) const override; 148 149 /** 150 * \returns \p InfHex8::edge_nodes_map[edge][edge_node] after doing some range checking. 151 */ 152 virtual unsigned int local_edge_node(unsigned int edge, 153 unsigned int edge_node) const override; 154 155 /** 156 * \returns A primitive (4-noded) quad or infquad for face i. 157 */ 158 virtual std::unique_ptr<Elem> side_ptr (const unsigned int i) override final; 159 160 /** 161 * Rebuilds a primitive (4-noded) quad or infquad for face i. 162 */ 163 virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) override final; 164 165 /** 166 * \returns A quantitative assessment of element quality based on 167 * the metric \p q specified by the user. 168 */ 169 virtual Real quality (const ElemQuality q) const override; 170 171 /** 172 * \returns The suggested quality bounds for the hex based on 173 * quality measure \p q. These are the values suggested by the 174 * CUBIT User's Manual. 175 */ 176 virtual std::pair<Real, Real> qual_bounds (const ElemQuality q) const override; 177 178 /** 179 * \returns \p true when this element contains the point 180 * \p p. Customized for infinite elements, since knowledge 181 * about the envelope can be helpful. 182 */ 183 virtual bool contains_point (const Point & p, Real tol=TOLERANCE) const override; 184 185 protected: 186 187 /** 188 * Data for links to parent/neighbor/interior_parent elements. 189 */ 190 Elem * _elemlinks_data[6+(LIBMESH_DIM>3)]; 191 192 193 194 /** 195 * For higher-order elements, namely \p InfHex16 and 196 * \p InfHex18, the matrices for adjacent vertices 197 * of second order nodes are quite similar (apart from 198 * the face nodes, which are directly handled by \p InfHex18). 199 * Therefore hold this matrix here, so that both can re-use 200 * this. Matrix that tells which vertices define the location 201 * of mid-side (or second-order) nodes. 202 */ 203 static const unsigned short int _second_order_adjacent_vertices[8][2]; 204 205 /** 206 * Vector that names a child sharing each second order node. 207 */ 208 static const unsigned short int _second_order_vertex_child_number[18]; 209 210 /** 211 * Vector that names the child vertex index for each second order node. 212 */ 213 static const unsigned short int _second_order_vertex_child_index[18]; 214 215 /** 216 * Master element node locations 217 */ 218 static const Real _master_points[18][3]; 219 }; 220 221 222 } // namespace libMesh 223 224 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 225 226 #endif // LIBMESH_CELL_INF_HEX_H 227