libMesh
face_tri3_subdivision.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2024 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 // Local includes
19 #include "libmesh/face_tri3_subdivision.h"
20 #include "libmesh/mesh_subdivision_support.h"
21 #include "libmesh/enum_order.h"
22 
23 namespace libMesh
24 {
25 
26 
27 
28 // ------------------------------------------------------------
29 // Tri3 subdivision class member functions
30 
32  Tri3(p),
33  _subdivision_updated(p ? true : false),
34  _is_ghost(p ? true : false)
35 {
36  if (p)
37  {
38  libmesh_assert_equal_to(p->type(), TRI3SUBDIVISION);
39  Tri3Subdivision * sd_elem = static_cast<Tri3Subdivision *>(p);
40  _is_ghost = sd_elem->is_ghost();
41 
42  if (!_is_ghost)
43  {
44  _ordered_nodes[0] = sd_elem->get_ordered_node(0);
45  _ordered_nodes[1] = sd_elem->get_ordered_node(1);
46  _ordered_nodes[2] = sd_elem->get_ordered_node(2);
47  }
48  }
49 }
50 
51 
52 
54 {
55  return FOURTH;
56 }
57 
58 
59 
61 {
62  /*
63  * Find the index of the irregular vertex, if any.
64  * The current implementation can only handle triangles with
65  * no more than one irregular vertex. That is, a vertex with
66  * valence != 6.
67  */
68  unsigned int irregular_idx = 0;
69  for (unsigned int i = 0; i < 3; ++i)
70  {
71  if (this->node_ptr(i)->valence() != 6)
72  {
73  irregular_idx = i;
74  libmesh_error_msg_if(this->node_ptr(MeshTools::Subdivision::next[i])->valence() != 6 ||
75  this->node_ptr(MeshTools::Subdivision::prev[i])->valence() != 6,
76  "Error: The mesh contains elements with more than one irregular vertex!");
77  }
78  }
79 
80  /*
81  * Rotate ordered vertices such that ordered_nodes[0] is the
82  * irregular vertex. Doing this once in advance lets the evaluation
83  * of subdivision interpolation be much more efficient afterward.
84  */
85  switch (irregular_idx)
86  {
87  case 0:
88  _ordered_nodes[0] = this->node_ptr(0);
89  _ordered_nodes[1] = this->node_ptr(1);
90  _ordered_nodes[2] = this->node_ptr(2);
91  break;
92  case 1:
93  _ordered_nodes[0] = this->node_ptr(1);
94  _ordered_nodes[1] = this->node_ptr(2);
95  _ordered_nodes[2] = this->node_ptr(0);
96  break;
97  case 2:
98  _ordered_nodes[0] = this->node_ptr(2);
99  _ordered_nodes[1] = this->node_ptr(0);
100  _ordered_nodes[2] = this->node_ptr(1);
101  break;
102  default:
103  libmesh_error_msg("Unrecognized irregular_idx = " << irregular_idx);
104  }
105 
106  _subdivision_updated = true;
107 }
108 
109 
110 unsigned int Tri3Subdivision::local_node_number(unsigned int node_id) const
111 {
112  return (_nodes[0]->id() == node_id) ? 0 : ( (_nodes[1]->id() == node_id) ? 1 : ( (_nodes[2]->id() == node_id) ? 2 : 3 ) );
113 }
114 
115 
116 unsigned int Tri3Subdivision::get_ordered_valence(unsigned int node_id) const
117 {
118  libmesh_assert_less(node_id, n_neighbors());
120  return get_ordered_node(node_id)->valence();
121 }
122 
123 
124 Node * Tri3Subdivision::get_ordered_node(unsigned int node_id) const
125 {
126  libmesh_assert_less(node_id, 3);
128  return _ordered_nodes[node_id];
129 }
130 
131 } // namespace libMesh
The Tri3 is an element in 2D composed of 3 nodes.
Definition: face_tri3.h:61
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
A Node is like a Point, but with more information.
Definition: node.h:52
Node ** _nodes
Pointers to the nodes we are connected to.
Definition: elem.h:2087
bool _subdivision_updated
true if the subdivision element is ready for use, i.e.
Tri3Subdivision()
Constructor without parent specification.
static const unsigned int prev[3]
A lookup table for the decrement modulo 3 operation, for iterating through the three nodes per elemen...
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
The libMesh namespace provides an interface to certain functionality in the library.
void prepare_subdivision_properties()
Prepares the element for use by reordering the nodes such that the irregular node (valence != 6)...
Node * get_ordered_node(unsigned int node_id) const
bool _is_ghost
true if the element is a ghost element (e.g.
dof_id_type id() const
Definition: dof_object.h:823
libmesh_assert(ctx)
The Tri3Subdivision element is a three-noded subdivision surface shell element used in mechanics calc...
unsigned int local_node_number(unsigned int node_id) const
unsigned int valence() const
Definition: node.h:178
Node * _ordered_nodes[3]
A list containing the ordered nodes such that the irregular node (valence != 6), if there is one...
unsigned int get_ordered_valence(unsigned int node_id) const
static const unsigned int next[3]
A lookup table for the increment modulo 3 operation, for iterating through the three nodes per elemen...
virtual Order default_order() const override
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2331
unsigned int n_neighbors() const
Definition: elem.h:670
virtual ElemType type() const =0
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2299