TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Quadrature_Ord5_Polygone.cpp
1/****************************************************************************
2 * Copyright (c) 2024, CEA
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9 *
10 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13 *
14 *****************************************************************************/
15
16#include <Quadrature_Ord5_Polygone.h>
17#include <cmath>
18/****************************************************************/
19/* Formule de quadrature 1D/2D : Formule Gauss-Lobatto Aide-memoire elements finis Ern p.220 */
20/****************************************************************/
21namespace
22{
23constexpr int nb_pts_integ_tri = {7};
24// constexpr int nb_pts_integ_quad = {16};
25// constexpr int nb_pts_integ_quad = {14}; // less expensive
26constexpr int nb_pts_integ_facet = {5};
27// constexpr double invsqrt5 = 1./2.2360679774;
28// constexpr double CONSTP = 0.5+invsqrt5/2.;
29// constexpr double CONSTM = 0.5-invsqrt5/2.;
30// constexpr double WEIGHTS_QUAD[16] = {1./144., 1./144., 1./144., 1./144., 5./144.,5./144.,5./144.,5./144.,5./144.,5./144.,5./144.,5./144.,25./144.,25./144.,25./144.,25./144.};
31
32/*constexpr double LAMBDA_QUAD[16][4] =
33{
34 {1.,0.,0.,0.},
35 {0.,1.,0.,0.},
36 {0.,0.,0.,1.},
37 {0.,0.,1.,0.},
38 {::CONSTM,::CONSTP,0.,0.},
39 {::CONSTP,::CONSTM,0.,0.},
40 {0.,::CONSTM,0.,::CONSTP},
41 {0.,::CONSTP,0.,::CONSTM},
42 {0.,0,::CONSTP,::CONSTM},
43 {0.,0,::CONSTM,::CONSTP},
44 {::CONSTP,0.,::CONSTM,0.},
45 {::CONSTM,0.,::CONSTP,0.},
46 {::invsqrt5,::CONSTM,::CONSTM,0.},
47 {::CONSTM,::invsqrt5,0.,::CONSTM},
48 {0.,::CONSTM,::CONSTM,::invsqrt5},
49 {::CONSTM,0.,::invsqrt5,::CONSTM}
50}; // Barycentric coordinates coefficients of integration points in elem */
51// constexpr double WEIGHTS_QUAD_POLY[16] = {1./144., 1./144., 1./144., 1./144., 5./144.,5./144.,5./144.,5./144.,5./144.,5./144.,5./144.,5./144.,25./144.,25./144.,25./144.,25./144.};
52
53/*constexpr double LAMBDA_QUAD_POLY[16][4] =
54{
55 {1.,0.,0.,0.},
56 {0.,1.,0.,0.},
57 {0.,0.,1.,0.},
58 {0.,0.,0.,1.},
59 {::CONSTM,::CONSTP,0.,0.},
60 {::CONSTP,::CONSTM,0.,0.},
61 {0.,::CONSTM,::CONSTP,0},
62 {0.,::CONSTP,::CONSTM,0},
63 {0.,0,::CONSTM,::CONSTP},
64 {0.,0,::CONSTP,::CONSTM},
65 {::CONSTP,0.,0.,::CONSTM},
66 {::CONSTM,0.,0.,::CONSTP},
67 {::invsqrt5,::CONSTM,0.,::CONSTM},
68 {::CONSTM,::invsqrt5,::CONSTM,0.},
69 {0.,::CONSTM,::invsqrt5,::CONSTM},
70 {::CONSTM,0.,::CONSTM,::invsqrt5}
71}; // Barycentric coordinates coefficients of integration points in elem */
72
73constexpr int N_TRI_IN_QUAD = {2};
74constexpr int TRI_IN_QUAD[2][3] =
75{
76 {0, 1, 2},
77 {0, 2, 3}
78}; // List of vertices that decomposes quad in tri */*
79
80constexpr int TRI_IN_CART[2][3] =
81{
82 {0, 1, 2},
83 {1, 2, 3}
84}; // List of vertices that decomposes quad in tri */
85
86constexpr double WEIGHTS_TRI[7] = {0.225, 0.125939180544827, 0.125939180544827, 0.125939180544827, 0.132394152788506, 0.132394152788506, 0.132394152788506};
87constexpr double WEIGHTS_FACETS[5] = {7. / 90., 32. / 90., 12. / 90., 32. / 90., 7. / 90.};
88constexpr double LAMBDA_TRI[7][3] =
89{
90 {1. / 3, 1. / 3, 1. / 3},
91 {0.797426985353087, 0.101286507323456, 0.101286507323456},
92 {0.101286507323456, 0.797426985353087, 0.101286507323456},
93 {0.101286507323456, 0.101286507323456, 0.797426985353087},
94 {0.059715871789770, 0.470142064105115, 0.470142064105115},
95 {0.470142064105115, 0.059715871789770, 0.470142064105115},
96 {0.470142064105115, 0.470142064105115, 0.059715871789770}
97}; // Barycentric coordinates coefficients of integration points in elem */
98constexpr double LAMBDA_FACETS[5][2] =
99{
100 {1., 0.},
101 {3. / 4., 1. / 4.},
102 {1. / 2., 1. / 2.},
103 {1. / 4., 3. / 4.},
104 {0., 1.}
105}; // Barycentric coordinates coefficients of integration points on facets */
106}
107
109{
110 assert(Objet_U::dimension == 2); // no triangle in 3D!
111
112 // Get infos of the mesh
113 const IntTab& vert_elems = dom_->domaine().les_elems();
114 int nb_elem_tot = dom_->nb_elem_tot();
115 int ndim = Objet_U::dimension;
116 const DoubleTab& xs = dom_->domaine().les_sommets(); // facets barycentre
117 DoubleVect& volumes = dom_->volumes();
118 const IntTab& nfaces_elem = dom_->get_nfaces_elem(); // IntTab that indicate the number of facet of each elem
119 const IntTab& elem_faces = dom_->elem_faces(); // IntTab connectivity between elem and facet
120 const IntTab& face_sommets = dom_->face_sommets(); // IntTab connectivity between facet and vertices
121 const DoubleTab& xp = dom_->xp(); // barycentre elem
122
123 // Filling the table Tab_nb_pts_integ
124 int cumul = 0;
125 tab_nb_pts_integ_.resize(dom_->nb_elem_tot());
126 ind_pts_integ_.resize(dom_->nb_elem_tot());
127 DoubleTab lambda_tri; // tesselation
128 IntTab tri_in_quad; // tesselation
129
131 int nb_pts_quad;
132 // only for quad
133 tri_in_quad.resize(::N_TRI_IN_QUAD, 3);
134 if (dom_->get_type_elem()->que_suis_je() == "Quadri_poly")
135 {
136 for (int n_tri = 0; n_tri < ::N_TRI_IN_QUAD; n_tri++)
137 for (int i = 0; i < 3; i++)
138 tri_in_quad(n_tri, i) = ::TRI_IN_CART[n_tri][i];
139 }
140 else
141 {
142 for (int n_tri = 0; n_tri < ::N_TRI_IN_QUAD; n_tri++)
143 for (int i = 0; i < 3; i++)
144 tri_in_quad(n_tri, i) = ::TRI_IN_QUAD[n_tri][i];
145 }
146
147 for (int e = 0; e < dom_->nb_elem_tot(); e++)
148 {
149 int nsom = nfaces_elem(e); // Récupération du nombre de faces de l'élément
150 switch (nsom)
151 {
152 case 3: // triangle
153 tab_nb_pts_integ_(e) = ::nb_pts_integ_tri;
154 ind_pts_integ_(e) = cumul;
155 cumul += ::nb_pts_integ_tri;
156 nb_pts_integ_max_ = std::max(nb_pts_integ_max_, ::nb_pts_integ_tri);
157 break;
158 case 4: // quadrangle
159 nb_pts_quad = 2 * ::nb_pts_integ_tri; // tesselation with 2 triangle S1S4S3 and S1S2S3
160 tab_nb_pts_integ_(e) = nb_pts_quad;
161 ind_pts_integ_(e) = cumul;
162 cumul += nb_pts_quad;
163 nb_pts_integ_max_ = std::max(nb_pts_integ_max_, nb_pts_quad);
164 break;
165 default: // other
166 int nb_pts_integ_e = nsom * ::nb_pts_integ_tri;
167 tab_nb_pts_integ_(e) = nb_pts_integ_e;
168 ind_pts_integ_(e) = cumul;
169 cumul += nb_pts_integ_e;
170 nb_pts_integ_max_ = std::max(nb_pts_integ_max_, nb_pts_integ_e);
171 break;
172 }
173 }
174 // Adjustment of weights for quadrature of triangle
175 weights_tri_.resize(::nb_pts_integ_tri);
176 weights_tri_[::nb_pts_integ_tri - 1] = 1.;
177 lambda_tri.resize(::nb_pts_integ_tri, 3); // tesselation
178 for (int pts = 0; pts < ::nb_pts_integ_tri; pts++)
179 {
180 if (pts < nb_pts_integ_tri - 1)
181 {
182 weights_tri_(pts) = ::WEIGHTS_TRI[pts];
183 weights_tri_(nb_pts_integ_tri - 1) -= weights_tri_(pts);
184 }
185 lambda_tri(pts, 0) = ::LAMBDA_TRI[pts][0];
186 lambda_tri(pts, 1) = ::LAMBDA_TRI[pts][1];
187 lambda_tri(pts, 2) = 1. - lambda_tri(pts, 1) - lambda_tri(pts, 0);
188 }
189
191
192 // We ensure that sum(weights)=1 and sum(Lambda[i])=1
193
194 integ_points_.resize(cumul, ndim); // cumul : number total of integ points
195 weights_.resize(cumul); // Each weight with global numerotation: Linked by the tables ind_elem and tab_nb_elem
196
197 for (int e = 0; e < nb_elem_tot; e++)
198 {
199 int ind_elem_e = ind_pts_integ_(e); // It may be faster to recalculate this with GPU
200 int nsom = nfaces_elem(e); // Récupération du nombre de faces de l'élément
201 switch (nsom)
202 {
203 case 3: // triangle
204 for (int pts = 0; pts < ::nb_pts_integ_tri; pts++)
205 {
206 for (int dim = 0; dim < ndim; dim++)
207 for (int loc_vert = 0; loc_vert < 3; loc_vert++) // ndim+2 = number of vertices
208 integ_points_(ind_elem_e + pts, dim) += xs(vert_elems(e, loc_vert), dim) * lambda_tri(pts, loc_vert);
209 weights_(ind_elem_e + pts) = weights_tri_(pts);
210 }
211 break;
212 case 4: // quadrangle
213 for (int n_tri = 0; n_tri < ::N_TRI_IN_QUAD; n_tri++)
214 {
215 double weight_scale = calculateWeightScale(vert_elems, xs, volumes, e, tri_in_quad(n_tri, 0), tri_in_quad(n_tri, 1), tri_in_quad(n_tri, 2));
216 for (int pts = 0; pts < ::nb_pts_integ_tri; pts++)
217 {
218 for (int dim = 0; dim < ndim; dim++)
219 for (int loc_vert = 0; loc_vert < 3; loc_vert++)
220 integ_points_(ind_elem_e + pts + n_tri * ::nb_pts_integ_tri, dim) += xs(vert_elems(e, tri_in_quad(n_tri, loc_vert)), dim) * lambda_tri(pts, loc_vert);
221 weights_(ind_elem_e + pts + n_tri * ::nb_pts_integ_tri) = weight_scale * weights_tri_(pts);
222 }
223 }
224 break;
225 default: // other
226 for (int n_tri = 0; n_tri < nsom; n_tri++)
227 {
228 int f = elem_faces(e, n_tri);
229 double weight_scale = calculateWeightScale(volumes(e), xs(face_sommets(f, 0), 0), xs(face_sommets(f, 0), 1), xs(face_sommets(f, 1), 0), xs(face_sommets(f, 1), 1), xp(e, 0), xp(e, 1));
230 for (int pts = 0; pts < ::nb_pts_integ_tri; pts++)
231 {
232 for (int dim = 0; dim < ndim; dim++)
233 {
234 for (int loc_vert = 0; loc_vert < 2; loc_vert++)
235 integ_points_(ind_elem_e + pts + n_tri * ::nb_pts_integ_tri, dim) += xs(face_sommets(f, loc_vert), dim) * lambda_tri(pts, loc_vert);
236 integ_points_(ind_elem_e + pts + n_tri * ::nb_pts_integ_tri, dim) += xp(e, dim) * lambda_tri(pts, 2);
237 }
238 weights_(ind_elem_e + pts + n_tri * ::nb_pts_integ_tri) = weight_scale * weights_tri_(pts);
239 }
240 }
241 break;
242 }
243 }
244}
245
247{
248 nb_pts_integ_facets_ = ::nb_pts_integ_facet;
249 assert(Objet_U::dimension == 2); // no quadrangle in 3D!
250
251 int nb_faces = dom_->nb_faces();
252 int ndim = Objet_U::dimension;
253 DoubleTab& xs = dom_->domaine().les_sommets(); // facets barycentre
254 IntTab& face_sommets = dom_->face_sommets();
255
256 integ_points_facets_.resize(nb_faces, nb_pts_integ_facets_, Objet_U::dimension); // one point per facets, 2D -> 1*2 = 2 columns
258
259 // We ensure that sum(weights)=1 and sum(Lambda[i])=1
260 DoubleTab lambda_facets(nb_pts_integ_facets_, ndim);
262 for (int pts = 0; pts < nb_pts_integ_facets_; pts++)
263 {
264 if (pts < nb_pts_integ_facets_ - 1)
265 {
266 weights_facets_(pts) = ::WEIGHTS_FACETS[pts];
268 }
269 lambda_facets(pts, 0) = ::LAMBDA_FACETS[pts][0];
270 lambda_facets(pts, 1) = 1. - lambda_facets(pts, 0);
271 }
272
273 for (int f = 0; f < nb_faces; f++)
274 {
275 for (int pts = 0; pts < nb_pts_integ_facets_; pts++)
276 {
277 for (int dim = 0; dim < ndim; dim++)
278 {
279 integ_points_facets_(f, pts, dim) = 0.;
280 for (int loc_vert = 0; loc_vert < 2; loc_vert++)
281 integ_points_facets_(f, pts, dim) += xs(face_sommets(f, loc_vert), dim) * lambda_facets(pts, loc_vert);
282 }
283 }
284 }
285}
static int dimension
Definition Objet_U.h:99
static double mp_max(double)
Definition Process.cpp:376
DoubleTab weights_facets_
DoubleTab integ_points_
double calculateWeightScale(const IntTab &vert_elems, const DoubleTab &xs, DoubleVect &volumes, int e, int s1, int s2, int s3)
DoubleTab weights_tri_
DoubleTab integ_points_facets_
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469