TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Maillage_FT_IJK.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 <Maillage_FT_IJK.h>
17#include <IJK_Field.h>
18#include <Param.h>
19#include <IJK_Lata_writer.h>
20#include <LataDB.h>
21#include <Process.h>
22#include <communications.h>
23#include <TRUSTTabFT.h>
24#include <Comm_Group.h>
25#include <Perf_counters.h>
26#include <TRUSTTabs.h>
27#include <TRUSTArrays.h>
28#include <Array_tools.h>
29#include <Domaine_IJK.h>
30#include <iostream>
31#include <vector>
32#include <cmath>
33#include <algorithm>
34#include <numeric>
35#include <variant>
36#include <Remaillage_FT_IJK.h>
37#include <IJK_communications.h>
38#include <Operator_FT_Disc.h>
39
40using namespace std;
41Implemente_instanciable(Maillage_FT_IJK,"Maillage_FT_IJK",Objet_U) ;
42
44{
46 return os;
47}
48
50{
51 Param param(que_suis_je());
52 param.ajouter("FT_Field", &Surfactant_facettes_);
53 param.lire_avec_accolades(is);
54 return is;
55}
56
57void Maillage_FT_IJK::initialize(const Domaine_IJK& dom, const Domaine_dis_base& domaine_dis, const Parcours_interface& parcours, const bool use_tryggvason_interfacial_source)
58{
59 ref_domaine_ = dom;
60 // Mise a jour des tableaux de processeurs voisins :
62 nbmailles_euler_i_ = dom.get_nb_elem_local(DIRECTION_I);
63 nbmailles_euler_j_ = dom.get_nb_elem_local(DIRECTION_J);
64 nbmailles_euler_k_ = dom.get_nb_elem_local(DIRECTION_K);
65 use_tryggvason_interfacial_source_ = use_tryggvason_interfacial_source ;
66
67 associer_domaine_dis_parcours(domaine_dis, parcours);
68}
69
70// Deplace tous les sommets lagrangiens dont les indices locaux sont mentionnes dans liste_sommets_initiale
71// d'un vecteur deplacement_initial.
72// Methode parallele qui doit etre appelee simultanement par tous les processeurs.
73// Elle gere les sommets qui changent de processeurs et met a jour le maillage en consequence.
74// Numero_face_sortie servait en vdf et vef a savoir par quelle face on sortait d'un processeur
75// il fallait ensuite relancer un deplacement pour continuer jusqu'a atteindre le point d'arrivee
76void Maillage_FT_IJK::deplacer_sommets(const ArrOfInt& liste_sommets,
77 const DoubleTab& deplacement,
78 ArrOfInt& liste_sommets_sortis,
79 ArrOfInt& numero_face_sortie, int skip_facettes)
80{
82 assert(deplacement.dimension(0) == liste_sommets.size_array());
83 assert(deplacement.dimension(1) == 3);
84
85 // Donnees de decoupage du maillage dans les trois directions, pour trouver
86 // sur quel processeur se trouve chaque point:
87 VECT(ArrOfInt) slice_offsets(3);
88 Int3 my_slice, my_new_slice;
89 //int i;
90 for (int i = 0; i < 3; i++)
91 {
92 ref_domaine_->get_slice_offsets(i, slice_offsets[i]);
93 // On ajoute un dernier element au tableau, une tranche virtuelle tout a la fin
94 // pour que la taille d'une tranche soit calculable par offset[n+1] - offset[n]
95 const int n = slice_offsets[i].size_array();
96 slice_offsets[i].resize_array(n+1);
97 slice_offsets[i][n] = ref_domaine_->get_nb_items_global(Domaine_IJK::ELEM, i);
98 my_slice[i] = ref_domaine_->get_local_slice_index(i);
99 }
100 // Pour chaque sommet, changer sa coordonnee et trouver l'indice de maille ou il se trouve,
101 // puis faire les echanges de donnees paralleles pour attribuer le sommet au bon processeur s'il change
102 // de processeur:
103 const int my_processor = Process::me();
104 const int nb_som = liste_sommets.size_array();
105 ArrOfInt liste_processeurs_destination; // Pour chaque sommet envoye, a qui on l'envoie
106 ArrOfInt send_pe_list; // Liste des processeurs a qui on envoie des sommets
107 ArrOfInt drapeau_processeur_destination(Process::nproc());
108 int max_voisinage = 0;
109 //////////////////////// GESTION DU CHAMP DE SURFACTANT QUAND ON DEPLACE LES SOMMETS DES FACETTES //////////////////
110 /* Idem a la procedure de suppression d'arrete (cas asymptotique de barycentrage)
111 * Avant de changer le sommet, on stocke les triangles (facettes) initiaux avant changement (i.e. les triangles dont l'un des trois sommets va changer)
112 * Apres la modification du sommet, on stocke les triangles modifiés (i.e. les triangles dont l'un des trois sommets va changer)
113 * On calcule ensuite toute les intersections entre les triangles initiaux et les triangles finaux
114 * Ces intersections permettent de reconstruire le champ de surfactant apres transport des sommets de maniere conservative et sans diffusion numerique
115 * ATTENTION : la fonction deplacer_sommets peut etre appeles dans le cas d'un transport physique des marqueurs
116 * Dans ce cas, il ne faut pas changer le champ de surfactant.
117 * Les modifications ne s'active que si during_barycentrage_=true
118 * */
120 if (!surfactant.get_disable_surfactant())
121 {
123 {
124 surfactant.echange_espace_virtuel(*this);
125 desc_sommets_.echange_espace_virtuel(sommets_);
126 const ArrOfDouble& Sfa7 = get_surface_facettes();
127 double longueur_cara_fa7 = 0.;
128 int n = 0 ;
129 for (int fa = 0; fa < Sfa7.size_array(); fa++)
130 {
131 longueur_cara_fa7 += Sfa7(fa);
132 n++;
133 }
134 longueur_cara_fa7= Process::mp_sum(longueur_cara_fa7);
136 if (n>0)
137 {
138 longueur_cara_fa7 /= n ;
139 longueur_cara_fa7 = std::sqrt(longueur_cara_fa7);
140 }
141
142 surfactant.set_tolerance_point_identique(longueur_cara_fa7);
143 surfactant.echange_espace_virtuel(*this);
144 DoubleTab liste_sommets_avant_deplacement(nb_som, 3);
145 DoubleTab liste_sommets_apres_deplacement(nb_som, 3);
146 ArrOfInt compo_connexe_sommets_deplace(nb_som);
149 ArrOfInt compo_connexe_sommet = surfactant.get_compo_connexe_sommets();
150 for (int i_sommet = 0; i_sommet < nb_som; i_sommet++)
151 {
152 const int num_sommet = liste_sommets[i_sommet];
153 Vecteur3 pos(sommets_, num_sommet);
154 Vecteur3 d(deplacement, i_sommet);
155 liste_sommets_avant_deplacement(i_sommet, 0) = pos[0];
156 liste_sommets_avant_deplacement(i_sommet, 1) = pos[1];
157 liste_sommets_avant_deplacement(i_sommet, 2) = pos[2];
158 pos += d;
159 liste_sommets_apres_deplacement(i_sommet, 0) = pos[0];
160 liste_sommets_apres_deplacement(i_sommet, 1) = pos[1];
161 liste_sommets_apres_deplacement(i_sommet, 2) = pos[2];
162 compo_connexe_sommets_deplace(i_sommet) = compo_connexe_sommet(num_sommet);
163 }
164
165 surfactant.completer_compo_connexe_partielle(*this, ref_domaine_.valeur(), liste_sommets_apres_deplacement, liste_sommets_avant_deplacement, compo_connexe_sommets_deplace);
166 DoubleTab& facettes_sommets_full_compo = surfactant.get_facettes_sommets_full_compo_non_const();
167 DoubleTab& liste_sommets_et_deplacements_full_compo = surfactant.get_liste_sommets_et_deplacements_non_const();
168 ArrOfInt sorted_index = surfactant.get_sorted_index();
169
170 int nb_facettes_compo_complete = facettes_sommets_full_compo.dimension(0);
171 int nbsom_compo_complete = liste_sommets_et_deplacements_full_compo.dimension(0);
172
173
174 for (int indice_sommet_unsorted = 0; indice_sommet_unsorted < nbsom_compo_complete; indice_sommet_unsorted++)
175 {
176 int indice_sommet = sorted_index(indice_sommet_unsorted);
177 Vecteur3 pos(liste_sommets_et_deplacements_full_compo(indice_sommet,0),liste_sommets_et_deplacements_full_compo(indice_sommet,1),liste_sommets_et_deplacements_full_compo(indice_sommet,2));
178 Vecteur3 pos_apres_dep(liste_sommets_et_deplacements_full_compo(indice_sommet,3),liste_sommets_et_deplacements_full_compo(indice_sommet,4),liste_sommets_et_deplacements_full_compo(indice_sommet,5));
179 int deplacement_residuel = 0;
180 Point3D dep = {pos_apres_dep[0]-pos[0],pos_apres_dep[1]-pos[1],pos_apres_dep[2]-pos[2]};
181 if(dep.norme()<Point3D::tol)
182 {
183 deplacement_residuel = 1;
184 }
185 surfactant.reinit_remeshing_table();
186 if(!deplacement_residuel)
187 {
188 for (int fa = 0; fa < nb_facettes_compo_complete; fa++)
189 {
190 for (int somfa7 = 0; somfa7 < 3; somfa7++)
191 {
192 double sx = facettes_sommets_full_compo(fa, 3*somfa7+0);
193 double sy = facettes_sommets_full_compo(fa, 3*somfa7+1);
194 double sz = facettes_sommets_full_compo(fa, 3*somfa7+2);
195 Point3D p1 = {sx,sy,sz};
196 Point3D p2 = {pos[0],pos[1],pos[2]};
197 if (p1==p2)
198 {
199 sx = facettes_sommets_full_compo(fa, 0);
200 sy = facettes_sommets_full_compo(fa, 1);
201 sz = facettes_sommets_full_compo(fa, 2);
202 Point3D s0 = {sx,sy,sz};
203 sx = facettes_sommets_full_compo(fa, 3);
204 sy = facettes_sommets_full_compo(fa, 4);
205 sz = facettes_sommets_full_compo(fa, 5);
206 Point3D s1 = {sx,sy,sz};
207 sx = facettes_sommets_full_compo(fa, 6);
208 sy = facettes_sommets_full_compo(fa, 7);
209 sz = facettes_sommets_full_compo(fa, 8);
210 Point3D s2 = {sx,sy,sz};
211
212 if (!(s0 == s1 or s1 == s2 or s0 == s2))
213 {
214 // on sauvegarde le triangle avant deplacement
215 // on deplace le sommet du triangle dans facettes_sommets_full_compo
216 // on sauvegarde le triangle apres deplacement
217 surfactant.sauvegarder_triangle(*this, fa, 0);
218 Point3D n_apres_dep = surfactant.calculer_normale_apres_deplacement(fa, somfa7, pos_apres_dep);
219 for (int dir = 0; dir < 3; dir++)
220 facettes_sommets_full_compo(fa, 3*somfa7+dir)=pos_apres_dep[dir];
221 facettes_sommets_full_compo(fa, 12)=n_apres_dep.x;
222 facettes_sommets_full_compo(fa, 13)=n_apres_dep.y;
223 facettes_sommets_full_compo(fa, 14)=n_apres_dep.z;
224 surfactant.sauvegarder_triangle(*this, fa, 1);
225 break;
226 }
227 }
228 }
229 }
230 surfactant.remailler_FT_Field(*this);
231 }
232 }
234 surfactant.echange_espace_virtuel(*this);
235 }
236
237 }
238 for (int i_sommet = 0; i_sommet < nb_som; i_sommet++)
239 {
240 // Indice dans le maillage du sommet a deplacer:
241 const int num_sommet = liste_sommets[i_sommet];
242 if (sommet_virtuel(num_sommet))
243 {
244 Cerr << "Erreur dans Maillage_FT_IJK::deplacer_sommets: \n"
245 << " le sommet "<<num_sommet<< "est dans la liste a deplacer et est virtuel" << finl;
247 }
248
249 // Coordonnee courante du sommet (on la deplace d'element en element)
250 Vecteur3 pos(sommets_, num_sommet);
251 // Position du point d'arrivee
252 Vecteur3 d(deplacement, i_sommet);
253 pos += d;
254 // Indice ijk de l'element contenant le sommet au depart
255 Int3 ijk_pos = get_ijk_cell_index(num_sommet);
256 // Trouver l'indice de la maille contenant le sommet:
257 // si on passe une paroi, bloquer le sommet sur la paroi, si on passe une frontiere periodique, passer de l'autre cote:
258 for (int direction = 0; direction < 3; direction++)
259 {
260 double coord = pos[direction];
261 int i_maille = ijk_pos[direction] + ref_domaine_->get_offset_local(direction);
262 const ArrOfDouble& coord_noeuds = ref_domaine_->get_node_coordinates(direction);
263 const int derniere_maille = coord_noeuds.size_array() - 2;
264 // Avancer vers la droite si besoin
265 while (coord_noeuds[i_maille+1] < coord)
266 {
267 // Le numero de la derniere maille est nbmailles-1 ou encore nbsommets-2
268 if (i_maille == derniere_maille)
269 {
270 //On est au bout du domaine... on colle le noeud sur la frontiere
271 coord = coord_noeuds[derniere_maille + 1];
272 break;
273 }
274 i_maille++;
275 }
276 // Avancer vers la gauche si besoin
277 while (coord_noeuds[i_maille] > coord)
278 {
279 // Le numero de la derniere maille est nbmailles-1 ou encore nbsommets-2
280 if (i_maille == 0)
281 {
282 //On est au bout du domaine:
283 coord = coord_noeuds[0];
284 break;
285 }
286 i_maille--;
287 }
288 // Cerr << "deplacement " << num_sommet << " " << direction << " de " << sommets_(num_sommet,direction) << " vers " << coord << finl;
289 sommets_(num_sommet,direction) = coord;
290
291 int current_slice = my_slice[direction];
292 while (i_maille >= slice_offsets[direction][current_slice+1]) // avancer vers la droite si besoin
293 {
294 current_slice++;
295 }
296 while (i_maille < slice_offsets[direction][current_slice]) // avancer vers la gauche si besoin
297 {
298 current_slice--;
299 }
300 my_new_slice[direction] = current_slice;
301 ijk_pos[direction] = i_maille - slice_offsets[direction][current_slice];
302 }
303
304 // Pour le assert :
305 Int3 nbmailles_euler_in_new_slice;
306 for (int direction = 0; direction < 3; direction++)
307 {
308 int new_slice = my_new_slice[direction];
309 nbmailles_euler_in_new_slice[direction] = slice_offsets[direction][new_slice+1] - slice_offsets[direction][new_slice] ;
310 // Si on n'a pas change de slice dans cette direction, on doit retrouver nbmailles_euler_ijk_
311 assert(!( (my_slice[direction] == my_new_slice[direction]) &&
312 (nbmailles_euler_in_new_slice[direction] != ref_domaine_->get_nb_elem_local(direction))));
313 }
314
315 // Dans le cas ou le sommet a change de tranche, et que celle-ci n'a pas le meme nombre de mailles (plus de mailles)
316 // et que le sommet est dans la derniere maille, il ne faut pas se comparer a nbmailles_euler_ijk_
317 // mais plutot a nbmailles_euler_in_new_slice[direction] :
318 assert((ijk_pos[0] < 0 && ijk_pos[1] < 0 && ijk_pos[2] < 0)
319 || (ijk_pos[0] >= 0 && ijk_pos[0] < nbmailles_euler_in_new_slice[0]
320 && ijk_pos[1] >= 0 && ijk_pos[1] < nbmailles_euler_in_new_slice[1]
321 && ijk_pos[2] >= 0 && ijk_pos[2] < nbmailles_euler_in_new_slice[2]));
322
323 // Traitement des changements de processeurs :
324 int new_processor = ref_domaine_->get_processor_by_ijk(my_new_slice[0],my_new_slice[1],my_new_slice[2]);
325 if (new_processor != my_processor)
326 {
327 // Le sommet change de processeur
328 // Il faut l'envoyer au voisin:
329 liste_sommets_sortis.append_array(num_sommet);
330 liste_processeurs_destination.append_array(new_processor);
331 if (drapeau_processeur_destination[new_processor] == 0)
332 {
333 // On n'a pas encore trouve de sommet a envoyer a ce processeur
334 drapeau_processeur_destination[new_processor] = 1;
335 send_pe_list.append_array(new_processor);
336 max_voisinage = std::max(max_voisinage, voisinage_processeur_[new_processor]);
337 }
338 }
339 // On stocke le numero local de l'element eulerien contenant le sommet
340 // sur le processeur qui contient ce sommet en reel.
341 // (la structure de donnee est donc pour l'instant invalide car ce n'est pas
342 // l'indice local sur mon processeur mais sur le processeur ou le sommet sera reel
343 // apres avoir cree les sommets virtuels et echange les proprietaires des sommets)
344
345 // Si on change de proc et que le nouveau n'a pas le meme nombre d'elem dans ses slices
346 if ((new_processor != my_processor)
347 && ( nbmailles_euler_i_ != nbmailles_euler_in_new_slice[0]
348 || nbmailles_euler_j_ != nbmailles_euler_in_new_slice[1]
349 || nbmailles_euler_k_ != nbmailles_euler_in_new_slice[2]))
350 {
351 // On fait comme set_ijk_cell_index mais pour le proc de destination, cad avec le nouveau nbmailles_euler...
352 const int i = ijk_pos[0];
353 const int j = ijk_pos[1];
354 const int k = ijk_pos[2];
355 assert((i < 0 && j < 0 && k < 0)
356 || (i >= 0 && i < nbmailles_euler_in_new_slice[0]
357 && j >= 0 && j < nbmailles_euler_in_new_slice[1]
358 && k >= 0 && k < nbmailles_euler_in_new_slice[2] ));
359 if (i < 0)
360 sommet_elem_[num_sommet]= -1;
361 else
362 sommet_elem_[num_sommet]= (k * nbmailles_euler_in_new_slice[1] + j) * nbmailles_euler_in_new_slice[0] + i;
363 }
364 else
365 {
366 set_ijk_cell_index(num_sommet, ijk_pos);
367 }
368
369 }
370 max_voisinage = Process::mp_max(max_voisinage);
371 ArrOfInt recv_pe_list; // Liste des processeurs qui recoivent des sommets
372 if (max_voisinage == 0)
373 {
374 // Il n'y a aucune communication de sommets
375 }
376 else if (max_voisinage == 1)
377 {
378 // On a trouve des communications par les faces... ajout des 6 voisins par faces
381 }
382 else if (max_voisinage == 2)
383 {
384 // On a trouve des communications par les faces et/ou les aretes
387 }
388 else if (max_voisinage == 3)
389 {
390 // On a trouve des communications par les faces/aretes/coins
393 }
394 else
395 {
396 // On a trouve des communications autres qu'avec les voisins directs
397 // On calcule la liste des communications a faire:
398 reverse_send_recv_pe_list(send_pe_list, recv_pe_list);
399 }
400 // Mise a jour de l'espace virtuel des coodonnees des sommets
401 desc_sommets_.echange_espace_virtuel(sommets_);
402
403 if (max_voisinage > 0)
404 {
405 Schema_Comm schema_comm;
406 schema_comm.set_send_recv_pe_list(send_pe_list, recv_pe_list);
407 // Cree les sommets sur les processeurs destination, et initialise les coordonnees
408 // le drapeau, le numero du processeur proprietaire (pour l'instant moi), etc...
409 creer_sommets_virtuels(liste_sommets_sortis, liste_processeurs_destination, schema_comm);
410
411 // Change le proprietaire des sommets qui ont ete envoyes:
412 // On s'inspire de la methode echanger_sommets_PE()
413 // * Remplissage du tableau sommet_PE_owner avec le nouveau proprietaire
414 // et -1 si le sommet ne change pas de main,
415 // * Appel a la methode echanger_elements qui transforme
416 // les espaces distants et virtuels en fonction du nouveau proprietaire.
417 sommet_PE_owner_ = -1;
418 const int nechange = liste_sommets_sortis.size_array();
419 for (int i = 0; i < nechange; i++)
420 {
421 const int sommet = liste_sommets_sortis[i];
422 const int pe_destination = liste_processeurs_destination[i];
423 sommet_PE_owner_[sommet] = pe_destination;
424 }
425 // L'echange espace virtuel va envoyer a tout le monde les nouveaux proprietaires de chaque sommet:
426 desc_sommets_.echange_espace_virtuel(sommet_PE_owner_);
427 // Envoi du numero d'element contenant les sommets a tous les processeurs
428 desc_sommets_.echange_espace_virtuel(sommet_elem_);
429 // Mise a jour des espaces distants et virtuels (c'est la qu'on change
430 // reelement de proprietaire, on deplace des numeros de sommets d'une liste d'elements virtuels
431 // a une autre (autre processeur) ou a une liste d'elements distants (si je deviens proprietaire)
432 // ou inversement..., mais il n'y a pas d'envoi de message proprement dit dans cette etape)
433 desc_sommets_.echanger_elements(sommet_PE_owner_);
434 // Recalcul de sommet_PE_owner a partir des descripteurs (on l'avait ecrase
435 // avec -1 partout sauf pour les sommets qui changent de procs).
436 desc_sommets_.remplir_element_pe(sommet_PE_owner_);
437 // On remet a -1 le numero d'element si le sommet n'est pas a moi
438 // Mise a jour de sommet_num_owner_: on fait comme si les sommets etaient tous a moi (l'indice sur le
439 // proprietaire est mon indice a moi), puis on echange pour ecraser les valeurs dont je ne suis pas proprietaire
440 const int nsommets = sommets_.dimension(0);
441 const int moi = me();
442 for (int i = 0; i < nsommets; i++)
443 {
444 if (sommet_PE_owner_[i] != moi)
445 sommet_elem_[i] = -1;
446 sommet_num_owner_[i] = i;
447 }
448 // Envoi du nouveau sommet_num_owner_ a tous les autres procs qui possedent le sommet
449 desc_sommets_.echange_espace_virtuel(sommet_num_owner_);
450 }
451 if (Comm_Group::check_enabled()) check_mesh(1, 1, 0); // ne pas tester que le proprietaire des facettes est conforme
452 // a la convention definie dans maillage_ft_disc, ce n'est pas cense etre fait par cette fonction
453 // On teste le compo_connexe : il n'a pas ete mis a jour, les facettes non plus... Ils sont donc en coherence.
454}
455
456/*! Reading the FT mesh from a LATA file.
457 * Assumption: FT mesh is always small enough so that all indices fit within 32b. This check implicitely in the 'ref_as_small' methods.
458 */
459void Maillage_FT_IJK::lire_maillage_ft_dans_lata(const char *filename_with_path, int tstep,
460 const char *geometryname)
461{
462 Cerr << "Maillage_FT_IJK::lire_maillage_ft_dans_lata fichier " << filename_with_path << " tstep=" << tstep
463 << " geom=" << geometryname << finl;
464 reset();
465
466 const int master = Process::je_suis_maitre();
467 Nom path, dbname;
468 split_path_filename(filename_with_path, path, dbname);
469 LataDB db;
470 BigFloatTab coord;
471
472 Vecteur3 origine;
473 for (int j = 0; j < 3; j++)
474 origine[j] = ref_domaine_->get_origin(j);
475
476 int nbsom = 0;
477
478 if (master)
479 {
480 db.read_master_file(path, filename_with_path);
481
482 const LataDBField& db_som = db.get_field(tstep, geometryname, "SOMMETS", "");
483 db.read_data(db_som, coord);
484 const LataDBField& db_elem = db.get_field(tstep, geometryname, "ELEMENTS", "");
485
486 // Lecture de la composante connexe:
487 {
488 if (!db.field_exists(tstep, geometryname, "COMPO_CONNEXE"))
489 {
490 Cerr << "Erreur a la reprise d'une interface ft dans le fichier lata " << filename_with_path
491 << ":\n Le champ COMPO_CONNEXE est absent." << finl;
493 }
494 const LataDBField& db_field = db.get_field(tstep, geometryname, "COMPO_CONNEXE", "ELEM");
495 BigIntTab tmp;
496 db.read_data(db_field, tmp);
497
498 // TODO : fix ref_as_XXXX for tabs in TRUST:
499 IntTab small_tmp;
500 tmp.ref_as_small(small_tmp); // Will check possible overflow issue
501 compo_connexe_facettes_ = small_tmp;
502 }
503
504 BigIntTab tmp_fac;
505 db.read_data(db_elem, tmp_fac);
506 // TODO : fix ref_as_XXXX for tabs in TRUST:
507 assert(tmp_fac.nb_dim() == 2);
508 IntTab tmp_fac_small((int)tmp_fac.dimension(0), tmp_fac.dimension_int(1));
509 tmp_fac.ref_as_small(tmp_fac_small); // Will check possible overflow issue
510 facettes_ = tmp_fac_small; // deep copy
511
512 // Il faut traduire les indices de sommets virtuels en indices reels avec le tableau INDEX_SOMMET_REEL
513 // En meme temps on supprime les facettes virtuelles
514 // Il faut a ce moment faire suivre le tableau compo_connex pour qu'il soit coherent...
515 // Si le champ INDEX_SOMMET_REEL n'est pas postraite, on suppose qu'il n'y a ni sommets virtuels
516 // ni facettes virtuelles
517 if (db.field_exists(tstep, geometryname, "INDEX_SOMMET_REEL"))
518 {
519 const LataDBField& db_index_sommet_reel = db.get_field(tstep, geometryname, "INDEX_SOMMET_REEL","");
520
521 BigIntTab big_idx;
522 db.read_data(db_index_sommet_reel, big_idx);
523 // TODO : fix ref_as_XXXX for tabs in TRUST:
524 assert(big_idx.nb_dim() == 2);
525 IntTab index_sommet_reel_tab((int)big_idx.dimension(0), big_idx.dimension_int(1));
526 big_idx.ref_as_small(index_sommet_reel_tab);
527
528 // le tableau lu est dimensionne (nsom,1), on cast en arrofint pour ne pas avoir a donner 2 indices
529 const ArrOfInt& index_sommet_reel = index_sommet_reel_tab;
530 // Traduction. On cast le IntTab en ArrOfInt pour adresser lineairement tous les sommets
531 // de tous les triangles. On a facettes_(i,j) = all_sommets[i*3+j]
532 const int nb_facettes_tot = facettes_.dimension(0);
533 // On va supprimer des facettes: index ou on ecrit la facette i:
534 int idest = 0;
535 for (int i = 0; i < nb_facettes_tot; i++)
536 {
537 // La facette est-elle reelle ? Oui si l'indice du premier sommet est un indice de sommet reel:
538 const int i_som0 = facettes_(i,0);
539 const int i_som0_renum = index_sommet_reel[i_som0];
540 if (i_som0 == i_som0_renum)
541 {
542 // Le sommet 0 de la facette est reel, on garde la facette
543 for (int j = 0; j < 3; j++)
544 {
545 const int i_sommet = facettes_(i,j);
546 const int i_som_renum = index_sommet_reel[i_sommet];
547 facettes_(idest,j) = i_som_renum;
548 }
549 // On met le tableau de compo connex en coherence :
551 idest++;
552 }
553 }
554 Journal() << " Renumerotation des facettes ft relues: " << nb_facettes_tot
555 << " facettes lues, " << idest << " facettes reelles conservees" << finl;
556 facettes_.resize(idest, 3);
557 // On resize aussi le tableau de compo connexe au cas ou il soit plus petit :
558 compo_connexe_facettes_.resize_array(idest);
559 }
560 else
561 {
562 Journal() << " Pas de champ INDEX_SOMMET_REEL, on suppose qu'il n'y a pas de sommet virtuel" << finl;
563 }
564 trustIdType nbSom0 = coord.dimension(0);
565 if (nbSom0 > std::numeric_limits<int>::max())
566 Process::exit("The FT mesh has too many vertices (>32b) - this is not implemented yet!!");
567 nbsom = static_cast<int>(nbSom0);
568 Cerr << "Le maillage a nbsom=" << nbsom << " (avant suppression des sommets virtuels lus)" << finl;
569 // Creation d'un maillage sur le proc0, tous les sommets a l'origine du maillage
570 sommets_.resize(nbsom, 3);
571 sommet_elem_.resize_array(nbsom);
572 sommet_face_bord_.resize_array(nbsom);
573 sommet_PE_owner_.resize_array(nbsom);
574 sommet_num_owner_.resize_array(nbsom);
575 drapeaux_sommets_.resize_array(nbsom);
576 Int3 ijk; // indice de l'element d'origine
577 ijk[0] = ijk[1] = ijk[2] = 0;
578 int i;
579 for (i = 0; i < nbsom; i++)
580 {
581 for (int j = 0; j < 3; j++)
582 sommets_(i,j) = origine[j];
583 set_ijk_cell_index(i, ijk);
584 sommet_face_bord_[i] = -1; // le sommet n'est pas sur un bord
585 sommet_PE_owner_[i] = 0; // Les sommets sont initialement sur le processeur maitre
586 sommet_num_owner_[i] = i;
587 }
588 const int nbelem= facettes_.dimension(0);
589 Cerr << "Le maillage a nbelem=" << nbelem << finl;
590 facette_num_owner_.resize_array(nbelem);
591 for (i = 0; i < nbelem; i++)
592 facette_num_owner_[i] = i;
593
594 // Avant, on lisait la compo_connexe ici, apres avoir potentiellement reduit le nombre de facettes...
595 // c'etait un bug. Il faut bien le faire avant comme c'est le cas maintenant
596 }
597 else
598 {
599 // On n'est pas sur le proc maitre. Pour l'instant, tous les elements lus sont sur le
600 // proc maitre. On force donc la dimension des tableaux a zero :
601 const int nbelem= 0;
602 sommets_.resize(nbsom, 3);
603 sommet_elem_.resize_array(nbsom);
604 sommet_face_bord_.resize_array(nbsom);
605 sommet_PE_owner_.resize_array(nbsom);
606 sommet_num_owner_.resize_array(nbsom);
607 drapeaux_sommets_.resize_array(nbsom);
608 facette_num_owner_.resize_array(nbelem);
609 compo_connexe_facettes_.resize_array(nbelem);
610 }
611 desc_sommets_.reset();
612 desc_facettes_.reset();
614
615 const int nbproc = Process::nproc();
616 DoubleTab liste_sommets_recus;
617 DoubleTab liste_coord_recues;
618 IntTab liste_facettes_recues;
619 ArrOfInt liste_compo_connexe_facettes_recues;
620 if (master)
621 {
622 int nb_bubbles =0;
623 if (compo_connexe_facettes_.size_array())
624 // On ne peut pas faire un max_array sur un tableau vide
625 nb_bubbles= max_array(compo_connexe_facettes_)+1;
626 Cerr << "We read " << nb_bubbles << " (real) bubbles on master proc and will redistribute them on procs." << finl;
627 VECT(DoubleTab) liste_sommets(nbproc);
628 VECT(DoubleTab) liste_coord(nbproc);
629 VECT(IntTab) liste_facettes(nbproc);
630 VECT(ArrOfInt) liste_compo_connexe_facettes(nbproc);
631 for(int p=0; p<nbproc; p++)
632 {
633 liste_sommets[p].resize(0,3);
634 liste_coord[p].resize(0,3);
635 liste_facettes[p].resize(0,3);
636 liste_compo_connexe_facettes[p].resize_array(0);
637 }
638
639 const int nbelem= facettes_.dimension(0);
640 ArrOfInt dest_proc_sommets(nbsom);
641 ArrOfInt sommets_renum(nbsom);
642 for (int i = 0; i < nbelem; i++)
643 {
644 // On envoie les bulles sur d'autres proc par un modulo :
645 const int icompo = compo_connexe_facettes_[i];
646 int new_owner = icompo % nbproc;
647 for (int j = 0; j < 3; j++)
648 {
649 const int i_som = facettes_(i,j);
650 dest_proc_sommets[i_som] = new_owner;
651 }
652 liste_facettes[new_owner].append_line(facettes_(i,0),facettes_(i,1),facettes_(i,2));
653 liste_compo_connexe_facettes[new_owner].append_array(icompo);
654 }
655
656 for (int i = 0; i < nbsom; i++)
657 {
658 const int new_owner = dest_proc_sommets[i];
659 sommets_renum[i] = liste_sommets[new_owner].dimension(0); // il est mis a la fin de la liste du proc p
660 liste_sommets[new_owner].append_line(sommets_(i,0),sommets_(i,1),sommets_(i,2));
661 liste_coord[new_owner].append_line(coord(i,0),coord(i,1),coord(i,2));
662 }
663 // Correction des numeros des sommets formant les nouvelles facettes...
664 for (int p=0; p< nbproc; p++)
665 {
666 const int nb_facettes_loc = liste_facettes[p].dimension(0);
667 for (int i = 0; i < nb_facettes_loc; i++)
668 for (int j=0; j<3; j++)
669 {
670 const int old_isom = liste_facettes[p](i,j); // le vieux numero du sommet
671 const int new_isom = sommets_renum[old_isom]; // le nouveau numero auquel il correspond
672 liste_facettes[p](i,j) = new_isom;// la correction de la facette.
673 }
674 }
675
676 // Cheking for lost elements :
677 {
678 int sum_nbsom = 0;
679 int sum_nbelem = 0;
680 for(int p=0; p<nbproc; p++)
681 {
682 sum_nbsom += liste_sommets[p].dimension(0);
683 sum_nbelem +=liste_facettes[p].dimension(0);
684 }
685 if (sum_nbsom != nbsom)
686 {
687 Cerr << "Some Front sommets have been lost!" << finl;
689 }
690 if (sum_nbelem != nbelem)
691 {
692 Cerr << "Some Front facettes have been lost!" << finl;
694 }
695 }
696 // On a rempli les listes a envoyer, y compris pour le proc maitre;
697 // Sauf que pour le mettre, on ne les envoie pas...
698 Cerr << "Master starts sending packages..." << finl;
699 // The loops starts at 1 because we dont want the master sending packages to himself!
700 for(int p=1; p<nbproc; p++)
701 {
702 // On envoi chaque tableau sur un canal different :
703 envoyer(liste_sommets[p],0,p,2000+4*p);
704 envoyer(liste_facettes[p],0,p,2000+4*p+1);
705 envoyer(liste_compo_connexe_facettes[p],0,p,2000+4*p+2);
706 envoyer(liste_coord[p],0,p,2000+4*p+3);
707 }
708 Cerr << "Master is done sending packages..." << finl;
709
710// Master fills lists for itself :
711 liste_sommets_recus = liste_sommets[0];
712 liste_facettes_recues = liste_facettes[0];
713 liste_compo_connexe_facettes_recues = liste_compo_connexe_facettes[0];
714 liste_coord_recues = liste_coord[0];
715 }
716 else
717 {
718 Journal() << "Receiving from master..." << finl;
719 // On recoit les envois du maitre :
720 const int p = Process::me();
721 recevoir(liste_sommets_recus,0,p,2000+4*p);
722 recevoir(liste_facettes_recues,0,p,2000+4*p+1 /* canal */);
723 recevoir(liste_compo_connexe_facettes_recues,0,p,2000+4*p+2);
724 recevoir(liste_coord_recues,0,p,2000+4*p+3);
725 Journal() << "All data recieved..." << finl;
726 }
727
728 // All processes rebuild the listes sommets and facettes (master has not recieved it, but it filled it itself.
729 const int p = Process::me();
730 sommets_ = liste_sommets_recus;
731 nbsom = sommets_.dimension(0);
732// On ne peut pas faire (mismatched types) : facettes_ = liste_facettes_recues;
733 const int nbelem = liste_facettes_recues.dimension(0);
734 assert(liste_compo_connexe_facettes_recues.size_array() == nbelem);
735 facettes_.resize(nbelem,3);
736 facette_num_owner_.resize_array(nbelem);
737 compo_connexe_facettes_.resize_array(nbelem);
738 if (!Surfactant_facettes_.get_disable_surfactant())
739 Surfactant_facettes_.resize_array(nbelem);
740 for (int i=0; i< nbelem; i++)
741 {
742 for (int j = 0; j < 3; j++)
743 facettes_(i,j) = liste_facettes_recues(i,j);
744 facette_num_owner_[i] = i;
745 compo_connexe_facettes_[i] = liste_compo_connexe_facettes_recues[i];
746 }
747// On remplit d'autres structures :
748 // Les sommets et facettes sont tous reels et ils ont ete redistribues sur chaque processeurs.
749 sommet_elem_.resize_array(nbsom);
750 sommet_face_bord_.resize_array(nbsom);
751 sommet_PE_owner_.resize_array(nbsom);
752 sommet_num_owner_.resize_array(nbsom);
753 drapeaux_sommets_.resize_array(nbsom); // Je ne sais pas a quoi il sert, donc je ne le remplis pas... Mais en tout cas, il faut qu'il ait la bonne taille!
754 for (int i = 0; i < nbsom; i++)
755 {
756 sommet_elem_[i] = 0; // On le met en 0,0,0 provisoirement. Cela changera au deplacement.
757 sommet_face_bord_[i] = -1; // le sommet n'est pas sur un bord
758 sommet_PE_owner_[i] = p; // Les sommets sont redistribues
759 sommet_num_owner_[i] = i;
760 drapeaux_sommets_[i] = 0; // Je ne sais pas quoi mettre...
761 }
762
763 desc_sommets_.calcul_schema_comm(nb_sommets());
764 desc_facettes_.calcul_schema_comm(nb_facettes());
765
766 // GB 2020/04/20. Je ne pense pas sur que cet appel soit necessaire si ce qui precede est bien fait.
767 // De plus, la creation possible de sommets virtuels est un probleme pour le deplacement ci-dessous,
768 // Dont la taille doit etre la meme que liste_coord_recues, c'est a dire nbsom (avant creation de potentiels som virt)
769 // corriger_proprietaires_facettes();
770 DoubleTab deplacement(nbsom,3);
771 for (int i = 0; i < nbsom; i++)
772 {
773 for (int j = 0; j < 3; j++)
774 deplacement(i,j) = liste_coord_recues(i,j) - origine[j];
775 }
776 transporter(deplacement);
777// Suppression des sommets inutilises et des facette virtuelles:
779
780}
781void Maillage_FT_IJK::transporter(const DoubleTab& deplacement)
782{
783 // La mise a jour du tableau compo_connexe_facette est realisee par une
784 // surcharge de creer_facettes_virtuelles, c'est une methode de plus bas niveau
785 // qui est utilisee aussi lors du parcours de l'interface, on centralise
786 // la gestion des compo connexes a moins d'endroits du code.
787 // Inconvenient: la mise a jour des compo connexes sera faite plus souvent,
788 // pas optimal en nombre d'operations.
789 // preparer_tableau_avant_transport(compo_connexe_facettes_, desc_facettes_);
791 // update_tableau_apres_transport(compo_connexe_facettes_, nb_facettes() , desc_facettes_);
792}
793
804
806{
807 // on stocke les barycentre de chaque fa7 ainsi que la quantite de surfactant associe avant que l'indexation des fa7 ne change
808 // Cela permet de reconstruire le champ de surfactant apres changement de l'indexation non deterministe.
809 // On suppose que les mouvements de l'interface sont suffisament faible pour que toutes les fa7 qui changent de proprietaires
810 // étaient initialement contenues dans l'espace virtuel du proc courant.
811 // Il faut donc stocker les valeurs dans les espaces virtuels.
812 {
814 for (int i = 0; i < nb_facettes(); i++)
815 {
816 // coordonnees centre gravite fa7_x
818 // coordonnees centre gravite fa7_y
820 // coordonnees centre gravite fa7_z
822 // quantite de surfactant sur cette facette
824 }
825 }
826}
827
829{
831 {
832 for (int i = 1; i < nb_facettes(); i++)
833 {
835 {
836 // on cherche la facette avant transport correspondante
837 int facette_avant_transport = -1 ;
838 for (int j = 0; j < indexation_facettes_avant_transport_.dimension(0); j++)
839 {
841 Point3D p2 = {(sommets_(facettes_(i,0),0)+sommets_(facettes_(i,1),0)+sommets_(facettes_(i,2),0))/3., (sommets_(facettes_(i,0),1)+sommets_(facettes_(i,1),1)+sommets_(facettes_(i,2),1))/3., (sommets_(facettes_(i,0),2)+sommets_(facettes_(i,1),2)+sommets_(facettes_(i,2),2))/3.};
842 if(p1 == p2)
843 {
844 facette_avant_transport = j;
845 break;
846 }
847 }
848 if (facette_avant_transport!=-1)
849 {
850 Surfactant_facettes_(i) = indexation_facettes_avant_transport_(facette_avant_transport, 3);
851 }
852 }
853 }
854 }
855 Surfactant_facettes_.echange_espace_virtuel(*this);
856}
858{
859 if (!Surfactant_facettes_.get_disable_surfactant())
861 // Lorsque le premier sommet d'une facette est recu ou envoyer,
862 // il faut changer son proprietaire.
863
865
866 // Nouvelle indexation des facettes, certaines ont change de proprietaire
867 // on reorganise le tableau des surfactant pour etre en accord avec le nouvel index
868 // Comme il ny a pas dindexation propre, on teste les position des fa7 pour retrouver qui va avec qui...
869 if (!Surfactant_facettes_.get_disable_surfactant())
871
872}
873
874void Maillage_FT_IJK::supprimer_facettes(const ArrOfInt& liste_facettes)
875{
877}
878
880{
881 const int nb_fa7 = facettes_.dimension(0);
882 int n = 0;
883 {
884 // Nettoyage des composantes connexes et du tableau de surfactant
885 n = 0;
886 for (int i = 0; i < nb_fa7; i++)
887 {
888 const int invalide = (facettes_(i,0) == facettes_(i,1));
889 const int virtuelle = facette_virtuelle(i);
890 if (!invalide && !virtuelle)
891 {
893 n++;
894 }
895 }
896 compo_connexe_facettes_.resize_array(n);
897 if (!Surfactant_facettes_.get_disable_surfactant())
898 {
899 n = 0;
900 for (int i = 0; i < nb_fa7; i++)
901 {
902 const int invalide = (facettes_(i,0) == facettes_(i,1));
903 const int virtuelle = facette_virtuelle(i);
904 if (!invalide && !virtuelle)
905 {
907 n++;
908 }
909 }
910 Surfactant_facettes_.resize_array(n);
911 }
912
913
914 }
915 // Appel a l'ancienne methode
917}
918
919void Maillage_FT_IJK::creer_facettes_virtuelles(const ArrOfInt& liste_facettes,
920 const ArrOfInt& liste_facettes_pe,
921 const ArrOfInt& facettes_send_pe_list,
922 const ArrOfInt& facettes_recv_pe_list)
923{
924 // Appel a l'ancienne methode
926 liste_facettes_pe,
927 facettes_send_pe_list,
928 facettes_recv_pe_list);
929
930 // Mise a jour des composantes connexes
931 compo_connexe_facettes_.resize_array(nb_facettes());
932 if (!Surfactant_facettes_.get_disable_surfactant())
933 Surfactant_facettes_.resize_array(nb_facettes());
934
936 if (!Surfactant_facettes_.get_disable_surfactant())
937 Surfactant_facettes_.echange_espace_virtuel(*this);
938
939 // La verification du tableau des compo_connexe n'a pas ete faite par
940 // Maillage_FT_Disc::creer_facettes_virtuelles. On la fait ici :
942 check_mesh(1, 1 /* ne pas tester le proprietaire de la facette */);
943
944}
945
947{
948 int np = Process::nproc();
949 int npx = ref_domaine_->get_nprocessor_per_direction(0);
950 int npy = ref_domaine_->get_nprocessor_per_direction(1);
951 int npz = ref_domaine_->get_nprocessor_per_direction(2);
952 voisinage_processeur_.resize_array(np);
953
954 voisinage_processeur_ = 4; // On initialize le tableau comme non-voisins.
955 Int3 my_ijk, voisin_ijk;
956 for (int i = 0; i < 3; i++)
957 my_ijk[i] = ref_domaine_->get_local_slice_index(i);
958
959 for (int i = -1; i< 2; i++)
960 {
961 for (int j = -1; j< 2; j++)
962 {
963 for (int k = -1; k< 2; k++)
964 {
965 voisin_ijk = my_ijk;
966 voisin_ijk[0] += i;
967 voisin_ijk[1] += j;
968 voisin_ijk[2] += k;
969 if (voisin_ijk[0] >=0 && voisin_ijk[0]<npx &&
970 voisin_ijk[1] >=0 && voisin_ijk[1]<npy &&
971 voisin_ijk[2] >=0 && voisin_ijk[2]<npz )
972 {
973 int rang_voisin = ref_domaine_->get_processor_by_ijk(voisin_ijk[0],voisin_ijk[1],voisin_ijk[2]);
974 int max_voisinage = abs(i)+abs(j)+abs(k);
975 voisinage_processeur_[rang_voisin] = max_voisinage;
976 if (max_voisinage == 0)
977 {
978 // Je suis sur me.
979 }
980 else if (max_voisinage == 1)
981 {
982 liste_processeurs_voisins_coins_.append_array(rang_voisin);
983 liste_processeurs_voisins_aretes_.append_array(rang_voisin);// On a un voisin par les aretes.
984 liste_processeurs_voisins_faces_.append_array(rang_voisin); // On a un voisin par les faces.
985 }
986 else if (max_voisinage == 2)
987 {
988 liste_processeurs_voisins_coins_.append_array(rang_voisin);
989 liste_processeurs_voisins_aretes_.append_array(rang_voisin);// On a un voisin par les aretes.
990 }
991 else if (max_voisinage == 3)
992 {
993 liste_processeurs_voisins_coins_.append_array(rang_voisin);
994 }
995 else
996 {
997 // Je ne suis pas voisin.
998 }
999 }
1000 }
1001 }
1002 }
1003}
1004
1005// TODO (from teo boutin) add a test case that uses this, there is none. Maybe unit testing on day
1006// Surcharge
1007int Maillage_FT_IJK::check_mesh(int error_is_fatal, int skip_facette_pe, int skip_facettes) const
1008{
1009
1010 //Optimisation : Ne pas faire le check_mesh sauf si on est en debug...
1011 // L'applique partout dans le code...
1013 {
1014 return -1;
1015 }
1016 Maillage_FT_Disc::check_mesh(error_is_fatal, skip_facette_pe, skip_facettes);
1017 const int nf = nb_facettes();
1018 if (nf != compo_connexe_facettes_.size_array())
1019 {
1020 Journal() << "Erreur Maillage_FT_IJK::check_mesh : taille de compo_connexe_facettes_ invalide" << finl;
1021 Journal() << "nb_facettes = " << nf << " et compo_connexe_facettes_ = " << compo_connexe_facettes_.size_array() << finl ;
1022 assert(0);
1023 Process::exit();
1024 }
1025 if (nf != Surfactant_facettes_.size_array() and !Surfactant_facettes_.get_disable_surfactant())
1026 {
1027 Journal() << "Erreur Maillage_FT_IJK::check_mesh : taille de Surfactant_facettes_ invalide" << finl;
1028 Journal() << "nb_facettes = " << nf << " et Surfactant_facettes_ = " << Surfactant_facettes_.size_array() << finl ;
1029 assert(0);
1030 exit();
1031 }
1032 return -1;
1033}
1034
1035// Surcharge de Maillage_FT_Disc::check_sommets, specialise pour le IJK:
1036int Maillage_FT_IJK::check_sommets(int error_is_fatal) const
1037{
1038 const double invalid_value = DMAXFLOAT*0.9;
1039
1040 if (statut_ == RESET)
1041 {
1042 int ok = (nb_sommets() == 0);
1043 ok = ok && (sommet_elem_.size_array() == 0);
1044 ok = ok && (sommet_face_bord_.size_array() == 0);
1045 ok = ok && (sommet_PE_owner_.size_array() == 0);
1046 ok = ok && (sommet_num_owner_.size_array() == 0);
1047 ok = ok && (desc_sommets_.espace_virtuel().pe_voisins().size_array() == 0);
1048 ok = ok && (desc_sommets_.espace_distant().pe_voisins().size_array() == 0);
1049 if (!ok && error_is_fatal)
1050 {
1051 Journal() << "Erreur Maillage_FT_Disc::check_sommets : maillage RESET invalide" << finl;
1052 assert(0);
1053 Process::exit();
1054 }
1055 return !ok;
1056 }
1057 // Verification que les espaces distants et virtuels sont coherents:
1058 desc_sommets_.check();
1059 const int nsom = sommets_.dimension(0);
1060 // Verification de sommet_PE_owner_ : on le recalcule et on compare
1061 {
1062 if (sommet_PE_owner_.size_array() != nsom)
1063 {
1064 if (error_is_fatal)
1065 {
1066 assert(0);
1067 Process::exit();
1068 }
1069 Cerr << "" << finl;
1070 }
1071 ArrOfIntFT pe_owner(nsom);
1072 desc_sommets_.remplir_element_pe(pe_owner);
1073 int som ;
1074 for (som = 0; som < nsom; som++)
1075 {
1076 if (sommet_PE_owner_[som] != pe_owner[som])
1077 {
1078 if (error_is_fatal)
1079 {
1080 assert(0);
1081 Process::exit();
1082 }
1083 break;
1084 }
1085 }
1086 if (som < nsom)
1087 Cerr << "Erreur Verification de sommet_PE_owner_" << finl;
1088 }
1089 // Verification de sommet_num_owner_ : on le recalcule et on compare
1090 {
1091 if (sommet_num_owner_.size_array() != nsom)
1092 {
1093 Journal() << "Erreur sommet_num_owner_.size_array() != nb_sommets" << finl;
1094 if (error_is_fatal)
1095 {
1096 assert(0);
1097 Process::exit();
1098 }
1099 }
1100 ArrOfIntFT num_owner(nsom);
1101 for (int i = 0; i < nsom; i++)
1102 num_owner[i] = i;
1103 desc_sommets_.echange_espace_virtuel(num_owner);
1104 for (int i = 0; i < nsom; i++)
1105 {
1106 if (num_owner[i] != sommet_num_owner_[i])
1107 {
1108 Journal() << "Erreur num_owner[" << i << "] = " << num_owner[i];
1109 Journal() << " sommet_num_owner_ = " << sommet_num_owner_[i] << finl;
1110 if (error_is_fatal)
1111 {
1112 assert(0);
1113 Process::exit();
1114 }
1115 }
1116 }
1117 }
1118 // Verification des coordonnees des sommets virtuels : comparaison avec une copie echangee
1119 {
1120 DoubleTabFT copie_sommets = sommets_;
1121 // On invalide les elements virtuels. Cela permet de detecter le cas
1122 // ou un element se trouverait a la fois dans l'espace distant et dans
1123 // l'espace virtuel.
1124 const Descripteur_FT& espace_virtuel = desc_sommets_.espace_virtuel();
1125 const ArrOfInt& pe_voisins = espace_virtuel.pe_voisins();
1126 const int nb_pe_voisins = pe_voisins.size_array();
1127 for (int indice_pe = 0; indice_pe < nb_pe_voisins; indice_pe++)
1128 {
1129 const int pe = pe_voisins[indice_pe];
1130 const ArrOfInt& elements = espace_virtuel.elements(pe);
1131 const int n = elements.size_array();
1132 for (int i = 0; i < n; i++)
1133 {
1134 const int num_sommet = elements[i];
1135 copie_sommets(num_sommet, 0) = invalid_value;
1136 copie_sommets(num_sommet, 1) = invalid_value;
1137 copie_sommets(num_sommet, 2) = invalid_value;
1138 }
1139 }
1140 // Echange espace virtuel sur la copie
1141 desc_sommets_.echange_espace_virtuel(copie_sommets);
1142 // Comparaison de la copie et du tableau des sommets.
1143 for (int i = 0; i < nsom; i++)
1144 {
1145 for (int j = 0; j < Objet_U::dimension; j++)
1146 {
1147 if (copie_sommets(i,j) == invalid_value)
1148 {
1149 Journal() << "Erreur copie_sommets(" << i << ",";
1150 Journal() << j << ") == DMAX_FLOAT" << finl;
1151 if (error_is_fatal)
1152 {
1153 assert(0);
1154 Process::exit();
1155 }
1156 }
1157 if (copie_sommets(i,j) != sommets_(i,j))
1158 {
1159 Journal() << "Erreur copie_sommets(" << i << ",";
1160 Journal() << j << ") = " << copie_sommets(i,j);
1161 Journal() << " sommets_ = " << sommets_(i,j) << finl;
1162 if (error_is_fatal)
1163 {
1164 assert(0);
1165 Process::exit();
1166 }
1167 }
1168 }
1169 }
1170 }
1171
1172 // Verification de sommet_elem_ :
1173 {
1174 if (sommet_elem_.size_array() != nsom)
1175 {
1176 Journal() << "Erreur sommet_elem_.size_array() != nb_sommets" << finl;
1177 if (error_is_fatal)
1178 {
1179 assert(0);
1180 Process::exit();
1181 }
1182 }
1183 // On verifie que les sommets virtuels ont bien sommet_elem_ < 0:
1184 const Descripteur_FT& espace_virtuel = desc_sommets_.espace_virtuel();
1185 const ArrOfInt& pe_voisins = espace_virtuel.pe_voisins();
1186 const int nb_pe_voisins = pe_voisins.size_array();
1187 for (int indice_pe = 0; indice_pe < nb_pe_voisins; indice_pe++)
1188 {
1189 const int pe = pe_voisins[indice_pe];
1190 const ArrOfInt& elements = espace_virtuel.elements(pe);
1191 const int n = elements.size_array();
1192 for (int i = 0; i < n; i++)
1193 {
1194 const int num_sommet = elements[i];
1195 if (sommet_elem_[num_sommet] >= 0)
1196 {
1197 Journal() << "Erreur sommet_elem_[" << num_sommet << "] = " << sommet_elem_[num_sommet]
1198 << " Il devrait etre negatif car le sommet est virtuel" << finl;
1199 if (error_is_fatal)
1200 {
1201 assert(0);
1202 Process::exit();
1203 }
1204 }
1205 }
1206 }
1207
1208 }
1209 return 0;
1210
1211}
1212
1213void Maillage_FT_IJK::calculer_compo_connexe_sommets(ArrOfIntFT& compo_connexe_sommets) const
1214{
1215
1216 const int nb_fa7 = facettes_.dimension(0);
1217 const int nbsom = sommets().dimension(0);
1218 compo_connexe_sommets.resize_array(nbsom, RESIZE_OPTIONS::NOCOPY_NOINIT); // tous les sommets, y compris virtuels.
1219 compo_connexe_sommets = -10000000; // Force une initialisation bidon.
1220 // On parcours toutes les facettes.
1221 for (int i = 0; i < nb_fa7; i++)
1222 {
1223 const int icompo = compo_connexe_facettes_[i];
1224 for (int j = 0; j < 3; j++)
1225 {
1226 const int i_som = facettes_(i,j);
1227 compo_connexe_sommets[i_som] = icompo;
1228 }
1229 }
1230
1231
1232 // Echange entre les processeurs pour mettre a jour la valeur aux sommets isoles sur un proc
1233 // qui n'appartiendrait qu'a des facettes d'autres processeurs.
1234 // On prend le max sur tous les processeurs qui partagent le sommet pour les sommets isoles
1235 const Desc_Structure_FT& desc_som = desc_sommets();
1236 desc_som.collecter_espace_virtuel(compo_connexe_sommets, MD_Vector_tools::EV_MAX);
1237 desc_som.echange_espace_virtuel(compo_connexe_sommets);
1238
1239}
1240
1241DoubleTab Maillage_FT_IJK::update_sigma_and_interfacial_source_term_sommet(const Domaine_IJK& splitting, bool compute_interfacial_source, bool, const double sigma_const)
1242
1243{
1244
1245 if (!Surfactant_facettes_.get_disable_surfactant())
1246 {
1247 // on est dans un cas sigma variable
1248 return Surfactant_facettes_.update_sigma_and_interfacial_source_term_sommet(*this, splitting, compute_interfacial_source, use_tryggvason_interfacial_source_);
1249 }
1250 else if (Surfactant_facettes_.get_disable_marangoni_source_term() and use_tryggvason_interfacial_source_)
1251 {
1252 // on est dans un cas sigma = cte, mais on veut le terme source de Tryggvason
1253 DoubleTab interfacial_source_term ;
1254 if (compute_interfacial_source)
1255 {
1256 const int nbfa7=nb_facettes();
1257 ArrOfDouble sigma_facettes;
1258 sigma_facettes.resize(nbfa7);
1259 for (int fa=0 ; fa<nbfa7 ; fa++)
1260 sigma_facettes[fa]= sigma_const;
1261
1262 Operator_FT_Disc OpFTDisc;
1263 OpFTDisc.Compute_interfaciale_source(sigma_facettes, *this, interfacial_source_term, true, use_tryggvason_interfacial_source_, !Surfactant_facettes_.get_disable_marangoni_source_term());
1264 }
1265 return interfacial_source_term ;
1266 }
1267 else
1268 {
1269 DoubleTab interfacial_source_term ;
1270 Cerr << "No surfactant nor tryggvason formulation for interfacial source term --> we must not be here ! " << finl;
1271 Process::exit();
1272 return interfacial_source_term ;
1273 }
1274 //
1275
1276}
1277
1278// Fait appel a la methode Maillage_FT_Disc::recopie pour copier le maillage.
1279// Puis initialise le tableau de composantes connexes avec la valeur imposee icompo.
1280void Maillage_FT_IJK::recopie_force_compo(const Maillage_FT_IJK& source_mesh, const int icompo)
1281{
1282 Cerr << "Methode Maillage_FT_IJK::recopie_force_compo inusite jusqu'a present"
1283 << " donc a tester! " << finl;
1284 Process::exit();
1285 recopie(source_mesh, MINIMAL);
1286 const int nf = nb_facettes();
1287 compo_connexe_facettes_.resize_array(nf, RESIZE_OPTIONS::NOCOPY_NOINIT); // tous les sommets, y compris virtuels.
1288 for (int i_facette = 0; i_facette < nf; i_facette++)
1289 {
1290 compo_connexe_facettes_[i_facette] = icompo;
1291 }
1292}
1293
1294// Surcharge la methode Maillage_FT_Disc::recopie pour copier le maillage.
1295// Puis initialise le tableau de composantes connexes avec la valeur dans source_mesh.
1296void Maillage_FT_IJK::recopie(const Maillage_FT_Disc& source_mesh, Statut_Maillage niveau_copie)
1297{
1298 if (sub_type(Maillage_FT_IJK, source_mesh))
1299 {
1300 const Maillage_FT_IJK& source_mesh_ijk = ref_cast(Maillage_FT_IJK, source_mesh);
1301
1302 nbmailles_euler_i_ = source_mesh_ijk.nbmailles_euler_i_;
1303 nbmailles_euler_j_ = source_mesh_ijk.nbmailles_euler_j_;
1304 nbmailles_euler_k_ = source_mesh_ijk.nbmailles_euler_k_;
1309
1310 Maillage_FT_Disc::recopie(source_mesh, niveau_copie);
1311 compo_connexe_facettes_.copy_array(source_mesh_ijk.compo_connexe_facettes());
1312 Surfactant_facettes_.copy_FT_Field(source_mesh_ijk.Surfactant_facettes());
1313 }
1314 else
1315 {
1316 // soit erreur, soit initialise avec une valeur par defaut.
1317 Cerr << "Maillage_FT_IJK::recopie_maillage : cette surcharge s'attend a "
1318 << "recevoir un Maillage_FT_IJK" << finl;
1319 Process::exit();
1320 }
1321
1322}
1323
1324// Surcharge de la methode Maillage_FT_Disc::ajouter_maillage
1325void Maillage_FT_IJK::ajouter_maillage(const Maillage_FT_Disc& maillage_tmp,int skip_facettes)
1326{
1327 if (sub_type(Maillage_FT_IJK, maillage_tmp))
1328 {
1329 ajouter_maillage_IJK(ref_cast(Maillage_FT_IJK, maillage_tmp)) ; // copie les compo connexes existantes
1330 }
1331 else
1332 {
1333 // soit erreur, soit initialise avec une valeur par defaut.
1334 Cerr << "Maillage_FT_IJK::ajouter_maillage : cette surcharge s'attend a "
1335 << "recevoir un Maillage_FT_IJK" << finl;
1336 Process::exit();
1337 }
1338}
1339
1340
1341// Pour remplir correctement le tableau des composantes connexes
1342// a partir du tableau compo_connex du maillage source.
1344{
1345
1346 const int nb_facettes_ini = nb_facettes(); // du maillage initial : *this.
1347 const int nb_facettes_add = added_mesh.nb_facettes(); // du maillage a ajouter.
1348 const ArrOfInt& compo_connexe_add = added_mesh.compo_connexe_facettes(); // Compo connexes a ajouter
1349 const FT_Field& Surfactant_add = added_mesh.Surfactant_facettes();
1350 // On etends le tableau de composantes connexes en ajoutant celui de added_mesh a la fin:
1351 compo_connexe_facettes_.resize_array(nb_facettes_ini+nb_facettes_add);
1352 compo_connexe_facettes_.inject_array(compo_connexe_add, -1, /* tous les elements de la source */
1353 nb_facettes_ini, /* indice destination */
1354 0); /* indice source */
1355
1356 if (!Surfactant_facettes_.get_disable_surfactant())
1357 {
1358 Surfactant_facettes_.resize_array(nb_facettes_ini+nb_facettes_add);
1359 Surfactant_facettes_.inject_array(Surfactant_add, -1, /* tous les elements de la source */
1360 nb_facettes_ini, /* indice destination */
1361 0); /* indice source */
1362 }
1363 // La methode Maillage_FT_Disc::ajouter_maillage va ajouter les facettes, les sommets...
1364 // et elle va mettre a jour les desc et les num_owner... en ajoutant des elements dans les decripteurs
1365 // Mais elle ne fait pas d'echange. Pas de renumerotation (seulement la gestion du decalage nb_facettes_ini
1366 // pour les elements ajoutes aux desc).
1367 // La compo connexe est donc valide apres :
1369
1370}
1371
1372
1373void Maillage_FT_IJK::calculer_costheta_minmax(DoubleTab& costheta) const
1374{
1375 const int nb_som = nb_sommets();
1376 costheta.resize(nb_som, 2);
1377 costheta = 0. ;
1378}
1379
1380static double distance_sommets(const DoubleTab& sommets, const int s0, const int s1)
1381{
1382 const double d = (sommets(s0,0) - sommets(s1,0)) * (sommets(s0,0) - sommets(s1,0))
1383 + (sommets(s0,1) - sommets(s1,1)) * (sommets(s0,1) - sommets(s1,1))
1384 + (sommets(s0,2) - sommets(s1,2)) * (sommets(s0,2) - sommets(s1,2));
1385 return sqrt(d);
1386}
1387
1389{
1390 // nettoyer_maillage();
1391 const int nb_fa7 = facettes_.dimension(0);
1392 const DoubleTab& tab_sommets = sommets();
1393 double lg = 1.e10;
1394 double petit = 1.e-7;
1395
1396 for (int i = 0; i < nb_fa7; i++)
1397 {
1398 const int s0 = facettes_(i,0);
1399 const int s1 = facettes_(i,1);
1400 const int s2 = facettes_(i,2);
1401 double d1 = distance_sommets(tab_sommets, s0, s1);
1402 double d2 = distance_sommets(tab_sommets, s0, s2);
1403 double d3 = distance_sommets(tab_sommets, s1, s2);
1404 //Cerr << d1 << " " << d2 << " " << d3 << finl;
1405
1406 if ((d1> petit) && (d1 < lg))
1407 {
1408 lg = d1;
1409 }
1410 if ((d2> petit) && (d2 < lg))
1411 {
1412 lg = d2;
1413 }
1414 if ((d3> petit) && (d3 < lg))
1415 {
1416 lg = d3;
1417 }
1418 }
1419
1420 // Syncronisation :
1421 lg = Process::mp_min(lg);
1422 return lg;
1423
1424}
1425
1427{
1428 if (statut_< MINIMAL)
1429 return 0;
1430 int compt = 0 ;
1431 for (int ifa=0 ; ifa<facettes_.dimension(0) ; ifa++)
1432 {
1433 if (compo_connexe_facettes_(ifa)>=0)
1434 {
1435 compt++;
1436 }
1437 }
1438 return compt;
1439}
static int check_enabled()
Definition Comm_Group.h:159
: class Desc_Structure_FT
void collecter_espace_virtuel(ArrOfDouble &tab, MD_Vector_tools::Operations_echange op) const
void echange_espace_virtuel(ArrOfDouble &tab) const
: class Descripteur_FT Descripteur_FT stocke pour chaque PE une liste de numeros d'elements.
const ArrOfInt & elements(int pe_voisin) const
Renvoie la liste des elements distants/virtuels du pe en parametre.
const ArrOfInt & pe_voisins() const
Renvoie la liste des PE pour lesquels la liste d'elements est non vide, dans l'ordre croissant des nu...
This class encapsulates all the information related to the eulerian mesh for TrioIJK.
Definition Domaine_IJK.h:47
int get_nb_elem_local(int direction) const
Returns the number of elements owned by this processor in the given direction.
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
void reinit_remeshing_table()
Definition FT_Field.h:452
void completer_compo_connexe_partielle(const Maillage_FT_IJK &mesh, const Domaine_IJK &splitting, const DoubleTab &liste_sommets_apres_deplacement, const DoubleTab &liste_sommets_avant_deplacement, const ArrOfInt &compo_connexe_sommets_deplace)
DoubleTab & get_liste_sommets_et_deplacements_non_const()
Definition FT_Field.h:435
void remailler_FT_Field(Maillage_FT_IJK &mesh)
Definition FT_Field.cpp:981
const ArrOfInt get_sorted_index()
Definition FT_Field.h:439
void set_tolerance_point_identique(double longueur_cara_fa7)
Definition FT_Field.h:462
ArrOfInt get_compo_connexe_sommets() const
Definition FT_Field.h:365
void echange_espace_virtuel(const Maillage_FT_Disc &mesh)
Definition FT_Field.cpp:378
void champ_sommet_from_facettes(const ArrOfInt &compo_connexe_facettes, const Maillage_FT_IJK &mesh)
Point3D calculer_normale_apres_deplacement(const int fa, const int somfa7, const Vecteur3 pos_apres_dep)
void sauvegarder_triangle(const Maillage_FT_IJK &mesh, const int i, const int avant_apres_remaillage)
Definition FT_Field.cpp:898
void update_FT_Field_local_from_full_compo(const Maillage_FT_IJK &mesh)
bool get_disable_surfactant() const
Definition FT_Field.h:351
DoubleTab & get_facettes_sommets_full_compo_non_const()
Definition FT_Field.h:431
virtual void creer_facettes_virtuelles(const ArrOfInt &liste_facettes, const ArrOfInt &liste_pe, const ArrOfInt &facettes_send_pe_list, const ArrOfInt &facettes_recv_pe_list)
Creation de facettes virtuelles sur le pe specifie.
int nb_sommets() const
renvoie le nombre de sommets (reels et virtuels) (egal a sommets().
const DoubleTab & sommets() const
renvoie le tableau des sommets (reels et virtuels) dimension(0) = nombre de sommets,
void corriger_proprietaires_facettes()
Sans changer les sommets existants ni la numerotation des facettes, on change le proprietaire des fac...
void supprimer_facettes(const ArrOfInt &liste_facettes)
Supprime les facettes dont les indices locaux sont donnes en parametre.
ArrOfIntFT sommet_PE_owner_
Desc_Structure_FT desc_facettes_
virtual const ArrOfDouble & get_surface_facettes() const
void creer_sommets_virtuels(const ArrOfInt &liste_sommets, const ArrOfInt &liste_pe, const Schema_Comm &comm)
Envoi des sommets dont le numero est donne dans liste_sommets au processeur dont le numero est donne ...
int nb_facettes() const
renvoie le nombre de facettes (reelles et virtuelles) (egal a facettes().
ArrOfIntFT sommet_face_bord_
ArrOfIntFT facette_num_owner_
virtual void nettoyer_maillage()
Retire toutes les facettes virtuelles, toutes les facettes invalides (sommet0 == sommet1) et tous les...
Desc_Structure_FT desc_sommets_
void associer_domaine_dis_parcours(const Domaine_dis_base &domaine_dis, const Parcours_interface &parcours)
int facette_virtuelle(int i) const
Renvoie 0 si la facette m'appartient, 1 sinon.
const Desc_Structure_FT & desc_sommets() const
renvoie le descripteur des sommets (espace_distant/virtuel)
virtual int check_mesh(int error_is_fatal=1, int skip_facette_owner=0, int skip_facettes=0) const
ArrOfIntFT sommet_num_owner_
virtual void ajouter_maillage(const Maillage_FT_Disc &maillage_tmp, int skip_facettes=0)
const Desc_Structure_FT & desc_facettes() const
renvoie le descripteur des facettes (espace_distant/virtuel)
ArrOfIntFT drapeaux_sommets_
void parcourir_maillage()
Remplit la structure intersections_elem_facettes_.
int sommet_virtuel(int i) const
virtual void recopie(const Maillage_FT_Disc &maillage_source, Statut_Maillage niveau_copie)
Recopie une partie du maillage source dans *this.
Maillage_FT_Disc()
constructeur par defaut.
virtual void transporter(const DoubleTab &deplacement)
Deplace les sommets de l'interface d'un vecteur "deplacement" fourni, Change eventuellement les somme...
friend class Parcours_interface
Statut_Maillage statut_
void reset()
vide toutes les structures du maillage, le statut passe a RESET.
: class Maillage_FT_IJK
ArrOfInt liste_processeurs_voisins_faces_
void calculer_costheta_minmax(DoubleTab &costheta) const override
Pour chaque sommet du maillage, s'il est sur un bord, on calcule costheta min et max (hysteresis) cor...
void deplacer_sommets(const ArrOfInt &liste_sommets_initiale, const DoubleTab &deplacement_initial, ArrOfInt &liste_sommets_sortis, ArrOfInt &numero_face_sortie, int skip_facettes=0) override
Applique un vecteur deplacement aux noeuds dont le numero est dans "liste_noeud", puis echange les es...
bool use_tryggvason_interfacial_source_
int check_mesh(int error_is_fatal=1, int skip_facette_owner=0, int skip_facettes=0) const override
int nb_facettes_sans_duplicata() const
void lire_maillage_ft_dans_lata(const char *filename_with_path, int tstep, const char *geometryname)
const ArrOfInt & compo_connexe_facettes() const
void ajouter_maillage(const Maillage_FT_Disc &maillage_tmp, int skip_facettes=0) override
FT_Field & Surfactant_facettes_non_const()
DoubleTab update_sigma_and_interfacial_source_term_sommet(const Domaine_IJK &splitting, bool compute_interfacial_source, bool use_tryggvason_formulation, const double sigma_const=-1.)
Int3 get_ijk_cell_index(int num_sommet) const
const FT_Field & Surfactant_facettes() const
ArrOfIntFT compo_connexe_facettes_
void creer_facettes_virtuelles(const ArrOfInt &liste_facettes, const ArrOfInt &liste_pe, const ArrOfInt &facettes_send_pe_list, const ArrOfInt &facettes_recv_pe_list) override
Creation de facettes virtuelles sur le pe specifie.
FT_Field Surfactant_facettes_
void transporter(const DoubleTab &deplacement) override
Deplace les sommets de l'interface d'un vecteur "deplacement" fourni, Change eventuellement les somme...
void nettoyer_maillage() override
Retire toutes les facettes virtuelles, toutes les facettes invalides (sommet0 == sommet1) et tous les...
ArrOfInt & compo_connexe_facettes_non_const()
void initialize_processor_neighbourhood()
int check_sommets(int error_is_fatal=1) const override
void recopie_force_compo(const Maillage_FT_IJK &source_mesh, const int icompo)
DoubleTab indexation_facettes_avant_transport_
void corriger_proprietaires_facettes()
void update_surfactant_apres_transport()
ArrOfInt liste_processeurs_voisins_coins_
void recopie(const Maillage_FT_Disc &source_mesh, Statut_Maillage niveau_copie) override
Recopie une partie du maillage source dans *this.
Maillage_FT_IJK(const Maillage_FT_IJK &)=default
void ajouter_maillage_IJK(const Maillage_FT_IJK &added_mesh)
ArrOfInt voisinage_processeur_
ArrOfInt liste_processeurs_voisins_aretes_
void supprimer_facettes(const ArrOfInt &liste_facettes)
double minimum_longueur_arrete() const
void calculer_compo_connexe_sommets(ArrOfIntFT &compo_connexe_sommets) const
void initialize(const Domaine_IJK &, const Domaine_dis_base &, const Parcours_interface &, const bool use_tryggvason_interfacial_source=false)
void sauv_facette_indexation_avant_transport()
void set_ijk_cell_index(int num_sommet, Int3 ijk)
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
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
: class Operator_FT_Disc
void Compute_interfaciale_source(const ArrOfDouble &sigma_Facet, const Maillage_FT_Disc &FTmesh, DoubleTab &df_sigma, bool Normalised_with_Surface, bool use_tryggvason_formulation, bool with_marangoni=false)
double z
Definition FT_Field.h:80
static double tol
Definition FT_Field.h:79
double y
Definition FT_Field.h:80
double x
Definition FT_Field.h:80
double norme()
Definition FT_Field.h:86
static double mp_min(double)
Definition Process.cpp:386
static int check_int_overflow(trustIdType)
Definition Process.cpp:428
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 int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
Definition Process.cpp:104
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
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
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
void set_send_recv_pe_list(const ArrOfInt &send_pe_list, const ArrOfInt &recv_pe_list, const int me_to_me=0)
Definit la liste des processeurs a qui on va envoyer et de qui on va recevoir des donnees.
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)
void resize(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTArray.h:156
int dimension_int(int d) const
Definition TRUSTTab.tpp:152
void ref_as_small(TRUSTTab< _TYPE_, int > &out) const
Definition TRUSTTab.tpp:198
int nb_dim() const
Definition TRUSTTab.h:199
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133