libMesh
face_tri3_subdivision.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 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 // C++ includes
19 
20 // Local includes
21 #include "libmesh/face_tri3_subdivision.h"
22 #include "libmesh/mesh_subdivision_support.h"
23 
24 namespace libMesh
25 {
26 
27 
28 
29 // ------------------------------------------------------------
30 // Tri3 subdivision class member functions
31 
32 Tri3Subdivision::Tri3Subdivision(Elem * p) : Tri3(p), _subdivision_updated(true)
33 {
34  if (p)
35  {
36  libmesh_assert_equal_to(p->type(), TRI3SUBDIVISION);
37  Tri3Subdivision * sd_elem = static_cast<Tri3Subdivision *>(p);
38  _is_ghost = sd_elem->is_ghost();
39 
40  if (!_is_ghost)
41  {
42  _ordered_nodes[0] = sd_elem->get_ordered_node(0);
43  _ordered_nodes[1] = sd_elem->get_ordered_node(1);
44  _ordered_nodes[2] = sd_elem->get_ordered_node(2);
45  }
46  }
47 }
48 
49 
50 void Tri3Subdivision::prepare_subdivision_properties()
51 {
52  /*
53  * Find the index of the irregular vertex, if any.
54  * The current implementation can only handle triangles with
55  * no more than one irregular vertex. That is, a vertex with
56  * valence != 6.
57  */
58  unsigned int irregular_idx = 0;
59  for (unsigned int i = 0; i < 3; ++i)
60  {
61  if (this->node_ptr(i)->valence() != 6)
62  {
63  irregular_idx = i;
64  if (this->node_ptr(MeshTools::Subdivision::next[i])->valence() != 6 || this->node_ptr(MeshTools::Subdivision::prev[i])->valence() != 6)
65  libmesh_error_msg("Error: The mesh contains elements with more than one irregular vertex!");
66  }
67  }
68 
69  /*
70  * Rotate ordered vertices such that ordered_nodes[0] is the
71  * irregular vertex. Doing this once in advance lets the evaluation
72  * of subdivision interpolation be much more efficient afterward.
73  */
74  switch (irregular_idx)
75  {
76  case 0:
77  _ordered_nodes[0] = this->node_ptr(0);
78  _ordered_nodes[1] = this->node_ptr(1);
79  _ordered_nodes[2] = this->node_ptr(2);
80  break;
81  case 1:
82  _ordered_nodes[0] = this->node_ptr(1);
83  _ordered_nodes[1] = this->node_ptr(2);
84  _ordered_nodes[2] = this->node_ptr(0);
85  break;
86  case 2:
87  _ordered_nodes[0] = this->node_ptr(2);
88  _ordered_nodes[1] = this->node_ptr(0);
89  _ordered_nodes[2] = this->node_ptr(1);
90  break;
91  default:
92  libmesh_error_msg("Unrecognized irregular_idx = " << irregular_idx);
93  }
94 
95  _subdivision_updated = true;
96 }
97 
98 
99 unsigned int Tri3Subdivision::local_node_number(unsigned int node_id) const
100 {
101  return (_nodes[0]->id() == node_id) ? 0 : ( (_nodes[1]->id() == node_id) ? 1 : ( (_nodes[2]->id() == node_id) ? 2 : 3 ) );
102 }
103 
104 
105 unsigned int Tri3Subdivision::get_ordered_valence(unsigned int node_id) const
106 {
107  libmesh_assert_less(node_id, n_neighbors());
108  libmesh_assert(_subdivision_updated);
109  return get_ordered_node(node_id)->valence();
110 }
111 
112 
113 Node * Tri3Subdivision::get_ordered_node(unsigned int node_id) const
114 {
115  libmesh_assert_less(node_id, 3);
116  libmesh_assert(_subdivision_updated);
117  return _ordered_nodes[node_id];
118 }
119 
120 } // namespace libMesh
Node ** _nodes
Pointers to the nodes we are connected to.
Definition: elem.h:1615
static const unsigned int prev[3]
A lookup table for the decrement modulo 3 operation, for iterating through the three nodes per elemen...
unsigned int n_neighbors() const
Definition: elem.h:613
The libMesh namespace provides an interface to certain functionality in the library.
libmesh_assert(j)
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:1874
static const unsigned int next[3]
A lookup table for the increment modulo 3 operation, for iterating through the three nodes per elemen...
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1831
dof_id_type id() const
Definition: dof_object.h:632