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_NODE_ELEM_H 21 #define LIBMESH_NODE_ELEM_H 22 23 // Local includes 24 #include "libmesh/elem.h" 25 26 namespace libMesh 27 { 28 29 /** 30 * The \p NodeElem is a point element, generally used as 31 * a side of a 1D element. 32 * 33 * \author Roy H. Stogner 34 * \date 2006 35 * \brief A zero-dimensional geometric entity implementing the Elem interface. 36 */ 37 class NodeElem : public Elem 38 { 39 public: 40 41 /** 42 * Constructor. By default this element has no parent. 43 */ 44 explicit 45 NodeElem (Elem * p=nullptr) : Elem(NodeElem::n_nodes (),NodeElem::n_sides (),p,_elemlinks_data,_nodelinks_data)46 Elem(NodeElem::n_nodes(), NodeElem::n_sides(), p, _elemlinks_data, 47 _nodelinks_data) 48 { 49 // Make sure the interior parent isn't undefined 50 if (LIBMESH_DIM > 0) 51 this->set_interior_parent(nullptr); 52 } 53 54 NodeElem (NodeElem &&) = delete; 55 NodeElem (const NodeElem &) = delete; 56 NodeElem & operator= (const NodeElem &) = delete; 57 NodeElem & operator= (NodeElem &&) = delete; 58 virtual ~NodeElem() = default; 59 60 /** 61 * \returns The \p Point associated with local \p Node \p i, 62 * in master element rather than physical coordinates. 63 */ master_point(const unsigned int libmesh_dbg_var (i))64 virtual Point master_point (const unsigned int libmesh_dbg_var(i)) const override 65 { 66 libmesh_assert_equal_to (i, 0); 67 return Point(0,0,0); 68 } 69 70 /** 71 * \returns 0, the dimensionality of the object. 72 */ dim()73 virtual unsigned short dim () const override { return 0; } 74 75 /** 76 * \returns 1. 77 */ n_nodes()78 virtual unsigned int n_nodes() const override { return 1; } 79 80 /** 81 * \returns 0. 82 */ n_sides()83 virtual unsigned int n_sides() const override { return 0; } 84 85 /** 86 * \returns 1. Every NodeElem is a vertex 87 */ n_vertices()88 virtual unsigned int n_vertices() const override { return 1; } 89 90 /** 91 * \returns 0. 92 */ n_edges()93 virtual unsigned int n_edges() const override { return 0; } 94 95 /** 96 * \returns 0. 97 */ n_faces()98 virtual unsigned int n_faces() const override { return 0; } 99 100 /** 101 * \returns 1. 102 */ n_children()103 virtual unsigned int n_children() const override { return 1; } 104 105 /** 106 * Don't hide Elem::key() defined in the base class. 107 */ 108 using Elem::key; 109 110 /** 111 * \returns An id associated with the \p s side of this element. 112 * This should never be important for NodeElems. 113 */ key(const unsigned int)114 virtual dof_id_type key (const unsigned int) const override 115 { libmesh_error_msg("Calling NodeElem::key(side) does not make sense."); return 0; } 116 117 /** 118 * NodeElems don't have sides, so they can't have nodes on sides. 119 */ local_side_node(unsigned int,unsigned int)120 virtual unsigned int local_side_node(unsigned int /*side*/, 121 unsigned int /*side_node*/) const override 122 { libmesh_error_msg("Calling NodeElem::local_side_node() does not make sense."); return 0; } 123 124 /** 125 * NodeElems don't have edges, so they can't have nodes on edges. 126 */ local_edge_node(unsigned int,unsigned int)127 virtual unsigned int local_edge_node(unsigned int /*edge*/, 128 unsigned int /*edge_node*/) const override 129 { libmesh_error_msg("Calling NodeElem::local_edge_node() does not make sense."); return 0; } 130 131 /** 132 * The \p Elem::side_ptr() member makes no sense for nodes. 133 */ side_ptr(const unsigned int)134 virtual std::unique_ptr<Elem> side_ptr (const unsigned int) override 135 { libmesh_not_implemented(); return std::unique_ptr<Elem>(); } 136 side_ptr(std::unique_ptr<Elem> &,const unsigned int)137 virtual void side_ptr (std::unique_ptr<Elem> &, const unsigned int) override 138 { libmesh_not_implemented(); } 139 140 /** 141 * The \p Elem::build_side_ptr() member makes no sense for nodes. 142 */ build_side_ptr(const unsigned int,bool)143 virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int, bool) override 144 { libmesh_not_implemented(); return std::unique_ptr<Elem>(); } 145 build_side_ptr(std::unique_ptr<Elem> &,const unsigned int)146 virtual void build_side_ptr (std::unique_ptr<Elem> &, const unsigned int) override 147 { libmesh_not_implemented(); } 148 149 /** 150 * The \p Elem::build_edge_ptr() member makes no sense for nodes. 151 */ build_edge_ptr(const unsigned int)152 virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int) override 153 { libmesh_not_implemented(); return std::unique_ptr<Elem>(); } 154 155 /** 156 * \returns 1. 157 */ n_sub_elem()158 virtual unsigned int n_sub_elem() const override { return 1; } 159 160 /** 161 * \returns \p true if the specified (local) node number is a vertex. 162 */ is_vertex(const unsigned int)163 virtual bool is_vertex(const unsigned int) const override { return true; } 164 165 /** 166 * NodeElem objects don't have faces or sides. 167 */ is_edge(const unsigned int)168 virtual bool is_edge(const unsigned int) const override { return false; } is_face(const unsigned int)169 virtual bool is_face(const unsigned int) const override { return false; } 170 is_child_on_side(const unsigned int,const unsigned int)171 virtual bool is_child_on_side(const unsigned int, 172 const unsigned int) const override 173 { libmesh_not_implemented(); return false; } 174 is_node_on_side(const unsigned int,const unsigned int)175 virtual bool is_node_on_side(const unsigned int, 176 const unsigned int) const override 177 { libmesh_not_implemented(); return false; } 178 nodes_on_side(const unsigned int)179 virtual std::vector<unsigned int> nodes_on_side(const unsigned int) const override 180 { 181 libmesh_not_implemented(); 182 return {0}; 183 } 184 nodes_on_edge(const unsigned int)185 virtual std::vector<unsigned int> nodes_on_edge(const unsigned int) const override 186 { 187 libmesh_not_implemented(); 188 return {0}; 189 } 190 sides_on_edge(const unsigned int)191 virtual std::vector<unsigned int> sides_on_edge(const unsigned int) const override 192 { 193 libmesh_not_implemented(); 194 return {0}; 195 } 196 is_node_on_edge(const unsigned int,const unsigned int)197 virtual bool is_node_on_edge(const unsigned int, 198 const unsigned int) const override 199 { libmesh_not_implemented(); return false; } 200 is_edge_on_side(const unsigned int,const unsigned int)201 virtual bool is_edge_on_side(const unsigned int, 202 const unsigned int) const override 203 { libmesh_not_implemented(); return false; } 204 205 /** 206 * \returns \p true if the element map is definitely affine within 207 * numerical tolerances. 208 */ has_affine_map()209 virtual bool has_affine_map () const override { return true; } 210 211 /** 212 * \returns \p true if the Lagrange shape functions on this element 213 * are linear. 214 */ is_linear()215 virtual bool is_linear () const override { return true; } 216 217 /** 218 * \returns \p NODEELEM. 219 */ type()220 virtual ElemType type() const override { return NODEELEM; } 221 222 /** 223 * \returns FIRST. 224 */ 225 virtual Order default_order() const override; 226 227 virtual void connectivity(const unsigned int sc, 228 const IOPackage iop, 229 std::vector<dof_id_type> & conn) const override; 230 231 232 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 233 234 /** 235 * \returns \p false. 236 */ infinite()237 virtual bool infinite () const override { return false; } 238 239 #endif 240 241 242 protected: 243 244 /** 245 * Data for links to parent/neighbor/interior_parent elements. 246 */ 247 Elem * _elemlinks_data[1+(LIBMESH_DIM>0)]; 248 249 /** 250 * Data for links to nodes. 251 */ 252 Node * _nodelinks_data[1]; 253 254 255 #ifdef LIBMESH_ENABLE_AMR 256 257 /** 258 * Matrix used to create the elements children. 259 */ embedding_matrix(const unsigned int i,const unsigned int j,const unsigned int k)260 virtual float embedding_matrix (const unsigned int i, 261 const unsigned int j, 262 const unsigned int k) const override 263 { return _embedding_matrix[i][j][k]; } 264 265 /** 266 * Matrix that computes new nodal locations/solution values 267 * from current nodes/solution. 268 */ 269 static const float _embedding_matrix[1][1][1]; 270 271 /** 272 * Matrix that allows children to inherit boundary conditions. 273 */ side_children_matrix(const unsigned int,const unsigned int)274 unsigned int side_children_matrix (const unsigned int, 275 const unsigned int) const 276 { libmesh_not_implemented(); return 0; } 277 278 LIBMESH_ENABLE_TOPOLOGY_CACHES; 279 280 #endif // LIBMESH_ENABLE_AMR 281 282 }; 283 284 } // namespace libMesh 285 286 #endif // LIBMESH_NODE_ELEM_H 287