TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Cut_cell_FT_Disc.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 <IJK_Interfaces.h>
17#include <Cut_cell_FT_Disc.h>
18#include <Maillage_FT_Disc.h>
19#include <IJK_Field.h>
20#include <Array_tools.h>
21#include <Domaine_IJK.h>
22
24 ghost_size_(4),
26 n_loc_(0),
27 n_tot_(0)
28{
29 independent_index_.associer_paresseux(*this);
30 permutation_.associer_paresseux(*this);
31 processed_.associer_paresseux(*this);
32
33 coord_.associer_persistant(*this);
34
35 index_sorted_by_k_.associer_paresseux(*this);
36 k_value_index_.resize(0, 1);
37
38 index_sorted_by_indicatrice_.associer_paresseux(*this);
39
40 index_sorted_by_statut_diphasique_.associer_paresseux(*this);
42}
43
45{
46 /* Initialisation sans indicatrice (suppose aucune cellule diphasique) */
47
48 ref_interfaces_ = interfaces;
49 ref_domaine_ = splitting;
50 localisation_ = loc;
51
52 // Initialisation des tableaux
53 n_loc_ = 0;
54 n_tot_ = 0;
55
56 permutation_.resize(0, permutation_.dimension(1));
57
58 processed_.resize(0, processed_.dimension(1));
59
60 resize_data(0);
61
62 // Initialisation du champ IJK_Field utilise pour le post-traitement
63 write_buffer_.allocate(ref_domaine_, localisation_, 1);
64
65 // Initialisation du champ IJK_Field des indices diphasiques
66 indice_diphasique_.allocate(ref_domaine_, localisation_, ghost_size_);
67
68 // Remplissage de certains champs a partir des valeurs sur la structure IJK_Field
69 set_coord();
70
71 // Communication des elements virtuels
73
76
78
79 // Calcul de l'indice lineaire pour les elements virtuels
80 independent_index_.resize(n_tot_, independent_index_.dimension(1));
82
83 // Remplissage du tableau des indices diphasiques
85
86 // Creation des tableaux des indices tries par k
88
89 // Verifications
92}
93
94
95void Cut_cell_FT_Disc::initialise(IJK_Interfaces& interfaces, Domaine_IJK& splitting, Domaine_IJK::Localisation loc, const IJK_Field_double& old_indicatrice, const IJK_Field_double& next_indicatrice)
96{
97 ref_interfaces_ = interfaces;
98 ref_domaine_ = splitting;
99 localisation_ = loc;
100 assert(localisation_ == old_indicatrice.get_localisation());
101 assert(localisation_ == next_indicatrice.get_localisation());
102
103 // Initialisation des tableaux
104 n_loc_ = initialise_independent_index(old_indicatrice, next_indicatrice);
105 n_tot_ = n_loc_;
106
107 permutation_.resize(n_loc_, permutation_.dimension(1));
109
110 processed_.resize(n_loc_, processed_.dimension(1));
112
114
115 // Initialisation du champ IJK_Field utilise pour le post-traitement
116 write_buffer_.allocate(ref_domaine_, localisation_, 1);
117
118 // Initialisation du champ IJK_Field des indices diphasiques
119 indice_diphasique_.allocate(ref_domaine_, localisation_, ghost_size_);
120
121 // Remplissage de certains champs a partir des valeurs sur la structure IJK_Field
122 set_coord();
123
124 // Communication des elements virtuels
126
129
131
132 // Calcul de l'indice lineaire pour les elements virtuels
133 independent_index_.resize(n_tot_, independent_index_.dimension(1));
135
136 // Remplissage du tableau des indices diphasiques
138
139 // Creation des tableaux des indices tries par k
141
142 // Creation des tableaux des indices tries par l'indicatrice
143 update_index_sorted_by_indicatrice(old_indicatrice, next_indicatrice);
144
145 // Creation des tableaux des indices tries par le statut diphasique
146 update_index_sorted_by_statut_diphasique(old_indicatrice, next_indicatrice);
147
148 // Verifications
150 assert(verifier_taille_tableaux());
151}
152
153void Cut_cell_FT_Disc::update(const IJK_Field_double& old_indicatrice, const IJK_Field_double& next_indicatrice)
154{
155 assert(localisation_ == old_indicatrice.get_localisation());
156 assert(localisation_ == next_indicatrice.get_localisation());
157
158 // Increment du compteur des iterations
159 processed_count_ += 1;
160
161 // Supprime les elements virtuels
162 independent_index_.resize(n_loc_, independent_index_.dimension(1));
163 permutation_.resize(n_loc_, permutation_.dimension(1));
164 processed_.resize(n_loc_, processed_.dimension(1));
166 n_tot_ = n_loc_;
167
168 // Mise a jour des elements locaus
169 n_loc_ = add_and_remove_local_elements(old_indicatrice, next_indicatrice);
170 n_tot_ = n_loc_;
171
172 // Remplissage de certains champs a partir des valeurs sur la structure IJK_Field
173 set_coord();
174
175 // Communication des elements virtuels
176 desc_.reset();
177
180
182
183 // Calcul de l'indice lineaire pour les elements virtuels
184 independent_index_.resize(n_tot_, independent_index_.dimension(1));
186
187 // Remplissage du tableau des indices diphasiques
189
190 // Creation des tableaux des indices tries par k
192
193 // Creation des tableaux des indices tries par l'indicatrice
194 update_index_sorted_by_indicatrice(old_indicatrice, next_indicatrice);
195
196 // Creation des tableaux des indices tries par le statut diphasique
197 update_index_sorted_by_statut_diphasique(old_indicatrice, next_indicatrice);
198
199 // Verifications
201 assert(verifier_taille_tableaux());
202
203 Nom string_localisation = (localisation_ == Domaine_IJK::ELEM) ? Nom("ELEM") :
204 ((localisation_ == Domaine_IJK::FACES_I) ? Nom("FACES_I") :
205 ((localisation_ == Domaine_IJK::FACES_J) ? Nom("FACES_J") :
206 (localisation_ == Domaine_IJK::FACES_K) ? Nom("FACES_K") : Nom("Error")));
207 Cerr << "(Cut_cell_FT_Disc::update " << string_localisation << ") Iter: " << processed_count_-1 << " n_tot_=" << n_tot_ << " n_loc_=" << n_loc_ << finl;
208}
209
210// Initialise le tableau des indices a partir du champ de l'indicatrice
211// et renvoie le nombre local d'elements diphasiques n_loc.
212int Cut_cell_FT_Disc::initialise_independent_index(const IJK_Field_double& old_indicatrice, const IJK_Field_double& next_indicatrice)
213{
214 const int ni = ref_domaine_->get_nb_elem_local(0);
215 const int nj = ref_domaine_->get_nb_elem_local(1);
216 const int nk = ref_domaine_->get_nb_elem_local(2);
217
218 int n_loc = n_loc_;
219
220 assert(n_loc == 0);
221 assert(n_loc == n_tot_);
222
223 for (int k = 0; k < nk; k++)
224 {
225 for (int j = 0; j < nj; j++)
226 {
227 for (int i = 0; i < ni; i++)
228 {
229 if (!ref_interfaces_->est_pure(0.5*(old_indicatrice(i,j,k) + next_indicatrice(i,j,k))))
230 {
231 n_loc += 1;
232 }
233 }
234 }
235 }
236
237 independent_index_.resize(n_loc, independent_index_.dimension(1));
238
239 {
240 int n = 0;
241 for (int k = 0; k < nk; k++)
242 {
243 for (int j = 0; j < nj; j++)
244 {
245 for (int i = 0; i < ni; i++)
246 {
247 if (!ref_interfaces_->est_pure(0.5*(old_indicatrice(i,j,k) + next_indicatrice(i,j,k))))
248 {
249 independent_index_(n) = ref_domaine_->get_independent_index(i, j, k);
250
251 // Verification de la fonction function get_ijk_from_independent_index
252 assert(get_ijk(n)[0] == i);
253 assert(get_ijk(n)[1] == j);
254 assert(get_ijk(n)[2] == k);
255
256 n += 1;
257 }
258 }
259 }
260 }
261 assert(n == n_loc);
262 }
263
264 return n_loc;
265}
266
268{
269 for (int n = 0; n < n_loc_; n++)
270 {
271 permutation_(n) = n;
272 }
273}
274
276{
278 for (int n = 0; n < n_loc_; n++)
279 {
281 }
282}
283
285{
286 const int processed_sign = (processed_.dimension(0) == 0) ? 1 : (processed_(0) > 0 ? 1 : -1);
287 assert(ref_domaine_->is_uniform(0));
288 assert(ref_domaine_->is_uniform(1));
289 assert(ref_domaine_->is_uniform(2));
290 for (int n = 0; n < n_loc_; n++)
291 {
292 Int3 ijk = get_ijk(n);
293 int i = ijk[0];
294 int j = ijk[1];
295 int k = ijk[2];
296
297 // Pour les cellules anciennement diphasiques, il n'y a pas de sens
298 // a fixer la valeur de coord_.
299 if (processed_(n) * processed_sign >= processed_count_)
300 {
301 coord_(n,0) = (i + ref_domaine_->get_offset_local(0) + .5)*ref_domaine_->get_constant_delta(0) + ref_domaine_->get_origin(0);
302 coord_(n,1) = (j + ref_domaine_->get_offset_local(1) + .5)*ref_domaine_->get_constant_delta(1) + ref_domaine_->get_origin(1);
303 coord_(n,2) = (k + ref_domaine_->get_offset_local(2) + .5)*ref_domaine_->get_constant_delta(2) + ref_domaine_->get_origin(2);
304
305 // Verification de la fonction function get_ijk_from_independent_index
306 assert(i == ref_domaine_->get_ijk_from_coord(coord_(n,0), coord_(n,1), coord_(n,2), Domaine_IJK::ELEM)[0]);
307 assert(j == ref_domaine_->get_ijk_from_coord(coord_(n,0), coord_(n,1), coord_(n,2), Domaine_IJK::ELEM)[1]);
308 assert(k == ref_domaine_->get_ijk_from_coord(coord_(n,0), coord_(n,1), coord_(n,2), Domaine_IJK::ELEM)[2]);
309 }
310 }
311}
312
313// Met a jour les tableaux des indices pour tenir compte des cellules
314// nouvellement diphasiques et les cellules anciennement diphasiques a supprimer
315// et renvoie le nombre local d'elements diphasiques n_loc.
316int Cut_cell_FT_Disc::add_and_remove_local_elements(const IJK_Field_double& old_indicatrice, const IJK_Field_double& next_indicatrice)
317{
318 const int ni = ref_domaine_->get_nb_elem_local(0);
319 const int nj = ref_domaine_->get_nb_elem_local(1);
320 const int nk = ref_domaine_->get_nb_elem_local(2);
321
322 int n_loc = n_loc_;
323
324 assert(n_loc == n_tot_);
325 assert(verifier_si_ordonne(independent_index_, 0, n_loc));
327
328 // Calcule une borne superieure au nombre d'elements anciennement diphasiques a supprimer
329 // Le nombre reeel pourrait etre plus faible si certains de ces elements redeviennent diphasiques.
330 const int processed_sign = (processed_.dimension(0) == 0) ? 1 : (processed_(0) > 0 ? 1 : -1);
331
332 // Mise a jour des tableaux independent_index_, permutation_ et processed_.
333 // Procedure :
334 // * Parcours du champ de l'indicatrice a la recherche de cellules diphasiques.
335 // Pour chaque cellule diphasique, verifier si elle deja dans la structure :
336 // les nouvelles cellules diphasiques sont ajoutes a la fin des tableaux,
337 // tout en notant l'endroit ou il aurait fallu les inserer dans permutation_.
338 // * Permutation des tableaux pour retrouver l'ordre des indices croissants,
339 // en placant les anciennes cellules diphasiques a supprimer a la fin.
340 // Il suffit alors de diminuer la taille des tableaux pour les supprimer.
341
342 int index_perm = 0;
343
344 int n_initial = n_loc;
345 for (int k = 0; k < nk; k++)
346 {
347 for (int j = 0; j < nj; j++)
348 {
349 for (int i = 0; i < ni; i++)
350 {
351 if (!ref_interfaces_->est_pure(0.5*(old_indicatrice(i,j,k) + next_indicatrice(i,j,k))))
352 {
353 int independent_index = ref_domaine_->get_independent_index(i, j, k);
354
355 // Recherche de l'element dans la structure cut-cell
356 // La zone de recherche est restreinte car on sait que l'on va trouver les
357 // elements dans l'ordre du tableau
358 int m = indice_diphasique_(i,j,k);
359
360 if (m < 0)
361 {
362 // Nouvel element diphasique trouve
363 // Ajout du nouvel element a la fin de independent_index_ et processed_
364 independent_index_.resize(n_loc + 1, independent_index_.dimension(1));
365 permutation_.resize(n_loc + 1, permutation_.dimension(1));
366 processed_.resize(n_loc + 1, processed_.dimension(1));
367
368 independent_index_(n_loc) = independent_index;
369 processed_(n_loc) = processed_count_ * processed_sign;
370
371 // Ajout a permutation_ : nouvel element diphasique trouve
372 permutation_(index_perm) = n_loc;
373 index_perm += 1;
374 n_loc += 1;
375 }
376 else
377 {
378 // Ajout a permutation_ : element diphasique trouve
379 permutation_(index_perm) = m;
380 index_perm += 1;
381 }
382
383 }
384 }
385 }
386 }
387
388 // Ajout a permutation_ : elements anciennement diphasiques a supprimer
389 int n_deletion = 0;
390 for (int n = 0; n < n_initial; n++)
391 {
392 Int3 ijk = ref_domaine_->get_ijk_from_coord(coord_(n,0), coord_(n,1), coord_(n,2), Domaine_IJK::ELEM);
393 int i = ijk[0];
394 int j = ijk[1];
395 int k = ijk[2];
396
397 if (ref_interfaces_->est_pure(0.5*(old_indicatrice(i,j,k) + next_indicatrice(i,j,k))))
398 {
399 permutation_(index_perm) = n;
400 index_perm += 1;
401
402 n_deletion += 1;
403 }
404 }
405
406 assert(index_perm == n_loc);
408
409 // Application des differentes permutations
412
413 assert(verifier_si_ordonne(independent_index_, 0, n_loc - n_deletion));
414
415 assert(persistent_double_data_(0).valeur().dimension(0) <= n_loc);
416 resize_data(n_loc);
417
418 for (int i = 0; i < persistent_double_data_.size(); i++)
419 {
420 apply_permutation(persistent_double_data_(i).valeur(), permutation_, processed_);
421 }
422
423 for (int i = 0; i < persistent_int_data_.size(); i++)
424 {
425 apply_permutation(persistent_int_data_(i).valeur(), permutation_, processed_);
426 }
427
428 // Redimensionnement pour suppression des elements anciennement diphasiques
429
430 resize_data(n_loc - n_deletion);
431
432 independent_index_.resize(n_loc - n_deletion, independent_index_.dimension(1));
433 permutation_.resize(n_loc - n_deletion, permutation_.dimension(1));
434 processed_.resize(n_loc - n_deletion, permutation_.dimension(1));
435
436 n_loc -= n_deletion;
437
438 assert(verifier_si_ordonne(independent_index_, 0, n_loc));
439
440 return n_loc;
441}
442
444{
445 // Changement de taille des tableaux de double
446 for (int i = 0; i < persistent_double_data_.size(); i++)
447 {
448 int n_initial = persistent_double_data_(i).valeur().dimension(0);
449
450 persistent_double_data_(i).valeur().resize(size, persistent_double_data_(i).valeur().dimension(1));
451
452 // Si la nouvelle taille est plus grande, initialise les valeurs
453 for (int n = n_initial; n < size; n++)
454 {
455 for (int j = 0; j < persistent_double_data_(i).valeur().dimension(1); j++)
456 {
457 persistent_double_data_(i).valeur()(n,j) = 0;
458 }
459 }
460 }
461
462 for (int i = 0; i < transient_double_data_.size(); i++)
463 {
464 transient_double_data_(i).valeur().resize(size, transient_double_data_(i).valeur().dimension(1));
465
466 // Initialise toutes les valeurs
467 for (int n = 0; n < size; n++)
468 {
469 for (int j = 0; j < transient_double_data_(i).valeur().dimension(1); j++)
470 {
471 transient_double_data_(i).valeur()(n,j) = 0;
472 }
473 }
474 }
475
476 for (int i = 0; i < lazy_double_data_.size(); i++)
477 {
478 lazy_double_data_(i).valeur().resize(size, lazy_double_data_(i).valeur().dimension(1));
479 }
480
481 // Changement de taille des tableaux d'entier
482 for (int i = 0; i < persistent_int_data_.size(); i++)
483 {
484 int n_initial = persistent_int_data_(i).valeur().dimension(0);
485
486 persistent_int_data_(i).valeur().resize(size, persistent_int_data_(i).valeur().dimension(1));
487
488 // Si la nouvelle taille est plus grande, initialise les valeurs
489 for (int n = n_initial; n < size; n++)
490 {
491 for (int j = 0; j < persistent_int_data_(i).valeur().dimension(1); j++)
492 {
493 persistent_int_data_(i).valeur()(n,j) = 0;
494 }
495 }
496 }
497
498 for (int i = 0; i < transient_int_data_.size(); i++)
499 {
500 transient_int_data_(i).valeur().resize(size, transient_int_data_(i).valeur().dimension(1));
501
502 // Initialise toutes les valeurs
503 for (int n = 0; n < size; n++)
504 {
505 for (int j = 0; j < transient_int_data_(i).valeur().dimension(1); j++)
506 {
507 transient_int_data_(i).valeur()(n,j) = 0;
508 }
509 }
510 }
511
512 for (int i = 0; i < lazy_int_data_.size(); i++)
513 {
514 lazy_int_data_(i).valeur().resize(size, lazy_int_data_(i).valeur().dimension(1));
515 }
516}
517
519{
520 assert(independent_index_.dimension(0) == n_tot_);
521
522 int independent_index;
523
524 // Verification de l'indice lineaire pour les elements locaux
525 for (int n = 0; n < n_loc_; n++)
526 {
527 Int3 ijk = ref_domaine_->get_ijk_from_coord(coord_(n,0), coord_(n,1), coord_(n,2), Domaine_IJK::ELEM);
528 int i = ijk[0];
529 int j = ijk[1];
530 int k = ijk[2];
531
532 independent_index = ref_domaine_->get_independent_index(i, j, k);
533
534 assert(independent_index_(n) == independent_index);
535 }
536
537 // Calcul de l'indice lineaire pour les elements virtuels
538 for (int n = n_loc_; n < n_tot_; n++)
539 {
540 Int3 ijk = ref_domaine_->get_ijk_from_coord(coord_(n,0), coord_(n,1), coord_(n,2), Domaine_IJK::ELEM);
541 int i = ijk[0];
542 int j = ijk[1];
543 int k = ijk[2];
544
545 independent_index = ref_domaine_->get_independent_index(i, j, k);
546
547 independent_index_(n) = independent_index;
548 }
549}
550
552{
553 int left_neighbour_x = (ref_domaine_->get_neighbour_processor(0, 0) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(0, 0);
554 int left_neighbour_y = (ref_domaine_->get_neighbour_processor(0, 1) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(0, 1);
555 int left_neighbour_z = (ref_domaine_->get_neighbour_processor(0, 2) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(0, 2);
556 int right_neighbour_x = (ref_domaine_->get_neighbour_processor(1, 0) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(1, 0);
557 int right_neighbour_y = (ref_domaine_->get_neighbour_processor(1, 1) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(1, 1);
558 int right_neighbour_z = (ref_domaine_->get_neighbour_processor(1, 2) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(1, 2);
559
560 int shift_x_min = - (left_neighbour_x != ref_domaine_->me());
561 int shift_y_min = - (left_neighbour_y != ref_domaine_->me());
562 int shift_z_min = - (left_neighbour_z != ref_domaine_->me());
563 int shift_x_max = + (right_neighbour_x != ref_domaine_->me())*(right_neighbour_x != left_neighbour_x);
564 int shift_y_max = + (right_neighbour_y != ref_domaine_->me())*(right_neighbour_y != left_neighbour_y);
565 int shift_z_max = + (right_neighbour_z != ref_domaine_->me())*(right_neighbour_z != left_neighbour_z);
566
567 ArrOfIntFT pe_list;
568 for (int shift_x = shift_x_min; shift_x <= shift_x_max; shift_x++)
569 {
570 for (int shift_y = shift_y_min; shift_y <= shift_y_max; shift_y++)
571 {
572 for (int shift_z = shift_z_min; shift_z <= shift_z_max; shift_z++)
573 {
574 int dest_pe_position_x = ref_domaine_->get_local_slice_index(0) + shift_x;
575 int dest_pe_position_y = ref_domaine_->get_local_slice_index(1) + shift_y;
576 int dest_pe_position_z = ref_domaine_->get_local_slice_index(2) + shift_z;
577 int dest_pe = ref_domaine_->periodic_get_processor_by_ijk(dest_pe_position_x, dest_pe_position_y, dest_pe_position_z);
578 if (dest_pe == ref_domaine_->me())
579 {
580 assert(shift_x == 0);
581 assert(shift_y == 0);
582 assert(shift_z == 0);
583 continue;
584 }
585
586 pe_list.append_array(dest_pe);
587 }
588 }
589 }
590 array_trier_retirer_doublons(pe_list);
591 schema_comm_.set_send_recv_pe_list(pe_list, pe_list);
592}
593
595{
596 int ni = ref_domaine_->get_nb_elem_local(0);
597 int nj = ref_domaine_->get_nb_elem_local(1);
598 int nk = ref_domaine_->get_nb_elem_local(2);
599
600 Descripteur_FT& espace_distant = desc_.espace_distant();
601
602 schema_comm_.begin_comm();
603
604 int n_loc = n_loc_;
605 int n_tot = n_tot_;
606
607 assert(n_tot == n_loc);
608
609 // next indique la direction du processeur :
610 // 0 voisin vers les petits indices
611 // 1 voisin vers les grands indices
612
613 int left_neighbour_x = (ref_domaine_->get_neighbour_processor(0, 0) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(0, 0);
614 int left_neighbour_y = (ref_domaine_->get_neighbour_processor(0, 1) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(0, 1);
615 int left_neighbour_z = (ref_domaine_->get_neighbour_processor(0, 2) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(0, 2);
616 int right_neighbour_x = (ref_domaine_->get_neighbour_processor(1, 0) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(1, 0);
617 int right_neighbour_y = (ref_domaine_->get_neighbour_processor(1, 1) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(1, 1);
618 int right_neighbour_z = (ref_domaine_->get_neighbour_processor(1, 2) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(1, 2);
619
620 int shift_x_min = - (left_neighbour_x != ref_domaine_->me());
621 int shift_y_min = - (left_neighbour_y != ref_domaine_->me());
622 int shift_z_min = - (left_neighbour_z != ref_domaine_->me());
623 int shift_x_max = + (right_neighbour_x != ref_domaine_->me())*(right_neighbour_x != left_neighbour_x);
624 int shift_y_max = + (right_neighbour_y != ref_domaine_->me())*(right_neighbour_y != left_neighbour_y);
625 int shift_z_max = + (right_neighbour_z != ref_domaine_->me())*(right_neighbour_z != left_neighbour_z);
626
627 for (int shift_x = shift_x_min; shift_x <= shift_x_max; shift_x++)
628 {
629 for (int shift_y = shift_y_min; shift_y <= shift_y_max; shift_y++)
630 {
631 for (int shift_z = shift_z_min; shift_z <= shift_z_max; shift_z++)
632 {
633 int dest_pe_position_x = ref_domaine_->get_local_slice_index(0) + shift_x;
634 int dest_pe_position_y = ref_domaine_->get_local_slice_index(1) + shift_y;
635 int dest_pe_position_z = ref_domaine_->get_local_slice_index(2) + shift_z;
636 int dest_pe = ref_domaine_->periodic_get_processor_by_ijk(dest_pe_position_x, dest_pe_position_y, dest_pe_position_z);
637 if (dest_pe == ref_domaine_->me())
638 {
639 assert(shift_x == 0);
640 assert(shift_y == 0);
641 assert(shift_z == 0);
642 continue;
643 }
644
645 Sortie& send_buffer = schema_comm_.send_buffer(dest_pe);
646
647 int left_bnd_x = (shift_x < 0);
648 int left_bnd_y = (shift_y < 0);
649 int left_bnd_z = (shift_z < 0);
650 int right_bnd_x = ((shift_x > 0) || ((shift_x_max == 0) && (shift_x < 0) && (right_neighbour_x != ref_domaine_->me())));
651 int right_bnd_y = ((shift_y > 0) || ((shift_y_max == 0) && (shift_y < 0) && (right_neighbour_y != ref_domaine_->me())));
652 int right_bnd_z = ((shift_z > 0) || ((shift_z_max == 0) && (shift_z < 0) && (right_neighbour_z != ref_domaine_->me())));
653
654 for (int n = 0; n < n_loc; n++)
655 {
656 int i_selon_x = ref_domaine_->get_i_along_dir_no_perio(0, coord_(n,0), Domaine_IJK::ELEM);
657 int i_selon_y = ref_domaine_->get_i_along_dir_no_perio(1, coord_(n,1), Domaine_IJK::ELEM);
658 int i_selon_z = ref_domaine_->get_i_along_dir_no_perio(2, coord_(n,2), Domaine_IJK::ELEM);
659
660 bool is_within_a_ghost_distance_of_boundary = ((i_selon_x < ghost_size_) || (i_selon_y < ghost_size_) || (i_selon_z < ghost_size_) || (i_selon_x >= ni - ghost_size_) || (i_selon_y >= nj - ghost_size_) || (i_selon_z >= nk - ghost_size_));
661 if (is_within_a_ghost_distance_of_boundary
662 && ((left_bnd_x == (i_selon_x < ghost_size_)) || (right_bnd_x == (i_selon_x >= ni - ghost_size_)))
663 && ((left_bnd_y == (i_selon_y < ghost_size_)) || (right_bnd_y == (i_selon_y >= nj - ghost_size_)))
664 && ((left_bnd_z == (i_selon_z < ghost_size_)) || (right_bnd_z == (i_selon_z >= nk - ghost_size_))))
665 {
666 assert(! espace_distant.contient_element(dest_pe, n));
667
668 espace_distant.ajoute_element(dest_pe, n);
669 double x = coord_(n,0);
670 double y = coord_(n,1);
671 double z = coord_(n,2);
672 send_buffer << n << x << y << z;
673 }
674 }
675 }
676 }
677 }
678
679 schema_comm_.echange_taille_et_messages();
680
681 Descripteur_FT& espace_virtuel = desc_.espace_virtuel();
682
683 const ArrOfInt& recv_pe_list = schema_comm_.get_recv_pe_list();
684 for (int indice_pe = 0; indice_pe < recv_pe_list.size_array(); indice_pe++)
685 {
686 const int pe_source = recv_pe_list[indice_pe];
687 Entree& recv_buffer = schema_comm_.recv_buffer(pe_source);
688
689 do
690 {
691 int numero_sur_pe_source;
692 double pos_x;
693 double pos_y;
694 double pos_z;
695 recv_buffer >> numero_sur_pe_source >> pos_x >> pos_y >> pos_z;
696 if (recv_buffer.eof())
697 break;
698
699 int nsom = coord_.dimension(0);
700 n_tot += 1;
701
702 coord_.append_line(pos_x, pos_y, pos_z);
703 espace_virtuel.ajoute_element(pe_source, nsom);
704 }
705 while (1);
706 }
707
708 schema_comm_.end_comm();
709
710 espace_distant.calcul_liste_pe_voisins();
711 espace_virtuel.calcul_liste_pe_voisins();
712 desc_.calcul_schema_comm(coord_.dimension(0));
713
714 return n_tot;
715}
716
718{
719 // Echange des tableaux de double
720 for (int i = 0; i < persistent_double_data_.size(); i++)
721 {
722 desc_.echange_espace_virtuel(persistent_double_data_(i).valeur());
723 }
724
725 // Echange des tableaux d'entier
726 for (int i = 0; i < persistent_int_data_.size(); i++)
727 {
728 desc_.echange_espace_virtuel(persistent_int_data_(i).valeur());
729 }
730}
731
733{
734 // Echange des tableaux de double
735 for (int i = 0; i < persistent_double_data_.size(); i++)
736 {
737 desc_.echange_espace_virtuel(persistent_double_data_(i).valeur(), op);
738 }
739
740 // Echange des tableaux d'entier
741 for (int i = 0; i < persistent_int_data_.size(); i++)
742 {
743 desc_.echange_espace_virtuel(persistent_int_data_(i).valeur(), op);
744 }
745}
746
748{
749 // Remplissage du tableau
750 for (int n = 0; n < n_loc_; n++)
751 {
752 Int3 ijk = get_ijk(n);
753 int k = ijk[2];
754
755 index_sorted_by_k_(n,0) = n;
756 index_sorted_by_k_(n,1) = k;
757 }
758
759 for (int n = n_loc_; n < n_tot_; n++)
760 {
761 Int3 ijk = get_ijk(n);
762 int k = ijk[2];
763
764 index_sorted_by_k_(n,0) = n;
765 index_sorted_by_k_(n,1) = k;
766 }
767
768 // Trie selon la colonne des k
769 index_sorted_by_k_.sort_tot(1);
770
771 // Trouve les indices des differents k
772 const int nk_tot = ref_domaine_->get_nb_elem_local(2) + 2*ghost_size_;
773 k_value_index_.resize(nk_tot+1, 1);
774
775 int previous_k = -ghost_size_;
776 k_value_index_(previous_k + ghost_size_) = 0;
777 for (int index = 0; index < n_tot_; index++)
778 {
779 int k = index_sorted_by_k_(index,1);
780
781 if (k > previous_k)
782 {
783 for (int k_intermediaire = previous_k+1; k_intermediaire <= k; k_intermediaire++)
784 {
785 k_value_index_(k_intermediaire + ghost_size_) = index;
786 }
787 previous_k = k;
788 }
789 }
790 for (int k_intermediaire = previous_k+1; k_intermediaire <= ref_domaine_->get_nb_elem_local(2) + ghost_size_; k_intermediaire++)
791 {
792 k_value_index_(k_intermediaire + ghost_size_) = n_tot_;
793 }
794}
795
796void Cut_cell_FT_Disc::update_index_sorted_by_indicatrice(const IJK_Field_double& old_indicatrice, const IJK_Field_double& next_indicatrice)
797{
798 // Remplissage du tableau
799 for (int n = 0; n < n_loc_; n++)
800 {
801 Int3 ijk = get_ijk(n);
802 int i = ijk[0];
803 int j = ijk[1];
804 int k = ijk[2];
805
806 union
807 {
808 double d;
809 long long int i;
810 } u;
811 u.i = (long long int)n;
812
813 index_sorted_by_indicatrice_(n,0) = u.d; // Storing the bits of the (int64) index of the cell into a double variable
814 index_sorted_by_indicatrice_(n,1) = std::min(next_indicatrice(i,j,k), 1 - next_indicatrice(i,j,k));
815 index_sorted_by_indicatrice_(n,2) = std::min(old_indicatrice(i,j,k), 1 - old_indicatrice(i,j,k));
816 }
817
818 for (int n = n_loc_; n < n_tot_; n++)
819 {
820 Int3 ijk = get_ijk(n);
821 int i = ijk[0];
822 int j = ijk[1];
823 int k = ijk[2];
824
825 union
826 {
827 double d;
828 long long int i;
829 } u;
830 u.i = (long long int)n;
831
832 index_sorted_by_indicatrice_(n,0) = u.d; // Storing the bits of the (int64) index of the cell into a double variable
833 index_sorted_by_indicatrice_(n,1) = std::min(next_indicatrice(i,j,k), 1 - next_indicatrice(i,j,k));
834 index_sorted_by_indicatrice_(n,2) = std::min(old_indicatrice(i,j,k), 1 - old_indicatrice(i,j,k));
835 }
836
837 // Trie selon la colonne des indicatrices
838 index_sorted_by_indicatrice_.sort_tot(1,2);
839}
840
841void Cut_cell_FT_Disc::update_index_sorted_by_statut_diphasique(const IJK_Field_double& old_indicatrice, const IJK_Field_double& next_indicatrice)
842{
843 for (int index = 0; index < n_tot_; index++)
844 {
845 int n = get_n_from_indicatrice_index(index);
846
847 Int3 ijk = get_ijk(n);
848 int i = ijk[0];
849 int j = ijk[1];
850 int k = ijk[2];
851
852 bool est_reguliere = ref_interfaces_->est_reguliere(old_indicatrice(i,j,k), next_indicatrice(i,j,k));
853 bool devient_pure = ref_interfaces_->devient_pure(old_indicatrice(i,j,k), next_indicatrice(i,j,k));
854 bool devient_diphasique = ref_interfaces_->devient_diphasique(old_indicatrice(i,j,k), next_indicatrice(i,j,k));
855 bool desequilibre_final = ref_interfaces_->a_desequilibre_final(old_indicatrice(i,j,k), next_indicatrice(i,j,k));
856 bool desequilibre_initial_uniquement = ref_interfaces_->a_desequilibre_initial_uniquement(old_indicatrice(i,j,k), next_indicatrice(i,j,k));
857 bool monophasique = ref_interfaces_->est_pure(.5*(old_indicatrice(i,j,k) + next_indicatrice(i,j,k)));
858 assert(est_reguliere + devient_pure + devient_diphasique + desequilibre_final + desequilibre_initial_uniquement + monophasique == 1);
859
861 index_sorted_by_statut_diphasique_(n,1) = est_reguliere*static_cast<int>(STATUT_DIPHASIQUE::REGULIER) + devient_pure*static_cast<int>(STATUT_DIPHASIQUE::MOURRANT) + devient_diphasique*static_cast<int>(STATUT_DIPHASIQUE::NAISSANT)
862 + desequilibre_final*static_cast<int>(STATUT_DIPHASIQUE::DESEQUILIBRE_FINAL) + desequilibre_initial_uniquement*static_cast<int>(STATUT_DIPHASIQUE::DESEQUILIBRE_INITIAL) + monophasique*static_cast<int>(STATUT_DIPHASIQUE::MONOPHASIQUE);
865 }
866
867 // Trie selon la colonne des statut diphasiques
868 // Le tri secondaire est selon l'indice du tableau trie selon l'indicatrice, c'est-a-dire
869 // dans le sens de l'indicatrice (de la plus petite phase) croissante.
871
872 // Trouve les indices des differents statut dipashiques
874
875 int previous_statut_diphasique = 0;
876 statut_diphasique_value_index_(previous_statut_diphasique) = 0;
877 for (int index = 0; index < n_tot_; index++)
878 {
879 int statut_diphasique = index_sorted_by_statut_diphasique_(index,1);
880
881 if (statut_diphasique > previous_statut_diphasique)
882 {
883 for (int k_intermediaire = previous_statut_diphasique+1; k_intermediaire <= statut_diphasique; k_intermediaire++)
884 {
885 statut_diphasique_value_index_(k_intermediaire) = index;
886 }
887 previous_statut_diphasique = statut_diphasique;
888 }
889 }
890 for (int k_intermediaire = previous_statut_diphasique+1; k_intermediaire <= static_cast<int>(STATUT_DIPHASIQUE::count); k_intermediaire++)
891 {
892 statut_diphasique_value_index_(k_intermediaire) = n_tot_;
893 }
894}
895
897{
898 const int ni = ref_domaine_->get_nb_elem_local(0);
899 const int nj = ref_domaine_->get_nb_elem_local(1);
900 const int nk = ref_domaine_->get_nb_elem_local(2);
901
902 for (int k = -ghost_size_; k < nk+ghost_size_; k++)
903 {
904 for (int j = -ghost_size_; j < nj+ghost_size_; j++)
905 {
906 for (int i = -ghost_size_; i < ni+ghost_size_; i++)
907 {
908 indice_diphasique_(i,j,k) = -1;
909 }
910 }
911 }
912
913 for (int n = 0; n < n_loc_; n++)
914 {
915 Int3 ijk_no_per = get_ijk(n);
916 int i = ijk_no_per[0];
917 int j = ijk_no_per[1];
918 int k = ijk_no_per[2];
919
920 {
921 int index_ijk_per = 0;
922 while (index_ijk_per >= 0)
923 {
924 Int3 ijk = ijk_per_of_index(i, j, k, index_ijk_per);
925 index_ijk_per = next_index_ijk_per(i, j, k, index_ijk_per, ghost_size_, ghost_size_);
926
927 indice_diphasique_(ijk[0],ijk[1],ijk[2]) = n;
928 }
929 }
930 }
931
932 for (int n = n_loc_; n < n_tot_; n++)
933 {
934 Int3 ijk_no_per = get_ijk(n);
935 int i = ijk_no_per[0];
936 int j = ijk_no_per[1];
937 int k = ijk_no_per[2];
938
939 {
940 int index_ijk_per = 0;
941 while (index_ijk_per >= 0)
942 {
943 Int3 ijk = ijk_per_of_index(i, j, k, index_ijk_per);
944 index_ijk_per = next_index_ijk_per(i, j, k, index_ijk_per, ghost_size_, ghost_size_);
945
946 indice_diphasique_(ijk[0],ijk[1],ijk[2]) = n;
947 }
948 }
949 }
950}
951
952void Cut_cell_FT_Disc::remove_dead_and_virtual_cells(const IJK_Field_double& next_indicatrice)
953{
954 // Annule l'information de l'indice diphasique pour les cellules pures au pas suivant.
955 // Motivation : Les cellules qui meurrent et reapparaissent au pas suivant doivent
956 // etre supprimees puis reajoutees.
957
958 independent_index_.resize(n_loc_, independent_index_.dimension(1));
959 permutation_.resize(n_loc_, permutation_.dimension(1));
960 processed_.resize(n_loc_, processed_.dimension(1));
962 n_tot_ = n_loc_;
963
964 int index_perm = 0;
965 int n_deletion = 0;
966
967 for (int n = 0; n < n_loc_; n++)
968 {
969 Int3 ijk = get_ijk(n);
970 int i = ijk[0];
971 int j = ijk[1];
972 int k = ijk[2];
973
974 if ((next_indicatrice(i,j,k) == 0) || (next_indicatrice(i,j,k) == 1))
975 {
976 n_deletion += 1;
977 permutation_(n_loc_ - n_deletion) = n;
978 }
979 else
980 {
981 permutation_(index_perm) = n;
982 index_perm += 1;
983 }
984 }
985
986 assert(index_perm + n_deletion == n_loc_);
988
989 // Application des differentes permutations
992
993 assert(verifier_si_ordonne(independent_index_, 0, n_loc_ - n_deletion));
994
995 assert(persistent_double_data_(0).valeur().dimension(0) <= n_loc_);
997
998 for (int i = 0; i < persistent_double_data_.size(); i++)
999 {
1000 apply_permutation(persistent_double_data_(i).valeur(), permutation_, processed_);
1001 }
1002
1003 for (int i = 0; i < persistent_int_data_.size(); i++)
1004 {
1005 apply_permutation(persistent_int_data_(i).valeur(), permutation_, processed_);
1006 }
1007
1008 // Redimensionnement pour suppression des elements anciennement diphasiques
1009 resize_data(n_loc_ - n_deletion);
1010 independent_index_.resize(n_loc_ - n_deletion, independent_index_.dimension(1));
1011 permutation_.resize(n_loc_ - n_deletion, permutation_.dimension(1));
1012 processed_.resize(n_loc_ - n_deletion, permutation_.dimension(1));
1013
1014 n_loc_ -= n_deletion;
1015
1017
1018 n_tot_ = n_loc_;
1019
1021}
1022
1023template<typename T>
1024void Cut_cell_FT_Disc::fill_buffer_with_variable(const TRUSTTabFT<T>& array, int component /* = 0 by default */) const
1025{
1026 assert(component < array.dimension(1));
1027 const int ni = ref_domaine_->get_nb_elem_local(0);
1028 const int nj = ref_domaine_->get_nb_elem_local(1);
1029 const int nk = ref_domaine_->get_nb_elem_local(2);
1030
1031 for (int k = 0; k < nk; k++)
1032 {
1033 for (int j = 0; j < nj; j++)
1034 {
1035 for (int i = 0; i < ni; i++)
1036 {
1037 write_buffer_(i,j,k) = 0.;
1038 }
1039 }
1040 }
1041
1043 for (int index_statut_diphasique = 0; index_statut_diphasique < 5; index_statut_diphasique++)
1044 {
1045 int statut_diphasique = liste_statuts_valides[index_statut_diphasique];
1046 int index_min = get_statut_diphasique_value_index(statut_diphasique);
1047 int index_max = get_statut_diphasique_value_index(statut_diphasique+1);
1048 for (int index = index_min; index < index_max; index++)
1049 {
1051
1052 Int3 ijk = get_ijk(n);
1053 int i = ijk[0];
1054 int j = ijk[1];
1055 int k = ijk[2];
1056
1057 if (!ref_domaine_->within_ghost(i, j, k, 0, 0))
1058 continue;
1059
1060 write_buffer_(i,j,k) = (double)(array(n,component));
1061 }
1062 }
1063}
1064
1065// Instantiation explicite pour IntTabFT et DoubleTabFT
1068
1069template<typename T>
1070void Cut_cell_FT_Disc::fill_variable_with_buffer(TRUSTTabFT<T>& array, int component /* = 0 by default */) const
1071{
1072 assert(component < array.dimension(1));
1073
1074 for (int n = 0; n < n_loc_; n++)
1075 {
1076 Int3 ijk = get_ijk(n);
1077 int i = ijk[0];
1078 int j = ijk[1];
1079 int k = ijk[2];
1080
1081 array(n,component) = (T)write_buffer_(i,j,k);
1082 }
1083}
1084
1085// Instantiation explicite pour IntTabFT et DoubleTabFT
1088
1090{
1091 // Verifie la coherence entre les tableaux coord_ et independent_index_
1092 for (int n = 0; n < n_loc_; n++)
1093 {
1094 Int3 ijk_1 = ref_domaine_->get_ijk_from_coord(coord_(n,0), coord_(n,1), coord_(n,2), Domaine_IJK::ELEM);
1095 int i_1 = ijk_1[0];
1096 int j_1 = ijk_1[1];
1097 int k_1 = ijk_1[2];
1098 Int3 ijk_2 = get_ijk(n);
1099 int i_2 = ijk_2[0];
1100 int j_2 = ijk_2[1];
1101 int k_2 = ijk_2[2];
1102
1103 if ((i_1 != i_2) || (j_1 != j_2) || (k_1 != k_2))
1104 return false;
1105 }
1106
1107 for (int n = n_loc_; n < n_tot_; n++)
1108 {
1109 Int3 ijk_1 = ref_domaine_->get_ijk_from_coord(coord_(n,0), coord_(n,1), coord_(n,2), Domaine_IJK::ELEM);
1110 int i_1 = ijk_1[0];
1111 int j_1 = ijk_1[1];
1112 int k_1 = ijk_1[2];
1113 Int3 ijk_2 = get_ijk(n);
1114 int i_2 = ijk_2[0];
1115 int j_2 = ijk_2[1];
1116 int k_2 = ijk_2[2];
1117
1118 if ((i_1 != i_2) || (j_1 != j_2) || (k_1 != k_2))
1119 return false;
1120 }
1121 return true;
1122}
1123
1125{
1126 if (independent_index_.dimension(0) != n_tot_)
1127 return false;
1128
1129 for (int i = 0; i < persistent_double_data_.size(); i++)
1130 {
1131 if (persistent_double_data_(i).valeur().dimension(0) != n_tot_)
1132 return false;
1133 }
1134
1135 for (int i = 0; i < transient_double_data_.size(); i++)
1136 {
1137 if (transient_double_data_(i).valeur().dimension(0) != n_tot_)
1138 return false;
1139 }
1140
1141 for (int i = 0; i < lazy_double_data_.size(); i++)
1142 {
1143 if (lazy_double_data_(i).valeur().dimension(0) != n_tot_)
1144 return false;
1145 }
1146
1147 for (int i = 0; i < persistent_int_data_.size(); i++)
1148 {
1149 if (persistent_int_data_(i).valeur().dimension(0) != n_tot_)
1150 return false;
1151 }
1152
1153 for (int i = 0; i < transient_int_data_.size(); i++)
1154 {
1155 if (transient_int_data_(i).valeur().dimension(0) != n_tot_)
1156 return false;
1157 }
1158
1159 for (int i = 0; i < lazy_int_data_.size(); i++)
1160 {
1161 if (lazy_int_data_(i).valeur().dimension(0) != n_tot_)
1162 return false;
1163 }
1164 return true;
1165}
1166
1168{
1169 Cerr << "# Impression des elements diphasiques pour le PE#" << ref_domaine_->me() << " [N IJK XYZ T]" << finl;
1170 for (int n = 0; n < n_loc_; n++)
1171 {
1172 Int3 ijk = get_ijk(n);
1173 int i = ijk[0];
1174 int j = ijk[1];
1175 int k = ijk[2];
1176
1177 // symbole qualifie le type d'element a l'impression :
1178 // (vide) element local
1179 // % element virtuel
1180 Nom symbole = (n < n_loc_ ? "" : "%");
1181
1182 Cerr << n << symbole << " " << i << " " << j << " " << k << " " << coord_(n,0) << " " << coord_(n,1) << " " << coord_(n,2) << finl;
1183 }
1184 for (int n = n_loc_; n < n_tot_; n++)
1185 {
1186 Int3 ijk = get_ijk(n);
1187 int i = ijk[0];
1188 int j = ijk[1];
1189 int k = ijk[2];
1190
1191 // symbole qualifie le type d'element a l'impression :
1192 // (vide) element local
1193 // % element virtuel
1194 Nom symbole = (n < n_loc_ ? "" : "%");
1195
1196 Cerr << n << symbole << " " << i << " " << j << " " << k << " " << coord_(n,0) << " " << coord_(n,1) << " " << coord_(n,2) << finl;
1197 }
1198 Cerr << "# Fin impression elements diphasiques" << finl;
1199}
1200
1202{
1203 Cerr << "# Impression des elements distants [N PE IJK XYZ T]" << finl;
1204 const int ni = ref_domaine_->get_nb_elem_local(0);
1205 const int nj = ref_domaine_->get_nb_elem_local(1);
1206 const int nk = ref_domaine_->get_nb_elem_local(2);
1207
1208 int left_neighbour_x = (ref_domaine_->get_neighbour_processor(0, 0) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(0, 0);
1209 int left_neighbour_y = (ref_domaine_->get_neighbour_processor(0, 1) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(0, 1);
1210 int left_neighbour_z = (ref_domaine_->get_neighbour_processor(0, 2) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(0, 2);
1211 int right_neighbour_x = (ref_domaine_->get_neighbour_processor(1, 0) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(1, 0);
1212 int right_neighbour_y = (ref_domaine_->get_neighbour_processor(1, 1) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(1, 1);
1213 int right_neighbour_z = (ref_domaine_->get_neighbour_processor(1, 2) < 0) ? ref_domaine_->me() : ref_domaine_->get_neighbour_processor(1, 2);
1214
1215 int shift_x_min = - (left_neighbour_x != ref_domaine_->me());
1216 int shift_y_min = - (left_neighbour_y != ref_domaine_->me());
1217 int shift_z_min = - (left_neighbour_z != ref_domaine_->me());
1218 int shift_x_max = + (right_neighbour_x != ref_domaine_->me())*(right_neighbour_x != left_neighbour_x);
1219 int shift_y_max = + (right_neighbour_y != ref_domaine_->me())*(right_neighbour_y != left_neighbour_y);
1220 int shift_z_max = + (right_neighbour_z != ref_domaine_->me())*(right_neighbour_z != left_neighbour_z);
1221 for (int shift_x = shift_x_min; shift_x <= shift_x_max; shift_x++)
1222 {
1223 for (int shift_y = shift_y_min; shift_y <= shift_y_max; shift_y++)
1224 {
1225 for (int shift_z = shift_z_min; shift_z <= shift_z_max; shift_z++)
1226 {
1227 int dest_pe_position_x = ref_domaine_->get_local_slice_index(0) + shift_x;
1228 int dest_pe_position_y = ref_domaine_->get_local_slice_index(1) + shift_y;
1229 int dest_pe_position_z = ref_domaine_->get_local_slice_index(2) + shift_z;
1230 int dest_pe = ref_domaine_->periodic_get_processor_by_ijk(dest_pe_position_x, dest_pe_position_y, dest_pe_position_z);
1231 if (dest_pe == ref_domaine_->me())
1232 {
1233 assert(shift_x == 0);
1234 assert(shift_y == 0);
1235 assert(shift_z == 0);
1236 continue;
1237 }
1238
1239 int left_bnd_x = (shift_x < 0);
1240 int left_bnd_y = (shift_y < 0);
1241 int left_bnd_z = (shift_z < 0);
1242 int right_bnd_x = ((shift_x > 0) || ((shift_x_max == 0) && (shift_x < 0) && (right_neighbour_x != ref_domaine_->me())));
1243 int right_bnd_y = ((shift_y > 0) || ((shift_y_max == 0) && (shift_y < 0) && (right_neighbour_y != ref_domaine_->me())));
1244 int right_bnd_z = ((shift_z > 0) || ((shift_z_max == 0) && (shift_z < 0) && (right_neighbour_z != ref_domaine_->me())));
1245
1246 for (int n = 0; n < n_loc_; n++)
1247 {
1248 int i_selon_x = ref_domaine_->get_i_along_dir_no_perio(0, coord_(n,0), Domaine_IJK::ELEM);
1249 int i_selon_y = ref_domaine_->get_i_along_dir_no_perio(1, coord_(n,1), Domaine_IJK::ELEM);
1250 int i_selon_z = ref_domaine_->get_i_along_dir_no_perio(2, coord_(n,2), Domaine_IJK::ELEM);
1251
1252 if ((left_bnd_x && (i_selon_x < ghost_size_))
1253 || (right_bnd_x && (i_selon_x >= ni - ghost_size_))
1254 || (left_bnd_y && (i_selon_y < ghost_size_))
1255 || (right_bnd_y && (i_selon_y >= nj - ghost_size_))
1256 || (left_bnd_z && (i_selon_z < ghost_size_))
1257 || (right_bnd_z && (i_selon_z >= nk - ghost_size_)))
1258 {
1259 Int3 ijk = get_ijk(n);
1260 int i = ijk[0];
1261 int j = ijk[1];
1262 int k = ijk[2];
1263
1264 Cerr << n << " " << dest_pe << " " << i << " " << j << " " << k << " " << coord_(n,0) << " " << coord_(n,1) << " " << coord_(n,2) << finl;
1265 }
1266 }
1267 }
1268 }
1269 }
1270 Cerr << "# Fin impression elements distants" << finl;
1271}
1272
1274{
1275 return ref_interfaces_;
1276}
1277
1279{
1280 return ref_domaine_;
1281}
1282
1284{
1285 return desc_;
1286}
1287
1288double Cut_cell_FT_Disc::indic_pure(const int i, const int j, const int k) const
1289{
1290 // When n is known to be negative, this function provides an access to the indicatrice that
1291 // neither require specifying a localisation or a time (old/next).
1292 assert(get_n(i, j, k) < 0);
1293
1294 double indic = ref_interfaces_->I(i, j, k);
1295 assert(indic == ref_interfaces_->In(i, j, k));
1296 return indic;
1297}
1298
1299// Recherche d'une valeur dans un tableau non trie.
1300template<typename T>
1301int Cut_cell_FT_Disc::find_value_unsorted(T value, const TRUSTTabFT<T>& array, int imin, int imax)
1302{
1303 assert(array.dimension(1) == 1);
1304 assert(imax < array.dimension(0));
1305
1306 for (int i = 0; i <= imax; i++)
1307 {
1308 if (array(i) == value)
1309 {
1310 return i;
1311 }
1312 }
1313 return -1;
1314}
1315
1316// Instantiation explicite pour IntTabFT et DoubleTabFT
1317template int Cut_cell_FT_Disc::find_value_unsorted<int>(int, const TRUSTTabFT<int>&, int, int);
1318template int Cut_cell_FT_Disc::find_value_unsorted<double>(double, const TRUSTTabFT<double>&, int, int);
1319
1321{
1322 assert(array.dimension(1) == 1);
1323
1324 const int initial_sign = array(0) > 0 ? 1 : -1;
1325 for (int i = 0; i < array.dimension(0); i++)
1326 {
1327 const int sign = array(i) > 0 ? 1 : -1;
1328 if ((array(i) == 0) || (sign != initial_sign))
1329 return false;
1330 }
1331 return true;
1332}
1333
1334bool Cut_cell_FT_Disc::verifier_tableau_jamais_nul(const DoubleTabFT_cut_cell& array)
1335{
1336 assert(array.dimension(1) == 3);
1337
1338 for (int i = 0; i < array.dimension(0); i++)
1339 {
1340 if ((array(i,0) == 0) || (array(i,0) == 1) || (array(i,0) == 2))
1341 return false;
1342 }
1343 return true;
1344}
1345
1346// Verifie que la permutation est valide, c'est-a-dire inclue tous les
1347// indices et une seule fois.
1348bool Cut_cell_FT_Disc::verifier_valide_permutation(const IntTabFT_cut_cell& array)
1349{
1350 assert(array.dimension(1) == 1);
1351 for (int i = 0; i < array.dimension(0); i++)
1352 {
1353 const int m = find_value_unsorted(i, array, 0, array.dimension(0) - 1);
1354 if (m < 0)
1355 return false;
1356 }
1357 return true;
1358}
1359
1360// Verifie qu'il n'y a pas de doublons.
1361bool Cut_cell_FT_Disc::verifier_pas_de_doublons(const IntTabFT_cut_cell& array)
1362{
1363 assert(array.dimension(1) == 1);
1364 for (int i = 0; i < array.dimension(0); i++)
1365 {
1366 const int m = find_value_unsorted(array(i), array, 0, array.dimension(0) - 1);
1367 if (m != i)
1368 return false;
1369 }
1370 return true;
1371}
1372
1373// Permutate le tableau array a partir des indices de permutation 'permutation'.
1374// Le tableau 'processed' permet de suivre les changements par son signe.
1375// La seule contrainte sur le tableau 'processed' est qu'il est toujours de meme signe et non nul.
1376// Le signe du tableau 'processed' est modifie par la fonction mais le tableau de permutation n'est pas modifie.
1377template<typename T>
1378void Cut_cell_FT_Disc::apply_permutation(TRUSTTabFT<T>& array, const IntTabFT_cut_cell& permutation, IntTabFT_cut_cell& processed)
1379{
1380 if (array.dimension(0) == 0)
1381 {
1382 assert(permutation.dimension(0) == 0);
1383 assert(processed.dimension(0) == 0);
1384 }
1385 else
1386 {
1387 assert(array.dimension(0) == permutation.dimension(0));
1388 assert(array.dimension(0) == processed.dimension(0));
1389
1390 const int max_nb_columns = 6;
1391 assert(array.dimension(1) <= max_nb_columns);
1392
1393 assert(verifier_toujours_meme_signe_et_non_nul(processed));
1394 int sign = processed(0) > 0 ? 1 : -1;
1395
1396 for (int i = 0; i < array.dimension(0); i++)
1397 {
1398 if (sign*processed(i) < 0)
1399 {
1400 continue;
1401 }
1402
1403 // L'element n'a pas deja ete traite, on stocke la valeur et on la remplace,
1404 // puis, on suit le tableau des permutations et on remplace chaque valeur
1405 // jusqu'a retrouver l'element initialement trouve.
1406 // Tous les elements traites sont marques dans 'processed', ce qui permet
1407 // de ne traiter par la suite que les elements d'un cycle different.
1408
1409 T first_cycle_value[max_nb_columns];
1410 for (int j = 0; j < array.dimension(1); j++)
1411 {
1412 first_cycle_value[j] = array(i,j);
1413 }
1414 int current_index = i;
1415 int next_index = permutation[i];
1416
1417 while (next_index != i)
1418 {
1419 for (int j = 0; j < array.dimension(1); j++)
1420 {
1421 array(current_index,j) = array(next_index,j);
1422 }
1423
1424 processed(current_index) = -processed(current_index);
1425
1426 current_index = next_index;
1427 next_index = permutation[next_index];
1428 }
1429
1430 for (int j = 0; j < array.dimension(1); j++)
1431 {
1432 array(current_index,j) = first_cycle_value[j];
1433 }
1434 processed(current_index) = -processed(current_index);
1435 }
1436 }
1437}
1438
1439bool Cut_cell_FT_Disc::verifier_si_ordonne(const IntTabFT_cut_cell& array, int imin, int imax)
1440{
1441 int old_independent_index = -1;
1442 for (int n = imin; n < imax; n++)
1443 {
1444 int independent_index = array(n);
1445 if (old_independent_index >= independent_index)
1446 return false;
1447 old_independent_index = independent_index;
1448 }
1449 return true;
1450}
1451
const Domaine_IJK & get_domaine() const
const IJK_Interfaces & get_interfaces() const
void update_index_sorted_by_indicatrice(const IJK_Field_double &old_indicatrice, const IJK_Field_double &next_indicatrice)
int get_n_from_indicatrice_index(int index) const
static bool verifier_toujours_meme_signe_et_non_nul(const IntTabFT_cut_cell &array)
Desc_Structure_FT desc_
void compute_virtual_independent_index()
Int3 ijk_per_of_index(int i, int j, int k, int index) const
int next_index_ijk_per(int i, int j, int k, int index, int negative_ghost_size, int positive_ghost_size) const
int add_and_remove_local_elements(const IJK_Field_double &old_indicatrice, const IJK_Field_double &next_indicatrice)
Schema_Comm schema_comm_
bool verifier_coherence_coord_independent_index()
const Desc_Structure_FT & get_desc_structure() const
IntTabFT_cut_cell_scalar permutation_
static bool verifier_pas_de_doublons(const IntTabFT_cut_cell &array)
Int3 get_ijk(int n) const
static int find_value_unsorted(T value, const TRUSTTabFT< T > &array, int imin, int imax)
IntTabFT_cut_cell_vector2 index_sorted_by_k_
void resize_data(int size)
void update_index_sorted_by_statut_diphasique(const IJK_Field_double &old_indicatrice, const IJK_Field_double &next_indicatrice)
static bool verifier_si_ordonne(const IntTabFT_cut_cell &array, int imin, int imax)
IJK_Field_int indice_diphasique_
IntTabFT_cut_cell_scalar independent_index_
int initialise_independent_index(const IJK_Field_double &old_indicatrice, const IJK_Field_double &next_indicatrice)
DoubleTabFT_cut_cell_vector3 index_sorted_by_indicatrice_
void fill_buffer_with_variable(const TRUSTTabFT< T > &array, int component=0) const
void fill_variable_with_buffer(TRUSTTabFT< T > &array, int component=0) const
void update(const IJK_Field_double &old_indicatrice, const IJK_Field_double &next_indicatrice)
IntTabFT_cut_cell_vector3 index_sorted_by_statut_diphasique_
double indic_pure(const int i, const int j, const int k) const
Domaine_IJK::Localisation localisation_
int get_n_from_statut_diphasique_index(int index) const
int get_statut_diphasique_value_index(int statut_diphasique) const
static bool verifier_tableau_jamais_nul(const DoubleTabFT_cut_cell &array)
int get_n(int i, int j, int k) const
static void apply_permutation(TRUSTTabFT< T > &array, const IntTabFT_cut_cell &permutation_indices, IntTabFT_cut_cell &processed)
IJK_Field_double write_buffer_
DoubleTabFT_cut_cell_vector3 coord_
static bool verifier_valide_permutation(const IntTabFT_cut_cell &array)
IntTabFT_cut_cell_scalar processed_
void remove_dead_and_virtual_cells(const IJK_Field_double &next_indicatrice)
IntTabFT statut_diphasique_value_index_
void initialise(IJK_Interfaces &interfaces, Domaine_IJK &splitting, Domaine_IJK::Localisation loc)
: class Desc_Structure_FT
: class Descripteur_FT Descripteur_FT stocke pour chaque PE une liste de numeros d'elements.
int contient_element(int pe, int element) const
Renvoie "pas zero" si l'element est deja dans le descripteur pour le pe donne, 0 sinon.
int ajoute_element(int PE_voisin, int element)
Ajoute l'element au tableau du PE_voisin.
void calcul_liste_pe_voisins()
Calcule la liste des PEs dont la liste d'elements est non vide, tries dans l'ordre croissant de numer...
This class encapsulates all the information related to the eulerian mesh for TrioIJK.
Definition Domaine_IJK.h:47
Localisation
Localisation sub class.
Definition Domaine_IJK.h:53
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual int eof()
Definition Entree.cpp:256
Domaine_IJK::Localisation get_localisation() const
: class IJK_Interfaces
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
Classe de base des flux de sortie.
Definition Sortie.h:52
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133