TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Topologie_Maillage_FT.cpp
1/****************************************************************************
2* Copyright (c) 2015 - 2016, 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 <Topologie_Maillage_FT.h>
17#include <TRUST_Deriv.h>
18#include <Transport_Interfaces_FT_Disc.h>
19#include <Motcle.h>
20#include <Remailleur_Collision_FT_Juric.h>
21#include <time.h>
22#include <SFichier.h>
23#include <Domaine_VF.h>
24#include <Connex_components.h>
25#include <Array_tools.h>
26#include <Param.h>
27#include <Check_espace_virtuel.h>
28#include <communications.h>
29
30Implemente_instanciable_sans_constructeur(Topologie_Maillage_FT,"Topologie_Maillage_FT",Objet_U);
31
32
36
38{
39 Cerr << "Topologie_Maillage_FT::printOn" << finl;
41 return os;
42}
43
45{
46 bool juric_pour_tout = false;
47 Param param(que_suis_je());
48 param.ajouter_flag("active", &active_);
49 param.ajouter("type_remaillage", &remailleur_Collision_, Param::REQUIRED);
50 param.ajouter_flag("juric_pour_tout", &juric_pour_tout);
51 param.ajouter_flag("juric_local", &juric_local_);
52 param.ajouter("phase_continue", &phase_continue_);
53 param.dictionnaire("0", 0);
54 param.dictionnaire("1", 1);
55 param.lire_avec_accolades_depuis(is);
56
57 if (juric_pour_tout)
58 {
59 Cerr<<"Error : juric_pour_tout is obsolete and does noting since v1.7.0"<<finl;
60 Cerr<<"remove juric_pour_tout from your datafile"<<finl;
62 }
63 // Verifications qu'on a bien tout lu :
64 if (!active_)
65 {
67 Cerr << "ATTENTION : vous n'avez pas active la gestion des ruptures-coalescences..." << finl;
68 }
69 else
70 {
71 if (!remailleur_Collision_)
72 {
73 Cerr << "Erreur dans Topologie_Maillage_FT::readOn :\n"
74 << " Il faut fournir le type du remailleur et ses parametres.\n"
75 << " Valeur conseillee: Juric { ... }" << finl;
77 }
78 if (!sub_type(Remailleur_Collision_FT_Juric, remailleur_Collision_.valeur()))
79 {
80 Cerr << "Erreur dans Topologie_Maillage_FT::readOn :\n"
81 << " Il faut un remailleur de type Juric" << finl;
83 }
84 }
85 return is;
86}
87
89{
90 if (phase_continue_ < 0.)
91 {
92 Cerr << "Error in Topologie_Maillage_FT::get_phase_continue(): phase_continue must be specified in the data file !" << finl;
94 }
95 return phase_continue_;
96}
97
98/*! @brief tri du tableau tab dans l'ordre croissant.
99 *
100 */
101static inline void trier_trois_entiers(int tab[3])
102{
103 int tmp;
104 int a = tab[0];
105 int b = tab[1];
106 int c = tab[2];
107 if (a > b)
108 {
109 tmp = a;
110 a = b;
111 b = tmp;
112 }
113 if (b > c)
114 {
115 tmp = b;
116 b = c;
117 c = tmp;
118 }
119 if (a > b)
120 {
121 tmp = a;
122 a = b;
123 b = tmp;
124 }
125 tab[0] = a;
126 tab[1] = b;
127 tab[2] = c;
128}
129
130/*! @brief Copie les coordonnees des trois sommets d'indices facette[i] dans la matrice coord.
131 *
132 */
133static inline void get_coord_sommets_triangle(const int facette[3],
134 const DoubleTab& sommets,
135 double coord[3][3])
136{
137 int i;
138 for (i = 0; i < 3; i++)
139 {
140 const int som = facette[i];
141 coord[i][0] = sommets(som,0);
142 coord[i][1] = sommets(som,1);
143 coord[i][2] = sommets(som,2);
144 }
145}
146
147static inline void calcul_equation_plan(const double *coord,
148 const DoubleTab& normales,
149 const int facette,
150 double plan[4])
151{
152 double a = normales(facette, 0);
153 double b = normales(facette, 1);
154 double c = normales(facette, 2);
155 plan[0] = a;
156 plan[1] = b;
157 plan[2] = c;
158 plan[3] = - (a * coord[0] + b * coord[1] + c * coord[2]);
159}
160
161static inline void calcul_distance_plan(const double coord[3][3],
162 const double plan[4],
163 double distance[3])
164{
165 double a = plan[0];
166 double b = plan[1];
167 double c = plan[2];
168 double d = plan[3];
169 int i;
170 for (i = 0; i < 3; i++)
171 distance[i] = a * coord[i][0] + b * coord[i][1] + c * coord[i][2] + d;
172}
173
174/*! @brief Calcul de la distance s_min et s_max par rapport au plan "2" des extremites du segment d'intersection entre un triangle est un plan "1".
175 *
176 * distance_1 est la distance entre les sommets du triangle et le plan "1".
177 * On suppose que les trois valeurs ne sont pas toutes de meme signe
178 * (donc l'intersection est non vide).
179 * distance_2 est la distance entre les sommets du triangle et le plan "2".
180 * On renvoie s_min et s_max avec s_min < s_max.
181 *
182 */
183static inline void calcul_intersection_plan_triangle(const double distance_1[3],
184 const double distance_2[3],
185 double& s_min,
186 double& s_max)
187{
188 int n = 0;
189 double s[2];
190 int i;
191 double z0 = distance_1[2];
192 double d0 = distance_2[2];
193 for (i = 0; i < 3; i++)
194 {
195 double z1 = distance_1[i];
196 double d1 = distance_2[i];
197 if (((z0 > 0.) + (z1 > 0.)) == 1)
198 {
199 // Changement de signe entre le sommet i et le sommet j
200 // Le denominateur ne peut pas etre nul :
201 const double inv_delta = 1. / (z1 - z0);
202 // Calcul de la distance au plan orthogonal aux deux facettes
203 s[n] = (d0 * z1 - d1 * z0) * inv_delta;
204 n++;
205 }
206 z0 = z1;
207 d0 = d1;
208 }
209 assert(n == 2);
210 if (s[0] < s[1])
211 {
212 s_min = s[0];
213 s_max = s[1];
214 }
215 else
216 {
217 s_min = s[1];
218 s_max = s[0];
219 }
220}
221
222// Recodage B. Mathieu
223
224
225// Calcul du determinant
226// det( (p2 - p1) , (p3 - p1) )
227// pour p1, p2 et p3 des vecteurs a deux composantes
228static inline double prod_vect_triangle(double *p1, double *p2, double *p3)
229{
230 return (p2[0]-p1[0])*(p3[1]-p1[1]) - (p2[1]-p1[1])*(p3[0]-p1[0]);
231}
232
233/*! @brief Voir test_intersection_facettes_3D.
234 *
235 * Algorithme B. Mathieu Renvoie 0 si les facettes ne se coupent pas
236 * -1 si 1 sommet commun
237 * -2 si 2 sommets communs
238 * 1 si les facettes se coupent
239 *
240 */
242 int fa70, int fa71,
243 const Maillage_FT_Disc& maillage) const
244{
245 const IntTab& facettes = maillage.facettes();
246 // Sommet commun ?
247 int facette[2][2];
248 facette[0][0] = facettes(fa70, 0);
249 facette[0][1] = facettes(fa70, 1);
250 facette[1][0] = facettes(fa71, 0);
251 facette[1][1] = facettes(fa71, 1);
252 int nb_sommets_communs = 0;
253 if (facette[0][0] == facette[1][0] || facette[0][0] == facette[1][1])
254 nb_sommets_communs++;
255 if (facette[0][1] == facette[1][0] || facette[0][1] == facette[1][1])
256 nb_sommets_communs++;
257
258 if (nb_sommets_communs)
259 return -nb_sommets_communs;
260
261 const DoubleTab& sommets = maillage.sommets();
262 double c[2][2][2];
263 for (int i = 0; i < 2; i++)
264 for (int j = 0; j < 2; j++)
265 {
266 int s = facette[i][j];
267 c[i][j][0] = sommets(s, 0);
268 c[i][j][1] = sommets(s, 1);
269 }
270
271 const double v00 = prod_vect_triangle(c[0][1],c[0][0],c[1][0]);
272 const double v01 = prod_vect_triangle(c[0][1],c[0][0],c[1][1]);
273 if (v00 * v01 > 0.)
274 return 0;
275 const double v10 = prod_vect_triangle(c[1][1],c[1][0],c[0][0]);
276 const double v11 = prod_vect_triangle(c[1][1],c[1][0],c[0][1]);
277 if (v10 * v11 > 0.)
278 return 0;
279
280 return 1;
281}
282
283/*! @brief Teste si les facettes fa70 et fa71 se coupent.
284 *
285 * Renvoie 0 si elles ne se coupent pas,
286 * -1 si elles ont deux sommets communs,
287 * -2 si elles ont trois sommets communs,
288 * -3 si le test preliminaire est positif et l'autre test non
289 * 1 si les facettes se coupent et n'ont aucun sommet commun
290 * -4 si les facettes ont un sommet commun.
291 * L'algorithme est identique a celui decrit dans
292 * http://www.cs.lth.se/home/Tomas_Akenine_Moller/pubs/tritri.pdf
293 * "a fast triangle-triangle intersection test (tomas moller)"
294 *
295 */
297 int fa70, int fa71,
298 const Maillage_FT_Disc& maillage) const
299{
300 // LA PREMIERE PARTIE DU TEST EST SPECIFIQUE AU FRONT-TRACKING:
301 // ignorer les intersections entre facettes voisines.
302
303 // Copie locale des indices des sommets des facettes
304 int facette0[3];
305 int facette1[3];
306 {
307 const IntTab& facettes = maillage.facettes();
308 facette0[0] = facettes(fa70,0);
309 facette0[1] = facettes(fa70,1);
310 facette0[2] = facettes(fa70,2);
311 facette1[0] = facettes(fa71,0);
312 facette1[1] = facettes(fa71,1);
313 facette1[2] = facettes(fa71,2);
314 }
315 // On teste si les facettes ont deux sommets en commun:
316 //int liste_sommets_communs[3];
317 int nb_sommets_communs = 0;
318 trier_trois_entiers(facette0);
319 trier_trois_entiers(facette1);
320 {
321 int i0 = 0;
322 int i1 = 0;
323 while (i0 < 3 && i1 < 3)
324 {
325 const int f0 = facette0[i0];
326 const int f1 = facette1[i1];
327 if (f0 <= f1)
328 i0++;
329 if (f0 >= f1)
330 i1++;
331 if (f0 == f1) // On a trouve un sommet commun :
332 {
333 // liste_sommets_communs[nb_sommets_communs] = f0;
334 nb_sommets_communs++;
335 }
336 }
337 }
338 // Trois sommets communs: c'est une facette dupliquee.
339 // Pas d'intersection...
340 if (nb_sommets_communs == 3)
341 {
342 return -3;
343 }
344 // Si les facettes sont voisines par une arete,
345 // on dit qu'elles n'ont pas d'intersection.
346 if (nb_sommets_communs == 2)
347 {
348 return -2;
349 }
350 // Essai: si les facettes ont un sommet commun,
351 // on dit qu'elles n'ont pas d'intersection
352 if (nb_sommets_communs == 1)
353 {
354 return -4;
355 }
356
357 // ICI COMMENCE L'ALGORITHME DE TOMAS MOLLER...
358
359 // Un sommet ou moins, on cherche une intersection geometrique
360 // On recupere les coordonnees des sommets
361 // coord[i][j] = coordonnee j du sommet i
362 double coord_0[3][3];
363 double coord_1[3][3];
364 {
365 const DoubleTab& sommets = maillage.sommets();
366 get_coord_sommets_triangle(facette0, sommets, coord_0);
367 get_coord_sommets_triangle(facette1, sommets, coord_1);
368 }
369 // Equation du plan contenant la facette
370 // Le plan s'ecrit a[0]*x+a[1]*y+a[2]*z+a[3]=0
371 double equation_plan_0[4];
372 double equation_plan_1[4];
373 {
374 const DoubleTab& facettes_normales = maillage.get_update_normale_facettes();
375 calcul_equation_plan(coord_0[0], facettes_normales, fa70, equation_plan_0);
376 calcul_equation_plan(coord_1[0], facettes_normales, fa71, equation_plan_1);
377 }
378 // Pour chaque sommet, calcul de la distance au plan
379 // equation du plan 0 appliquee aux sommets de la facette 1
380 double distance_plan0_som1[3];
381 // equation du plan 1 appliquee aux sommets de la facette 0
382 double distance_plan1_som0[3];
383 calcul_distance_plan(coord_1, equation_plan_0, distance_plan0_som1);
384 calcul_distance_plan(coord_0, equation_plan_1, distance_plan1_som0);
385 // Y a-t-il changement de signe (sommets de part et d'autre du plan) ?
386 int test_intersection = 0;
387 {
388 int n_positifs_0 = 0;
389 int n_positifs_1 = 0;
390 int i;
391 for (i = 0; i < 3; i++)
392 {
393 n_positifs_0 += (distance_plan0_som1[i] > 0.);
394 n_positifs_1 += (distance_plan1_som0[i] > 0.);
395 }
396 if ((n_positifs_0 * n_positifs_1) % 3 != 0)
397 {
398 test_intersection = -3;
399 }
400 }
401 // Changement de signe => possibilite d'une intersection, on fait le test complet.
402 if (test_intersection)
403 {
404 static const double TOLERANCE_FACETTES_PARALLELES = 1e-12;
405 // Equation d'un plan orthogonal aux deux facettes
406 // normale = produit vectoriel des normales aux facettes
407 double equation_plan_2[4];
408 double a = equation_plan_0[1] * equation_plan_1[2] - equation_plan_0[2] * equation_plan_1[1];
409 double b = equation_plan_0[2] * equation_plan_1[0] - equation_plan_0[0] * equation_plan_1[2];
410 double c = equation_plan_0[0] * equation_plan_1[1] - equation_plan_0[1] * equation_plan_1[0];
411 equation_plan_2[0] = a;
412 equation_plan_2[1] = b;
413 equation_plan_2[2] = c;
414 equation_plan_2[3] = 0.; // Constante : indifferent
415 double norme_carre = a * a + b * b + c * c;
416 // Les normales aux facettes sont unitaires, norme_carre est donc adimensionnel,
417 // c'est le carre du sinus de l'angle entre les facettes.
418 if (norme_carre < TOLERANCE_FACETTES_PARALLELES)
419 {
420 // Les deux facettes sont paralleles et coplanaires
421 test_intersection = 0;
422 }
423 else
424 {
425 double distance_plan2_som0[3];
426 double distance_plan2_som1[3];
427 calcul_distance_plan(coord_0, equation_plan_2, distance_plan2_som0);
428 calcul_distance_plan(coord_1, equation_plan_2, distance_plan2_som1);
429 // Calcul de l'intersection entre la facette_0 et le plan contenant facette_1:
430 // c'est un segment dont les extremites sont a une 'distance' s0_min et s0_max
431 // du plan_2
432 double s0_min, s0_max, s1_min, s1_max;
433 calcul_intersection_plan_triangle(distance_plan1_som0, distance_plan2_som0,
434 s0_min, s0_max);
435 // Idem avec la facette_1 et le plan contenant facette_0:
436 calcul_intersection_plan_triangle(distance_plan0_som1, distance_plan2_som1,
437 s1_min, s1_max);
438 // Les deux segments ont-ils une intersection non vide ? Si oui alors les
439 // triangles se coupent.
440 {
441 double s_min = (s0_min > s1_min) ? s0_min : s1_min;
442 double s_max = (s0_max < s1_max) ? s0_max : s1_max;
443 if (s_min < s_max)
444 // Intersection non vide => les facettes se coupent
445 test_intersection = 1 + nb_sommets_communs;
446 }
447 }
448 }
449 return test_intersection;
450}
451
452/*! @brief Teste s'il existe deux facettes du maillage qui se coupent (avec test_intersection_facettes_2D/3D).
453 *
454 * On ne teste pas tous les couples
455 * possibles, seulement les couples de facettes qui coupent un meme
456 * element eulerien.
457 *
458 */
460 ArrOfInt& liste_elements_collision) const
461{
462 // Note BM 08/2009: on peut reecrire cet algorithme en utilisant un OctreeDouble des
463 // facettes du maillage. Cela permet de ne pas utiliser le maillage eulerien, temps cpu
464 // independant du rapport lagrangien/eulerien et on s'affranchit des erreurs potentielles sur le parcours.
465 // Attention quand-meme a avoir les mailles virtuelles pour ne pas oublier des collisions
466 // avec des mailles d'un autre proc.
467
468 int i_facette;
469 const int nb_facettes = maillage.nb_facettes();
470 ArrOfBit facettes_testees(nb_facettes);
471 facettes_testees = 0;
472 ArrOfIntFT liste_facettes_testees;
473 const Intersections_Elem_Facettes& intersection =
475
476 const ArrOfInt& index_elem = intersection.index_elem();
477 const ArrOfInt& index_facettes = intersection.index_facette();
478 int collision_trouvee = 0;
479
480 liste_elements_collision.resize_array(0);
481
482 // Methode de recherche des intersections:
483 // pour chaque facette,
484 // quels elements euleriens sont traverses ?
485 // pour chaque element eulerien traverse,
486 // quelles sont les facettes_2 qui coupent cet element ?
487 // pour chaque facette_2,
488 // cette facette_2, coupe-t-elle la facette ?
489 // pour ne pas tester plusieurs fois le meme couple:
490 // on ne teste que si facette_2 > facette
491 // on maintient pour chaque facette un tableau de marqueurs
492 // des facettes_2 deja testees.
493
494 for (i_facette = 0; i_facette < nb_facettes && !collision_trouvee; i_facette++)
495 {
496
497 // Boucle sur les elements traverses par la facette
498 int index = index_facettes[i_facette];
499 while (index >= 0 && !collision_trouvee)
500 {
501 const Intersections_Elem_Facettes_Data& data = intersection.data_intersection(index);
502 // -----------------------------------------------------
503 // Numero de l'element traverse
504 const int i_elem = data.numero_element_;
505 // Boucle sur les facettes traversees par l'element
506 int index2 = index_elem[i_elem];
507 while (index2 >= 0 && !collision_trouvee)
508 {
510 intersection.data_intersection(index2);
511 const int i_facette2 = data2.numero_facette_;
512 // On ne teste que les couples (i_facette2 > i_facette)
513 if (i_facette2 > i_facette)
514 {
515 if (!facettes_testees.testsetbit(i_facette2))
516 {
517 // La facette n'a pas encore ete testee
518 liste_facettes_testees.append_array(i_facette2);
519 int resu;
520 if (Objet_U::dimension == 3)
521 resu = test_intersection_facettes_3D(i_facette, i_facette2, maillage);
522 else
523 resu = test_intersection_facettes_2D(i_facette, i_facette2, maillage);
524 if (resu > 0)
525 {
526 // Intersection si le resultat est positif.
527 collision_trouvee = resu > 0;
528 liste_elements_collision.append_array(i_elem);
529 }
530 }
531 }
532 index2 = data2.index_facette_suivante_;
533 }
534 // ----------------------------------------------------
535 index = data.index_element_suivant_;
536 }
537 // Efface les marqueurs des facettes testees
538 {
539 int i;
540 const int n = liste_facettes_testees.size_array();
541 for (i = 0; i < n; i++)
542 {
543 int i_facette2 = liste_facettes_testees[i];
544 facettes_testees.clearbit(i_facette2);
545 }
546 liste_facettes_testees.resize_array(0);
547 }
548 }
549 array_trier_retirer_doublons(liste_elements_collision);
550 collision_trouvee = (int)mp_max(collision_trouvee);
551 return collision_trouvee;
552}
553
554/*! @brief Computes eulerian connex components of the phase indicator function "indicatrice" according to the get_phase_continue() property.
555 *
556 * This method must be used to
557 * compute the input data for supprimer_interfaces.
558 *
559 * For each eulerian mesh cell
560 * num_compo[i] = -1 for all mesh cells containing phase "get_phase_continue()"
561 * num_compo[i] = N with 0 <= N < Nmax, for all other mesh cells.
562 * N is a global connex component number. Two adjacent cells (by face) for
563 * which indicatrice[i] != get_phase_continue() will have the same N.
564 *
565 * @param (num_compo) output: resized, md_vector setup, filled with -1 <= num_compo[i] < Nmax, and virtual space updated. Valeur de retour: Returns Nmax, global number of connex components found.
566 */
568 const DoubleTab& indicatrice,
569 IntVect& num_compo) const
570{
571 domaine_vf.domaine().creer_tableau_elements(num_compo);
572
573 double phase_cont = get_phase_continue();
574 const int nb_elem = domaine_vf.domaine().nb_elem();
575 // On marque les elements dont on veut avoir les composantes connexes:
576 // -1 pour la phase a conserver (ne pas ranger ces elements dans une compo connexe)
577 // 1 pour la phase a supprimer
578 int i;
579 for (i = 0; i < nb_elem; i++)
580 {
581 const double indic = indicatrice[i];
582 // Pas de epsilon pour ce test: on attend une egalite exacte avec 0. ou 1.
583 // sinon c'est une maille diphasique qui contient une interface.
584 num_compo[i] = (indic == phase_cont) ? -1 : 1;
585 }
586 num_compo.echange_espace_virtuel();
587 const int nb_local_components = search_connex_components_local(domaine_vf.elem_faces(), domaine_vf.face_voisins(), num_compo);
588 const int nb_compo_glob = compute_global_connex_components(num_compo, nb_local_components);
589
590 return nb_compo_glob;
591}
592
593/*! @brief Removes all interfaces contained in eulerian elements marked by the "flags_" array, and updates the "indicatrice" field by putting
594 *
595 * "get_phase_condinue()" in those elements.
596 * Virtual lagrangian elements are removed.
597 * "flags" must be of size "nb_elem" and must be built with one or more
598 * connex components (see calcul_composantes_connexes_eurleriennes).
599 * Return value: Integral of the "indicatrice" change (e.g. volume of phase changed,
600 * positive or negative)
601 *
602 */
603//#include <Connex_components_FT.h>
604double Topologie_Maillage_FT::suppression_interfaces(const IntVect& num_compo,
605 const ArrOfInt& flags_compo_a_supprimer,
606 Maillage_FT_Disc& maillage,
607 DoubleTab& indicatrice)
608{
609 const int n = num_compo.size();
610 double phase_cont = get_phase_continue();
611
612 assert(n == indicatrice.dimension(0));
613
614 const int nb_facettes = maillage.nb_facettes();
615 ArrOfInt liste_facettes_a_supprimer;
616 liste_facettes_a_supprimer.resize_array(nb_facettes, RESIZE_OPTIONS::NOCOPY_NOINIT); // get memory for the requested size
617 liste_facettes_a_supprimer.resize_array(0); // and set actual size to zero
618
619
620 const Intersections_Elem_Facettes& intersections = maillage.intersections_elem_facettes();
621 const ArrOfInt& index_elem = intersections.index_elem();
622 ArrOfBit flags(nb_facettes);
623 flags = 0;
624
625 //ArrOfInt compo_connexe_facettes(nb_facettes); // Init a zero
626 //int nb_compo_local = search_connex_components_local_FT(maillage, compo_connexe_facettes, 1 /* include_virtual */);
627 //int nb_front_components = compute_global_connex_components_FT(maillage, compo_connexe_facettes, nb_compo_local);
628 //ArrOfBit flags_compo_front_a_supprimer(nb_front_components);
629 //flags_compo_front_a_supprimer = 0;
630
631 double variation_indicatrice = 0.;
632 const Domaine_VF& domaine_vf = ref_cast(Domaine_VF, maillage.refdomaine_dis_.valeur());
633 const DoubleVect& volumes = domaine_vf.volumes();
634 for (int i = 0; i < n; i++)
635 {
636 const int compo_connexe = num_compo[i];
637 if (compo_connexe >= 0 && flags_compo_a_supprimer[compo_connexe])
638 {
639 // On vide la maille i:
640 variation_indicatrice += (phase_cont - indicatrice[i])*volumes(i);
641 indicatrice[i] = phase_cont;
642 // Parcours des facettes traversant l'element i:
643 int index = index_elem[i];
644 while (index >= 0)
645 {
646 const Intersections_Elem_Facettes_Data& data = intersections.data_intersection(index);
647 const int i_facette = data.numero_facette_;
648 //const int compo_front = compo_connexe_facettes[i_facette];
649 //flags_compo_front_a_supprimer.setbit(compo_front);
650 if (!flags.testsetbit(i_facette))
651 liste_facettes_a_supprimer.append_array(i_facette);
652 index = data.index_facette_suivante_;
653 }
654 }
655 }
656
657 // On a potentiellement rate des facettes qui sont maintenant hors du domaine:
658 // On les reparcourt toutes (en fait, on pourrait ne creer et remplir la liste
659 // que maintenant, mais bon)
660 //for (int iface = 0; iface < nb_facettes; iface++)
661 // {
662 // const int compo = compo_connexe_facettes[iface];
663 // if (flags_compo_front_a_supprimer[compo])
664 // if (!flags.testsetbit(iface))
665 // // la, on n'ajoute que les facettes ratees au premier tour...
666 // liste_facettes_a_supprimer.append_array(iface);
667 // }
668
669 maillage.supprimer_facettes(liste_facettes_a_supprimer);
670 variation_indicatrice = mp_sum(variation_indicatrice);
671 declare_espace_virtuel_invalide(indicatrice);
672 return variation_indicatrice;
673}
674
675/*! @brief Remaillage de l'interface: - amelioration petites et grandes facettes,
676 *
677 * - barycentrage,
678 * - gestion des coalescences-fragmentations.
679 *
680 */
682 Maillage_FT_Disc& maillage,
683 Champ_base& indicatrice,
684 Remaillage_FT& algo_remaillage_local)
685{
686 // Le remaillage qui suit le traitement des coalescences peut a nouveau
687 // produire un maillage impropre (avec des facettes qui se coupent).
688 // Dans ce cas, on s'arrete apres le traitement des coalescences.
689
690 // Note B.M. : le remaillag systematique peut retarder la necessite de remailler
691 // localement (apparition de grandes ou petites aretes). Donc je le fais d'abord,
692 // et ensuite je teste s'il faut faire un remaillage local.
693
694 // L'intervalle de temps entre deux lissages est-il ecoule ?
695 if (algo_remaillage_local.a_lisser(temps))
696 {
697 algo_remaillage_local.barycentrer_lisser_systematique(temps,maillage);
698 }
699
700 // L'intervalle de temps entre deux remaillages locaux est-il ecoule:
701 if (algo_remaillage_local.a_remailler(temps, maillage))
702 {
703 // Declanchement d'un remaillage local.
704 // Pour que ca marche bien, les parametres de barycentrage et lissage "apres_remaillage"
705 // doivent etre suffisants pour ramener le maillage dans un etat correct sans
706 // appliquer de lissage systematique apres
707 algo_remaillage_local.remaillage_local_interface(temps, maillage);
708 }
709
710 // Test de collision des interfaces (peut declancher un remaillage "global")
711 if (active_)
712 {
713 ArrOfInt liste_elements_collision;
714 for (int num_tentative = 0; num_tentative < 2; num_tentative++)
715 {
716 maillage.parcourir_maillage();
717 const int collision_trouvee = test_collision_facettes(maillage, liste_elements_collision);
718 if (!collision_trouvee)
719 {
720 // Pas de coalescence: on quitte la boucle tout de suite
721 break;
722 }
723
725 Journal() << "Collision t= " << temps << finl;
726 Remailleur_Collision_FT_base& remesh = remailleur_Collision_.valeur();
727 if (juric_local_)
728 {
729 // Indicatrice de la partie du maillage a conserver (ie a ne pas remailler)
730 // (COPIE !)
731 Maillage_FT_Disc maillage2;
732 maillage2.recopie(maillage, Maillage_FT_Disc::MINIMAL);
733 // On fait une copie car on va modifier indicatrice et on veut avoir acces a la valeur precedente:
734 DoubleTab indicatrice_partie_non_remaillee = indicatrice.valeurs();
735 // Supprimer les triangles des composantes connexes ou se trouvent les collisions
736 const Domaine_VF& domaine_vf = ref_cast(Domaine_VF, indicatrice.domaine_dis_base());
737 {
738 IntVect num_compo;
739 const int nb_compo = calculer_composantes_connexes_pour_suppression(domaine_vf, indicatrice_partie_non_remaillee, num_compo);
740 // Selection des composantes a supprimer, initialisation a zero
741 ArrOfInt flags_compo_a_supprimer(nb_compo);
742 const int n = liste_elements_collision.size_array();
743 for (int i = 0; i < n; i++)
744 {
745 const int elem = liste_elements_collision[i];
746 const int compo = num_compo[elem];
747 if (compo >= 0)
748 flags_compo_a_supprimer[compo] = 1;
749 }
750 // Tous les procs d'accord sur les composantes a supprimer:
751 mp_max_for_each_item(flags_compo_a_supprimer);
752 suppression_interfaces(num_compo,
753 flags_compo_a_supprimer,
754 maillage,
755 indicatrice_partie_non_remaillee);
756 }
757 // Constuire une fonction indicatrice contenant uniquement les interfaces a remailler
758 DoubleTab& indic = indicatrice.valeurs();
759 const int nb_elem = indic.dimension(0);
760 int i;
761 const double phase_cont = get_phase_continue();
762 for (i = 0; i < nb_elem; i++)
763 {
764 const double ind = indic[i];
765 const double indic2 = indicatrice_partie_non_remaillee[i];
766 if (ind == indic2)
767 indic[i] = phase_cont;
768 }
770 // Recontruire la portion de maillage dans une structure separee
771 maillage2.parcourir_maillage();
772 if (num_tentative == 0)
773 remesh.traite_RuptureCoalescenceInterfaces_Conservatif(maillage2, indicatrice);
774 else
775 remesh.traite_RuptureCoalescenceInterfaces(maillage2, indicatrice);
776 // Remaillage local du maillage2:
777 algo_remaillage_local.remaillage_local_interface(temps, maillage2);
778 // Concatener les deux maillages
779 maillage.ajouter_maillage(maillage2);
780 // Concatener les indicatrices
781 for (i = 0; i < nb_elem; i++)
782 {
783 const double indic2 = indicatrice_partie_non_remaillee[i];
784 if (indic2 != phase_cont)
785 indic[i] = indic2;
786 }
787 }
788 else
789 {
790 if (num_tentative == 0)
791 {
792 remesh.traite_RuptureCoalescenceInterfaces_Conservatif(maillage, indicatrice);
793 // Remaillage local:
794 algo_remaillage_local.remaillage_local_interface(temps, maillage);
795 }
796 else
797 {
798 remesh.traite_RuptureCoalescenceInterfaces(maillage, indicatrice);
799 // Le premier remaillage local a reproduit une coalescence, ne pas remailler localement
800 }
801 }
802 }
803 }
804}
int testsetbit(int_t i) const
Renvoie la valeur du bit e, puis met le bit e a 1.
Definition ArrOfBit.h:85
void clearbit(int_t i) const
Met le bit e a 0.
Definition ArrOfBit.h:100
virtual DoubleTab & valeurs()=0
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
virtual const Domaine_dis_base & domaine_dis_base() const
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
creation d'un tableau parallele de valeurs aux elements.
Definition Domaine.cpp:851
int_t nb_elem() const
Definition Domaine.h:131
class Domaine_VF
Definition Domaine_VF.h:44
double volumes(int i) const
Definition Domaine_VF.h:113
int elem_faces(int i, int j) const
renvoie le numero de le ieme face de la maille num_elem la facon dont ces faces sont numerotees est
Definition Domaine_VF.h:543
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
: class Intersections_Elem_Facettes
const ArrOfInt & index_elem() const
Renvoie un tableau de taille domaine.
const ArrOfInt & index_facette() const
Renvoie un tableau de taille "nombre de facettes de l'interface" pour un element 0 <= facette < nb_fa...
const Intersections_Elem_Facettes_Data & data_intersection(int index) const
Renvoie les donnees de l'intersection stockee a l'indice "index" dans le tableau "data" ( 0 <= index ...
: class Maillage_FT_Disc Cette classe decrit un maillage:
const DoubleTab & sommets() const
renvoie le tableau des sommets (reels et virtuels) dimension(0) = nombre de sommets,
void supprimer_facettes(const ArrOfInt &liste_facettes)
Supprime les facettes dont les indices locaux sont donnes en parametre.
int nb_facettes() const
renvoie le nombre de facettes (reelles et virtuelles) (egal a facettes().
virtual void ajouter_maillage(const Maillage_FT_Disc &maillage_tmp, int skip_facettes=0)
virtual const DoubleTab & get_update_normale_facettes() const
Calcule la grandeur demandee, stocke le resultat dans un tableau interne a la classe et renvoie le re...
void parcourir_maillage()
Remplit la structure intersections_elem_facettes_.
virtual void recopie(const Maillage_FT_Disc &maillage_source, Statut_Maillage niveau_copie)
Recopie une partie du maillage source dans *this.
const Intersections_Elem_Facettes & intersections_elem_facettes() const
const IntTab & facettes() const
renvoie le tableau des facettes (reelles et virtuelles) dimension(0) = nombre de facettes,
classe Objet_U Cette classe est la classe de base des Objets de TRUST
Definition Objet_U.h:73
static int dimension
Definition Objet_U.h:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
@ REQUIRED
Definition Param.h:115
static void mp_max_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
Definition Process.cpp:196
static double mp_max(double)
Definition Process.cpp:376
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
Definition Process.cpp:588
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
: class Remaillage_FT Cette classe implemente les procedures de remaillage des interfaces pour le Fro...
void barycentrer_lisser_systematique(double temps, Maillage_FT_Disc &maillage)
applique barycentrage, lissage et correction de volume.
int a_remailler(double temps, const Maillage_FT_Disc &maillage) const
void remaillage_local_interface(double temps, Maillage_FT_Disc &maillage)
Verifie les criteres de remaillage locaux (longueur des aretes) et effectue les remaillages locaux si...
int a_lisser(double temps) const
classe Remailleur_Collision_FT_base Classe de base pour la hierarchie des remailleurs d'interfaces en...
virtual int traite_RuptureCoalescenceInterfaces_Conservatif(Maillage_FT_Disc &, Champ_base &)
algorithme de remaillage qui tente de conserver le volume.
virtual int traite_RuptureCoalescenceInterfaces(Maillage_FT_Disc &maillage, Champ_base &indicatrice) const =0
Classe de base des flux de sortie.
Definition Sortie.h:52
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
: class Topologie_Maillage_FT Cette classe implemente les procedures de remaillage des interfaces pou...
int test_collision_facettes(const Maillage_FT_Disc &maillage, ArrOfInt &liste_elements_collision) const
Teste s'il existe deux facettes du maillage qui se coupent (avec test_intersection_facettes_2D/3D).
virtual int calculer_composantes_connexes_pour_suppression(const Domaine_VF &domaine_vf, const DoubleTab &indicatrice, IntVect &num_compo) const
Computes eulerian connex components of the phase indicator function "indicatrice" according to the ge...
int test_intersection_facettes_3D(int fa70, int fa71, const Maillage_FT_Disc &maillage) const
Teste si les facettes fa70 et fa71 se coupent.
virtual void remailler_interface(const double temps, Maillage_FT_Disc &maillage, Champ_base &indicatrice, Remaillage_FT &algo_remaillage_local)
Remaillage de l'interface: - amelioration petites et grandes facettes,.
virtual double suppression_interfaces(const IntVect &num_compo, const ArrOfInt &flags_compo_a_supprimer, Maillage_FT_Disc &maillage, DoubleTab &indicatrice)
Removes all interfaces contained in eulerian elements marked by the "flags_" array,...
int test_intersection_facettes_2D(int fa70, int fa71, const Maillage_FT_Disc &maillage) const
Voir test_intersection_facettes_3D.