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_H
21 : #define LIBMESH_NODE_H
22 :
23 : // Local includes
24 : #include "libmesh/point.h"
25 : #include "libmesh/dof_object.h"
26 : #include "libmesh/reference_counted_object.h"
27 :
28 : // C++ includes
29 : #include <iostream>
30 : #include <memory>
31 : #include <vector>
32 :
33 : namespace libMesh
34 : {
35 :
36 : // forward declarations
37 : class Node;
38 : class MeshBase;
39 : class MeshRefinement;
40 :
41 : /**
42 : * A \p Node is like a \p Point, but with more information. A \p Node
43 : * is located in space and is associated with some \p (x,y,z)
44 : * coordinates. Additionally, a \p Node may be enumerated with a
45 : * global \p id. Finally, a \p Node may have an arbitrary number of
46 : * degrees of freedom associated with it.
47 : *
48 : * \author Benjamin S. Kirk
49 : * \date 2003
50 : * \brief A geometric point in (x,y,z) space associated with a DOF.
51 : */
52 : class Node : public Point,
53 : public DofObject,
54 : public ReferenceCountedObject<Node>
55 : {
56 :
57 : public:
58 :
59 : /**
60 : * Constructor. By default sets all entries to 0. Gives the point 0 in
61 : * \p LIBMESH_DIM dimensions with an \p id of \p Node::invalid_id.
62 : */
63 : explicit
64 : Node (const Real x=0,
65 : const Real y=0,
66 : const Real z=0,
67 : const dof_id_type id = invalid_id);
68 :
69 : /**
70 : * "Copy"-constructor: deliberately slices the source Node and only
71 : * copies its' Point information, since copying anything else would
72 : * likely be a bug.
73 : *
74 : * \deprecated - the constructor from Point is what we really want.
75 : */
76 : #ifdef LIBMESH_ENABLE_DEPRECATED
77 : Node (const Node & n);
78 : #else
79 : Node (const Node & n) = delete;
80 : #endif
81 :
82 : /**
83 : * Copy-constructor from a \p Point. Optionally assigned the \p id.
84 : */
85 : explicit Node (const Point & p,
86 : const dof_id_type id = invalid_id);
87 :
88 : /**
89 : * Disambiguate constructing from non-Real scalars
90 : */
91 : template <typename T,
92 : typename = typename
93 : boostcopy::enable_if_c<ScalarTraits<T>::value,void>::type>
94 : explicit Node (const T x) :
95 : Point (x,0,0)
96 : { this->set_id() = invalid_id; }
97 :
98 : /**
99 : * Destructor.
100 : */
101 : ~Node ();
102 :
103 : /**
104 : * Assign to a node from a point.
105 : */
106 : Node & operator= (const Point & p);
107 :
108 : /**
109 : * \returns A \p Node copied from \p n and wrapped in a smart pointer.
110 : *
111 : * \deprecated - anyone copying a Node would almost certainly be
112 : * better off copying the much cheaper Point or taking a reference
113 : * to the Node.
114 : */
115 : #ifdef LIBMESH_ENABLE_DEPRECATED
116 : static std::unique_ptr<Node> build (const Node & n);
117 : #endif
118 :
119 : /**
120 : * \returns A \p Node copied from \p p with id == \p id and wrapped in a smart pointer.
121 : */
122 : static std::unique_ptr<Node> build (const Point & p,
123 : const dof_id_type id);
124 :
125 : /**
126 : * \returns A \p Node created from the specified (x,y,z) positions
127 : * with id == \p id and wrapped in a smart pointer.
128 : */
129 : static std::unique_ptr<Node> build (const Real x,
130 : const Real y,
131 : const Real z,
132 : const dof_id_type id);
133 :
134 : /**
135 : * \returns \p true if the node is active. An active node is
136 : * defined as one for which \p id() is not \p Node::invalid_id.
137 : * Inactive nodes are nodes that are in the mesh but are not
138 : * connected to any elements.
139 : */
140 : bool active () const;
141 :
142 :
143 : /**
144 : * \returns \p true if this node equals rhs, false otherwise.
145 : */
146 : bool operator ==(const Node & rhs) const;
147 :
148 : /**
149 : * Prints relevant information about the node.
150 : */
151 : void print_info (std::ostream & os=libMesh::out) const;
152 :
153 : /**
154 : * Prints relevant information about the node to a string.
155 : */
156 : std::string get_info () const;
157 :
158 : #ifdef LIBMESH_HAVE_MPI
159 : unsigned int packed_size() const
160 : {
161 : const unsigned int header_size = 2;
162 :
163 : // use "(a+b-1)/b" trick to get a/b to round up
164 : static const unsigned int idtypes_per_Real =
165 : (sizeof(Real) + sizeof(largest_id_type) - 1) / sizeof(largest_id_type);
166 :
167 : return header_size + LIBMESH_DIM*idtypes_per_Real +
168 : this->packed_indexing_size();
169 : }
170 :
171 : #endif // #ifdef LIBMESH_HAVE_MPI
172 :
173 : /**
174 : * \returns The number of nodes connected with this node.
175 : * Currently, this value is invalid (zero) except for
176 : * subdivision meshes.
177 : */
178 6192 : unsigned int valence() const
179 : {
180 : #ifdef LIBMESH_ENABLE_NODE_VALENCE
181 61776 : return _valence;
182 : #else
183 : libmesh_not_implemented();
184 : return libMesh::invalid_uint;
185 : #endif
186 : }
187 :
188 : /**
189 : * Sets the number of nodes connected with this node.
190 : */
191 : void set_valence(unsigned int val);
192 :
193 : /**
194 : * Return which of pid1 and pid2 would be preferred by the current
195 : * load-balancing heuristic applied to this node.
196 : */
197 : processor_id_type choose_processor_id(processor_id_type pid1, processor_id_type pid2) const;
198 :
199 : private:
200 :
201 : /**
202 : * This class need access to the node key information,
203 : * but no one else should be able to mess with it.
204 : */
205 : friend class MeshRefinement;
206 : friend class Elem;
207 :
208 : #ifdef LIBMESH_ENABLE_NODE_VALENCE
209 : /**
210 : * Type used to store node valence.
211 : */
212 : typedef unsigned char valence_idx_t;
213 :
214 : /**
215 : * The number of nodes connected with this node.
216 : * Currently, this value is invalid (zero) except for
217 : * subdivision meshes.
218 : */
219 : valence_idx_t _valence;
220 : #endif
221 : };
222 :
223 :
224 :
225 : // ------------------------------------------------------------
226 : // Global Node functions
227 :
228 : inline
229 0 : std::ostream & operator << (std::ostream & os, const Node & n)
230 : {
231 11 : n.print_info(os);
232 0 : return os;
233 : }
234 :
235 :
236 :
237 : //------------------------------------------------------
238 : // Inline functions
239 : inline
240 31933 : Node::Node (const Real x,
241 : const Real y,
242 : const Real z,
243 29387019 : const dof_id_type dofid) :
244 : Point(x,y,z)
245 : #ifdef LIBMESH_ENABLE_NODE_VALENCE
246 : ,
247 29387019 : _valence(0)
248 : #endif
249 : {
250 29387019 : this->set_id() = dofid;
251 31933 : }
252 :
253 :
254 : #ifdef LIBMESH_ENABLE_DEPRECATED
255 : inline
256 : Node::Node (const Node & n) :
257 : Point(n),
258 : DofObject(), // Deliberately slicing!
259 : ReferenceCountedObject<Node>()
260 : #ifdef LIBMESH_ENABLE_NODE_VALENCE
261 : ,
262 : _valence(0)
263 : #endif
264 : {
265 : libmesh_deprecated(); // Cast to Point first!
266 : }
267 : #endif // LIBMESH_ENABLE_DEPRECATED
268 :
269 :
270 :
271 : inline
272 49708826 : Node::Node (const Point & p,
273 49708826 : const dof_id_type dofid) :
274 : Point(p)
275 : #ifdef LIBMESH_ENABLE_NODE_VALENCE
276 : ,
277 49708826 : _valence(0)
278 : #endif
279 : {
280 : // optionally assign the id. We have
281 : // to do it like this otherwise
282 : // Node n = Point p would erase
283 : // the id!
284 49708826 : if (dofid != invalid_id)
285 33676957 : this->set_id() = dofid;
286 49708826 : }
287 :
288 :
289 :
290 : inline
291 2983580 : Node::~Node ()
292 : {
293 77235553 : }
294 :
295 :
296 :
297 : inline
298 12010 : Node & Node::operator= (const Point & p)
299 : {
300 6263354 : (*this)(0) = p(0);
301 : #if LIBMESH_DIM > 1
302 6263354 : (*this)(1) = p(1);
303 : #endif
304 : #if LIBMESH_DIM > 2
305 6204956 : (*this)(2) = p(2);
306 : #endif
307 :
308 70408 : return *this;
309 : }
310 :
311 :
312 :
313 : #ifdef LIBMESH_ENABLE_DEPRECATED
314 : inline
315 : std::unique_ptr<Node> Node::build(const Node & n)
316 : {
317 : libmesh_deprecated();
318 : return std::make_unique<Node>(n);
319 : }
320 : #endif
321 :
322 :
323 :
324 : inline
325 1098469 : std::unique_ptr<Node> Node::build(const Point & p,
326 : const dof_id_type id)
327 : {
328 47903082 : return std::make_unique<Node>(p,id);
329 : }
330 :
331 :
332 :
333 : inline
334 3626 : std::unique_ptr<Node> Node::build(const Real x,
335 : const Real y,
336 : const Real z,
337 : const dof_id_type id)
338 : {
339 94017 : return std::make_unique<Node>(x,y,z,id);
340 : }
341 :
342 :
343 :
344 : inline
345 32858 : bool Node::active () const
346 : {
347 75094 : return (this->id() != Node::invalid_id);
348 : }
349 :
350 :
351 :
352 : #ifdef LIBMESH_ENABLE_NODE_VALENCE
353 :
354 : inline
355 362 : void Node::set_valence (unsigned int val)
356 : {
357 12851 : _valence = cast_int<valence_idx_t>(val);
358 362 : }
359 :
360 : #else
361 :
362 : inline
363 : void Node::set_valence (unsigned int)
364 : {
365 : libmesh_not_implemented();
366 : }
367 :
368 : #endif // #ifdef LIBMESH_ENABLE_NODE_VALENCE
369 :
370 : } // namespace libMesh
371 :
372 :
373 : #endif // LIBMESH_NODE_H
|