Flow123d  release_1.8.2-1603-g0109a2b
ref_element.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file ref_element.hh
15  * @brief Class RefElement defines numbering of vertices, sides, calculation of normal vectors etc.
16  * @author Jan Stebel
17  * @todo
18  *
19  * - design interface in such a way, that we can change numbering
20  * - design numbering and orientations on ref element that is consistent (orientation and numbering od 2d el. match sides of 3d),
21  * and possibly allows permute vertices of elements so that sides sharing an edge match numbering and orientation (we dos'nt need permute faces)
22  *
23  * Proposal(prefers combinatoric order) :
24  * 1D - orientation V0 -> V1
25  *
26  * 2D - edges: E0: V0 -> V1,
27  * E1: V0 -> V2
28  * E2: V1 -> V2
29  * This maximize number of edge orientations achievable by edge permutations
30  * edge numbering edge orientation( in original numbering)
31  * 0 1 2 + + +
32  * 0 2 1 - + +
33  * 1 0 2 + + -
34  * 1 2 0 - - +
35  * 2 0 1 + - -
36  * 2 1 0 - - -
37  *
38  * vertices edges normal (out = +)
39  * 3D - sides: S0: 0 1 2 E0 E1 E3 -
40  * S1: 0 1 3 E0 E2 E4 +
41  * S2: 0 2 3 E1 E2 E5 -
42  * S3: 1 2 3 E3 E4 E5 -
43  *
44  * edges: E0: V0 -> V1 x direction
45  * E1: V0 -> V2 y direction
46  * E2: V0 -> V3 z direction
47  * E3: V1 -> V2
48  * E4: V1 -> V3
49  * E5: V2 -> V3
50  *
51  * - functions from DEAL.ii:
52  * bool is_inside_unit_cell( point )
53  * line_to_cell_vertices(line, vertex) vertex index on line to index on whole element
54  * face_to_cell_vertices(face, vertex, Orientation), Orientation should be some class describing permutation of shared face to element's face/side
55  * face_to_cel_lines
56  * standard_to_real_face_vertex(vertex, Orientation), maps vertex to permuted face
57  * real_to_standard_face_vertex - inverse
58  * ... same for line; we should need also something like standard_to_real_line_vertex; Deal dosn;t support Orientation changes for 2D element faces
59  * Point unit_cell_vertex(vertex) - coordinates
60  * project_to_unit_cell
61  * distance_to_unit_cell
62  * d_linear_shape_function
63  *
64  * - can not change numbering of element sides due to DarcyFlow, which use hardwired side numbering in construction of basis functions
65  *
66  *
67  */
68 
69 #ifndef REF_ELEMENT_HH_
70 #define REF_ELEMENT_HH_
71 
72 #include <armadillo>
73 
74 /*
75  * Ordering of nodes and sides in reference elements
76  * =================================================
77  *
78  * 1D element (line segment) 2D element (triangle) 3D element (tetrahedron)
79  *
80  * y
81  * .
82  * ,/
83  * /
84  * 2
85  * y ,/|`\
86  * ^ ,/ | `\
87  * | ,/ '. `\
88  * 2 ,/ | `\
89  * |`\ ,/ | `\
90  * | `\ 0-----------'.--------1 --> x
91  * | `\ `\. | ,/
92  * | `\ `\. | ,/
93  * | `\ `\. '. ,/
94  * 0----------1 --> x 0----------1 --> x `\. |/
95  * `3
96  * `\.
97  * ` z
98  *
99  * side id node ids side id node ids side id node ids normal
100  * 0 1 0 1,2 0 1,2,3 OUT
101  * 1 0 1 0,2 1 0,2,3 IN
102  * 2 0,1 2 0,1,3 OUT
103  * 3 0,1,2 IN
104  *
105  *
106  *
107  *
108  *
109  *
110  */
111 template<unsigned int dim>
113 {
114 public:
115 
116  /**
117  * Return local coordinates of given node.
118  * @param nid Node number.
119  */
120  static arma::vec::fixed<dim> node_coords(unsigned int nid);
121 
122  /**
123  * Return barycentric coordinates of given node.
124  * @param nid Node number.
125  */
126  static arma::vec::fixed<dim+1> node_barycentric_coords(unsigned int nid);
127 
128  /**
129  * Compute normal vector to a given side.
130  * @param sid Side number.
131  */
132  static arma::vec::fixed<dim> normal_vector(unsigned int sid);
133 
134  static double side_measure(unsigned int sid);
135 
136  /**
137  * Returns index of the node that is oposite to side of given index @p sid.
138  * Note: It is dependent on current node and side numbering.
139  * @param sid Side number.
140  */
141  static unsigned int oposite_node(unsigned int sid);
142 
143  /**
144  * Return index of 1D line, shared by two faces @p f1 and @p f2 of the reference tetrahedron.
145  * Implemented only for @p dim == 3.
146  */
147  static unsigned int line_between_faces(unsigned int f1, unsigned int f2);
148 
149 
150  /**
151  * Number of sides.
152  */
153  static const unsigned int n_sides = dim + 1;
154 
155  /**
156  * Number of vertices.
157  */
158  static const unsigned int n_nodes = dim + 1;
159 
160  /**
161  * Number of nodes on one side.
162  */
163  static const unsigned int n_nodes_per_side = dim;
164 
165  /// Number of lines on boundary of one side.
166  static const unsigned int n_lines_per_side = ( dim == 3 ? 3 : 0);
167 
168  /// Number of lines, i.e. @p object of dimension @p dim-2 on the boundary of the reference element.
169  static const unsigned int n_lines = ( dim == 3 ? 6 : 0);
170 
171  /**
172  * Node numbers for each side.
173  */
174  static const unsigned int side_nodes[n_sides][n_nodes_per_side];
175 
176  /**
177  * Indices of 1D lines of the 2D sides of an tetrahedron. Nonempty only for @p dim==3.
178  */
179  static const unsigned int side_lines[n_sides][n_lines_per_side];
180 
181  /**
182  * Nodes of 1D lines of the tetrahedron.
183  */
184  static const unsigned int line_nodes[n_lines][2];
185 
186  /**
187  * Number of permutations of nodes on sides.
188  * dim value
189  * -----------
190  * 1 1
191  * 2 2
192  * 3 6
193  */
194  static const unsigned int n_side_permutations = (dim+1)*(2*dim*dim-5*dim+6)/6;
195 
196  /**
197  * Permutations of nodes on sides.
198  */
200 
201  /**
202  * For a given permutation @p p of nodes finds its index within @p side_permutations.
203  * @param p Permutation of nodes.
204  */
205  static unsigned int permutation_index(unsigned int p[n_nodes_per_side]);
206 
207 };
208 
209 
210 template<unsigned int dim>
211 inline unsigned int RefElement<dim>::oposite_node(unsigned int sid)
212 {
213  // Is dependent on current node and side numbering.
214  return n_sides - sid - 1;
215  // (sid + dim) % (dim + 1); //older numbering
216 }
217 
218 
219 
220 
221 #endif /* REF_ELEMENT_HH_ */
static arma::vec::fixed< dim > normal_vector(unsigned int sid)
const unsigned int line_nodes[][2]
Definition: ref_element.cc:69
static arma::vec::fixed< dim > node_coords(unsigned int nid)
Definition: ref_element.cc:80
static unsigned int permutation_index(unsigned int p[n_nodes_per_side])
Definition: ref_element.cc:206
static unsigned int line_between_faces(unsigned int f1, unsigned int f2)
static const unsigned int n_side_permutations
Definition: ref_element.hh:194
static unsigned int oposite_node(unsigned int sid)
Definition: ref_element.hh:211
const unsigned int side_lines[][3]
Definition: ref_element.cc:60
const unsigned int side_nodes[][1]
Definition: ref_element.cc:40
static const unsigned int n_lines_per_side
Number of lines on boundary of one side.
Definition: ref_element.hh:166
static double side_measure(unsigned int sid)
static const unsigned int n_lines
Number of lines, i.e. object of dimension dim-2 on the boundary of the reference element.
Definition: ref_element.hh:169
const unsigned int side_permutations[][n_nodes_per_side]
Definition: ref_element.cc:26
static const unsigned int n_sides
Definition: ref_element.hh:153
static const unsigned int n_nodes
Definition: ref_element.hh:158
static arma::vec::fixed< dim+1 > node_barycentric_coords(unsigned int nid)
Definition: ref_element.cc:95
static const unsigned int n_nodes_per_side
Definition: ref_element.hh:163