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