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