TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Champ_Q4_implementation.h
1/****************************************************************************
2* Copyright (c) 2022, 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#ifndef Champ_Q4_implementation_included
17#define Champ_Q4_implementation_included
18
19#include <Champ_implementation_divers.h>
20#include <TRUSTTab.h>
21
23{
24public:
25
26 DoubleVect& valeur_a_elem(const DoubleVect& position, DoubleVect& val, int le_poly) const override;
27 double valeur_a_elem_compo(const DoubleVect& position, int le_poly, int ncomp) const override;
28 DoubleTab& valeur_aux_elems(const DoubleTab& positions, const IntVect& les_polys, DoubleTab& valeurs) const override;
29 DoubleVect& valeur_aux_elems_compo(const DoubleTab& positions, const IntVect& les_polys, DoubleVect& valeurs, int ncomp) const override;
30 DoubleTab& valeur_aux_sommets(const Domaine&, DoubleTab&) const override;
31 DoubleVect& valeur_aux_sommets_compo(const Domaine&, DoubleVect&, int) const override;
32 DoubleTab& remplir_coord_noeuds(DoubleTab& positions) const override;
33 int remplir_coord_noeuds_et_polys(DoubleTab& positions, IntVect& polys) const override;
34 int imprime_Q4(Sortie&, int) const;
35};
36
37/*! @brief Calcule la coordonnee barycentrique d'un point (x,y) par rapport au sommet specifie d'un triangle ou d'un rectange (un element)
38 *
39 * Ce calcul concerne un point 2D.
40 *
41 * @param (IntTab& polys) tableau contenant les numeros des elements par rapport auxquels on veut calculer une coordonnee barycentrique. polys(i,0) est l'indice du sommet 0 de l'element i dans le tableau des coordonnees (coord).
42 * @param (DoubleTab& coord) les coordonnees des sommets par auxquels on veut calculer les coordonnees barycentriques.
43 * @param (double x) la premiere coordonnee cartesienne du point dont on veut calculer les coordonnees barycentriques
44 * @param (double y) la deuxieme coordonnee cartesienne du point dont on veut calculer les coordonnees barycentriques
45 * @param (int le_poly) le numero de l'element (dans le tableau polys) par rapport auquel on calculera la coordonnee barycentrique.
46 * @param (int i) le numero du sommet par rapport auquel on veut la coordonnee barycentrique.
47 * @return (double) la coordonnee barycentrique du point (x,y) par rapport au sommet specifie (i) dans l'element specifie (le_poly)
48 * @throws erreur arithmetique, denominateur nul
49 * @throws erreur de calcul, coordonnee barycentrique invalide
50 */
51inline double coord_barycentrique(const IntTab& polys, const DoubleTab& coord, double x, double y, int le_poly, int i)
52{
53 int som0, som1, som2;
54 int nb_som_elem = polys.dimension(1);
55 //Distinction du calcul de la coordonnee barycentrique en fonction du type de l element
56 //Cas Triangle
57 if (nb_som_elem == 3)
58 {
59 switch(i)
60 {
61 case 0:
62 {
63 som0 = polys(le_poly, 0);
64 som1 = polys(le_poly, 1);
65 som2 = polys(le_poly, 2);
66 break;
67 }
68 case 1:
69 {
70 som0 = polys(le_poly, 1);
71 som1 = polys(le_poly, 2);
72 som2 = polys(le_poly, 0);
73 break;
74 }
75 case 2:
76 {
77 som0 = polys(le_poly, 2);
78 som1 = polys(le_poly, 0);
79 som2 = polys(le_poly, 1);
80 break;
81 }
82 default:
83 {
84 som0 = -1;
85 som1 = -1;
86 som2 = -1;
87 Cerr << "Error in Champ_P1::coord_barycentrique : " << finl;
88 Cerr << "A triangle does not have " << i << "nodes " << finl;
90 }
91
92 }
93 double den = (coord(som2, 0) - coord(som1, 0)) * (coord(som0, 1) - coord(som1, 1)) - (coord(som2, 1) - coord(som1, 1)) * (coord(som0, 0) - coord(som1, 0));
94
95 double num = (coord(som2, 0) - coord(som1, 0)) * (y - coord(som1, 1)) - (coord(som2, 1) - coord(som1, 1)) * (x - coord(som1, 0));
96
97 assert(den != 0.);
98 double coord_bary = num / den;
99 if ((coord_bary < -Objet_U::precision_geom) || (coord_bary > 1. + Objet_U::precision_geom))
100 {
101 Cerr << "WARNING: The barycentric coordinate of point :" << finl;
102 Cerr << "x= " << x << " y=" << y << finl;
103 Cerr << "is not between 0 and 1 : " << coord_bary << finl;
104 Cerr << "On the element " << le_poly << " of the processor " << Process::me() << finl;
105 }
106 return coord_bary;
107 }
108 //Cas Rectangle
109 else if (nb_som_elem == 4)
110 {
111 double alpha_x = 0.;
112 double alpha_y = 0.;
113 double delta_x, delta_y;
114// int som0,som1,som2;
115 double x0, y0;
116
117 switch(i)
118 {
119 case 0:
120 {
121 alpha_x = -1.;
122 alpha_y = -1;
123
124 break;
125 }
126 case 1:
127 {
128 alpha_x = 1.;
129 alpha_y = -1.;
130
131 break;
132 }
133 case 2:
134 {
135 alpha_x = -1.;
136 alpha_y = 1.;
137
138 break;
139 }
140 case 3:
141 {
142 alpha_x = 1.;
143 alpha_y = 1.;
144
145 break;
146 }
147 default:
148 {
149 Cerr << "Error in Champ_P1::coord_barycentrique : " << finl;
151 }
152
153 }
154
155 som0 = polys(le_poly, 0);
156 som1 = polys(le_poly, 1);
157 som2 = polys(le_poly, 2);
158 delta_x = coord(som1, 0) - coord(som0, 0);
159 delta_y = coord(som2, 1) - coord(som0, 1);
160 x0 = coord(som0, 0) + delta_x / 2.;
161 y0 = coord(som0, 1) + delta_y / 2.;
162 double coord_bary = 0.25 * (1. + 2. * alpha_x * (x - x0) / delta_x) * (1. + 2. * alpha_y * (y - y0) / delta_y);
163
164 if ((coord_bary < -Objet_U::precision_geom) || (coord_bary > 1. + Objet_U::precision_geom))
165 {
166 Cerr << "WARNING: The barycentric coordinate of point :" << finl;
167 Cerr << "x= " << x << " y=" << y << finl;
168 Cerr << "is not between 0 and 1 : " << coord_bary << finl;
169 Cerr << "On the element " << le_poly << " of the processor " << Process::me() << finl;
170 }
171 return coord_bary;
172 }
173
174 Cerr << "The number of nodes by element " << nb_som_elem << " does not correspond to a treated situation." << finl;
176 return 0.;
177}
178
179/*! @brief Calcule la coordonnee barycentrique d'un point (x,y,z) par rapport au sommet specifie d'un tetraedre ou d'un hexaedre (un element)
180 *
181 * Ce calcul concerne un point 3D.
182 *
183 * @param (IntTab& polys) tableau contenant les numeros des elements par rapport auxquels on veut calculer une coordonnee barycentrique. polys(i,0) est l'indice du sommet 0 de l'element i dans le tableau des coordonnees (coord).
184 * @param (DoubleTab& coord) les coordonnees des sommets par auxquels on veut calculer les coordonnees barycentriques.
185 * @param (double x) la premiere coordonnee cartesienne du point dont on veut calculer les coordonnees barycentriques
186 * @param (double y) la deuxieme coordonnee cartesienne du point dont on veut calculer les coordonnees barycentriques
187 * @param (double z) la troisieme coordonnee cartesienne du point dont on veut calculer les coordonnees barycentriques
188 * @param (int le_poly) le numero de l'element (dans le tableau polys) par rapport auquel on calculera la coordonnee barycentrique.
189 * @param (int i) le numero du sommet par rapport auquel on veut la coordonnee barycentrique.
190 * @return (double) la coordonnee barycentrique du point (x,y,z) par rapport au sommet specifie (i) dans l'element specifie (le_poly)
191 * @throws un tetraedre n'a pas plus de 4 sommets
192 * @throws un hexaedre n'a pas plus de 8 sommets
193 * @throws erreur arithmetique, denominateur nul
194 * @throws erreur de calcul, coordonnee barycentrique invalide
195 */
196inline double coord_barycentrique(const IntTab& polys, const DoubleTab& coord, double x, double y, double z, int le_poly, int i)
197{
198 int som0, som1, som2, som3;
199 int nb_som_elem = polys.dimension(1);
200 //Distinction du calcul de la coordonnee barycentrique en fonction du type de l element
201 //Cas Tetraedre
202 if (nb_som_elem == 4)
203 {
204 switch(i)
205 {
206 case 0:
207 {
208 som0 = polys(le_poly, 0);
209 som1 = polys(le_poly, 1);
210 som2 = polys(le_poly, 2);
211 som3 = polys(le_poly, 3);
212 break;
213 }
214 case 1:
215 {
216 som0 = polys(le_poly, 1);
217 som1 = polys(le_poly, 2);
218 som2 = polys(le_poly, 3);
219 som3 = polys(le_poly, 0);
220 break;
221 }
222 case 2:
223 {
224 som0 = polys(le_poly, 2);
225 som1 = polys(le_poly, 3);
226 som2 = polys(le_poly, 0);
227 som3 = polys(le_poly, 1);
228 break;
229 }
230 case 3:
231 {
232 som0 = polys(le_poly, 3);
233 som1 = polys(le_poly, 0);
234 som2 = polys(le_poly, 1);
235 som3 = polys(le_poly, 2);
236 break;
237 }
238 default:
239 {
240 som0 = -1;
241 som1 = -1;
242 som2 = -1;
243 som3 = -1;
244 Cerr << "Error in Champ_P1::coord_barycentrique : " << finl;
245 Cerr << "A tetrahedron does not have " << i << "nodes " << finl;
247 }
248 }
249
250 double xp = (coord(som2, 1) - coord(som1, 1)) * (coord(som0, 2) - coord(som1, 2)) - (coord(som2, 2) - coord(som1, 2)) * (coord(som0, 1) - coord(som1, 1));
251 double yp = (coord(som2, 2) - coord(som1, 2)) * (coord(som0, 0) - coord(som1, 0)) - (coord(som2, 0) - coord(som1, 0)) * (coord(som0, 2) - coord(som1, 2));
252 double zp = (coord(som2, 0) - coord(som1, 0)) * (coord(som0, 1) - coord(som1, 1)) - (coord(som2, 1) - coord(som1, 1)) * (coord(som0, 0) - coord(som1, 0));
253 double den = xp * (coord(som3, 0) - coord(som1, 0)) + yp * (coord(som3, 1) - coord(som1, 1)) + zp * (coord(som3, 2) - coord(som1, 2));
254
255 xp = (coord(som2, 1) - coord(som1, 1)) * (z - coord(som1, 2)) - (coord(som2, 2) - coord(som1, 2)) * (y - coord(som1, 1));
256 yp = (coord(som2, 2) - coord(som1, 2)) * (x - coord(som1, 0)) - (coord(som2, 0) - coord(som1, 0)) * (z - coord(som1, 2));
257 zp = (coord(som2, 0) - coord(som1, 0)) * (y - coord(som1, 1)) - (coord(som2, 1) - coord(som1, 1)) * (x - coord(som1, 0));
258 double num = xp * (coord(som3, 0) - coord(som1, 0)) + yp * (coord(som3, 1) - coord(som1, 1)) + zp * (coord(som3, 2) - coord(som1, 2));
259
260 assert(den != 0.);
261 double coord_bary = num / den;
262 if ((coord_bary < -Objet_U::precision_geom) || (coord_bary > 1. + Objet_U::precision_geom))
263 {
264 Cerr << "WARNING: The barycentric coordinate of point :" << finl;
265 Cerr << "x= " << x << " y=" << y << " z=" << z << finl;
266 Cerr << "is not between 0 and 1 : " << coord_bary << finl;
267 Cerr << "On the element " << le_poly << " of the processor " << Process::me() << finl;
268 }
269 return coord_bary;
270 }
271 //Cas Hexaedre
272 else if (nb_som_elem == 8)
273 {
274 double alpha_x = 0.;
275 double alpha_y = 0.;
276 double alpha_z = 0.;
277 double delta_x, delta_y, delta_z;
278 //int som0,som1,som2;
279 double x0, y0, z0;
280
281 switch(i)
282 {
283 case 0:
284 {
285 alpha_x = -1.;
286 alpha_y = -1.;
287 alpha_z = -1.;
288 break;
289 }
290 case 1:
291 {
292 alpha_x = 1.;
293 alpha_y = -1.;
294 alpha_z = -1.;
295 break;
296 }
297 case 2:
298 {
299 alpha_x = -1.;
300 alpha_y = 1.;
301 alpha_z = -1.;
302 break;
303 }
304 case 3:
305 {
306 alpha_x = 1.;
307 alpha_y = 1.;
308 alpha_z = -1.;
309 break;
310 }
311 case 4:
312 {
313 alpha_x = -1.;
314 alpha_y = -1;
315 alpha_z = 1.;
316 break;
317 }
318 case 5:
319 {
320 alpha_x = 1.;
321 alpha_y = -1.;
322 alpha_z = 1.;
323 break;
324 }
325 case 6:
326 {
327 alpha_x = -1.;
328 alpha_y = 1.;
329 alpha_z = 1.;
330 break;
331 }
332 case 7:
333 {
334 alpha_x = 1.;
335 alpha_y = 1.;
336 alpha_z = 1.;
337 break;
338 }
339 default:
340 {
341 Cerr << "Error in Champ_P1::coord_barycentrique : " << finl;
343 }
344 }
345
346 som0 = polys(le_poly, 0);
347 som1 = polys(le_poly, 1);
348 som2 = polys(le_poly, 2);
349 som3 = polys(le_poly, 4);
350
351 delta_x = coord(som1, 0) - coord(som0, 0);
352 delta_y = coord(som2, 1) - coord(som0, 1);
353 delta_z = coord(som3, 2) - coord(som0, 2);
354
355 x0 = coord(som0, 0) + delta_x / 2.;
356 y0 = coord(som0, 1) + delta_y / 2.;
357 z0 = coord(som0, 2) + delta_z / 2.;
358
359 double coord_bary = (1. / 8.) * (1. + 2. * alpha_x * (x - x0) / delta_x) * (1. + 2. * alpha_y * (y - y0) / delta_y) * (1. + 2. * alpha_z * (z - z0) / delta_z);
360
361 if ((coord_bary < -Objet_U::precision_geom) || (coord_bary > 1. + Objet_U::precision_geom))
362 {
363 Cerr << "WARNING: The barycentric coordinate of point :" << finl;
364 Cerr << "x= " << x << " y=" << y << " z=" << z << finl;
365 Cerr << "is not between 0 and 1 : " << coord_bary << finl;
366 Cerr << "On the element " << le_poly << " of the processor " << Process::me() << finl;
367 }
368 return coord_bary;
369 }
370
371 Cerr << "The number of nodes by element " << nb_som_elem << " does not correspond to a treated situation." << finl;
373 return 0.;
374}
375
376#endif
DoubleTab & valeur_aux_sommets(const Domaine &, DoubleTab &) const override
DoubleVect & valeur_aux_elems_compo(const DoubleTab &positions, const IntVect &les_polys, DoubleVect &valeurs, int ncomp) const override
double valeur_a_elem_compo(const DoubleVect &position, int le_poly, int ncomp) const override
int imprime_Q4(Sortie &, int) const
DoubleTab & valeur_aux_elems(const DoubleTab &positions, const IntVect &les_polys, DoubleTab &valeurs) const override
int remplir_coord_noeuds_et_polys(DoubleTab &positions, IntVect &polys) const override
DoubleVect & valeur_a_elem(const DoubleVect &position, DoubleVect &val, int le_poly) const override
DoubleVect & valeur_aux_sommets_compo(const Domaine &, DoubleVect &, int) const override
DoubleTab & remplir_coord_noeuds(DoubleTab &positions) const override
static double precision_geom
Definition Objet_U.h:86
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133