Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2026 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 374632 : NodeElem (Elem * p=nullptr) :
46 374632 : Elem(num_nodes, num_sides, p, _elemlinks_data,
47 374632 : _nodelinks_data)
48 : {
49 : // Make sure the interior parent isn't undefined
50 : if (LIBMESH_DIM > 0)
51 374632 : this->set_interior_parent(nullptr);
52 374632 : }
53 :
54 : NodeElem (NodeElem &&) = delete;
55 : NodeElem (const NodeElem &) = delete;
56 : NodeElem & operator= (const NodeElem &) = delete;
57 : NodeElem & operator= (NodeElem &&) = delete;
58 389605 : virtual ~NodeElem() = default;
59 :
60 : /**
61 : * Geometric constants for NodeElem;
62 : */
63 : static const int num_nodes = 1;
64 : static const int num_sides = 0;
65 :
66 : /**
67 : * \returns The \p Point associated with local \p Node \p i,
68 : * in master element rather than physical coordinates.
69 : */
70 15 : virtual Point master_point (const unsigned int libmesh_dbg_var(i)) const override
71 : {
72 2 : libmesh_assert_equal_to (i, 0);
73 15 : return Point(0,0,0);
74 : }
75 :
76 : /**
77 : * \returns 0, the dimensionality of the object.
78 : */
79 6715640 : virtual unsigned short dim () const override { return 0; }
80 :
81 : /**
82 : * \returns 1.
83 : */
84 5473197 : virtual unsigned int n_nodes() const override { return 1; }
85 :
86 : /**
87 : * \returns 0.
88 : */
89 2445918 : virtual unsigned int n_sides() const override { return 0; }
90 :
91 : /**
92 : * \returns 1. Every NodeElem is a vertex
93 : */
94 334171 : virtual unsigned int n_vertices() const override { return 1; }
95 :
96 : /**
97 : * \returns 0.
98 : */
99 785314 : virtual unsigned int n_edges() const override { return 0; }
100 :
101 : /**
102 : * \returns 0.
103 : */
104 391407 : virtual unsigned int n_faces() const override { return 0; }
105 :
106 : /**
107 : * \returns 1.
108 : */
109 420 : virtual unsigned int n_children() const override { return 1; }
110 :
111 : /**
112 : * Don't hide Elem::key() defined in the base class.
113 : */
114 : using Elem::key;
115 :
116 : /**
117 : * \returns An id associated with the \p s side of this element.
118 : * This should never be important for NodeElems.
119 : */
120 0 : virtual dof_id_type key (const unsigned int) const override
121 0 : { libmesh_error_msg("Calling NodeElem::key(side) does not make sense."); return 0; }
122 :
123 : /**
124 : * \returns An id associated with the \p s side of this element.
125 : * This should never be important for NodeElems.
126 : */
127 0 : virtual dof_id_type low_order_key (const unsigned int) const override
128 0 : { libmesh_error_msg("Calling NodeElem::low_order_key(side) does not make sense."); return 0; }
129 :
130 : /**
131 : * NodeElems don't have sides, so they can't have nodes on sides.
132 : */
133 0 : virtual unsigned int local_side_node(unsigned int /*side*/,
134 : unsigned int /*side_node*/) const override
135 0 : { libmesh_error_msg("Calling NodeElem::local_side_node() does not make sense."); return 0; }
136 :
137 : /**
138 : * NodeElems don't have edges, so they can't have nodes on edges.
139 : */
140 0 : virtual unsigned int local_edge_node(unsigned int /*edge*/,
141 : unsigned int /*edge_node*/) const override
142 0 : { libmesh_error_msg("Calling NodeElem::local_edge_node() does not make sense."); return 0; }
143 :
144 : /**
145 : * The \p Elem::side_ptr() member makes no sense for nodes.
146 : */
147 0 : virtual std::unique_ptr<Elem> side_ptr (const unsigned int) override
148 0 : { libmesh_not_implemented(); return std::unique_ptr<Elem>(); }
149 :
150 0 : virtual void side_ptr (std::unique_ptr<Elem> &, const unsigned int) override
151 0 : { libmesh_not_implemented(); }
152 :
153 : /**
154 : * The \p Elem::build_side_ptr() member makes no sense for nodes.
155 : */
156 0 : virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int) override
157 0 : { libmesh_not_implemented(); return std::unique_ptr<Elem>(); }
158 :
159 0 : virtual void build_side_ptr (std::unique_ptr<Elem> &, const unsigned int) override
160 0 : { libmesh_not_implemented(); }
161 :
162 : // Avoid hiding deprecated version with different signature
163 : using Elem::build_side_ptr;
164 :
165 : /**
166 : * The \p Elem::build_edge_ptr() member makes no sense for nodes.
167 : */
168 0 : virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int) override
169 0 : { libmesh_not_implemented(); return std::unique_ptr<Elem>(); }
170 :
171 : /**
172 : * The \p Elem::build_edge_ptr() member makes no sense for nodes.
173 : */
174 0 : virtual void build_edge_ptr (std::unique_ptr<Elem> &, const unsigned int) override
175 0 : { libmesh_not_implemented(); }
176 :
177 : /**
178 : * \returns 1.
179 : */
180 0 : virtual unsigned int n_sub_elem() const override { return 1; }
181 :
182 : /**
183 : * \returns \p true if the specified (local) node number is a vertex.
184 : */
185 1784889 : virtual bool is_vertex(const unsigned int libmesh_dbg_var(n)) const override
186 1784889 : { libmesh_assert_not_equal_to (n, invalid_uint); return true; }
187 :
188 : /**
189 : * NodeElem objects don't have faces or sides.
190 : */
191 0 : virtual bool is_edge(const unsigned int) const override { return false; }
192 0 : virtual bool is_face(const unsigned int) const override { return false; }
193 :
194 0 : virtual bool is_child_on_side(const unsigned int,
195 : const unsigned int) const override
196 0 : { libmesh_not_implemented(); return false; }
197 :
198 0 : virtual bool is_node_on_side(const unsigned int,
199 : const unsigned int) const override
200 0 : { libmesh_not_implemented(); return false; }
201 :
202 0 : virtual std::vector<unsigned int> nodes_on_side(const unsigned int) const override
203 : {
204 0 : libmesh_not_implemented();
205 : return {0};
206 : }
207 :
208 0 : virtual std::vector<unsigned int> nodes_on_edge(const unsigned int) const override
209 : {
210 0 : libmesh_not_implemented();
211 : return {0};
212 : }
213 :
214 12 : virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int) const override
215 : {
216 12 : return {};
217 : }
218 :
219 0 : virtual std::vector<unsigned int> sides_on_edge(const unsigned int) const override
220 : {
221 0 : libmesh_not_implemented();
222 : return {0};
223 : }
224 :
225 0 : virtual bool is_node_on_edge(const unsigned int,
226 : const unsigned int) const override
227 0 : { libmesh_not_implemented(); return false; }
228 :
229 0 : virtual bool is_edge_on_side(const unsigned int,
230 : const unsigned int) const override
231 0 : { libmesh_not_implemented(); return false; }
232 :
233 : /**
234 : * \returns The "circumcenter of mass" (area-weighted average of
235 : * triangulation circumcenters) of the element.
236 : *
237 : * Trivial in 0D.
238 : */
239 12 : virtual Point quasicircumcenter () const override
240 13 : { return this->point(0); }
241 :
242 : /**
243 : * \returns \p true if the element map is definitely affine within
244 : * numerical tolerances.
245 : */
246 198879 : virtual bool has_affine_map () const override { return true; }
247 :
248 : /**
249 : * \returns \p true because it doesn't really make sense for a NodeElem.
250 : */
251 0 : virtual bool has_invertible_map(Real /*tol*/) const override { return true; }
252 :
253 : /**
254 : * \returns \p true if the Lagrange shape functions on this element
255 : * are linear.
256 : */
257 198780 : virtual bool is_linear () const override { return true; }
258 :
259 : /**
260 : * \returns \p NODEELEM.
261 : */
262 10932275 : virtual ElemType type() const override { return NODEELEM; }
263 :
264 : /**
265 : * \returns \p CONSTANT.
266 : */
267 : virtual Order default_order() const override;
268 :
269 : /**
270 : * \returns \p MAXIMUM.
271 : */
272 : virtual Order supported_nodal_order() const override;
273 :
274 : /**
275 : * Elem::volume() returns the N-dimensional measure of an
276 : * N-dimensional element. For N=2 "volume" is area; for N=1 "volume"
277 : * is length, and for N=0 "volume" is cardinality. A set with 1
278 : * point has 0-"volume" of 1.
279 : */
280 27 : virtual Real volume () const override { return Real(1); }
281 :
282 : virtual void connectivity(const unsigned int sc,
283 : const IOPackage iop,
284 : std::vector<dof_id_type> & conn) const override;
285 :
286 :
287 : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
288 :
289 : /**
290 : * \returns \p false.
291 : */
292 635976 : virtual bool infinite () const override { return false; }
293 :
294 : #endif
295 :
296 : /**
297 : * No way to reorient a single node.
298 : */
299 12 : virtual unsigned int n_permutations() const override final { return 0; }
300 :
301 0 : virtual void permute(unsigned int) override final { libmesh_error(); }
302 :
303 12 : virtual void flip(BoundaryInfo *) override final { return; /* no-op */ }
304 63 : virtual bool is_flipped() const override final { return false; }
305 :
306 0 : virtual ElemType side_type (const unsigned int) const override
307 : {
308 0 : libmesh_not_implemented();
309 : return INVALID_ELEM;
310 : }
311 :
312 : /**
313 : * \returns \p true if the point p is within a distance of "tol" from
314 : * the point representing this element, false otherwise.
315 : *
316 : * The tolerance "tol" is normally treated as a relative tolerance in
317 : * contains_point() checks, but in this case there is no relevant length
318 : * to use in determing a relative tolerance, so "tol" is treated as an
319 : * absolute tolerance. The NodeElem contains_point() and close_to_point()
320 : * implementations are identical, whereas they differ for other element
321 : * types.
322 : */
323 : virtual bool contains_point(const Point & p, Real tol) const override;
324 :
325 : /**
326 : * \returns this->contains_point(p, tol)
327 : */
328 : virtual bool close_to_point(const Point & p, Real tol) const override;
329 :
330 : virtual bool on_reference_element(const Point & p,
331 : const Real eps = TOLERANCE) const override final;
332 :
333 : protected:
334 :
335 : /**
336 : * Data for links to parent/neighbor/interior_parent elements.
337 : */
338 : Elem * _elemlinks_data[1+(LIBMESH_DIM>0)];
339 :
340 : /**
341 : * Data for links to nodes.
342 : */
343 : Node * _nodelinks_data[1];
344 :
345 :
346 : #ifdef LIBMESH_ENABLE_AMR
347 :
348 : /**
349 : * Matrix used to create the elements children.
350 : */
351 15 : virtual Real embedding_matrix (const unsigned int i,
352 : const unsigned int j,
353 : const unsigned int k) const override
354 15 : { return _embedding_matrix[i][j][k]; }
355 :
356 : /**
357 : * Matrix that computes new nodal locations/solution values
358 : * from current nodes/solution.
359 : */
360 : static const Real _embedding_matrix[1][1][1];
361 :
362 : /**
363 : * Matrix that allows children to inherit boundary conditions.
364 : */
365 : unsigned int side_children_matrix (const unsigned int,
366 : const unsigned int) const
367 : { libmesh_not_implemented(); return 0; }
368 :
369 105 : LIBMESH_ENABLE_TOPOLOGY_CACHES;
370 :
371 : #endif // LIBMESH_ENABLE_AMR
372 :
373 : };
374 :
375 : } // namespace libMesh
376 :
377 : #endif // LIBMESH_NODE_ELEM_H
|