1 /*
2 XLiFE++ is an extended library of finite elements written in C++
3 Copyright (C) 2014 Lunéville, Eric; Kielbasiewicz, Nicolas; Lafranche, Yvon; Nguyen, Manh-Ha; Chambeyron, Colin
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 This program 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
12 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 /*!
18 \file Hexahedron.cpp
19 \author Y. Lafranche
20 \since 3 Fev 2014
21 \date 19 Mar 2014
22
23 \brief Implementation of xlifepp::subdivision::Hexahedron class members and related functions
24 */
25
26 #include "Hexahedron.hpp"
27
28 #include <algorithm>
29 using namespace std;
30
31 namespace xlifepp {
32 namespace subdivision {
33
34 //-------------------------------------------------------------------------------
35 // Static variables
36 //-------------------------------------------------------------------------------
37 // Index array defining the edges according to the following numering convention:
38 // edge #1=(1,2), edge #2 =(3,4), edge #3 =(5,6), edge #4 =(7,8),
39 // edge #5=(1,3), edge #6 =(2,4), edge #7 =(5,7), edge #8 =(6,8),
40 // edge #9=(1,5), edge #10=(2,6), edge #11=(3,7), edge #12=(4,8),
41 short Hexahedron::rkEdge[/* nb_edges_ */][2] = {{0,1}, {2,3}, {4,5}, {6,7},
42 {0,2}, {1,3}, {4,6}, {5,7},
43 {0,4}, {1,5}, {2,6}, {3,7}};
44
45 // Index array defining the faces according to the following numering convention:
46 // face #1=(1,3,4,2), face #2=(5,7,8,6) : orthogonal to X
47 // face #3=(1,2,6,5), face #4=(3,4,8,7) : orthogonal to Y
48 // face #5=(1,5,7,3), face #6=(2,6,8,4) : orthogonal to Z
49 short Hexahedron::rkFace[/* nb_faces_ */][4] = {{0,2,3,1}, {4,6,7,5}, {0,1,5,4},
50 {2,3,7,6}, {0,4,6,2}, {1,5,7,3}};
51
52 // Array containing the edge numbers (>=1) defining a face
53 // face #1=(5,2,6,1), face #2=(7,4,8,3), face #3=(1,10,3,9),
54 // face #4=(2,12,4,11), face #5=(9,7,11,5), face #6=(10,8,12,6)
55 short Hexahedron::nuEdge[/* nb_faces_ */][4] = {{5,2,6,1}, {7,4,8,3}, {1,10,3,9},
56 {2,12,4,11}, {9,7,11,5}, {10,8,12,6}};
57 //-------------------------------------------------------------------------------
58 // Constructors, Destructor
59 //-------------------------------------------------------------------------------
60 /*!
61 Conversion constructor. Constructor by vertices, given by their rank in the list
62 */
Hexahedron(const number_t num,const number_t rV1,const number_t rV2,const number_t rV3,const number_t rV4,const number_t rV5,const number_t rV6,const number_t rV7,const number_t rV8,const number_t bdSideNum)63 Hexahedron::Hexahedron(const number_t num,
64 const number_t rV1, const number_t rV2, const number_t rV3, const number_t rV4,
65 const number_t rV5, const number_t rV6, const number_t rV7, const number_t rV8,
66 const number_t bdSideNum)
67 :CartesianFig<Hexahedron>(num,bdSideNum){
68 vertices_[0] = rV1;
69 vertices_[1] = rV2;
70 vertices_[2] = rV3;
71 vertices_[3] = rV4;
72 vertices_[4] = rV5;
73 vertices_[5] = rV6;
74 vertices_[6] = rV7;
75 vertices_[7] = rV8;
76 }
77
78 //-------------------------------------------------------------------------------
79 // Other public member functions
80 //-------------------------------------------------------------------------------
81 /*!
82 returns the numbers (>= 1) of the edges defining the face number i
83 */
numEdgesOfFace(const number_t i)84 vector<short> Hexahedron::numEdgesOfFace(const number_t i) {
85 return vector<short> (nuEdge[i-1], nuEdge[i-1]+4);
86 }
87 /*!
88 returns the ranks (>= 0) of the vertices defining the edges of the hexahedron
89 */
rkEdgeVertices()90 vector<pair<short,short> > Hexahedron::rkEdgeVertices() {
91 vector<pair<short,short> > V(nb_edges_);
92 for (number_t i=0; i<nb_edges_; i++) { V[i] = make_pair(rkEdge[i][0],rkEdge[i][1]); }
93 return V;
94 }
95 /*!
96 This function gives the local position of the vertices of any hexahedron of
97 the mesh correspondig to the numbering convention explained on top of the
98 Hexahedron class header file (Hexahedron.hpp).
99
100 The numbering convention of high order vertices is deduced from a triple tensor
101 product of the standard numbering over the segment defined by the integers [0,1,...k].
102 Thus, the entry BC[i] in the returned vector BC contains a vector of 3 integers whose
103 components BC[i][j] are such that 0<= BC[i][j] <= k, where k is the order of the mesh.
104 Each component is the result of a permutation of a 3D tensor product of the uniform
105 subdivision of the interval [0,1,...k]. This gives an intrinsic way of numbering and
106 localization of the points if these components are sorted in alphanumeric order.
107 Nota: this does not match with the numbering of the vertices XLiFE++ uses.
108
109 Moreover, the returned vector gives the location of the vertices according
110 to the way they are encountered in the numbering process implemented by the
111 functions GeomFigureMesh<T_>::createHOV, GeomFigureMesh<T_>::createHOeV, HexahedronMesh::createHOfV
112 and HexahedronMesh::createHOiV.
113 */
numberingOfVertices(const number_t Order)114 vector< vector<number_t> > Hexahedron::numberingOfVertices(const number_t Order) {
115 number_t order = Order;
116 if (order < 1) {order = 1;}
117
118 number_t NbVert((order+1)*(order+1)*(order+1));
119 vector<number_t> V(3,0);
120 vector< vector<number_t> > BC(NbVert,V);
121
122 // main vertices (order 1)
123 // #1 -> (0, 0, 0), #2 -> (0, 0, k), #3 -> (0, k, 0), #4 -> (0, k, k)
124 // #5 -> (k, 0, 0), #6 -> (k, 0, k), #7 -> (k, k, 0), #8 -> (k, k, k)
125 // int rkVert[] = {3,7,2,6, 0,4,1,5}; // Vertices 4,8,3,7, 1,5,2,6 in Melina++
126 const number_t ivx(0), ivy(1), ivz(2);
127 number_t indBC(0);
128 for (number_t ix=0; ix<2; ix++) {
129 V[ivx] = ix*order;
130 for (number_t iy=0; iy<2; iy++) {
131 V[ivy] = iy*order;
132 for (number_t iz=0; iz<2; iz++) {
133 V[ivz] = iz*order;
134 // BC[rkVert[indBC++]] = V;
135 BC[indBC++] = V;
136 }
137 }
138 }
139 // Order 2 : rkVert[] = {4, 12, 8, 14, 24, 17, 3, 18, 7, 13, 25, 19, 26, 27, 23, 16, 22, 10, 1, 15, 5, 20, 21, 11, 2, 9, 6}
140
141 /*
142 edge vertices (cf. GeomFigureMesh<T_>::createHOeV)
143 vertex numbering is decreasing along the edges
144 1. 4 edges along Z : edge #1 =(1,2) -> (0, 0, .)
145 edge #2 =(3,4) -> (0, k, .)
146 edge #3 =(5,6) -> (k, 0, .)
147 edge #4 =(7,8) -> (k, k, .)
148 2. 4 edges along Y : edge #5 =(1,3) -> (0, ., 0)
149 edge #6 =(2,4) -> (0, ., k)
150 edge #7 =(5,7) -> (k, ., 0)
151 edge #8 =(6,8) -> (k, ., k)
152 3. 4 edges along X : edge #9 =(1,5) -> (., 0, 0)
153 edge #10=(2,6) -> (., 0, k)
154 edge #11=(3,7) -> (., k, 0)
155 edge #12=(4,8) -> (., k, k)
156 */
157 number_t tiv[]={2,1,0}; // Z, Y, X
158 for (number_t indEdge=0; indEdge<nb_edges_; indEdge++) {
159 V = BC[rkEdge[indEdge][0]];
160 number_t iv = tiv[indEdge/4];
161 for (number_t i1=1; i1<order; i1++) {
162 V[iv] = order-i1;
163 BC[indBC++] = V;
164 }
165 }
166 /*
167 face vertices (cf. HexahedronMesh::createHOfV)
168 1. 2 faces orthogonal to X : face #1=(1,3,4,2) -> (0, ., .)
169 face #2=(5,7,8,6) -> (k, ., .)
170 increasing order along Y first then Z
171 2. 2 faces orthogonal to Y : face #3=(1,2,6,5) -> (., 0, .)
172 face #4=(3,4,8,7) -> (., k, .)
173 increasing order along Z first then X
174 3. 2 faces orthogonal to Z : face #5=(1,5,7,3) -> (., ., 0)
175 face #6=(2,6,8,4) -> (., ., k)
176 increasing order along X first then Y
177 */
178 number_t tiv1[]={2,0,1}, tiv2[]={1,2,0}; // couples (iv1,iv2) : (Z,Y), (X,Z) and (Y,X)
179 for (number_t indFace=0; indFace<nb_faces_; indFace++) {
180 V = BC[rkFace[indFace][0]];
181 number_t iv1 = tiv1[indFace/2], iv2 = tiv2[indFace/2];
182 for (number_t i1=1; i1<order; i1++) {
183 V[iv1] = i1;
184 for (number_t i2=1; i2<order; i2++) {
185 V[iv2] = i2;
186 BC[indBC++] = V;
187 }
188 }
189 }
190 // internal vertices (cf. HexahedronMesh::createHOiV)
191 // increasing order along X first then Y then Z
192 for (number_t iz=1; iz<order; iz++) {
193 V[ivz] = iz;
194 for (number_t iy=1; iy<order; iy++) {
195 V[ivy] = iy;
196 for (number_t ix=1; ix<order; ix++) {
197 V[ivx] = ix;
198 BC[indBC++] = V;
199 }
200 }
201 }
202 return BC;
203 }
204
205 } // end of namespace subdivision
206 } // end of namespace xlifepp
207