Flow123d
ref_element.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2007 Technical University of Liberec. All rights reserved.
4  *
5  * Please make a following refer to Flow123d on your project site if you use the program for any purpose,
6  * especially for academic research:
7  * Flow123d, Research Centre: Advanced Remedial Technologies, Technical University of Liberec, Czech Republic
8  *
9  * This program is free software; you can redistribute it and/or modify it under the terms
10  * of the GNU General Public License version 3 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along with this program; if not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 021110-1307, USA.
18  *
19  *
20  * $Id$
21  * $Revision$
22  * $LastChangedBy$
23  * $LastChangedDate$
24  *
25  * @file
26  * @brief Class RefElement defines numbering of vertices, sides, calculation of normal vectors etc.
27  * @author Jan Stebel
28  */
29 
30 #include "system/global_defs.h"
31 #include "system/system.hh"
32 #include "mesh/ref_element.hh"
33 
34 using namespace arma;
35 using namespace std;
36 
37 template<> const unsigned int RefElement<1>::side_permutations[][n_nodes_per_side] = { { 0 } };
38 
39 template<> const unsigned int RefElement<2>::side_permutations[][n_nodes_per_side] = { { 0, 1 }, { 1, 0 } };
40 
41 template<> const unsigned int RefElement<3>::side_permutations[][n_nodes_per_side] = {
42  { 0, 1, 2 },
43  { 0, 2, 1 },
44  { 1, 0, 2 },
45  { 1, 2, 0 },
46  { 2, 0, 1 },
47  { 2, 1, 0 }
48 };
49 
50 
51 template<> const unsigned int RefElement<1>::side_nodes[][1] = {
52  { 0 },
53  { 1 }
54 };
55 
56 template<> const unsigned int RefElement<2>::side_nodes[][2] = {
57 /* { 0, 1 },
58  { 0, 2 },
59  { 1, 2 }*/
60  { 0, 1},
61  { 1, 2},
62  { 0, 2}
63 };
64 
65 template<> const unsigned int RefElement<3>::side_nodes[][3] = {
66 /* { 0, 1, 2 },
67  { 0, 1, 3 },
68  { 0, 2, 3 },
69  { 1, 2, 3 }*/
70  {1,2,3},
71  {0,2,3},
72  {0,1,3},
73  {0,1,2}
74 };
75 
76 
77 
78 template<> const unsigned int RefElement<3>::side_lines[][3] = {
79  {3,4,5},
80  {1,2,5},
81  {0,2,4},
82  {0,1,3}
83 };
84 
85 //template<unsigned int dim>
86 //const unsigned int RefElement<dim>::side_lines[][0] = {{}};
87 
88 
89 
90 template<> const unsigned int RefElement<3>::line_nodes[][2] = {
91  {0,1},
92  {0,2},
93  {0,3},
94  {1,2},
95  {1,3},
96  {2,3}
97 };
98 //template<unsigned int dim>
99 //const unsigned int RefElement<dim>::line_nodes[][0] = {};
100 
101 
102 
103 template<unsigned int dim>
104 vec::fixed<dim+1> RefElement<dim>::node_coords(unsigned int nid)
105 {
106  ASSERT(nid < n_nodes, "Vertex number is out of range!");
107 
108  vec::fixed<dim+1> p;
109  p.zeros();
110 
111  if (nid == 0)
112  p(dim) = 1;
113  else
114  p(nid-1) = 1;
115 
116  return p;
117 }
118 
119 
120 template<unsigned int dim>
121 vec::fixed<dim> RefElement<dim>::normal_vector(unsigned int sid)
122 {
123  ASSERT(sid < n_sides, "Side number is out of range!");
124  vec::fixed<dim> p;
125  unsigned int new_sid = sid;
126 
127  if (dim==1)
128  new_sid = (sid+1)%2;
129  else if (dim==2)
130  new_sid = (sid+2)%3;
131 
132  if (new_sid == 0)
133  p.fill(1./sqrt(dim));
134  else
135  {
136  p.zeros();
137  p(new_sid-1) = -1;
138  }
139 
140  return p;
141 }
142 
143 
144 
145 template <>
146 unsigned int RefElement<3>::line_between_faces(unsigned int f1, unsigned int f2) {
147  unsigned int i,j;
148  i=j=0;
149  while (side_lines[f1][i] != side_lines[f2][j])
150  if (side_lines[f1][i] < side_lines[f2][j]) i++;
151  else j++;
152  return side_lines[f1][i];
153 }
154 
155 
156 
157 template<unsigned int dim>
158 unsigned int RefElement<dim>::permutation_index(unsigned int p[n_nodes_per_side])
159 {
160  unsigned int index;
161  for (index = 0; index < n_side_permutations; index++)
162  if (equal(p, p + n_nodes_per_side, side_permutations[index]))
163  return index;
164 
165  xprintf(PrgErr, "Side permutation not found.\n");
166 
167  // The following line is present in order to suppress compilers warning
168  // about missing return value.
169  return 0;
170 }
171 
172 
173 template class RefElement<1>;
174 template class RefElement<2>;
175 template class RefElement<3>;
176 
177 
178 
179