face_tri3_subdivision.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 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
21 #include "libmesh/enum_order.h"
22 
23 namespace libMesh
24 {
25 
26 
27 
28 // ------------------------------------------------------------
29 // Tri3 subdivision class member functions
30 
31 Tri3Subdivision::Tri3Subdivision(Elem * p) : Tri3(p), _subdivision_updated(true)
32 {
33  if (p)
34  {
35  libmesh_assert_equal_to(p->type(), TRI3SUBDIVISION);
36  Tri3Subdivision * sd_elem = static_cast<Tri3Subdivision *>(p);
37  _is_ghost = sd_elem->is_ghost();
38 
39  if (!_is_ghost)
40  {
41  _ordered_nodes[0] = sd_elem->get_ordered_node(0);
42  _ordered_nodes[1] = sd_elem->get_ordered_node(1);
43  _ordered_nodes[2] = sd_elem->get_ordered_node(2);
44  }
45  }
46 }
47 
48 
49 
51 {
52  return FOURTH;
53 }
54 
55 
56 
58 {
59  /*
60  * Find the index of the irregular vertex, if any.
61  * The current implementation can only handle triangles with
62  * no more than one irregular vertex. That is, a vertex with
63  * valence != 6.
64  */
65  unsigned int irregular_idx = 0;
66  for (unsigned int i = 0; i < 3; ++i)
67  {
68  if (this->node_ptr(i)->valence() != 6)
69  {
70  irregular_idx = i;
71  if (this->node_ptr(MeshTools::Subdivision::next[i])->valence() != 6 || this->node_ptr(MeshTools::Subdivision::prev[i])->valence() != 6)
72  libmesh_error_msg("Error: The mesh contains elements with more than one irregular vertex!");
73  }
74  }
75 
76  /*
77  * Rotate ordered vertices such that ordered_nodes[0] is the
78  * irregular vertex. Doing this once in advance lets the evaluation
79  * of subdivision interpolation be much more efficient afterward.
80  */
81  switch (irregular_idx)
82  {
83  case 0:
84  _ordered_nodes[0] = this->node_ptr(0);
85  _ordered_nodes[1] = this->node_ptr(1);
86  _ordered_nodes[2] = this->node_ptr(2);
87  break;
88  case 1:
89  _ordered_nodes[0] = this->node_ptr(1);
90  _ordered_nodes[1] = this->node_ptr(2);
91  _ordered_nodes[2] = this->node_ptr(0);
92  break;
93  case 2:
94  _ordered_nodes[0] = this->node_ptr(2);
95  _ordered_nodes[1] = this->node_ptr(0);
96  _ordered_nodes[2] = this->node_ptr(1);
97  break;
98  default:
99  libmesh_error_msg("Unrecognized irregular_idx = " << irregular_idx);
100  }
101 
102  _subdivision_updated = true;
103 }
104 
105 
106 unsigned int Tri3Subdivision::local_node_number(unsigned int node_id) const
107 {
108  return (_nodes[0]->id() == node_id) ? 0 : ( (_nodes[1]->id() == node_id) ? 1 : ( (_nodes[2]->id() == node_id) ? 2 : 3 ) );
109 }
110 
111 
112 unsigned int Tri3Subdivision::get_ordered_valence(unsigned int node_id) const
113 {
114  libmesh_assert_less(node_id, n_neighbors());
115  libmesh_assert(_subdivision_updated);
116  return get_ordered_node(node_id)->valence();
117 }
118 
119 
120 Node * Tri3Subdivision::get_ordered_node(unsigned int node_id) const
121 {
122  libmesh_assert_less(node_id, 3);
123  libmesh_assert(_subdivision_updated);
124  return _ordered_nodes[node_id];
125 }
126 
127 } // namespace libMesh
A 2D triangular element with 3 nodes.
Definition: face_tri3.h:56
A geometric point in (x,y,z) space associated with a DOF.
Definition: node.h:52
Node ** _nodes
Definition: elem.h:1695
static const unsigned int prev[3]
The base class for all geometric element types.
Definition: elem.h:100
Node * get_ordered_node(unsigned int node_id) const
dof_id_type id() const
Definition: dof_object.h:655
A surface shell element used in mechanics calculations.
unsigned int local_node_number(unsigned int node_id) const
unsigned int valence() const
Definition: node.h:166
unsigned int get_ordered_valence(unsigned int node_id) const
static const unsigned int next[3]
virtual Order default_order() const override
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:1957
unsigned int n_neighbors() const
Definition: elem.h:644
virtual ElemType type() const =0
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1914