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_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 356861 : NodeElem (Elem * p=nullptr) :
46 356861 : Elem(num_nodes, num_sides, p, _elemlinks_data,
47 356861 : _nodelinks_data)
48 : {
49 : // Make sure the interior parent isn't undefined
50 : if (LIBMESH_DIM > 0)
51 356861 : this->set_interior_parent(nullptr);
52 356861 : }
53 :
54 : NodeElem (NodeElem &&) = delete;
55 : NodeElem (const NodeElem &) = delete;
56 : NodeElem & operator= (const NodeElem &) = delete;
57 : NodeElem & operator= (NodeElem &&) = delete;
58 371506 : 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 7401486 : virtual unsigned short dim () const override { return 0; }
80 :
81 : /**
82 : * \returns 1.
83 : */
84 5465120 : virtual unsigned int n_nodes() const override { return 1; }
85 :
86 : /**
87 : * \returns 0.
88 : */
89 2545637 : virtual unsigned int n_sides() const override { return 0; }
90 :
91 : /**
92 : * \returns 1. Every NodeElem is a vertex
93 : */
94 828121 : virtual unsigned int n_vertices() const override { return 1; }
95 :
96 : /**
97 : * \returns 0.
98 : */
99 784313 : virtual unsigned int n_edges() const override { return 0; }
100 :
101 : /**
102 : * \returns 0.
103 : */
104 391392 : 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 1784961 : virtual bool is_vertex(const unsigned int libmesh_dbg_var(n)) const override
186 1784961 : { 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 198864 : 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 10906083 : 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 : virtual void connectivity(const unsigned int sc,
275 : const IOPackage iop,
276 : std::vector<dof_id_type> & conn) const override;
277 :
278 :
279 : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
280 :
281 : /**
282 : * \returns \p false.
283 : */
284 635971 : virtual bool infinite () const override { return false; }
285 :
286 : #endif
287 :
288 : /**
289 : * No way to reorient a single node.
290 : */
291 12 : virtual unsigned int n_permutations() const override final { return 0; }
292 :
293 0 : virtual void permute(unsigned int) override final { libmesh_error(); }
294 :
295 12 : virtual void flip(BoundaryInfo *) override final { return; /* no-op */ }
296 63 : virtual bool is_flipped() const override final { return false; }
297 :
298 0 : virtual ElemType side_type (const unsigned int) const override
299 : {
300 0 : libmesh_not_implemented();
301 : return INVALID_ELEM;
302 : }
303 :
304 : /**
305 : * \returns \p true if the point p is within a distance of "tol" from
306 : * the point representing this element, false otherwise.
307 : *
308 : * The tolerance "tol" is normally treated as a relative tolerance in
309 : * contains_point() checks, but in this case there is no relevant length
310 : * to use in determing a relative tolerance, so "tol" is treated as an
311 : * absolute tolerance. The NodeElem contains_point() and close_to_point()
312 : * implementations are identical, whereas they differ for other element
313 : * types.
314 : */
315 : virtual bool contains_point(const Point & p, Real tol) const override;
316 :
317 : /**
318 : * \returns this->contains_point(p, tol)
319 : */
320 : virtual bool close_to_point(const Point & p, Real tol) const override;
321 :
322 : virtual bool on_reference_element(const Point & p,
323 : const Real eps = TOLERANCE) const override final;
324 :
325 : protected:
326 :
327 : /**
328 : * Data for links to parent/neighbor/interior_parent elements.
329 : */
330 : Elem * _elemlinks_data[1+(LIBMESH_DIM>0)];
331 :
332 : /**
333 : * Data for links to nodes.
334 : */
335 : Node * _nodelinks_data[1];
336 :
337 :
338 : #ifdef LIBMESH_ENABLE_AMR
339 :
340 : /**
341 : * Matrix used to create the elements children.
342 : */
343 15 : virtual Real embedding_matrix (const unsigned int i,
344 : const unsigned int j,
345 : const unsigned int k) const override
346 15 : { return _embedding_matrix[i][j][k]; }
347 :
348 : /**
349 : * Matrix that computes new nodal locations/solution values
350 : * from current nodes/solution.
351 : */
352 : static const Real _embedding_matrix[1][1][1];
353 :
354 : /**
355 : * Matrix that allows children to inherit boundary conditions.
356 : */
357 : unsigned int side_children_matrix (const unsigned int,
358 : const unsigned int) const
359 : { libmesh_not_implemented(); return 0; }
360 :
361 105 : LIBMESH_ENABLE_TOPOLOGY_CACHES;
362 :
363 : #endif // LIBMESH_ENABLE_AMR
364 :
365 : };
366 :
367 : } // namespace libMesh
368 :
369 : #endif // LIBMESH_NODE_ELEM_H
|