TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Quadrature_Ord3_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_Ord3_Polygone.h>
17/****************************************************************/
18/* Formule de quadrature 1D/2D : Formule Gauss-Lobatto Aide-memoire elements finis Ern p.220 */
19/****************************************************************/
20namespace
21{
22constexpr int nb_pts_integ_tri = {3};
23// constexpr int nb_pts_integ_quad = {9};
24// constexpr int nb_pts_integ_quad = {5}; // less expensive
25constexpr int nb_pts_integ_facet = {3};
26
27// constexpr double WEIGHTS_QUAD[9] = {1./36., 1./36., 1./36., 1./36., 1./9., 1./9., 1./9., 1./9., 4./9.};
28// constexpr double WEIGHTS_QUAD_POLY[9] = {1./36., 1./36., 1./36., 1./36., 1./9., 1./9., 1./9., 1./9., 4./9.};
29// constexpr double WEIGHTS_QUAD[5] = {1./6., 1./6., 1./6., 1./6., 2./6.}; // less expensive -> wrong, need to be ponderate by the fraction of volume of each triangle
30// constexpr double WEIGHTS_QUAD_POLY[5] = {1./6., 1./6., 1./6., 1./6., 2./6.}; // less expensive
31constexpr double WEIGHTS_FACETS[3] = {1. / 6., 1. / 6., 2. / 3.};
32/*constexpr double LAMBDA_QUAD[9][4] =
33{
34 {1.,0.,0.,0.},
35 {0.,1.,0.,0.},
36 {0.,0.,1.,0.},
37 {0.,0.,0.,1.},
38 {1./2.,1./2.,0.,0.},
39 {0.,1./2.,0.,1./2.},
40 {0.,0.,1./2.,1./2.},
41 {1./2.,0.,1./2.,0.},
42 {1./4.,1./4.,1./4.,1./4.}
43}; // Barycentric coordinates coefficients of integration points in elem */
44/*constexpr double LAMBDA_QUAD_POLY[9][4] =
45{
46 {1.,0.,0.,0.},
47 {0.,1.,0.,0.},
48 {0.,0.,0.,1.},
49 {0.,0.,1.,0.},
50 {1./2.,1./2.,0.,0.},
51 {0.,1./2.,1./2.,0.},
52 {0.,0.,1./2.,1./2.},
53 {1./2.,0.,0.,1./2.},
54 {1./4.,1./4.,1./4.,1./4.}
55}; // Barycentric coordinates coefficients of integration points in elem */
56
57/*constexpr double LAMBDA_QUAD[5][4] = // doesn't work for the moment
58{
59 {1./2.,1./2.,0.,0.},
60 {0.,1./2.,0.,1./2.},
61 {0.,0.,1./2.,1./2.},
62 {1./2.,0.,1./2.,0.},
63 {1./2.,0.,0.,1./2.}
64}; // Barycentric coordinates coefficients of integration points in elem */
65// less expensive
66
67/*constexpr double LAMBDA_QUAD_POLY[5][4] = // doesn't work for the moment
68{
69 {1./2.,1./2.,0.,0.},
70 {0.,1./2.,1./2.,0},
71 {0.,0.,1./2.,1./2.},
72 {1./2.,0.,0.,1./2.},
73 {1./2.,0.,1./2.,0.}
74}; // Barycentric coordinates coefficients of integration points in elem */
75// less expensive
76
77constexpr int N_TRI_IN_QUAD = {2};
78constexpr int TRI_IN_QUAD[2][3] =
79{
80 {0, 1, 2},
81 {0, 2, 3}
82}; // List of vertices that decomposes quad in tri */*
83
84constexpr int TRI_IN_CART[2][3] =
85{
86 {0, 1, 2},
87 {1, 2, 3}
88}; // List of vertices that decomposes quad in tri */
89
90constexpr double LAMBDA_FACETS[3][2] =
91{
92 {1., 0.},
93 {0., 1.},
94 {1. / 2., 1. / 2.}
95}; // Barycentric coordinates coefficients of integration points on facets */
96
97constexpr double LAMBDA_TRI[3][3] =
98{
99 {1. / 2., 1. / 2., 0.},
100 {0., 1. / 2., 1. / 2.},
101 {1. / 2., 0., 1. / 2.}
102}; // Barycentric coordinates coefficients of integration points in elem */
103constexpr double WEIGHTS_TRI[3] = {1. / 3, 1. / 3, 1. / 3};
104}
105
107{
108 assert(Objet_U::dimension == 2); // no triangle in 3D!
109
110 // Get infos of the mesh
111 const IntTab& vert_elems = dom_->domaine().les_elems();
112 int nb_elem_tot = dom_->nb_elem_tot();
113 int ndim = Objet_U::dimension;
114 const DoubleTab& xs = dom_->domaine().les_sommets(); // facets barycentre
115 DoubleVect& volumes = dom_->volumes();
116 const IntTab& nfaces_elem = dom_->get_nfaces_elem(); // IntTab that indicate the number of facet of each elem
117 const IntTab& elem_faces = dom_->elem_faces(); // IntTab connectivity between elem and facet
118 const IntTab& face_sommets = dom_->face_sommets(); // IntTab connectivity between facet and vertices
119 const DoubleTab& xp = dom_->xp(); // barycentre elem
120
121 // Filling the table Tab_nb_pts_integ
122 int cumul = 0;
123 tab_nb_pts_integ_.resize(dom_->nb_elem_tot());
124 ind_pts_integ_.resize(dom_->nb_elem_tot());
125 DoubleTab lambda_tri; // tesselation
126 IntTab tri_in_quad; // tesselation
127
129 int nb_pts_quad;
130 // only for quad
131 tri_in_quad.resize(::N_TRI_IN_QUAD, 3);
132 if (dom_->get_type_elem()->que_suis_je() == "Quadri_poly")
133 {
134 for (int n_tri = 0; n_tri < ::N_TRI_IN_QUAD; n_tri++)
135 for (int i = 0; i < 3; i++)
136 tri_in_quad(n_tri, i) = ::TRI_IN_CART[n_tri][i];
137 }
138 else
139 {
140 for (int n_tri = 0; n_tri < ::N_TRI_IN_QUAD; n_tri++)
141 for (int i = 0; i < 3; i++)
142 tri_in_quad(n_tri, i) = ::TRI_IN_QUAD[n_tri][i];
143 }
144
145 for (int e = 0; e < dom_->nb_elem_tot(); e++)
146 {
147 int nsom = nfaces_elem(e); // Récupération du nombre de faces de l'élément
148 switch (nsom)
149 {
150 case 3: // triangle
151 tab_nb_pts_integ_(e) = ::nb_pts_integ_tri;
152 ind_pts_integ_(e) = cumul;
153 cumul += ::nb_pts_integ_tri;
154 nb_pts_integ_max_ = std::max(nb_pts_integ_max_, ::nb_pts_integ_tri);
155 break;
156 case 4: // quadrangle
157 nb_pts_quad = 2 * ::nb_pts_integ_tri; // tesselation with 2 triangle S1S4S3 and S1S2S3
158 tab_nb_pts_integ_(e) = nb_pts_quad;
159 ind_pts_integ_(e) = cumul;
160 cumul += nb_pts_quad;
161 nb_pts_integ_max_ = std::max(nb_pts_integ_max_, nb_pts_quad);
162 break;
163 default: // other
164 int nb_pts_integ_e = nsom * ::nb_pts_integ_tri;
165 tab_nb_pts_integ_(e) = nb_pts_integ_e;
166 ind_pts_integ_(e) = cumul;
167 cumul += nb_pts_integ_e;
168 nb_pts_integ_max_ = std::max(nb_pts_integ_max_, nb_pts_integ_e);
169 break;
170 }
171 }
172 // Adjustment of weights for quadrature of triangle
173 weights_tri_.resize(::nb_pts_integ_tri);
174 weights_tri_[::nb_pts_integ_tri - 1] = 1.;
175 lambda_tri.resize(::nb_pts_integ_tri, 3); // tesselation
176 for (int pts = 0; pts < ::nb_pts_integ_tri; pts++)
177 {
178 if (pts < nb_pts_integ_tri - 1)
179 {
180 weights_tri_(pts) = ::WEIGHTS_TRI[pts];
181 weights_tri_(nb_pts_integ_tri - 1) -= weights_tri_(pts);
182 }
183 lambda_tri(pts, 0) = ::LAMBDA_TRI[pts][0];
184 lambda_tri(pts, 1) = ::LAMBDA_TRI[pts][1];
185 lambda_tri(pts, 2) = 1. - lambda_tri(pts, 1) - lambda_tri(pts, 0);
186 }
187
189
190 // We ensure that sum(weights)=1 and sum(Lambda[i])=1
191
192 integ_points_.resize(cumul, ndim); // cumul : number total of integ points
193 weights_.resize(cumul); // Each weight with global numerotation: Linked by the tables ind_elem and tab_nb_elem
194
195 for (int e = 0; e < nb_elem_tot; e++)
196 {
197 int ind_elem_e = ind_pts_integ_(e); // It may be faster to recalculate this with GPU
198 int nsom = nfaces_elem(e); // Récupération du nombre de faces de l'élément
199 switch (nsom)
200 {
201 case 3: // triangle
202 for (int pts = 0; pts < ::nb_pts_integ_tri; pts++)
203 {
204 for (int dim = 0; dim < ndim; dim++)
205 for (int loc_vert = 0; loc_vert < 3; loc_vert++) // ndim+2 = number of vertices
206 integ_points_(ind_elem_e + pts, dim) += xs(vert_elems(e, loc_vert), dim) * lambda_tri(pts, loc_vert);
207 weights_(ind_elem_e + pts) = weights_tri_(pts);
208 }
209 break;
210 case 4: // quadrangle
211 for (int n_tri = 0; n_tri < ::N_TRI_IN_QUAD; n_tri++)
212 {
213 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));
214 for (int pts = 0; pts < ::nb_pts_integ_tri; pts++)
215 {
216 for (int dim = 0; dim < ndim; dim++)
217 for (int loc_vert = 0; loc_vert < 3; loc_vert++)
218 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);
219 weights_(ind_elem_e + pts + n_tri * ::nb_pts_integ_tri) = weight_scale * weights_tri_(pts);
220 }
221 }
222 break;
223 default: // other
224 for (int n_tri = 0; n_tri < nsom; n_tri++)
225 {
226 int f = elem_faces(e, n_tri);
227 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));
228 for (int pts = 0; pts < ::nb_pts_integ_tri; pts++)
229 {
230 for (int dim = 0; dim < ndim; dim++)
231 {
232 for (int loc_vert = 0; loc_vert < 2; loc_vert++)
233 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);
234 integ_points_(ind_elem_e + pts + n_tri * ::nb_pts_integ_tri, dim) += xp(e, dim) * lambda_tri(pts, 2);
235 }
236 weights_(ind_elem_e + pts + n_tri * ::nb_pts_integ_tri) = weight_scale * weights_tri_(pts);
237 }
238 }
239 break;
240 }
241 }
242}
243
245{
246 nb_pts_integ_facets_ = ::nb_pts_integ_facet;
247 assert(Objet_U::dimension == 2); // no quadrangle in 3D!
248
249 int nb_faces = dom_->nb_faces();
250 int ndim = Objet_U::dimension;
251 DoubleTab& xs = dom_->domaine().les_sommets(); // facets barycentre
252 IntTab& face_sommets = dom_->face_sommets();
253
254 integ_points_facets_.resize(nb_faces, nb_pts_integ_facets_, Objet_U::dimension); // one point per facets, 2D -> 1*2 = 2 columns
256
257 // We ensure that sum(weights)=1 and sum(Lambda[i])=1
258 DoubleTab lambda_facets(nb_pts_integ_facets_, ndim);
260 for (int pts = 0; pts < nb_pts_integ_facets_; pts++)
261 {
262 if (pts < nb_pts_integ_facets_ - 1)
263 {
264 weights_facets_(pts) = ::WEIGHTS_FACETS[pts];
266 }
267 lambda_facets(pts, 0) = ::LAMBDA_FACETS[pts][0];
268 lambda_facets(pts, 1) = 1. - lambda_facets(pts, 0);
269 }
270
271 for (int f = 0; f < nb_faces; f++)
272 {
273 for (int pts = 0; pts < nb_pts_integ_facets_; pts++)
274 {
275 for (int dim = 0; dim < ndim; dim++)
276 {
277 integ_points_facets_(f, pts, dim) = 0.;
278 for (int loc_vert = 0; loc_vert < 2; loc_vert++)
279 integ_points_facets_(f, pts, dim) += xs(face_sommets(f, loc_vert), dim) * lambda_facets(pts, loc_vert);
280 }
281 }
282 }
283}
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