Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
CartesianMeshAMRPatchMng.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* CartesianMeshAMRPatchMng.cc (C) 2000-2024 */
9/* */
10/* Gestionnaire de l'AMR par patch d'un maillage cartésien. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "CartesianMeshAMRPatchMng.h"
15
16#include "arcane/core/IGhostLayerMng.h"
17#include "arcane/core/IMesh.h"
18#include "arcane/core/ItemPrinter.h"
19#include "arcane/core/IParallelMng.h"
20#include "arcane/core/VariableTypes.h"
21#include "arcane/core/IMeshModifier.h"
22
23#include "arcane/cartesianmesh/CellDirectionMng.h"
24#include "arcane/cartesianmesh/CartesianMeshNumberingMng.h"
25#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
26
27#include "arcane/utils/Array2View.h"
28#include "arcane/utils/Array3View.h"
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39CartesianMeshAMRPatchMng::
40CartesianMeshAMRPatchMng(ICartesianMesh* cmesh)
41: TraceAccessor(cmesh->mesh()->traceMng())
42, m_mesh(cmesh->mesh())
43, m_cmesh(cmesh)
44, m_num_mng(Arccore::makeRef(new CartesianMeshNumberingMng(cmesh->mesh())))
45{
46}
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
51void CartesianMeshAMRPatchMng::
52flagCellToRefine(Int32ConstArrayView cells_lids)
53{
54 ItemInfoListView cells(m_mesh->cellFamily());
55 for (int lid : cells_lids) {
56 Item item = cells[lid];
57 item.mutableItemBase().addFlags(ItemFlags::II_Refine);
58 }
59 _syncFlagCell();
60}
61
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
65void CartesianMeshAMRPatchMng::
66_syncFlagCell()
67{
68 if (!m_mesh->parallelMng()->isParallel())
69 return;
70
71 VariableCellInteger flag_cells_consistent(VariableBuildInfo(m_mesh, "FlagCellsConsistent"));
72 ENUMERATE_ (Cell, icell, m_mesh->ownCells()) {
73 Cell cell = *icell;
74 flag_cells_consistent[cell] = cell.mutableItemBase().flags();
75 // debug() << "Send " << cell
76 // << " -- flag : " << cell.mutableItemBase().flags()
77 // << " -- II_Refine : " << (cell.itemBase().flags() & ItemFlags::II_Refine)
78 // << " -- II_Inactive : " << (cell.itemBase().flags() & ItemFlags::II_Inactive)
79 // ;
80 }
81
82 flag_cells_consistent.synchronize();
83
84 ENUMERATE_ (Cell, icell, m_mesh->allCells().ghost()) {
85 Cell cell = *icell;
86
87 // On ajoute uniquement les flags qui nous interesse (pour éviter d'ajouter le flag "II_Own" par exemple).
88 // On utilise set au lieu de add puisqu'une maille ne peut être à la fois II_Refine et II_Inactive.
89 if (flag_cells_consistent[cell] & ItemFlags::II_Refine) {
90 cell.mutableItemBase().setFlags(ItemFlags::II_Refine);
91 }
92 if (flag_cells_consistent[cell] & ItemFlags::II_Inactive) {
93 cell.mutableItemBase().setFlags(ItemFlags::II_Inactive);
94 }
95
96 // debug() << "After Compute " << cell
97 // << " -- flag : " << cell.mutableItemBase().flags()
98 // << " -- II_Refine : " << (cell.itemBase().flags() & ItemFlags::II_Refine)
99 // << " -- II_Inactive : " << (cell.itemBase().flags() & ItemFlags::II_Inactive)
100 // ;
101 }
102}
103
104/*---------------------------------------------------------------------------*/
105/*---------------------------------------------------------------------------*/
106
107/*
108 * Pour les commentaires de cette méthode, on considère le repère suivant :
109 * (top)
110 * y (front)
111 * ^ z
112* | /
113 * | /
114 * (left) ------->x (right)
115 * (rear)(bottom)
116 */
117void CartesianMeshAMRPatchMng::
118refine()
119{
120 IParallelMng* pm = m_mesh->parallelMng();
121 Int32 nb_rank = pm->commSize();
122 Int32 my_rank = pm->commRank();
123 Int32 max_level = 0;
124
125 UniqueArray<Cell> cell_to_refine_internals;
126 ENUMERATE_ (Cell, icell, m_mesh->allActiveCells()) {
127 Cell cell = *icell;
128 if (cell.itemBase().flags() & ItemFlags::II_Refine) {
129 cell_to_refine_internals.add(cell);
130 if (cell.level() > max_level)
131 max_level = cell.level();
132 }
133 }
134 m_num_mng->prepareLevel(max_level + 1);
135
136 UniqueArray<Int64> cells_infos;
137 UniqueArray<Int64> faces_infos;
138 UniqueArray<Int64> nodes_infos;
139
140 Integer total_nb_cells = 0;
141 Integer total_nb_nodes = 0;
142 Integer total_nb_faces = 0;
143
144 std::unordered_map<Int64, Int32> node_uid_to_owner;
145 std::unordered_map<Int64, Int32> face_uid_to_owner;
146
147 UniqueArray<Int64> node_uid_change_owner_only;
148 UniqueArray<Int64> face_uid_change_owner_only;
149
150 // Deux tableaux permettant de récupérer les uniqueIds des noeuds et des faces
151 // de chaque maille enfant à chaque appel à getNodeUids()/getFaceUids().
152 UniqueArray<Int64> child_nodes_uids(m_num_mng->nbNodeByCell());
153 UniqueArray<Int64> child_faces_uids(m_num_mng->nbFaceByCell());
154
155 // On doit enregistrer les mailles parentes de chaque maille enfant pour mettre à jour les connectivités
156 // lors de la création des mailles.
157 UniqueArray<Cell> parent_cells;
158
159 // Maps remplaçant les mailles fantômes.
160 std::unordered_map<Int64, Integer> around_parent_cells_uid_to_owner;
161 std::unordered_map<Int64, Int32> around_parent_cells_uid_to_flags;
162
163 // Partie échange d'informations sur les mailles autour du patch
164 // (pour remplacer les mailles fantômes).
165 {
166 // On a uniquement besoin de ses deux flags pour les mailles autour.
167 // (II_Refine pour savoir si les mailles autour sont dans le même patch)
168 // (II_Inactive pour savoir si les mailles autour sont déjà raffinées)
169 Int32 usefull_flags = ItemFlags::II_Refine + ItemFlags::II_Inactive;
170
171 // On remplit le tableau avec nos infos, pour les autres processus.
172 ENUMERATE_ (Cell, icell, m_mesh->ownCells()) {
173 Cell cell = *icell;
174 around_parent_cells_uid_to_owner[cell.uniqueId()] = my_rank;
175 around_parent_cells_uid_to_flags[cell.uniqueId()] = ((cell.itemBase().flags() & usefull_flags) + ItemFlags::II_UserMark1);
176 }
177
178 ENUMERATE_ (Cell, icell, m_mesh->allCells().ghost()) {
179 Cell cell = *icell;
180 around_parent_cells_uid_to_owner[cell.uniqueId()] = cell.owner();
181 around_parent_cells_uid_to_flags[cell.uniqueId()] = ((cell.itemBase().flags() & usefull_flags) + ItemFlags::II_UserMark1);
182 }
183
184 // Tableau qui contiendra les uids des mailles dont on a besoin des infos.
185 UniqueArray<Int64> uid_of_cells_needed;
186 {
187 UniqueArray<Int64> cell_uids_around((m_mesh->dimension() == 2) ? 9 : 27);
188 for (Cell parent_cell : cell_to_refine_internals) {
189 m_num_mng->cellUniqueIdsAroundCell(cell_uids_around, parent_cell);
190 for (Int64 cell_uid : cell_uids_around) {
191 // Si -1 alors il n'y a pas de mailles à cette position.
192 if (cell_uid == -1)
193 continue;
194
195 // TODO C++20 : Mettre map.contains().
196 // SI on a la maille, on n'a pas besoin de demander d'infos.
197 if (around_parent_cells_uid_to_owner.find(cell_uid) != around_parent_cells_uid_to_owner.end())
198 continue;
199
200 uid_of_cells_needed.add(cell_uid);
201 }
202 }
203 }
204
205 UniqueArray<Int64> uid_of_cells_needed_all_procs;
206 pm->allGatherVariable(uid_of_cells_needed, uid_of_cells_needed_all_procs);
207
208 UniqueArray<Int32> flags_of_cells_needed_all_procs(uid_of_cells_needed_all_procs.size());
209 UniqueArray<Int32> owner_of_cells_needed_all_procs(uid_of_cells_needed_all_procs.size());
210
211 {
212 UniqueArray<Int32> local_ids(uid_of_cells_needed_all_procs.size());
213 m_mesh->cellFamily()->itemsUniqueIdToLocalId(local_ids, uid_of_cells_needed_all_procs, false);
214 Integer compt = 0;
215 ENUMERATE_ (Cell, icell, m_mesh->cellFamily()->view(local_ids)) {
216 // Le isOwn est important vu qu'il peut y avoir les mailles fantômes.
217 if (!icell->null() && icell->isOwn()) {
218 owner_of_cells_needed_all_procs[compt] = my_rank;
219 flags_of_cells_needed_all_procs[compt] = (icell->itemBase().flags() & usefull_flags);
220 }
221 else {
222 owner_of_cells_needed_all_procs[compt] = -1;
223 flags_of_cells_needed_all_procs[compt] = 0;
224 }
225 compt++;
226 }
227 }
228
229 pm->reduce(Parallel::eReduceType::ReduceMax, owner_of_cells_needed_all_procs);
230 pm->reduce(Parallel::eReduceType::ReduceMax, flags_of_cells_needed_all_procs);
231
232 // A partir de ce moment, si les parent_cells sont au niveau 0, le tableau
233 // "owner_of_cells_needed_all_procs" ne devrait plus contenir de "-1".
234 // Si les parent_cells sont au niveau 1 ou plus, il peut y avoir des "-1"
235 // car les mailles autour ne sont pas forcément toutes raffinées.
236 // (exemple : on est en train de faire le niveau 2, donc on regarde les mailles
237 // parent de niveau 1 tout autour. Il se peut que la maille d'à coté n'ai jamais
238 // été raffinée, donc n'a pas de mailles de niveau 1. Comme la maille n'existe pas,
239 // aucun processus ne peut mettre un propriétaire, donc le tableau des propriétaires
240 // contiendra "-1".
241
242 // On récupère les infos des mailles autour qui nous intéressent.
243 {
244 Integer size_uid_of_cells_needed = uid_of_cells_needed.size();
245 Integer my_pos_in_all_procs_arrays = 0;
246 UniqueArray<Integer> size_uid_of_cells_needed_per_proc(nb_rank);
247 ArrayView<Integer> av(1, &size_uid_of_cells_needed);
248 pm->allGather(av, size_uid_of_cells_needed_per_proc);
249
250 for (Integer i = 0; i < my_rank; ++i) {
251 my_pos_in_all_procs_arrays += size_uid_of_cells_needed_per_proc[i];
252 }
253
254 ArrayView<Int32> owner_of_cells_needed = owner_of_cells_needed_all_procs.subView(my_pos_in_all_procs_arrays, size_uid_of_cells_needed);
255 ArrayView<Int32> flags_of_cells_needed = flags_of_cells_needed_all_procs.subView(my_pos_in_all_procs_arrays, size_uid_of_cells_needed);
256 for (Integer i = 0; i < size_uid_of_cells_needed; ++i) {
257 around_parent_cells_uid_to_owner[uid_of_cells_needed[i]] = owner_of_cells_needed[i];
258 around_parent_cells_uid_to_flags[uid_of_cells_needed[i]] = flags_of_cells_needed[i];
259 }
260 }
261 }
262
263 if (m_mesh->dimension() == 2) {
264
265 // Masques pour les cas "voisins enfants" et "voisins parents du même patch".
266 // Ces masques permettent de savoir si l'on doit créer un noeud ou pas selon
267 // les mailles autour.
268 // Par exemple, si l'on est en train d'étudier une maille enfant et qu'il y a
269 // une maille enfant à gauche, on ne doit pas créer les noeuds 0 et 3 (mask_node_if_cell_left[]) (car
270 // ils ont déjà été créés par la maille à gauche).
271 // Idem pour les mailles parentes voisines : si l'on est sur une maille enfant située
272 // sur la partie gauche de la maille parente (mailles enfants 0 et 2 dans le cas d'un
273 // pattern de raffinement = 2), qu'il y a une maille parente à gauche et que cette maille parente
274 // est en train ((d'être raffiné et à notre sous-domaine) ou (qu'elle est inactive)), on applique
275 // la règle mask_node_if_cell_left[] car les noeuds ont été créé par celle-ci et on veut éviter
276 // les noeuds en doubles.
277 // Ces masques permettent aussi de déterminer le propriétaire des noeuds dans
278 // le cas de multiples sous-domaines.
279 // Par exemple, si l'on est sur une maille enfant située
280 // sur la partie gauche de la maille parente (mailles enfants 0 et 2 dans le cas d'un
281 // pattern de raffinement = 2), qu'il y a une maille parente à gauche et que cette maille
282 // parente (appartient à un autre sous-domaine) et (est en train d'être raffiné),
283 // on crée ce noeud mais on lui donne comme propriétaire le processus à qui appartient
284 // la maille parente à gauche.
285 const bool mask_node_if_cell_left[] = { false, true, true, false };
286 const bool mask_node_if_cell_bottom[] = { false, false, true, true };
287
288 const bool mask_node_if_cell_right[] = { true, false, false, true };
289 const bool mask_node_if_cell_top[] = { true, true, false, false };
290
291 const bool mask_face_if_cell_left[] = { true, true, true, false };
292 const bool mask_face_if_cell_bottom[] = { false, true, true, true };
293
294 const bool mask_face_if_cell_right[] = { true, false, true, true };
295 const bool mask_face_if_cell_top[] = { true, true, false, true };
296
297 // Pour la taille :
298 // - on a "cell_to_refine_internals.size() * 4" mailles enfants,
299 // - pour chaque maille, on a 2 infos (type de maille et uniqueId de la maille)
300 // - pour chaque maille, on a "m_num_mng->getNbNode()" uniqueIds (les uniqueId de chaque noeud de la maille).
301 cells_infos.reserve((cell_to_refine_internals.size() * 4) * (2 + m_num_mng->nbNodeByCell()));
302
303 // Pour la taille, au maximum :
304 // - on a "cell_to_refine_internals.size() * 12" faces
305 // - pour chaque face, on a 2 infos (type de face et uniqueId de la face)
306 // - pour chaque face, on a 2 uniqueIds de noeuds.
307 faces_infos.reserve((cell_to_refine_internals.size() * 12) * (2 + 2));
308
309 // Pour la taille, au maximum :
310 // - on a (cell_to_refine_internals.size() * 9) uniqueIds de noeuds.
311 nodes_infos.reserve(cell_to_refine_internals.size() * 9);
312
313 for (Cell parent_cell : cell_to_refine_internals) {
314 const Int64 parent_cell_uid = parent_cell.uniqueId();
315 const Int32 parent_cell_level = parent_cell.level();
316 const bool parent_cell_is_own = (parent_cell.owner() == my_rank);
317
318 const Int64 parent_coord_x = m_num_mng->cellUniqueIdToCoordX(parent_cell_uid, parent_cell_level);
319 const Int64 parent_coord_y = m_num_mng->cellUniqueIdToCoordY(parent_cell_uid, parent_cell_level);
320
321 const Int64 child_coord_x = m_num_mng->offsetLevelToLevel(parent_coord_x, parent_cell_level, parent_cell_level + 1);
322 const Int64 child_coord_y = m_num_mng->offsetLevelToLevel(parent_coord_y, parent_cell_level, parent_cell_level + 1);
323
324 const Integer pattern = m_num_mng->pattern();
325
326 UniqueArray<Int64> uid_cells_around_parent_cell_1d(9);
327 UniqueArray<Int32> owner_cells_around_parent_cell_1d(9);
328 UniqueArray<Int32> flags_cells_around_parent_cell_1d(9);
329
330 m_num_mng->cellUniqueIdsAroundCell(uid_cells_around_parent_cell_1d, parent_cell);
331
332 for (Integer i = 0; i < 9; ++i) {
333 Int64 uid_cell = uid_cells_around_parent_cell_1d[i];
334 // Si uid_cell != -1 alors il y a peut-être une maille (mais on ne sait pas si elle est bien présente).
335 // Si around_parent_cells_uid_to_owner[uid_cell] != -1 alors il y a bien une maille.
336 if (uid_cell != -1 && around_parent_cells_uid_to_owner[uid_cell] != -1) {
337 owner_cells_around_parent_cell_1d[i] = around_parent_cells_uid_to_owner[uid_cell];
338 flags_cells_around_parent_cell_1d[i] = around_parent_cells_uid_to_flags[uid_cell];
339 }
340 else {
341 uid_cells_around_parent_cell_1d[i] = -1;
342 owner_cells_around_parent_cell_1d[i] = -1;
343 flags_cells_around_parent_cell_1d[i] = 0;
344 }
345 }
346
347 // Pour simplifier, on utilise des vues 2D. (array[Y][X]).
348 ConstArray2View uid_cells_around_parent_cell(uid_cells_around_parent_cell_1d.data(), 3, 3);
349 ConstArray2View owner_cells_around_parent_cell(owner_cells_around_parent_cell_1d.data(), 3, 3);
350 ConstArray2View flags_cells_around_parent_cell(flags_cells_around_parent_cell_1d.data(), 3, 3);
351
352 // Voici les priorités pour la propriété des noeuds et des faces :
353 // ┌─────────┐
354 // │6 7 8│
355 // └───────┐ │
356 // ┌─┐ ┌─┐ │ │
357 // │3│ │4│ │5│
358 // │ │ └─┘ └─┘
359 // │ └───────┐
360 // │0 1 2│
361 // └─────────┘
362 // Chaque chiffre désigne une maille parente et une priorité (0 étant la priorité la plus forte).
363 // 4 = parent_cell ("nous")
364
365 // Exemple 1 :
366 // On cherche à raffiner des mailles de niveau 0 (donc créer des mailles de niveau 1).
367 // En bas, il n'y a pas de mailles.
368 // À gauche (donc priorité 3), il y a une maille qui est déjà raffinée (flag "II_Inactive").
369 // On est priorité 4 donc il est prioritaire. Donc les noeuds et des faces que l'on a en commun
370 // lui appartiennent.
371
372 // Exemple 2 :
373 // On cherche à raffiner des mailles de niveau 0 (donc créer des mailles de niveau 1).
374 // En haut, il y a des mailles déjà raffinées (flag "II_Inactive").
375 // On est prioritaire sur elles, on récupère donc la propriété des noeuds et des faces que l'on a
376 // en commun. Ce changement de propriété doit leur être signalé.
377
378 // On simplifie avec un tableau de booléens.
379 // Si true, alors on doit appliquer la priorité de propriété.
380 // Si false, alors on considère qu'il n'y a pas de maille à la position définie.
381 bool is_cell_around_parent_cell_present_and_useful[3][3] = { { false } };
382
383 // Pour les mailles prioritaires sur nous, on doit regarder les deux flags.
384 // Si une maille a le flag "II_Refine", on n'existe pas pour elle donc elle prend la propriété
385 // des faces et des noeuds qu'on a en commun.
386 // Si une maille a le flag "II_Inactive", elle a déjà les bons propriétaires.
387 // Quoi qu'il en soit, si true alors les faces et noeuds qu'on a en commun leurs appartiennent.
388 is_cell_around_parent_cell_present_and_useful[0][0] = ((uid_cells_around_parent_cell(0, 0) != -1) && (flags_cells_around_parent_cell(0, 0) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
389 is_cell_around_parent_cell_present_and_useful[0][1] = ((uid_cells_around_parent_cell(0, 1) != -1) && (flags_cells_around_parent_cell(0, 1) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
390 is_cell_around_parent_cell_present_and_useful[0][2] = ((uid_cells_around_parent_cell(0, 2) != -1) && (flags_cells_around_parent_cell(0, 2) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
391
392 is_cell_around_parent_cell_present_and_useful[1][0] = ((uid_cells_around_parent_cell(1, 0) != -1) && (flags_cells_around_parent_cell(1, 0) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
393 // is_cell_around_parent_cell_present_and_useful[1][1] = parent_cell;
394
395 // Pour les mailles non prioritaires, on doit regarder qu'un seul flag.
396 // Si une maille a le flag "II_Inactive", alors elle doit être avertie qu'on récupère la propriété
397 // des noeuds et des faces qu'on a en commun.
398 // On ne regarde pas le flag "II_Refine" car, si ces mailles sont aussi en train d'être raffinée,
399 // elles savent qu'on existe et qu'on obtient la propriété des noeuds et des faces qu'on a en commun.
400 // En résumé, si true alors les faces et noeuds qu'on a en commun nous appartiennent.
401 is_cell_around_parent_cell_present_and_useful[1][2] = ((uid_cells_around_parent_cell(1, 2) != -1) && (flags_cells_around_parent_cell(1, 2) & ItemFlags::II_Inactive));
402
403 is_cell_around_parent_cell_present_and_useful[2][0] = ((uid_cells_around_parent_cell(2, 0) != -1) && (flags_cells_around_parent_cell(2, 0) & ItemFlags::II_Inactive));
404 is_cell_around_parent_cell_present_and_useful[2][1] = ((uid_cells_around_parent_cell(2, 1) != -1) && (flags_cells_around_parent_cell(2, 1) & ItemFlags::II_Inactive));
405 is_cell_around_parent_cell_present_and_useful[2][2] = ((uid_cells_around_parent_cell(2, 2) != -1) && (flags_cells_around_parent_cell(2, 2) & ItemFlags::II_Inactive));
406
407 // En plus de regarder si chaque maille parent autour de notre maille parent existe et possède (II_Inactive) ou possédera (II_Refine) des enfants...
408 // ... on regarde si chaque maille parent est présente sur notre sous-domaine, que ce soit une maille fantôme ou non.
409 auto is_cell_around_parent_cell_in_subdomain = [&](Integer y, Integer x) {
410 return is_cell_around_parent_cell_present_and_useful[y][x] && (flags_cells_around_parent_cell(y, x) & ItemFlags::II_UserMark1);
411 };
412
413 // ... on regarde si chaque maille parent est possédé par le même propriétaire que notre maille parent.
414 auto is_cell_around_parent_cell_same_owner = [&](Integer y, Integer x) {
415 return is_cell_around_parent_cell_present_and_useful[y][x] && (owner_cells_around_parent_cell(y, x) == owner_cells_around_parent_cell(1, 1));
416 };
417
418 // ... on regarde si chaque maille parent a un propriétaire différent par rapport à notre maille parent.
419 auto is_cell_around_parent_cell_different_owner = [&](Integer y, Integer x) {
420 return is_cell_around_parent_cell_present_and_useful[y][x] && (owner_cells_around_parent_cell(y, x) != owner_cells_around_parent_cell(1, 1));
421 };
422
423 // On itère sur toutes les mailles enfants.
424 for (Int64 j = child_coord_y; j < child_coord_y + pattern; ++j) {
425 for (Int64 i = child_coord_x; i < child_coord_x + pattern; ++i) {
426 parent_cells.add(parent_cell);
427 total_nb_cells++;
428
429 const Int64 child_cell_uid = m_num_mng->cellUniqueId(parent_cell_level + 1, Int64x2(i, j));
430 debug() << "Child -- x : " << i << " -- y : " << j << " -- level : " << parent_cell_level + 1 << " -- uid : " << child_cell_uid;
431
432 m_num_mng->cellNodeUniqueIds(child_nodes_uids, parent_cell_level + 1, Int64x2(i, j));
433 m_num_mng->cellFaceUniqueIds(child_faces_uids, parent_cell_level + 1, Int64x2(i, j));
434
435 const Integer type_cell = IT_Quad4;
436 const Integer type_face = IT_Line2;
437
438 // Partie Cell.
439 cells_infos.add(type_cell);
440 cells_infos.add(child_cell_uid);
441 for (Integer nc = 0; nc < m_num_mng->nbNodeByCell(); nc++) {
442 cells_infos.add(child_nodes_uids[nc]);
443 }
444
445 // Partie Face.
446 for (Integer l = 0; l < m_num_mng->nbFaceByCell(); ++l) {
447 Integer child_face_owner = -1;
448 bool is_new_face = false;
449
450 // Deux parties :
451 // D'abord, on regarde si l'on doit créer la face l. Pour cela, on doit regarder si elle est présente sur la
452 // maille à côté.
453 // Pour gauche/bas, c'est le même principe. Si la maille enfant est tout à gauche/bas de la maille parente, on regarde
454 // s'il y a une maille parente à gauche/bas. Sinon, on crée la face. Si oui, on regarde le masque pour savoir si l'on
455 // doit créer la face.
456 // Pour droite/haut, le principe est différent de gauche/bas. On ne suit le masque que si on est tout à droite/haut
457 // de la maille parente. Sinon on crée toujours les faces droites/hautes.
458 // Enfin, on utilise le tableau "is_cell_around_parent_cell_in_subdomain". Si la maille parente d'à côté est sur
459 // notre sous-domaine, alors il se peut que les faces en communes avec notre maille parente existent déjà, dans ce cas,
460 // pas de doublon.
461 if (
462 ((i == child_coord_x && !is_cell_around_parent_cell_in_subdomain(1, 0)) || (mask_face_if_cell_left[l])) &&
463 ((i != (child_coord_x + pattern - 1) || !is_cell_around_parent_cell_in_subdomain(1, 2)) || mask_face_if_cell_right[l]) &&
464 ((j == child_coord_y && !is_cell_around_parent_cell_in_subdomain(0, 1)) || (mask_face_if_cell_bottom[l])) &&
465 ((j != (child_coord_y + pattern - 1) || !is_cell_around_parent_cell_in_subdomain(2, 1)) || mask_face_if_cell_top[l])) {
466 is_new_face = true;
467 faces_infos.add(type_face);
468 faces_infos.add(child_faces_uids[l]);
469
470 // Les noeuds de la face sont toujours les noeuds l et l+1
471 // car on utilise la même exploration pour les deux cas.
472 for (Integer nc = l; nc < l + 2; nc++) {
473 faces_infos.add(child_nodes_uids[nc % m_num_mng->nbNodeByCell()]);
474 }
475 total_nb_faces++;
476
477 // Par défaut, parent_cell est propriétaire de la nouvelle face.
478 child_face_owner = owner_cells_around_parent_cell(1, 1);
479 }
480
481 // Deuxième partie.
482 // On doit maintenant trouver le bon propriétaire pour la face. Mis à part le tableau "is_cell_around_parent_cell_same_owner",
483 // la condition est identique à celle au-dessus.
484 // Le changement de tableau est important puisqu'à partir d'ici, on est sûr qu'il y a la face qui nous intéresse.
485 // Le nouveau tableau permet de savoir si la maille d'à côté est aussi à nous ou pas. Si ce n'est pas le cas, alors
486 // un changement de propriétaire est possible, selon les priorités définies au-dessus. On n'a pas besoin de savoir
487 // si la maille est présente sur le sous-domaine.
488 if (
489 ((i == child_coord_x && !is_cell_around_parent_cell_same_owner(1, 0)) || (mask_face_if_cell_left[l])) &&
490 ((i != (child_coord_x + pattern - 1) || !is_cell_around_parent_cell_same_owner(1, 2)) || mask_face_if_cell_right[l]) &&
491 ((j == child_coord_y && !is_cell_around_parent_cell_same_owner(0, 1)) || (mask_face_if_cell_bottom[l])) &&
492 ((j != (child_coord_y + pattern - 1) || !is_cell_around_parent_cell_same_owner(2, 1)) || mask_face_if_cell_top[l])) {
493 // Ici, la construction des conditions est la même à chaque fois.
494 // Le premier booléen (i == child_coord_x) regarde si l'enfant se trouve
495 // du bon côté de la maille parent.
496 // Le second booléen (!mask_face_if_cell_left[l]) nous dit si la face l est bien
497 // la face en commun avec la maille parent d'à côté.
498 // Le troisième booléen (is_cell_around_parent_cell_different_owner(1, 0)) regarde s'il y a une
499 // maille à côté qui prend la propriété de la face ou à qui on prend la propriété.
500
501 // En outre, il y a deux cas différents selon les priorités définies au-dessus :
502 // - soit nous ne sommes pas prioritaire, alors on attribue le propriétaire prioritaire à notre face,
503 // - soit nous sommes prioritaire, alors on se positionne comme propriétaire de la face et on doit prévenir
504 // tous les autres processus (le processus ancien propriétaire mais aussi les processus qui peuvent
505 // avoir la face en fantôme).
506
507 // Enfin, dans le cas du changement de propriétaire, seul le processus (re)prenant la propriété doit
508 // faire une communication à ce propos. Les processus ne possédant que la face en fantôme ne doit pas
509 // faire de communication (mais ils peuvent définir localement le bon propriétaire, TODO Optimisation possible ?).
510
511 // À gauche, priorité 3 < 4 donc il prend la propriété de la face.
512 if (i == child_coord_x && (!mask_face_if_cell_left[l]) && is_cell_around_parent_cell_different_owner(1, 0)) {
513 child_face_owner = owner_cells_around_parent_cell(1, 0);
514 }
515
516 // En bas, priorité 1 < 4 donc il prend la propriété de la face.
517 else if (j == child_coord_y && (!mask_face_if_cell_bottom[l]) && is_cell_around_parent_cell_different_owner(0, 1)) {
518 child_face_owner = owner_cells_around_parent_cell(0, 1);
519 }
520
521 // Sinon, parent_cell est propriétaire de la face.
522 else {
523
524 // Sinon, c'est une face interne donc au parent_cell.
525 child_face_owner = owner_cells_around_parent_cell(1, 1);
526 }
527 }
528
529 // S'il y a une création de face et/ou un changement de propriétaire.
530 if (child_face_owner != -1) {
531 face_uid_to_owner[child_faces_uids[l]] = child_face_owner;
532
533 // Lorsqu'il y a un changement de propriétaire sans création de face,
534 // on doit mettre de côté les uniqueIds de ces faces pour pouvoir
535 // itérer dessus par la suite.
536 if (!is_new_face) {
537 face_uid_change_owner_only.add(child_faces_uids[l]);
538 debug() << "Child face (change owner) -- x : " << i
539 << " -- y : " << j
540 << " -- level : " << parent_cell_level + 1
541 << " -- face : " << l
542 << " -- uid_face : " << child_faces_uids[l]
543 << " -- owner : " << child_face_owner;
544 }
545 else {
546 debug() << "Child face (create face) -- x : " << i
547 << " -- y : " << j
548 << " -- level : " << parent_cell_level + 1
549 << " -- face : " << l
550 << " -- uid_face : " << child_faces_uids[l]
551 << " -- owner : " << child_face_owner;
552 }
553 }
554 }
555
556 // Partie Node.
557 // Cette partie est assez ressemblante à la partie face, mis à part le fait qu'il peut y avoir
558 // plus de propriétaires possibles.
559 for (Integer l = 0; l < m_num_mng->nbNodeByCell(); ++l) {
560 Integer child_node_owner = -1;
561 bool is_new_node = false;
562
563 // Deux parties :
564 // D'abord, on regarde si l'on doit créer le noeud l. Pour cela, on doit regarder s'il est présente sur la
565 // maille à côté.
566 // Pour gauche/bas, c'est le même principe. Si la maille enfant est tout à gauche/bas de la maille parente, on regarde
567 // s'il y a une maille parente à gauche/bas. Sinon, on crée le noeud. Si oui, on regarde le masque pour savoir si l'on
568 // doit créer le noeud.
569 // Pour droite/haut, le principe est différent de gauche/bas. On ne suit le masque que si la maille enfant est toute à droite/haut
570 // de la maille parente. Sinon on crée toujours les noeuds droites/hautes.
571 // Enfin, on utilise le tableau "is_cell_around_parent_cell_in_subdomain". Si la maille parente d'à côté est sur
572 // notre sous-domaine, alors il se peut que les noeuds en communs avec notre maille parente existent déjà, dans ce cas,
573 // pas de doublon.
574 if (
575 ((i == child_coord_x && !is_cell_around_parent_cell_in_subdomain(1, 0)) || (mask_node_if_cell_left[l])) &&
576 ((i != (child_coord_x + pattern - 1) || !is_cell_around_parent_cell_in_subdomain(1, 2)) || mask_node_if_cell_right[l]) &&
577 ((j == child_coord_y && !is_cell_around_parent_cell_in_subdomain(0, 1)) || (mask_node_if_cell_bottom[l])) &&
578 ((j != (child_coord_y + pattern - 1) || !is_cell_around_parent_cell_in_subdomain(2, 1)) || mask_node_if_cell_top[l])) {
579 is_new_node = true;
580 nodes_infos.add(child_nodes_uids[l]);
581 total_nb_nodes++;
582
583 // Par défaut, parent_cell est propriétaire du nouveau noeud.
584 child_node_owner = owner_cells_around_parent_cell(1, 1);
585 }
586
587 // Deuxième partie.
588 // On doit maintenant trouver le bon propriétaire pour le noeud. Mis à part le tableau "is_cell_around_parent_cell_same_owner",
589 // la condition est identique à celle au-dessus.
590 // Le changement de tableau est important puisqu'à partir d'ici, on est sûr que le noeud qui nous intéresse existe.
591 // Le nouveau tableau permet de savoir si la maille d'à côté est aussi à nous ou pas. Si ce n'est pas le cas, alors
592 // un changement de propriétaire est possible, selon les priorités définies au-dessus. On n'a pas besoin de savoir
593 // si la maille est présente sur le sous-domaine.
594 if (
595 ((i == child_coord_x && !is_cell_around_parent_cell_same_owner(1, 0)) || (mask_node_if_cell_left[l])) &&
596 ((i != (child_coord_x + pattern - 1) || !is_cell_around_parent_cell_same_owner(1, 2)) || mask_node_if_cell_right[l]) &&
597 ((j == child_coord_y && !is_cell_around_parent_cell_same_owner(0, 1)) || (mask_node_if_cell_bottom[l])) &&
598 ((j != (child_coord_y + pattern - 1) || !is_cell_around_parent_cell_same_owner(2, 1)) || mask_node_if_cell_top[l])) {
599 // Par rapport aux faces qui n'ont que deux propriétaires possibles, un noeud peut
600 // en avoir jusqu'à quatre.
601 // (Et oui, en 3D, c'est encore plus amusant !)
602
603 // Si le noeud est sur le côté gauche de la maille parente ("sur la face gauche").
604 if (i == child_coord_x && (!mask_node_if_cell_left[l])) {
605
606 // Si le noeud est sur le bas de la maille parente ("sur la face basse").
607 // Donc noeud en bas à gauche (même position que le noeud de la maille parente).
608 if (j == child_coord_y && (!mask_node_if_cell_bottom[l])) {
609
610 // Priorité 0 < 4.
611 if (is_cell_around_parent_cell_different_owner(0, 0)) {
612 child_node_owner = owner_cells_around_parent_cell(0, 0);
613 }
614
615 // Priorité 1 < 4.
616 else if (is_cell_around_parent_cell_different_owner(0, 1)) {
617 child_node_owner = owner_cells_around_parent_cell(0, 1);
618 }
619
620 // Priorité 3 < 4.
621 else if (is_cell_around_parent_cell_different_owner(1, 0)) {
622 child_node_owner = owner_cells_around_parent_cell(1, 0);
623 }
624
625 else {
626 child_node_owner = owner_cells_around_parent_cell(1, 1);
627 }
628 }
629
630 // Si le noeud est en haut de la maille parente ("sur la face haute").
631 // Donc noeud en haut à gauche (même position que le noeud de la maille parente).
632 else if (j == (child_coord_y + pattern - 1) && (!mask_node_if_cell_top[l])) {
633
634 // Priorité 3 < 4.
635 if (is_cell_around_parent_cell_different_owner(1, 0)) {
636 child_node_owner = owner_cells_around_parent_cell(1, 0);
637 }
638
639 // Sinon, parent_cell est propriétaire du noeud.
640 else {
641 child_node_owner = owner_cells_around_parent_cell(1, 1);
642 }
643 }
644
645 // Si le noeud est quelque part sur la face parente gauche...
646 else {
647 // S'il y a une maille à gauche, elle est propriétaire du noeud.
648 if (is_cell_around_parent_cell_different_owner(1, 0)) {
649 child_node_owner = owner_cells_around_parent_cell(1, 0);
650 }
651
652 // Sinon parent_cell est propriétaire du noeud.
653 else {
654 child_node_owner = owner_cells_around_parent_cell(1, 1);
655 }
656 }
657 }
658
659 // Si le noeud est sur le côté droit de la maille parente ("sur la face droite").
660 else if (i == (child_coord_x + pattern - 1) && (!mask_node_if_cell_right[l])) {
661
662 // Si le noeud est sur le bas de la maille parente ("sur la face basse").
663 // Donc noeud en bas à droite (même position que le noeud de la maille parente).
664 if (j == child_coord_y && (!mask_node_if_cell_bottom[l])) {
665
666 // Priorité 1 < 4.
667 if (is_cell_around_parent_cell_different_owner(0, 1)) {
668 child_node_owner = owner_cells_around_parent_cell(0, 1);
669 }
670
671 // Priorité 2 < 4.
672 else if (is_cell_around_parent_cell_different_owner(0, 2)) {
673 child_node_owner = owner_cells_around_parent_cell(0, 2);
674 }
675
676 // Sinon, parent_cell est propriétaire du noeud.
677 else {
678 child_node_owner = owner_cells_around_parent_cell(1, 1);
679 }
680 }
681
682 // Si le noeud est en haut de la maille parente ("sur la face haute").
683 // Donc noeud en haut à droite (même position que le noeud de la maille parente).
684 else if (j == (child_coord_y + pattern - 1) && (!mask_node_if_cell_top[l])) {
685 child_node_owner = owner_cells_around_parent_cell(1, 1);
686 }
687
688 // Si le noeud est quelque part sur la face parente droite...
689 else {
690 child_node_owner = owner_cells_around_parent_cell(1, 1);
691 }
692 }
693
694 // Si le noeud est ni sur la face parente gauche, ni sur la face parente droite...
695 else {
696
697 // Si le noeud est sur le bas de la maille parente ("sur la face basse") et
698 // qu'il y a une maille en bas de priorité 1 < 4, elle est propriétaire du noeud.
699 if (j == child_coord_y && (!mask_node_if_cell_bottom[l]) && is_cell_around_parent_cell_different_owner(0, 1)) {
700 child_node_owner = owner_cells_around_parent_cell(0, 1);
701 }
702
703 // Si le noeud est sur le haut de la maille parente ("sur la face haute") et
704 // qu'il y a une maille en haut de priorité 7 > 4, parent_cell est propriétaire du noeud.
705 else if (parent_cell_is_own && j == (child_coord_y + pattern - 1) && (!mask_node_if_cell_top[l]) && is_cell_around_parent_cell_different_owner(2, 1)) {
706 child_node_owner = owner_cells_around_parent_cell(1, 1);
707 }
708
709 // Noeuds qui ne sont sur aucune face de la maille parente.
710 else {
711 child_node_owner = owner_cells_around_parent_cell(1, 1);
712 }
713 }
714 }
715
716 // S'il y a une création de noeud et/ou un changement de propriétaire.
717 if (child_node_owner != -1) {
718 node_uid_to_owner[child_nodes_uids[l]] = child_node_owner;
719
720 // Lorsqu'il y a un changement de propriétaire sans création de noeud,
721 // on doit mettre de côté les uniqueIds de ces noeuds pour pouvoir
722 // itérer dessus par la suite.
723 if (!is_new_node) {
724 node_uid_change_owner_only.add(child_nodes_uids[l]);
725 debug() << "Child node (change owner) -- x : " << i
726 << " -- y : " << j
727 << " -- level : " << parent_cell_level + 1
728 << " -- node : " << l
729 << " -- uid_node : " << child_nodes_uids[l]
730 << " -- owner : " << child_node_owner;
731 }
732 else {
733 debug() << "Child node (create node) -- x : " << i
734 << " -- y : " << j
735 << " -- level : " << parent_cell_level + 1
736 << " -- node : " << l
737 << " -- uid_node : " << child_nodes_uids[l]
738 << " -- owner : " << child_node_owner;
739 }
740 }
741 }
742 }
743 }
744 }
745 }
746
747 // Pour le 3D, c'est très ressemblant, juste un peu plus long. Je recopie les commentaires, mais avec quelques adaptations.
748 else if (m_mesh->dimension() == 3) {
749
750 // Masques pour les cas "voisins enfants" et "voisins parents du même patch".
751 // Ces masques permettent de savoir si l'on doit créer un noeud ou pas selon
752 // les mailles autour.
753 // Par exemple, si l'on est en train d'étudier une maille enfant et qu'il y a
754 // une maille enfant à gauche, on ne doit pas créer les noeuds 0, 3, 4, 7 (mask_node_if_cell_left[]) (car
755 // ils ont déjà été créés par la maille à gauche).
756 // Idem pour les mailles parentes voisines : si l'on est sur une maille enfant située
757 // sur la partie gauche de la maille parente (mailles enfants 0, 2, 4, 6 dans le cas d'un
758 // pattern de raffinement = 2), qu'il y a une maille parente à gauche et que cette maille parente
759 // est en train ((d'être raffiné et à notre sous-domaine) ou (qu'elle est inactive)), on applique
760 // la règle mask_node_if_cell_left[] car les noeuds ont été créé par celle-ci et on veut éviter
761 // les noeuds en doubles.
762 // Ces masques permettent aussi de déterminer le propriétaire des noeuds dans
763 // le cas de multiples sous-domaines.
764 // Par exemple, si l'on est sur une maille enfant située
765 // sur la partie gauche de la maille parente (mailles enfants 0, 2, 4, 6 dans le cas d'un
766 // pattern de raffinement = 2), qu'il y a une maille parente à gauche et que cette maille
767 // parente (appartient à un autre sous-domaine) et (est en train d'être raffiné),
768 // on crée ce noeud mais on lui donne comme propriétaire le processus à qui appartient
769 // la maille parente à gauche.
770 const bool mask_node_if_cell_left[] = { false, true, true, false, false, true, true, false };
771 const bool mask_node_if_cell_bottom[] = { false, false, true, true, false, false, true, true };
772 const bool mask_node_if_cell_rear[] = { false, false, false, false, true, true, true, true };
773
774 const bool mask_node_if_cell_right[] = { true, false, false, true, true, false, false, true };
775 const bool mask_node_if_cell_top[] = { true, true, false, false, true, true, false, false };
776 const bool mask_node_if_cell_front[] = { true, true, true, true, false, false, false, false };
777
778 const bool mask_face_if_cell_left[] = { true, false, true, true, true, true };
779 const bool mask_face_if_cell_bottom[] = { true, true, false, true, true, true };
780 const bool mask_face_if_cell_rear[] = { false, true, true, true, true, true };
781
782 const bool mask_face_if_cell_right[] = { true, true, true, true, false, true };
783 const bool mask_face_if_cell_top[] = { true, true, true, true, true, false };
784 const bool mask_face_if_cell_front[] = { true, true, true, false, true, true };
785
786 // Petite différence par rapport au 2D. Pour le 2D, la position des noeuds des faces
787 // dans le tableau "child_nodes_uids" est toujours pareil (l et l+1, voir le 2D).
788 // Pour le 3D, ce n'est pas le cas donc on a des tableaux pour avoir une correspondance
789 // entre les noeuds de chaque face et la position des noeuds dans le tableau "child_nodes_uids".
790 // (Exemple : pour la face 1 (même ordre d'énumération qu'Arcane), on doit prendre le
791 // tableau "nodes_in_face_1" et donc les noeuds "child_nodes_uids[0]", "child_nodes_uids[3]",
792 // "child_nodes_uids[7]" et "child_nodes_uids[4]").
793 const Integer nodes_in_face_0[] = { 0, 1, 2, 3 };
794 const Integer nodes_in_face_1[] = { 0, 3, 7, 4 };
795 const Integer nodes_in_face_2[] = { 0, 1, 5, 4 };
796 const Integer nodes_in_face_3[] = { 4, 5, 6, 7 };
797 const Integer nodes_in_face_4[] = { 1, 2, 6, 5 };
798 const Integer nodes_in_face_5[] = { 3, 2, 6, 7 };
799
800 const Integer nb_nodes_in_face = 4;
801
802 // Pour la taille :
803 // - on a "cell_to_refine_internals.size() * 8" mailles enfants,
804 // - pour chaque maille, on a 2 infos (type de maille et uniqueId de la maille)
805 // - pour chaque maille, on a "m_num_mng->getNbNode()" uniqueIds (les uniqueId de chaque noeud de la maille).
806 cells_infos.reserve((cell_to_refine_internals.size() * 8) * (2 + m_num_mng->nbNodeByCell()));
807
808 // Pour la taille, au maximum :
809 // - on a "cell_to_refine_internals.size() * 36" faces enfants,
810 // - pour chaque face, on a 2 infos (type de face et uniqueId de la face)
811 // - pour chaque face, on a 4 uniqueIds de noeuds.
812 faces_infos.reserve((cell_to_refine_internals.size() * 36) * (2 + 4));
813
814 // Pour la taille, au maximum :
815 // - on a (cell_to_refine_internals.size() * 27) uniqueIds de noeuds.
816 nodes_infos.reserve(cell_to_refine_internals.size() * 27);
817
818 for (Cell parent_cell : cell_to_refine_internals) {
819 const Int64 parent_cell_uid = parent_cell.uniqueId();
820 const Int32 parent_cell_level = parent_cell.level();
821
822 const Int64 parent_coord_x = m_num_mng->cellUniqueIdToCoordX(parent_cell_uid, parent_cell_level);
823 const Int64 parent_coord_y = m_num_mng->cellUniqueIdToCoordY(parent_cell_uid, parent_cell_level);
824 const Int64 parent_coord_z = m_num_mng->cellUniqueIdToCoordZ(parent_cell_uid, parent_cell_level);
825
826 const Int64 child_coord_x = m_num_mng->offsetLevelToLevel(parent_coord_x, parent_cell_level, parent_cell_level + 1);
827 const Int64 child_coord_y = m_num_mng->offsetLevelToLevel(parent_coord_y, parent_cell_level, parent_cell_level + 1);
828 const Int64 child_coord_z = m_num_mng->offsetLevelToLevel(parent_coord_z, parent_cell_level, parent_cell_level + 1);
829
830 const Integer pattern = m_num_mng->pattern();
831
832 UniqueArray<Int64> uid_cells_around_parent_cell_1d(27);
833 UniqueArray<Int32> owner_cells_around_parent_cell_1d(27);
834 UniqueArray<Int32> flags_cells_around_parent_cell_1d(27);
835
836 m_num_mng->cellUniqueIdsAroundCell(uid_cells_around_parent_cell_1d, parent_cell);
837
838 for (Integer i = 0; i < 27; ++i) {
839 Int64 uid_cell = uid_cells_around_parent_cell_1d[i];
840 // Si uid_cell != -1 alors il y a peut-être une maille (mais on ne sait pas si elle est bien présente).
841 // Si around_parent_cells_uid_to_owner[uid_cell] != -1 alors il y a bien une maille.
842 if (uid_cell != -1 && around_parent_cells_uid_to_owner[uid_cell] != -1) {
843 owner_cells_around_parent_cell_1d[i] = around_parent_cells_uid_to_owner[uid_cell];
844 flags_cells_around_parent_cell_1d[i] = around_parent_cells_uid_to_flags[uid_cell];
845 }
846 else {
847 uid_cells_around_parent_cell_1d[i] = -1;
848 owner_cells_around_parent_cell_1d[i] = -1;
849 flags_cells_around_parent_cell_1d[i] = 0;
850 }
851 }
852
853 // Pour simplifier, on utilise des vues 3D. (array[Z][Y][X]).
854 ConstArray3View uid_cells_around_parent_cell(uid_cells_around_parent_cell_1d.data(), 3, 3, 3);
855 ConstArray3View owner_cells_around_parent_cell(owner_cells_around_parent_cell_1d.data(), 3, 3, 3);
856 ConstArray3View flags_cells_around_parent_cell(flags_cells_around_parent_cell_1d.data(), 3, 3, 3);
857
858 // Voici les priorités pour la propriété des noeuds et des faces :
859 // ┌──────────┐ │ ┌──────────┐ │ ┌──────────┐
860 // │ 6 7 8│ │ │15 16 17│ │ │24 25 26│
861 // │ │ │ └───────┐ │ │ │ │
862 // │ │ │ ┌──┐┌──┐│ │ │ │ │
863 // │ 3 4 5│ │ │12││13││14│ │ │21 22 23│
864 // │ │ │ │ │└──┘└──┘ │ │ │
865 // │ │ │ │ └───────┐ │ │ │
866 // │ 0 1 2│ │ │ 9 10 11│ │ │18 19 20│
867 // └──────────┘ │ └──────────┘ │ └──────────┘
868 // Z=0 │ Z=1 │ Z=2
869 // ("arrière") │ │ ("avant")
870
871 // Chaque chiffre désigne une maille parente et une priorité (0 étant la priorité la plus forte).
872 // 13 = parent_cell ("nous")
873
874 // Exemple 1 :
875 // On cherche à raffiner des mailles de niveau 0 (donc créer des mailles de niveau 1).
876 // En bas, il n'y a pas de mailles.
877 // À gauche (donc priorité 12), il y a une maille qui est déjà raffinée (flag "II_Inactive").
878 // On est priorité 13 donc il est prioritaire. Donc les noeuds et des faces que l'on a en commun
879 // lui appartiennent.
880
881 // Exemple 2 :
882 // On cherche à raffiner des mailles de niveau 0 (donc créer des mailles de niveau 1).
883 // En haut, il y a des mailles déjà raffinées (flag "II_Inactive").
884 // On est prioritaire sur elles, on récupère donc la propriété des noeuds et des faces que l'on a
885 // en commun. Ce changement de propriété doit leur être signalé.
886
887 // On simplifie avec un tableau de booléens.
888 // Si true, alors on doit appliquer la priorité de propriété.
889 // Si false, alors on considère qu'il n'y a pas de maille à la position définie.
890 bool is_cell_around_parent_cell_present_and_useful[3][3][3] = { { { false } } };
891
892 // Pour les mailles prioritaires sur nous, on doit regarder les deux flags.
893 // Si une maille a le flag "II_Refine", on n'existe pas pour elle donc elle prend la propriété
894 // des faces et des noeuds qu'on a en commun.
895 // Si une maille a le flag "II_Inactive", elle a déjà les bons propriétaires.
896 // Quoi qu'il en soit, si true alors les faces et noeuds qu'on a en commun leurs appartiennent.
897 is_cell_around_parent_cell_present_and_useful[0][0][0] = ((uid_cells_around_parent_cell(0, 0, 0) != -1) && (flags_cells_around_parent_cell(0, 0, 0) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
898 is_cell_around_parent_cell_present_and_useful[0][0][1] = ((uid_cells_around_parent_cell(0, 0, 1) != -1) && (flags_cells_around_parent_cell(0, 0, 1) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
899 is_cell_around_parent_cell_present_and_useful[0][0][2] = ((uid_cells_around_parent_cell(0, 0, 2) != -1) && (flags_cells_around_parent_cell(0, 0, 2) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
900 is_cell_around_parent_cell_present_and_useful[0][1][0] = ((uid_cells_around_parent_cell(0, 1, 0) != -1) && (flags_cells_around_parent_cell(0, 1, 0) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
901 is_cell_around_parent_cell_present_and_useful[0][1][1] = ((uid_cells_around_parent_cell(0, 1, 1) != -1) && (flags_cells_around_parent_cell(0, 1, 1) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
902 is_cell_around_parent_cell_present_and_useful[0][1][2] = ((uid_cells_around_parent_cell(0, 1, 2) != -1) && (flags_cells_around_parent_cell(0, 1, 2) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
903 is_cell_around_parent_cell_present_and_useful[0][2][0] = ((uid_cells_around_parent_cell(0, 2, 0) != -1) && (flags_cells_around_parent_cell(0, 2, 0) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
904 is_cell_around_parent_cell_present_and_useful[0][2][1] = ((uid_cells_around_parent_cell(0, 2, 1) != -1) && (flags_cells_around_parent_cell(0, 2, 1) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
905 is_cell_around_parent_cell_present_and_useful[0][2][2] = ((uid_cells_around_parent_cell(0, 2, 2) != -1) && (flags_cells_around_parent_cell(0, 2, 2) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
906
907 is_cell_around_parent_cell_present_and_useful[1][0][0] = ((uid_cells_around_parent_cell(1, 0, 0) != -1) && (flags_cells_around_parent_cell(1, 0, 0) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
908 is_cell_around_parent_cell_present_and_useful[1][0][1] = ((uid_cells_around_parent_cell(1, 0, 1) != -1) && (flags_cells_around_parent_cell(1, 0, 1) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
909 is_cell_around_parent_cell_present_and_useful[1][0][2] = ((uid_cells_around_parent_cell(1, 0, 2) != -1) && (flags_cells_around_parent_cell(1, 0, 2) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
910
911 is_cell_around_parent_cell_present_and_useful[1][1][0] = ((uid_cells_around_parent_cell(1, 1, 0) != -1) && (flags_cells_around_parent_cell(1, 1, 0) & (ItemFlags::II_Refine | ItemFlags::II_Inactive)));
912 // is_cell_around_parent_cell_present_and_useful[1][1][1] = parent_cell;
913
914 // Pour les mailles non prioritaires, on doit regarder qu'un seul flag.
915 // Si une maille a le flag "II_Inactive", alors elle doit être avertie qu'on récupère la propriété
916 // des noeuds et des faces qu'on a en commun.
917 // On ne regarde pas le flag "II_Refine" car, si ces mailles sont aussi en train d'être raffinée,
918 // elles savent qu'on existe et qu'on obtient la propriété des noeuds et des faces qu'on a en commun.
919 // En résumé, si true alors les faces et noeuds qu'on a en commun nous appartiennent.
920 is_cell_around_parent_cell_present_and_useful[1][1][2] = ((uid_cells_around_parent_cell(1, 1, 2) != -1) && (flags_cells_around_parent_cell(1, 1, 2) & ItemFlags::II_Inactive));
921
922 is_cell_around_parent_cell_present_and_useful[1][2][0] = ((uid_cells_around_parent_cell(1, 2, 0) != -1) && (flags_cells_around_parent_cell(1, 2, 0) & ItemFlags::II_Inactive));
923 is_cell_around_parent_cell_present_and_useful[1][2][1] = ((uid_cells_around_parent_cell(1, 2, 1) != -1) && (flags_cells_around_parent_cell(1, 2, 1) & ItemFlags::II_Inactive));
924 is_cell_around_parent_cell_present_and_useful[1][2][2] = ((uid_cells_around_parent_cell(1, 2, 2) != -1) && (flags_cells_around_parent_cell(1, 2, 2) & ItemFlags::II_Inactive));
925
926 is_cell_around_parent_cell_present_and_useful[2][0][0] = ((uid_cells_around_parent_cell(2, 0, 0) != -1) && (flags_cells_around_parent_cell(2, 0, 0) & ItemFlags::II_Inactive));
927 is_cell_around_parent_cell_present_and_useful[2][0][1] = ((uid_cells_around_parent_cell(2, 0, 1) != -1) && (flags_cells_around_parent_cell(2, 0, 1) & ItemFlags::II_Inactive));
928 is_cell_around_parent_cell_present_and_useful[2][0][2] = ((uid_cells_around_parent_cell(2, 0, 2) != -1) && (flags_cells_around_parent_cell(2, 0, 2) & ItemFlags::II_Inactive));
929 is_cell_around_parent_cell_present_and_useful[2][1][0] = ((uid_cells_around_parent_cell(2, 1, 0) != -1) && (flags_cells_around_parent_cell(2, 1, 0) & ItemFlags::II_Inactive));
930 is_cell_around_parent_cell_present_and_useful[2][1][1] = ((uid_cells_around_parent_cell(2, 1, 1) != -1) && (flags_cells_around_parent_cell(2, 1, 1) & ItemFlags::II_Inactive));
931 is_cell_around_parent_cell_present_and_useful[2][1][2] = ((uid_cells_around_parent_cell(2, 1, 2) != -1) && (flags_cells_around_parent_cell(2, 1, 2) & ItemFlags::II_Inactive));
932 is_cell_around_parent_cell_present_and_useful[2][2][0] = ((uid_cells_around_parent_cell(2, 2, 0) != -1) && (flags_cells_around_parent_cell(2, 2, 0) & ItemFlags::II_Inactive));
933 is_cell_around_parent_cell_present_and_useful[2][2][1] = ((uid_cells_around_parent_cell(2, 2, 1) != -1) && (flags_cells_around_parent_cell(2, 2, 1) & ItemFlags::II_Inactive));
934 is_cell_around_parent_cell_present_and_useful[2][2][2] = ((uid_cells_around_parent_cell(2, 2, 2) != -1) && (flags_cells_around_parent_cell(2, 2, 2) & ItemFlags::II_Inactive));
935
936 // En plus de regarder si chaque maille parent autour de notre maille parent existe et possède (II_Inactive) ou possédera (II_Refine) des enfants...
937 // ... on regarde si chaque maille parent est présente sur notre sous-domaine, que ce soit une maille fantôme ou non.
938 auto is_cell_around_parent_cell_in_subdomain = [&](Integer z, Integer y, Integer x) {
939 return is_cell_around_parent_cell_present_and_useful[z][y][x] && (flags_cells_around_parent_cell(z, y, x) & ItemFlags::II_UserMark1);
940 };
941
942 // ... on regarde si chaque maille parent est possédé par le même propriétaire que notre maille parent.
943 auto is_cell_around_parent_cell_same_owner = [&](Integer z, Integer y, Integer x) {
944 return is_cell_around_parent_cell_present_and_useful[z][y][x] && (owner_cells_around_parent_cell(z, y, x) == owner_cells_around_parent_cell(1, 1, 1));
945 };
946
947 // ... on regarde si chaque maille parent a un propriétaire différent par rapport à notre maille parent.
948 auto is_cell_around_parent_cell_different_owner = [&](Integer z, Integer y, Integer x) {
949 return is_cell_around_parent_cell_present_and_useful[z][y][x] && (owner_cells_around_parent_cell(z, y, x) != owner_cells_around_parent_cell(1, 1, 1));
950 };
951
952 // On itère sur toutes les mailles enfants.
953 for (Int64 k = child_coord_z; k < child_coord_z + pattern; ++k) {
954 for (Int64 j = child_coord_y; j < child_coord_y + pattern; ++j) {
955 for (Int64 i = child_coord_x; i < child_coord_x + pattern; ++i) {
956 parent_cells.add(parent_cell);
957 total_nb_cells++;
958
959 const Int64 child_cell_uid = m_num_mng->cellUniqueId(parent_cell_level + 1, Int64x3(i, j, k));
960 debug() << "Child -- x : " << i << " -- y : " << j << " -- z : " << k << " -- level : " << parent_cell_level + 1 << " -- uid : " << child_cell_uid;
961
962 m_num_mng->cellNodeUniqueIds(child_nodes_uids, parent_cell_level + 1, Int64x3(i, j, k));
963 m_num_mng->cellFaceUniqueIds(child_faces_uids, parent_cell_level + 1, Int64x3(i, j, k));
964
965 const Integer type_cell = IT_Hexaedron8;
966 const Integer type_face = IT_Quad4;
967
968 // Partie Cell.
969 cells_infos.add(type_cell);
970 cells_infos.add(child_cell_uid);
971 for (Integer nc = 0; nc < m_num_mng->nbNodeByCell(); nc++) {
972 cells_infos.add(child_nodes_uids[nc]);
973 }
974
975 // Partie Face.
976 for (Integer l = 0; l < m_num_mng->nbFaceByCell(); ++l) {
977 Integer child_face_owner = -1;
978 bool is_new_face = false;
979
980 // Deux parties :
981 // D'abord, on regarde si l'on doit créer la face l. Pour cela, on doit regarder si elle est présente sur la
982 // maille à côté.
983 // Pour gauche/bas/arrière, c'est le même principe. Si la maille enfant est tout à gauche/bas/arrière de la maille parente, on regarde
984 // s'il y a une maille parente à gauche/bas/arrière. Sinon, on crée la face. Si oui, on regarde le masque pour savoir si l'on
985 // doit créer la face.
986 // Pour droite/haut/avant, le principe est différent de gauche/bas/arrière. On ne suit le masque que si on est tout à droite/haut/avant
987 // de la maille parente. Sinon on crée toujours les faces droites/hautes/avant.
988 // Enfin, on utilise le tableau "is_cell_around_parent_cell_in_subdomain". Si la maille parente d'à côté est sur
989 // notre sous-domaine, alors il se peut que les faces en communes avec notre maille parente existent déjà, dans ce cas,
990 // pas de doublon.
991 if (
992 ((i == child_coord_x && !is_cell_around_parent_cell_in_subdomain(1, 1, 0)) || mask_face_if_cell_left[l]) &&
993 ((i != (child_coord_x + pattern - 1) || !is_cell_around_parent_cell_in_subdomain(1, 1, 2)) || mask_face_if_cell_right[l]) &&
994 ((j == child_coord_y && !is_cell_around_parent_cell_in_subdomain(1, 0, 1)) || mask_face_if_cell_bottom[l]) &&
995 ((j != (child_coord_y + pattern - 1) || !is_cell_around_parent_cell_in_subdomain(1, 2, 1)) || mask_face_if_cell_top[l]) &&
996 ((k == child_coord_z && !is_cell_around_parent_cell_in_subdomain(0, 1, 1)) || mask_face_if_cell_rear[l]) &&
997 ((k != (child_coord_z + pattern - 1) || !is_cell_around_parent_cell_in_subdomain(2, 1, 1)) || mask_face_if_cell_front[l])) {
998 is_new_face = true;
999 faces_infos.add(type_face);
1000 faces_infos.add(child_faces_uids[l]);
1001
1002 // On récupère la position des noeuds de la face dans le tableau "ua_node_uid".
1003 ConstArrayView<Integer> nodes_in_face_l;
1004 switch (l) {
1005 case 0:
1006 nodes_in_face_l = ConstArrayView<Integer>::create(nodes_in_face_0, nb_nodes_in_face);
1007 break;
1008 case 1:
1009 nodes_in_face_l = ConstArrayView<Integer>::create(nodes_in_face_1, nb_nodes_in_face);
1010 break;
1011 case 2:
1012 nodes_in_face_l = ConstArrayView<Integer>::create(nodes_in_face_2, nb_nodes_in_face);
1013 break;
1014 case 3:
1015 nodes_in_face_l = ConstArrayView<Integer>::create(nodes_in_face_3, nb_nodes_in_face);
1016 break;
1017 case 4:
1018 nodes_in_face_l = ConstArrayView<Integer>::create(nodes_in_face_4, nb_nodes_in_face);
1019 break;
1020 case 5:
1021 nodes_in_face_l = ConstArrayView<Integer>::create(nodes_in_face_5, nb_nodes_in_face);
1022 break;
1023 default:
1024 ARCANE_FATAL("Bizarre...");
1025 }
1026 for (Integer nc : nodes_in_face_l) {
1027 faces_infos.add(child_nodes_uids[nc]);
1028 }
1029 total_nb_faces++;
1030
1031 // Par défaut, parent_cell est propriétaire de la nouvelle face.
1032 child_face_owner = owner_cells_around_parent_cell(1, 1, 1);
1033 }
1034
1035 // Deuxième partie.
1036 // On doit maintenant trouver le bon propriétaire pour la face. Mis à part le tableau "is_cell_around_parent_cell_same_owner",
1037 // la condition est identique à celle au-dessus.
1038 // Le changement de tableau est important puisqu'à partir d'ici, on est sûr qu'il y a la face qui nous intéresse.
1039 // Le nouveau tableau permet de savoir si la maille d'à côté est aussi à nous ou pas. Si ce n'est pas le cas, alors
1040 // un changement de propriétaire est possible, selon les priorités définies au-dessus. On n'a pas besoin de savoir
1041 // si la maille est présente sur le sous-domaine.
1042 if (
1043 ((i == child_coord_x && !is_cell_around_parent_cell_same_owner(1, 1, 0)) || mask_face_if_cell_left[l]) &&
1044 ((i != (child_coord_x + pattern - 1) || !is_cell_around_parent_cell_same_owner(1, 1, 2)) || mask_face_if_cell_right[l]) &&
1045 ((j == child_coord_y && !is_cell_around_parent_cell_same_owner(1, 0, 1)) || mask_face_if_cell_bottom[l]) &&
1046 ((j != (child_coord_y + pattern - 1) || !is_cell_around_parent_cell_same_owner(1, 2, 1)) || mask_face_if_cell_top[l]) &&
1047 ((k == child_coord_z && !is_cell_around_parent_cell_same_owner(0, 1, 1)) || mask_face_if_cell_rear[l]) &&
1048 ((k != (child_coord_z + pattern - 1) || !is_cell_around_parent_cell_same_owner(2, 1, 1)) || mask_face_if_cell_front[l])) {
1049 // Ici, la construction des conditions est la même à chaque fois.
1050 // Le premier booléen (i == child_coord_x) regarde si l'enfant se trouve
1051 // du bon côté de la maille parent.
1052 // Le second booléen (!mask_face_if_cell_left[l]) nous dit si la face l est bien
1053 // la face en commun avec la maille parent d'à côté.
1054 // Le troisième booléen (is_cell_around_parent_cell_different_owner(1, 0)) regarde s'il y a une
1055 // maille à côté qui prend la propriété de la face ou à qui on prend la propriété.
1056
1057 // En outre, il y a deux cas différents selon les priorités définies au-dessus :
1058 // - soit nous ne sommes pas prioritaire, alors on attribue le propriétaire prioritaire à notre face,
1059 // - soit nous sommes prioritaire, alors on se positionne comme propriétaire de la face et on doit prévenir
1060 // tous les autres processus (le processus ancien propriétaire mais aussi les processus qui peuvent
1061 // avoir la face en fantôme).
1062
1063 // Enfin, dans le cas du changement de propriétaire, seul le processus (re)prenant la propriété doit
1064 // faire une communication à ce propos. Les processus ne possédant que la face en fantôme ne doit pas
1065 // faire de communication (mais ils peuvent définir localement le bon propriétaire, TODO Optimisation possible ?).
1066
1067 // À gauche, priorité 12 < 13 donc il prend la propriété de la face.
1068 if (i == child_coord_x && (!mask_face_if_cell_left[l]) && is_cell_around_parent_cell_different_owner(1, 1, 0)) {
1069 child_face_owner = owner_cells_around_parent_cell(1, 1, 0);
1070 }
1071
1072 // En bas, priorité 10 < 13 donc il prend la propriété de la face.
1073 else if (j == child_coord_y && (!mask_face_if_cell_bottom[l]) && is_cell_around_parent_cell_different_owner(1, 0, 1)) {
1074 child_face_owner = owner_cells_around_parent_cell(1, 0, 1);
1075 }
1076
1077 // À l'arrière, priorité 4 < 13 donc il prend la propriété de la face.
1078 else if (k == child_coord_z && (!mask_face_if_cell_rear[l]) && is_cell_around_parent_cell_different_owner(0, 1, 1)) {
1079 child_face_owner = owner_cells_around_parent_cell(0, 1, 1);
1080 }
1081
1082 // Sinon, parent_cell est propriétaire de la face.
1083 else {
1084
1085 // Sinon, c'est une face interne donc au parent_cell.
1086 child_face_owner = owner_cells_around_parent_cell(1, 1, 1);
1087 }
1088 }
1089
1090 // S'il y a une création de face et/ou un changement de propriétaire.
1091 if (child_face_owner != -1) {
1092 face_uid_to_owner[child_faces_uids[l]] = child_face_owner;
1093
1094 // Lorsqu'il y a un changement de propriétaire sans création de face,
1095 // on doit mettre de côté les uniqueIds de ces faces pour pouvoir
1096 // itérer dessus par la suite.
1097 if (!is_new_face) {
1098 face_uid_change_owner_only.add(child_faces_uids[l]);
1099 debug() << "Child face (change owner) -- x : " << i
1100 << " -- y : " << j
1101 << " -- z : " << k
1102 << " -- level : " << parent_cell_level + 1
1103 << " -- face : " << l
1104 << " -- uid_face : " << child_faces_uids[l]
1105 << " -- owner : " << child_face_owner;
1106 }
1107 else {
1108 debug() << "Child face (create face) -- x : " << i
1109 << " -- y : " << j
1110 << " -- z : " << k
1111 << " -- level : " << parent_cell_level + 1
1112 << " -- face : " << l
1113 << " -- uid_face : " << child_faces_uids[l]
1114 << " -- owner : " << child_face_owner;
1115 }
1116 }
1117 }
1118
1119 // Partie Node.
1120 // Cette partie est assez ressemblante à la partie face, mis à part le fait qu'il peut y avoir
1121 // plus de propriétaires possibles.
1122 for (Integer l = 0; l < m_num_mng->nbNodeByCell(); ++l) {
1123 Integer child_node_owner = -1;
1124 bool is_new_node = false;
1125
1126 // Deux parties :
1127 // D'abord, on regarde si l'on doit créer le noeud l. Pour cela, on doit regarder s'il est présente sur la
1128 // maille à côté.
1129 // Pour gauche/bas/arrière, c'est le même principe. Si la maille enfant est tout à gauche/bas/arrière de la maille parente, on regarde
1130 // s'il y a une maille parente à gauche/bas/arrière. Sinon, on crée le noeud. Si oui, on regarde le masque pour savoir si l'on
1131 // doit créer le noeud.
1132 // Pour droite/haut/avant, le principe est différent de gauche/bas/arrière. On ne suit le masque que si la maille
1133 // enfant est toute à droite/haut/avant
1134 // de la maille parente. Sinon on crée toujours les noeuds droites/hautes/avant.
1135 // Enfin, on utilise le tableau "is_cell_around_parent_cell_in_subdomain". Si la maille parente d'à côté est sur
1136 // notre sous-domaine, alors il se peut que les noeuds en communs avec notre maille parente existent déjà, dans ce cas,
1137 // pas de doublon.
1138 if (
1139 ((i == child_coord_x && !is_cell_around_parent_cell_in_subdomain(1, 1, 0)) || mask_node_if_cell_left[l]) &&
1140 ((i != (child_coord_x + pattern - 1) || !is_cell_around_parent_cell_in_subdomain(1, 1, 2)) || mask_node_if_cell_right[l]) &&
1141 ((j == child_coord_y && !is_cell_around_parent_cell_in_subdomain(1, 0, 1)) || mask_node_if_cell_bottom[l]) &&
1142 ((j != (child_coord_y + pattern - 1) || !is_cell_around_parent_cell_in_subdomain(1, 2, 1)) || mask_node_if_cell_top[l]) &&
1143 ((k == child_coord_z && !is_cell_around_parent_cell_in_subdomain(0, 1, 1)) || mask_node_if_cell_rear[l]) &&
1144 ((k != (child_coord_z + pattern - 1) || !is_cell_around_parent_cell_in_subdomain(2, 1, 1)) || mask_node_if_cell_front[l])) {
1145 is_new_node = true;
1146 nodes_infos.add(child_nodes_uids[l]);
1147 total_nb_nodes++;
1148
1149 // Par défaut, parent_cell est propriétaire du nouveau noeud.
1150 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1151 }
1152
1153 // Deuxième partie.
1154 // On doit maintenant trouver le bon propriétaire pour le noeud. Mis à part le tableau "is_cell_around_parent_cell_same_owner",
1155 // la condition est identique à celle au-dessus.
1156 // Le changement de tableau est important puisqu'à partir d'ici, on est sûr que le noeud qui nous intéresse existe.
1157 // Le nouveau tableau permet de savoir si la maille d'à côté est aussi à nous ou pas. Si ce n'est pas le cas, alors
1158 // un changement de propriétaire est possible, selon les priorités définies au-dessus. On n'a pas besoin de savoir
1159 // si la maille est présente sur le sous-domaine.
1160 if (
1161 ((i == child_coord_x && !is_cell_around_parent_cell_same_owner(1, 1, 0)) || mask_node_if_cell_left[l]) &&
1162 ((i != (child_coord_x + pattern - 1) || !is_cell_around_parent_cell_same_owner(1, 1, 2)) || mask_node_if_cell_right[l]) &&
1163 ((j == child_coord_y && !is_cell_around_parent_cell_same_owner(1, 0, 1)) || mask_node_if_cell_bottom[l]) &&
1164 ((j != (child_coord_y + pattern - 1) || !is_cell_around_parent_cell_same_owner(1, 2, 1)) || mask_node_if_cell_top[l]) &&
1165 ((k == child_coord_z && !is_cell_around_parent_cell_same_owner(0, 1, 1)) || mask_node_if_cell_rear[l]) &&
1166 ((k != (child_coord_z + pattern - 1) || !is_cell_around_parent_cell_same_owner(2, 1, 1)) || mask_node_if_cell_front[l])) {
1167
1168 // Par rapport aux faces qui n'ont que deux propriétaires possibles, un noeud peut
1169 // en avoir jusqu'à huit.
1170
1171 // Si le noeud est sur la face gauche de la maille parente.
1172 if (i == child_coord_x && (!mask_node_if_cell_left[l])) {
1173
1174 // Si le noeud est sur la face basse de la maille parente.
1175 // Donc noeud sur l'arête à gauche en bas.
1176 if (j == child_coord_y && (!mask_node_if_cell_bottom[l])) {
1177
1178 // Si le noeud est sur la face arrière de la maille parente.
1179 // Donc noeud à gauche, en bas, en arrière (même position que le noeud de la maille parente).
1180 if (k == child_coord_z && (!mask_node_if_cell_rear[l])) {
1181
1182 // Priorité 0 < 13.
1183 if (is_cell_around_parent_cell_different_owner(0, 0, 0)) {
1184 child_node_owner = owner_cells_around_parent_cell(0, 0, 0);
1185 }
1186
1187 // Priorité 1 < 13.
1188 else if (is_cell_around_parent_cell_different_owner(0, 0, 1)) {
1189 child_node_owner = owner_cells_around_parent_cell(0, 0, 1);
1190 }
1191
1192 // Priorité 3 < 13.
1193 else if (is_cell_around_parent_cell_different_owner(0, 1, 0)) {
1194 child_node_owner = owner_cells_around_parent_cell(0, 1, 0);
1195 }
1196
1197 // Priorité 4 < 13.
1198 else if (is_cell_around_parent_cell_different_owner(0, 1, 1)) {
1199 child_node_owner = owner_cells_around_parent_cell(0, 1, 1);
1200 }
1201
1202 // Priorité 9 < 13.
1203 else if (is_cell_around_parent_cell_different_owner(1, 0, 0)) {
1204 child_node_owner = owner_cells_around_parent_cell(1, 0, 0);
1205 }
1206
1207 // Priorité 10 < 13.
1208 else if (is_cell_around_parent_cell_different_owner(1, 0, 1)) {
1209 child_node_owner = owner_cells_around_parent_cell(1, 0, 1);
1210 }
1211
1212 // Priorité 12 < 13.
1213 else if (is_cell_around_parent_cell_different_owner(1, 1, 0)) {
1214 child_node_owner = owner_cells_around_parent_cell(1, 1, 0);
1215 }
1216
1217 // Pas de mailles autour.
1218 else {
1219 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1220 }
1221 }
1222
1223 // Si le noeud est sur la face avant de la maille parente.
1224 // Donc noeud à gauche, en bas, en avant (même position que le noeud de la maille parente).
1225 else if (k == (child_coord_z + pattern - 1) && (!mask_node_if_cell_front[l])) {
1226
1227 // Priorité 9 < 13.
1228 if (is_cell_around_parent_cell_different_owner(1, 0, 0)) {
1229 child_node_owner = owner_cells_around_parent_cell(1, 0, 0);
1230 }
1231
1232 // Priorité 10 < 13.
1233 else if (is_cell_around_parent_cell_different_owner(1, 0, 1)) {
1234 child_node_owner = owner_cells_around_parent_cell(1, 0, 1);
1235 }
1236
1237 // Priorité 12 < 13.
1238 else if (is_cell_around_parent_cell_different_owner(1, 1, 0)) {
1239 child_node_owner = owner_cells_around_parent_cell(1, 1, 0);
1240 }
1241
1242 // Sinon, parent_cell est propriétaire du noeud.
1243 else {
1244 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1245 }
1246 }
1247
1248 // Sinon le noeud est quelque part sur l'arête à gauche en bas...
1249 else {
1250
1251 // Priorité 9 < 13.
1252 if (is_cell_around_parent_cell_different_owner(1, 0, 0)) {
1253 child_node_owner = owner_cells_around_parent_cell(1, 0, 0);
1254 }
1255
1256 // Priorité 10 < 13.
1257 else if (is_cell_around_parent_cell_different_owner(1, 0, 1)) {
1258 child_node_owner = owner_cells_around_parent_cell(1, 0, 1);
1259 }
1260
1261 // Priorité 12 < 13.
1262 else if (is_cell_around_parent_cell_different_owner(1, 1, 0)) {
1263 child_node_owner = owner_cells_around_parent_cell(1, 1, 0);
1264 }
1265
1266 // Pas de mailles autour.
1267 else {
1268 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1269 }
1270 }
1271 }
1272
1273 // Si le noeud est sur la face haute de la maille parente.
1274 // Donc noeud sur l'arête à gauche en haut.
1275 else if (j == (child_coord_y + pattern - 1) && (!mask_node_if_cell_top[l])) {
1276
1277 // Si le noeud est sur la face arrière de la maille parente.
1278 // Donc noeud à gauche, en haut, en arrière (même position que le noeud de la maille parente).
1279 if (k == child_coord_z && (!mask_node_if_cell_rear[l])) {
1280
1281 // Priorité 3 < 13.
1282 if (is_cell_around_parent_cell_different_owner(0, 1, 0)) {
1283 child_node_owner = owner_cells_around_parent_cell(0, 1, 0);
1284 }
1285
1286 // Priorité 4 < 13.
1287 else if (is_cell_around_parent_cell_different_owner(0, 1, 1)) {
1288 child_node_owner = owner_cells_around_parent_cell(0, 1, 1);
1289 }
1290
1291 // Priorité 6 < 13.
1292 else if (is_cell_around_parent_cell_different_owner(0, 2, 0)) {
1293 child_node_owner = owner_cells_around_parent_cell(0, 2, 0);
1294 }
1295
1296 // Priorité 7 < 13.
1297 else if (is_cell_around_parent_cell_different_owner(0, 2, 1)) {
1298 child_node_owner = owner_cells_around_parent_cell(0, 2, 1);
1299 }
1300
1301 // Priorité 12 < 13.
1302 else if (is_cell_around_parent_cell_different_owner(1, 1, 0)) {
1303 child_node_owner = owner_cells_around_parent_cell(1, 1, 0);
1304 }
1305
1306 // Sinon, parent_cell est propriétaire du noeud.
1307 else {
1308 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1309 }
1310 }
1311
1312 // Si le noeud est sur la face avant de la maille parente.
1313 // Donc noeud à gauche, en haut, en avant (même position que le noeud de la maille parente).
1314 else if (k == (child_coord_z + pattern - 1) && (!mask_node_if_cell_front[l])) {
1315
1316 // Priorité 4 < 13.
1317 if (is_cell_around_parent_cell_different_owner(1, 1, 0)) {
1318 child_node_owner = owner_cells_around_parent_cell(1, 1, 0);
1319 }
1320
1321 // Sinon, parent_cell est propriétaire du noeud.
1322 else {
1323 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1324 }
1325 }
1326
1327 // Sinon le noeud est quelque part sur l'arête à gauche en haut...
1328 else {
1329
1330 // Priorité 12 < 13.
1331 if (is_cell_around_parent_cell_different_owner(1, 1, 0)) {
1332 child_node_owner = owner_cells_around_parent_cell(1, 1, 0);
1333 }
1334
1335 // Sinon, parent_cell est propriétaire du noeud.
1336 else {
1337 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1338 }
1339 }
1340 }
1341
1342 // Sinon le noeud est ni sur l'arête à gauche en bas, ni sur l'arête à gauche en haut.
1343 else {
1344
1345 // Si le noeud est quelque part sur l'arête à gauche en arrière.
1346 if (k == child_coord_z && (!mask_node_if_cell_rear[l])) {
1347
1348 // Priorité 3 < 13.
1349 if (is_cell_around_parent_cell_different_owner(0, 1, 0)) {
1350 child_node_owner = owner_cells_around_parent_cell(0, 1, 0);
1351 }
1352
1353 // Priorité 4 < 13.
1354 else if (is_cell_around_parent_cell_different_owner(0, 1, 1)) {
1355 child_node_owner = owner_cells_around_parent_cell(0, 1, 1);
1356 }
1357
1358 // Priorité 12 < 13.
1359 else if (is_cell_around_parent_cell_different_owner(1, 1, 0)) {
1360 child_node_owner = owner_cells_around_parent_cell(1, 1, 0);
1361 }
1362
1363 // Pas de mailles autour.
1364 else {
1365 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1366 }
1367 }
1368
1369 // Si le noeud est quelque part sur l'arête à gauche en avant.
1370 else if (k == (child_coord_z + pattern - 1) && (!mask_node_if_cell_front[l])) {
1371
1372 // Priorité 12 < 13.
1373 if (is_cell_around_parent_cell_different_owner(1, 1, 0)) {
1374 child_node_owner = owner_cells_around_parent_cell(1, 1, 0);
1375 }
1376
1377 // Sinon, parent_cell est propriétaire du noeud.
1378 else {
1379 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1380 }
1381 }
1382
1383 // Sinon le noeud est quelque part sur la face gauche...
1384 else {
1385
1386 // Priorité 12 < 13.
1387 if (is_cell_around_parent_cell_different_owner(1, 1, 0)) {
1388 child_node_owner = owner_cells_around_parent_cell(1, 1, 0);
1389 }
1390
1391 // Parent_cell est le proprio.
1392 else {
1393 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1394 }
1395 }
1396 }
1397 }
1398
1399 // À partir de là, on a exploré tous les noeuds et toutes les arêtes de la face parente gauche.
1400
1401 // Si le noeud est sur la face droite de la maille parente.
1402 else if (i == (child_coord_x + pattern - 1) && (!mask_node_if_cell_right[l])) {
1403
1404 // Si le noeud est sur la face basse de la maille parente.
1405 // Donc noeud sur l'arête à droite en bas.
1406 if (j == child_coord_y && (!mask_node_if_cell_bottom[l])) {
1407
1408 // Si le noeud est sur la face arrière de la maille parente.
1409 // Donc noeud à droite, en bas, en arrière (même position que le noeud de la maille parente).
1410 if (k == child_coord_z && (!mask_node_if_cell_rear[l])) {
1411
1412 // Priorité 1 < 13.
1413 if (is_cell_around_parent_cell_different_owner(0, 0, 1)) {
1414 child_node_owner = owner_cells_around_parent_cell(0, 0, 1);
1415 }
1416
1417 // Priorité 2 < 13.
1418 else if (is_cell_around_parent_cell_different_owner(0, 0, 2)) {
1419 child_node_owner = owner_cells_around_parent_cell(0, 0, 2);
1420 }
1421
1422 // Priorité 4 < 13.
1423 else if (is_cell_around_parent_cell_different_owner(0, 1, 1)) {
1424 child_node_owner = owner_cells_around_parent_cell(0, 1, 1);
1425 }
1426
1427 // Priorité 5 < 13.
1428 else if (is_cell_around_parent_cell_different_owner(0, 1, 2)) {
1429 child_node_owner = owner_cells_around_parent_cell(0, 1, 2);
1430 }
1431
1432 // Priorité 10 < 13.
1433 else if (is_cell_around_parent_cell_different_owner(1, 0, 1)) {
1434 child_node_owner = owner_cells_around_parent_cell(1, 0, 1);
1435 }
1436
1437 // Priorité 11 < 13.
1438 else if (is_cell_around_parent_cell_different_owner(1, 0, 2)) {
1439 child_node_owner = owner_cells_around_parent_cell(1, 0, 2);
1440 }
1441
1442 // Sinon, parent_cell est propriétaire du noeud.
1443 else {
1444 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1445 }
1446 }
1447
1448 // Si le noeud est sur la face avant de la maille parente.
1449 // Donc noeud à droite, en bas, en avant (même position que le noeud de la maille parente).
1450 else if (k == (child_coord_z + pattern - 1) && (!mask_node_if_cell_front[l])) {
1451
1452 // Priorité 10 < 13.
1453 if (is_cell_around_parent_cell_different_owner(1, 0, 1)) {
1454 child_node_owner = owner_cells_around_parent_cell(1, 0, 1);
1455 }
1456
1457 // Priorité 11 < 13.
1458 else if (is_cell_around_parent_cell_different_owner(1, 0, 2)) {
1459 child_node_owner = owner_cells_around_parent_cell(1, 0, 2);
1460 }
1461
1462 // Sinon, parent_cell est propriétaire du noeud.
1463 else {
1464 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1465 }
1466 }
1467
1468 // Sinon le noeud est quelque part sur l'arête à droite en bas...
1469 else {
1470
1471 // Priorité 10 < 13.
1472 if (is_cell_around_parent_cell_different_owner(1, 0, 1)) {
1473 child_node_owner = owner_cells_around_parent_cell(1, 0, 1);
1474 }
1475
1476 // Priorité 11 < 13.
1477 else if (is_cell_around_parent_cell_different_owner(1, 0, 2)) {
1478 child_node_owner = owner_cells_around_parent_cell(1, 0, 2);
1479 }
1480
1481 // Sinon, parent_cell est propriétaire du noeud.
1482 else {
1483 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1484 }
1485 }
1486 }
1487
1488 // Si le noeud est sur la face haute de la maille parente.
1489 // Donc noeud sur l'arête à droite en haut.
1490 else if (j == (child_coord_y + pattern - 1) && (!mask_node_if_cell_top[l])) {
1491
1492 // Si le noeud est sur la face arrière de la maille parente.
1493 // Donc noeud à droite, en haut, en arrière (même position que le noeud de la maille parente).
1494 if (k == child_coord_z && (!mask_node_if_cell_rear[l])) {
1495
1496 // Priorité 4 < 13.
1497 if (is_cell_around_parent_cell_different_owner(0, 1, 1)) {
1498 child_node_owner = owner_cells_around_parent_cell(0, 1, 1);
1499 }
1500
1501 // Priorité 5 < 13.
1502 else if (is_cell_around_parent_cell_different_owner(0, 1, 2)) {
1503 child_node_owner = owner_cells_around_parent_cell(0, 1, 2);
1504 }
1505
1506 // Priorité 7 < 13.
1507 else if (is_cell_around_parent_cell_different_owner(0, 2, 1)) {
1508 child_node_owner = owner_cells_around_parent_cell(0, 2, 1);
1509 }
1510
1511 // Priorité 8 < 13.
1512 else if (is_cell_around_parent_cell_different_owner(0, 2, 2)) {
1513 child_node_owner = owner_cells_around_parent_cell(0, 2, 2);
1514 }
1515
1516 // Sinon, parent_cell est propriétaire du noeud.
1517 else {
1518 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1519 }
1520 }
1521
1522 // Si le noeud est sur la face avant de la maille parente.
1523 // Donc noeud à droite, en haut, en avant (même position que le noeud de la maille parente).
1524 else if (k == (child_coord_z + pattern - 1) && (!mask_node_if_cell_front[l])) {
1525 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1526 }
1527
1528 // Sinon le noeud est quelque part sur l'arête à droite en haut...
1529 else {
1530 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1531 }
1532 }
1533
1534 // Sinon le noeud est ni sur l'arête à droite en bas, ni sur l'arête à droite en haut.
1535 else {
1536 // Si le noeud est quelque part sur l'arête à droite en arrière.
1537 if (k == child_coord_z && (!mask_node_if_cell_rear[l])) {
1538
1539 // Priorité 4 < 13.
1540 if (is_cell_around_parent_cell_different_owner(0, 1, 1)) {
1541 child_node_owner = owner_cells_around_parent_cell(0, 1, 1);
1542 }
1543
1544 // Priorité 5 < 13.
1545 else if (is_cell_around_parent_cell_different_owner(0, 1, 2)) {
1546 child_node_owner = owner_cells_around_parent_cell(0, 1, 2);
1547 }
1548
1549 // Sinon, parent_cell est propriétaire du noeud.
1550 else {
1551 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1552 }
1553 }
1554
1555 // Si le noeud est quelque part sur l'arête à droite en avant.
1556 else if (k == (child_coord_z + pattern - 1) && (!mask_node_if_cell_front[l])) {
1557 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1558 }
1559
1560 // Sinon le noeud est quelque part sur la face droite...
1561 else {
1562 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1563 }
1564 }
1565 }
1566
1567 // À partir de là, on a exploré tous les noeuds de la maille parente et toutes les arêtes
1568 // de la face parente droite (et gauche).
1569 // Donc il ne reste que quatre arêtes et quatre faces à explorer.
1570
1571 // Sinon le noeud est ni sur la face gauche, ni sur la face droite.
1572 else {
1573
1574 // Si le noeud est sur la face basse de la maille parente.
1575 if (j == child_coord_y && (!mask_node_if_cell_bottom[l])) {
1576
1577 // Si le noeud est sur la face arrière de la maille parente.
1578 // Donc noeud sur l'arête en arrière en bas.
1579 if (k == child_coord_z && (!mask_node_if_cell_rear[l])) {
1580
1581 // Priorité 1 < 13.
1582 if (is_cell_around_parent_cell_different_owner(0, 0, 1)) {
1583 child_node_owner = owner_cells_around_parent_cell(0, 0, 1);
1584 }
1585
1586 // Priorité 4 < 13.
1587 else if (is_cell_around_parent_cell_different_owner(0, 1, 1)) {
1588 child_node_owner = owner_cells_around_parent_cell(0, 1, 1);
1589 }
1590
1591 // Priorité 10 < 13.
1592 else if (is_cell_around_parent_cell_different_owner(1, 0, 1)) {
1593 child_node_owner = owner_cells_around_parent_cell(1, 0, 1);
1594 }
1595
1596 // Pas de mailles autour.
1597 else {
1598 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1599 }
1600 }
1601
1602 // Si le noeud est sur la face avant de la maille parente.
1603 // Donc noeud sur l'arête en avant en bas.
1604 else if (k == (child_coord_z + pattern - 1) && (!mask_node_if_cell_front[l])) {
1605
1606 // Priorité 10 < 13.
1607 if (is_cell_around_parent_cell_different_owner(1, 0, 1)) {
1608 child_node_owner = owner_cells_around_parent_cell(1, 0, 1);
1609 }
1610
1611 // Sinon, parent_cell est propriétaire du noeud.
1612 else {
1613 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1614 }
1615 }
1616
1617 // Sinon le noeud est quelque part sur la face en bas...
1618 else {
1619
1620 // Priorité 10 < 13.
1621 if (is_cell_around_parent_cell_different_owner(1, 0, 1)) {
1622 child_node_owner = owner_cells_around_parent_cell(1, 0, 1);
1623 }
1624
1625 // Parent_cell est le proprio.
1626 else {
1627 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1628 }
1629 }
1630 }
1631
1632 // Si le noeud est sur la face haute de la maille parente.
1633 else if (j == (child_coord_y + pattern - 1) && (!mask_node_if_cell_top[l])) {
1634
1635 // Si le noeud est sur la face arrière de la maille parente.
1636 // Donc noeud sur l'arête en arrière en haut.
1637 if (k == child_coord_z && (!mask_node_if_cell_rear[l])) {
1638
1639 // Priorité 4 < 13.
1640 if (is_cell_around_parent_cell_different_owner(0, 1, 1)) {
1641 child_node_owner = owner_cells_around_parent_cell(0, 1, 1);
1642 }
1643
1644 // Priorité 7 < 13.
1645 else if (is_cell_around_parent_cell_different_owner(0, 2, 1)) {
1646 child_node_owner = owner_cells_around_parent_cell(0, 2, 1);
1647 }
1648
1649 // Sinon, parent_cell est propriétaire du noeud.
1650 else {
1651 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1652 }
1653 }
1654
1655 // Si le noeud est sur la face avant de la maille parente.
1656 // Donc noeud sur l'arête en avant en haut.
1657 else if (k == (child_coord_z + pattern - 1) && (!mask_node_if_cell_front[l])) {
1658 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1659 }
1660
1661 // Sinon le noeud est quelque part sur la face en haut...
1662 else {
1663 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1664 }
1665 }
1666
1667 // Il ne reste plus que deux faces, la face arrière et la face avant...
1668 else {
1669
1670 // Si le noeud est quelque part sur la face arrière...
1671 if (k == child_coord_z && (!mask_node_if_cell_rear[l])) {
1672
1673 // Priorité 4 < 13.
1674 if (is_cell_around_parent_cell_different_owner(0, 1, 1)) {
1675 child_node_owner = owner_cells_around_parent_cell(0, 1, 1);
1676 }
1677
1678 // Parent_cell est le proprio.
1679 else {
1680 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1681 }
1682 }
1683
1684 // Si le noeud est quelque part sur la face avant...
1685 else if (k == (child_coord_z + pattern - 1) && (!mask_node_if_cell_front[l])) {
1686 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1687 }
1688
1689 // Sinon, le noeud est à l'intérieur de la maille parente.
1690 else {
1691 child_node_owner = owner_cells_around_parent_cell(1, 1, 1);
1692 }
1693 }
1694 }
1695 }
1696
1697 // S'il y a une création de noeud et/ou un changement de propriétaire.
1698 if (child_node_owner != -1) {
1699 node_uid_to_owner[child_nodes_uids[l]] = child_node_owner;
1700
1701 // Lorsqu'il y a un changement de propriétaire sans création de noeud,
1702 // on doit mettre de côté les uniqueIds de ces noeuds pour pouvoir
1703 // itérer dessus par la suite.
1704 if (!is_new_node) {
1705 node_uid_change_owner_only.add(child_nodes_uids[l]);
1706 debug() << "Child node (change owner) -- x : " << i
1707 << " -- y : " << j
1708 << " -- z : " << k
1709 << " -- level : " << parent_cell_level + 1
1710 << " -- node : " << l
1711 << " -- uid_node : " << child_nodes_uids[l]
1712 << " -- owner : " << child_node_owner;
1713 }
1714 else {
1715 debug() << "Child node (create node) -- x : " << i
1716 << " -- y : " << j
1717 << " -- z : " << k
1718 << " -- level : " << parent_cell_level + 1
1719 << " -- node : " << l
1720 << " -- uid_node : " << child_nodes_uids[l]
1721 << " -- owner : " << child_node_owner;
1722 }
1723 }
1724 }
1725 }
1726 }
1727 }
1728 }
1729 }
1730 else {
1731 ARCANE_FATAL("Bad dimension");
1732 }
1733
1734 // Nodes
1735 {
1736 debug() << "Nb new nodes in patch : " << total_nb_nodes;
1737 {
1738 const Integer nb_node_owner_change = node_uid_change_owner_only.size();
1739
1740 // Ce tableau contiendra les localIds des nouveaux noeuds mais aussi les localIds
1741 // des noeuds qui changent juste de propriétaire.
1742 UniqueArray<Int32> nodes_lid(total_nb_nodes + nb_node_owner_change);
1743
1744 // On crée les noeuds. On met les localIds des nouveaux noeuds au début du tableau.
1745 m_mesh->modifier()->addNodes(nodes_infos, nodes_lid.subView(0, total_nb_nodes));
1746
1747 // On cherche les localIds des noeuds qui changent de proprio et on les met à la fin du tableau.
1748 m_mesh->nodeFamily()->itemsUniqueIdToLocalId(nodes_lid.subView(total_nb_nodes, nb_node_owner_change), node_uid_change_owner_only, true);
1749
1750 UniqueArray<Int64> uid_child_nodes(total_nb_nodes + nb_node_owner_change);
1751 UniqueArray<Int32> lid_child_nodes(total_nb_nodes + nb_node_owner_change);
1752 Integer index = 0;
1753
1754 // On attribue les bons propriétaires aux noeuds.
1755 ENUMERATE_ (Node, inode, m_mesh->nodeFamily()->view(nodes_lid)) {
1756 Node node = *inode;
1757 node.mutableItemBase().setOwner(node_uid_to_owner[node.uniqueId()], my_rank);
1758
1759 if (node_uid_to_owner[node.uniqueId()] == my_rank) {
1760 node.mutableItemBase().addFlags(ItemFlags::II_Own);
1761 }
1762 // TODO : Corriger ça dans la partie concerné directement.
1763 else {
1764 node.mutableItemBase().removeFlags(ItemFlags::II_Shared);
1765 }
1766 // Attention, node.level() == -1 ici.
1767 uid_child_nodes[index++] = m_num_mng->parentNodeUniqueIdOfNode(node.uniqueId(), max_level + 1, false);
1768 }
1769
1770 m_mesh->nodeFamily()->itemsUniqueIdToLocalId(lid_child_nodes, uid_child_nodes, false);
1771 NodeInfoListView nodes(m_mesh->nodeFamily());
1772
1773 index = 0;
1774 ENUMERATE_ (Node, inode, m_mesh->nodeFamily()->view(nodes_lid)) {
1775 const Int32 child_lid = lid_child_nodes[index++];
1776 if (child_lid == NULL_ITEM_ID) {
1777 continue;
1778 }
1779
1780 Node parent = nodes[child_lid];
1781 Node child = *inode;
1782
1783 m_mesh->modifier()->addParentNodeToNode(child, parent);
1784 m_mesh->modifier()->addChildNodeToNode(parent, child);
1785 }
1786 }
1787 m_mesh->nodeFamily()->notifyItemsOwnerChanged();
1788 }
1789
1790 // Faces
1791 {
1792 debug() << "Nb new faces in patch : " << total_nb_faces;
1793 {
1794 const Integer nb_face_owner_change = face_uid_change_owner_only.size();
1795
1796 // Ce tableau contiendra les localIds des nouvelles faces mais aussi les localIds
1797 // des faces qui changent juste de propriétaire.
1798 UniqueArray<Int32> faces_lid(total_nb_faces + nb_face_owner_change);
1799
1800 // On crée les faces. On met les localIds des nouvelles faces au début du tableau.
1801 m_mesh->modifier()->addFaces(total_nb_faces, faces_infos, faces_lid.subView(0, total_nb_faces));
1802
1803 // On cherche les localIds des faces qui changent de proprio et on les met à la fin du tableau.
1804 m_mesh->faceFamily()->itemsUniqueIdToLocalId(faces_lid.subView(total_nb_faces, nb_face_owner_change), face_uid_change_owner_only, true);
1805
1806 UniqueArray<Int64> uid_parent_faces(total_nb_faces + nb_face_owner_change);
1807 UniqueArray<Int32> lid_parent_faces(total_nb_faces + nb_face_owner_change);
1808 Integer index = 0;
1809
1810 // On attribue les bons propriétaires aux faces.
1811 ENUMERATE_ (Face, iface, m_mesh->faceFamily()->view(faces_lid)) {
1812 Face face = *iface;
1813 face.mutableItemBase().setOwner(face_uid_to_owner[face.uniqueId()], my_rank);
1814
1815 if (face_uid_to_owner[face.uniqueId()] == my_rank) {
1816 face.mutableItemBase().addFlags(ItemFlags::II_Own);
1817 }
1818 // TODO : Corriger ça dans la partie concerné directement.
1819 else {
1820 face.mutableItemBase().removeFlags(ItemFlags::II_Shared);
1821 }
1822 // Attention, face.level() == -1 ici.
1823 uid_parent_faces[index++] = m_num_mng->parentFaceUniqueIdOfFace(face.uniqueId(), max_level + 1, false);
1824 //debug() << "Parent of : " << face.uniqueId() << " is : " << uid_child_faces[index - 1];
1825 }
1826
1827 m_mesh->faceFamily()->itemsUniqueIdToLocalId(lid_parent_faces, uid_parent_faces, false);
1828 FaceInfoListView faces(m_mesh->faceFamily());
1829
1830 index = 0;
1831 ENUMERATE_ (Face, iface, m_mesh->faceFamily()->view(faces_lid)) {
1832 const Int32 child_lid = lid_parent_faces[index++];
1833 if (child_lid == NULL_ITEM_ID) {
1834 continue;
1835 }
1836
1837 Face parent = faces[child_lid];
1838 Face child = *iface;
1839
1840 m_mesh->modifier()->addParentFaceToFace(child, parent);
1841 m_mesh->modifier()->addChildFaceToFace(parent, child);
1842 }
1843 }
1844 m_mesh->faceFamily()->notifyItemsOwnerChanged();
1845 }
1846
1847 // Cells
1848 {
1849 debug() << "Nb new cells in patch : " << total_nb_cells;
1850
1851 UniqueArray<Int32> cells_lid(total_nb_cells);
1852 m_mesh->modifier()->addCells(total_nb_cells, cells_infos, cells_lid);
1853
1854 // Itération sur les nouvelles mailles.
1855 CellInfoListView cells(m_mesh->cellFamily());
1856 for (Integer i = 0; i < total_nb_cells; ++i) {
1857 Cell child = cells[cells_lid[i]];
1858
1859 child.mutableItemBase().setOwner(parent_cells[i].owner(), my_rank);
1860
1861 child.mutableItemBase().addFlags(ItemFlags::II_JustAdded);
1862
1863 if (parent_cells[i].owner() == my_rank) {
1864 child.mutableItemBase().addFlags(ItemFlags::II_Own);
1865 }
1866
1867 if (parent_cells[i].itemBase().flags() & ItemFlags::II_Shared) {
1868 child.mutableItemBase().addFlags(ItemFlags::II_Shared);
1869 }
1870
1871 m_mesh->modifier()->addParentCellToCell(child, parent_cells[i]);
1872 m_mesh->modifier()->addChildCellToCell(parent_cells[i], child);
1873 }
1874
1875 // Itération sur les mailles parentes.
1876 for (Cell cell : cell_to_refine_internals) {
1877 cell.mutableItemBase().removeFlags(ItemFlags::II_Refine);
1878 cell.mutableItemBase().addFlags(ItemFlags::II_JustRefined | ItemFlags::II_Inactive);
1879 }
1880 m_mesh->cellFamily()->notifyItemsOwnerChanged();
1881 }
1882
1883 m_mesh->modifier()->endUpdate();
1884
1885 // On positionne les noeuds dans l'espace.
1886 for (Cell parent_cell : cell_to_refine_internals) {
1887 m_num_mng->setChildNodeCoordinates(parent_cell);
1888 // On ajoute le flag "II_Shared" aux noeuds et aux faces des mailles partagées.
1889 if (parent_cell.mutableItemBase().flags() & ItemFlags::II_Shared) {
1890 for (Integer i = 0; i < parent_cell.nbHChildren(); ++i) {
1891 Cell child_cell = parent_cell.hChild(i);
1892 for (Node node : child_cell.nodes()) {
1893 if (node.mutableItemBase().flags() & ItemFlags::II_Own) {
1894 node.mutableItemBase().addFlags(ItemFlags::II_Shared);
1895 }
1896 }
1897
1898 for (Face face : child_cell.faces()) {
1899 if (face.mutableItemBase().flags() & ItemFlags::II_Own) {
1900 face.mutableItemBase().addFlags(ItemFlags::II_Shared);
1901 }
1902 }
1903 }
1904 }
1905 }
1906
1907 // ENUMERATE_(Cell, icell, m_mesh->allCells()){
1908 // debug() << "\t" << *icell;
1909 // for(Node node : icell->nodes()){
1910 // debug() << "\t\t" << node;
1911 // }
1912 // for(Face face : icell->faces()){
1913 // debug() << "\t\t\t" << face;
1914 // }
1915 // }
1916 // info() << "Résumé :";
1917 // ENUMERATE_ (Cell, icell, m_mesh->allCells()) {
1918 // debug() << "\tCell uniqueId : " << icell->uniqueId() << " -- level : " << icell->level() << " -- nbChildren : " << icell->nbHChildren();
1919 // for (Integer i = 0; i < icell->nbHChildren(); ++i) {
1920 // debug() << "\t\tChild uniqueId : " << icell->hChild(i).uniqueId() << " -- level : " << icell->hChild(i).level() << " -- nbChildren : " << icell->hChild(i).nbHChildren();
1921 // }
1922 // }
1923 // info() << "Résumé node:";
1924 // ENUMERATE_ (Node, inode, m_mesh->allNodes()) {
1925 // debug() << "\tNode uniqueId : " << inode->uniqueId() << " -- level : " << inode->level() << " -- nbChildren : " << inode->nbHChildren();
1926 // for (Integer i = 0; i < inode->nbHChildren(); ++i) {
1927 // debug() << "\t\tNode Child uniqueId : " << inode->hChild(i).uniqueId() << " -- level : " << inode->hChild(i).level() << " -- nbChildren : " << inode->hChild(i).nbHChildren();
1928 // }
1929 // }
1930 //
1931 // info() << "Résumé :";
1932 // ENUMERATE_ (Face, iface, m_mesh->allFaces()) {
1933 // debug() << "\tFace uniqueId : " << iface->uniqueId() << " -- level : " << iface->level() << " -- nbChildren : " << iface->nbHChildren();
1934 // for (Integer i = 0; i < iface->nbHChildren(); ++i) {
1935 // debug() << "\t\tChild uniqueId : " << iface->hChild(i).uniqueId() << " -- level : " << iface->hChild(i).level() << " -- nbChildren : " << iface->hChild(i).nbHChildren();
1936 // }
1937 // }
1938}
1939
1940/*---------------------------------------------------------------------------*/
1941/*---------------------------------------------------------------------------*/
1942
1943void CartesianMeshAMRPatchMng::
1944coarse()
1945{
1946 IParallelMng* pm = m_mesh->parallelMng();
1947 Int32 nb_rank = pm->commSize();
1948 Int32 my_rank = pm->commRank();
1949
1950 UniqueArray<Int64> cell_uid_to_create;
1951
1952 // TODO : Remplacer around_parent_cells_uid_to_owner par parent_to_child_cells ?
1953 std::unordered_map<Int64, Int32> around_parent_cells_uid_to_owner;
1954 std::unordered_map<Int64, bool> around_parent_cells_uid_is_in_subdomain;
1955 std::unordered_map<Int64, UniqueArray<Cell>> parent_to_child_cells;
1956
1957 std::unordered_map<Int64, Int32> node_uid_to_owner;
1958 std::unordered_map<Int64, Int32> face_uid_to_owner;
1959
1960 // On va créer le niveau -1.
1961 // À noter qu'à la fin de la méthode, on replacera ce niveau
1962 // à 0.
1963 m_num_mng->prepareLevel(-1);
1964
1965 // On crée une ou plusieurs couches de mailles fantômes
1966 // pour éviter qu'une maille parente n'ai pas le même
1967 // nombre de mailles enfant.
1968 // ----------
1969 // CartesianMeshCoarsening2::_doDoubleGhostLayers()
1970 IMeshModifier* mesh_modifier = m_mesh->modifier();
1971 IGhostLayerMng* gm = m_mesh->ghostLayerMng();
1972 // Il faut au moins utiliser la version 3 pour pouvoir supporter
1973 // plusieurs couches de mailles fantômes
1974 Int32 version = gm->builderVersion();
1975 if (version < 3)
1976 gm->setBuilderVersion(3);
1977 Int32 nb_ghost_layer = gm->nbGhostLayer();
1978 gm->setNbGhostLayer(nb_ghost_layer + (nb_ghost_layer % m_num_mng->pattern()));
1979 mesh_modifier->setDynamic(true);
1980 mesh_modifier->updateGhostLayers();
1981 // Remet le nombre initial de couches de mailles fantômes
1982 gm->setNbGhostLayer(nb_ghost_layer);
1983 // CartesianMeshCoarsening2::_doDoubleGhostLayers()
1984 // ----------
1985
1986 // On récupère les uniqueIds des parents à créer.
1987 ENUMERATE_ (Cell, icell, m_mesh->allLevelCells(0)) {
1988 Cell cell = *icell;
1989
1990 Int64 parent_uid = m_num_mng->parentCellUniqueIdOfCell(cell);
1991
1992 // On évite les doublons.
1993 if (!cell_uid_to_create.contains(parent_uid)) {
1994 cell_uid_to_create.add(parent_uid);
1995 // On en profite pour sauvegarder les owners des futures mailles
1996 // qui seront les mêmes owners que les mailles enfants.
1997 around_parent_cells_uid_to_owner[parent_uid] = cell.owner();
1998 around_parent_cells_uid_is_in_subdomain[parent_uid] = true;
1999 }
2000 else {
2001 // Ça peut arriver si le partitionnement n'est pas adapté.
2002 if (around_parent_cells_uid_to_owner[parent_uid] != cell.owner()) {
2003 ARCANE_FATAL("Pb owner");
2004 }
2005 }
2006
2007 // On doit sauvegarder les enfants des parents pour créer les connectivités
2008 // à la fin.
2009 parent_to_child_cells[parent_uid].add(cell);
2010 }
2011
2012 // info() << cell_uid_to_create;
2013 // for (const auto& [key, value] : parent_to_child_cells) {
2014 // info() << "Parent : " << key << " -- Children : " << value;
2015 // }
2016
2017 UniqueArray<Int64> cells_infos;
2018 UniqueArray<Int64> faces_infos;
2019 UniqueArray<Int64> nodes_infos;
2020
2021 Integer total_nb_cells = 0;
2022 Integer total_nb_nodes = 0;
2023 Integer total_nb_faces = 0;
2024
2025 // Deux tableaux permettant de récupérer les uniqueIds des noeuds et des faces
2026 // de chaque maille parent à chaque appel à getNodeUids()/getFaceUids().
2027 UniqueArray<Int64> parent_nodes_uids(m_num_mng->nbNodeByCell());
2028 UniqueArray<Int64> parent_faces_uids(m_num_mng->nbFaceByCell());
2029
2030 // Partie échange d'informations sur les mailles autour du patch
2031 // (pour remplacer les mailles fantômes).
2032 {
2033 // Tableau qui contiendra les uids des mailles dont on a besoin des infos.
2034 UniqueArray<Int64> uid_of_cells_needed;
2035 {
2036 UniqueArray<Int64> cell_uids_around((m_mesh->dimension() == 2) ? 9 : 27);
2037 for (Int64 parent_cell : cell_uid_to_create) {
2038 m_num_mng->cellUniqueIdsAroundCell(cell_uids_around, parent_cell, -1);
2039 for (Int64 cell_uid : cell_uids_around) {
2040 // Si -1 alors il n'y a pas de mailles à cette position.
2041 if (cell_uid == -1)
2042 continue;
2043
2044 // TODO C++20 : Mettre map.contains().
2045 // SI on a la maille, on n'a pas besoin de demander d'infos.
2046 if (around_parent_cells_uid_to_owner.find(cell_uid) != around_parent_cells_uid_to_owner.end())
2047 continue;
2048
2049 // TODO : Bof
2050 if (!uid_of_cells_needed.contains(cell_uid)) {
2051 uid_of_cells_needed.add(cell_uid);
2052
2053 // Si on a besoin des infos, c'est que l'on ne les possèdent pas :-)
2054 // On en profite pour enregistrer cette information pour distinguer les
2055 // mailles fantômes dont on possède les items (faces/noeuds) de celle dont
2056 // on ne possède rien.
2057 around_parent_cells_uid_is_in_subdomain[cell_uid] = false;
2058 }
2059 }
2060 }
2061 }
2062
2063 // On partage les cell uid nécessaires de tout le monde.
2064 UniqueArray<Int64> uid_of_cells_needed_all_procs;
2065 pm->allGatherVariable(uid_of_cells_needed, uid_of_cells_needed_all_procs);
2066
2067 UniqueArray<Int32> owner_of_cells_needed_all_procs(uid_of_cells_needed_all_procs.size());
2068
2069 {
2070 // On enregistre le propriétaire des mailles que l'on possède.
2071 for (Integer i = 0; i < uid_of_cells_needed_all_procs.size(); ++i) {
2072 if (around_parent_cells_uid_to_owner.find(uid_of_cells_needed_all_procs[i]) != around_parent_cells_uid_to_owner.end()) {
2073 owner_of_cells_needed_all_procs[i] = around_parent_cells_uid_to_owner[uid_of_cells_needed_all_procs[i]];
2074 }
2075 else {
2076 // Le ReduceMax fera disparaitre ce -1.
2077 owner_of_cells_needed_all_procs[i] = -1;
2078 }
2079 }
2080 }
2081
2082 // On récupère les owners de toutes les mailles nécessaires.
2083 pm->reduce(Parallel::eReduceType::ReduceMax, owner_of_cells_needed_all_procs);
2084
2085 // On ne traite que les owners des mailles nécessaires pour nous.
2086 {
2087 Integer size_uid_of_cells_needed = uid_of_cells_needed.size();
2088 Integer my_pos_in_all_procs_arrays = 0;
2089 UniqueArray<Integer> size_uid_of_cells_needed_per_proc(nb_rank);
2090 ArrayView<Integer> av(1, &size_uid_of_cells_needed);
2091 pm->allGather(av, size_uid_of_cells_needed_per_proc);
2092
2093 // On zap les mailles de tous les procs avant nous.
2094 for (Integer i = 0; i < my_rank; ++i) {
2095 my_pos_in_all_procs_arrays += size_uid_of_cells_needed_per_proc[i];
2096 }
2097
2098 // On enregistre les owners nécessaires.
2099 ArrayView<Int32> owner_of_cells_needed = owner_of_cells_needed_all_procs.subView(my_pos_in_all_procs_arrays, size_uid_of_cells_needed);
2100 for (Integer i = 0; i < size_uid_of_cells_needed; ++i) {
2101 around_parent_cells_uid_to_owner[uid_of_cells_needed[i]] = owner_of_cells_needed[i];
2102
2103 // En rafinnement, il peut y avoir plusieurs niveaux d'écarts entre les patchs.
2104 // En déraffinement, c'est impossible vu que le niveau 0 n'a pas de "trous".
2105 if (owner_of_cells_needed[i] == -1) {
2106 ARCANE_FATAL("En déraffinement, c'est normalement impossible");
2107 }
2108 }
2109 }
2110 }
2111
2112 if (m_mesh->dimension() == 2) {
2113
2114 // Masques permettant de savoir si on doit créer une faces/noeuds (true)
2115 // ou si on doit regarder la maille d'à côté avant (false).
2116 // Rappel que le parcours des faces par Arcane est dans l'ordre NumPad{2, 6, 8, 4}.
2117 const bool mask_face_if_cell_left[] = { true, true, true, false };
2118 const bool mask_face_if_cell_bottom[] = { false, true, true, true };
2119
2120 // Rappel que le parcours des nodes par Arcane est dans l'ordre NumPad{1, 3, 9, 7}.
2121 const bool mask_node_if_cell_left[] = { false, true, true, false };
2122 const bool mask_node_if_cell_bottom[] = { false, false, true, true };
2123
2124 // Pour le raffinement, on parcourait les mailles parents existantes.
2125 // Ici, les mailles parents n'existent pas encore, donc on parcours les uid.
2126 for (Int64 parent_cell_uid : cell_uid_to_create) {
2127
2128 UniqueArray<Int64> cells_uid_around(9);
2129 m_num_mng->cellUniqueIdsAroundCell(cells_uid_around, parent_cell_uid, -1);
2130
2131 UniqueArray<Int32> owner_cells_around_parent_cell_1d(9);
2132 UniqueArray<bool> is_not_in_subdomain_cells_around_parent_cell_1d(9);
2133
2134 ConstArray2View owner_cells_around_parent_cell(owner_cells_around_parent_cell_1d.data(), 3, 3);
2135 // Attention au "not" dans le nom de la variable.
2136 ConstArray2View is_not_in_subdomain_cells_around_parent_cell(is_not_in_subdomain_cells_around_parent_cell_1d.data(), 3, 3);
2137
2138 for (Integer i = 0; i < 9; ++i) {
2139 Int64 uid_cell = cells_uid_around[i];
2140 // Si uid_cell != -1 alors il y a peut-être une maille (mais on ne sait pas si elle est bien présente).
2141 // Si around_parent_cells_uid_to_owner[uid_cell] != -1 alors il y a bien une maille.
2142 if (uid_cell != -1 && around_parent_cells_uid_to_owner[uid_cell] != -1) {
2143 owner_cells_around_parent_cell_1d[i] = around_parent_cells_uid_to_owner[uid_cell];
2144 is_not_in_subdomain_cells_around_parent_cell_1d[i] = !around_parent_cells_uid_is_in_subdomain[uid_cell];
2145 }
2146 else {
2147 cells_uid_around[i] = -1;
2148 owner_cells_around_parent_cell_1d[i] = -1;
2149 is_not_in_subdomain_cells_around_parent_cell_1d[i] = true;
2150 }
2151 }
2152
2153 // Ces deux lambdas sont différentes.
2154 // Quand une parent_cell n'existe pas, il y a -1 dans le tableau adéquat,
2155 // la première lambda répondra donc forcément true alors que la seconde false.
2156 auto is_cell_around_parent_cell_different_owner = [&](Integer y, Integer x) {
2157 return (owner_cells_around_parent_cell(y, x) != owner_cells_around_parent_cell(1, 1));
2158 };
2159
2160 auto is_cell_around_parent_cell_exist_and_different_owner = [&](Integer y, Integer x) {
2161 return (owner_cells_around_parent_cell(y, x) != -1 && (owner_cells_around_parent_cell(y, x) != owner_cells_around_parent_cell(1, 1)));
2162 };
2163
2164 total_nb_cells++;
2165 debug() << "Parent"
2166 << " -- x : " << m_num_mng->cellUniqueIdToCoordX(parent_cell_uid, -1)
2167 << " -- y : " << m_num_mng->cellUniqueIdToCoordY(parent_cell_uid, -1)
2168 << " -- level : " << -1
2169 << " -- uid : " << parent_cell_uid;
2170
2171 // On récupère les uniqueIds des nodes et faces à créer.
2172 m_num_mng->cellNodeUniqueIds(parent_nodes_uids, -1, parent_cell_uid);
2173 m_num_mng->cellFaceUniqueIds(parent_faces_uids, -1, parent_cell_uid);
2174
2175 const Integer type_cell = IT_Quad4;
2176 const Integer type_face = IT_Line2;
2177
2178 // Partie Cell.
2179 cells_infos.add(type_cell);
2180 cells_infos.add(parent_cell_uid);
2181 for (Integer nc = 0; nc < m_num_mng->nbNodeByCell(); nc++) {
2182 cells_infos.add(parent_nodes_uids[nc]);
2183 }
2184
2185 // Partie Face.
2186 for (Integer l = 0; l < m_num_mng->nbFaceByCell(); ++l) {
2187 Integer parent_face_owner = -1;
2188
2189 // On regarde si l'on doit traiter la face.
2190 // Si mask_face_if_cell_left[l] == false, on doit regarder si la maille à gauche est à nous ou non
2191 // ou si la maille à gauche est dans notre sous-domaine ou non.
2192 // Si cette maille n'est pas à nous et/ou n'est pas sur notre sous-domaine,
2193 // on doit créer la face en tant que face fantôme.
2194 if (
2195 (mask_face_if_cell_left[l] || is_cell_around_parent_cell_different_owner(1, 0) || is_not_in_subdomain_cells_around_parent_cell(1, 0)) &&
2196 (mask_face_if_cell_bottom[l] || is_cell_around_parent_cell_different_owner(0, 1) || is_not_in_subdomain_cells_around_parent_cell(0, 1))) {
2197 faces_infos.add(type_face);
2198 faces_infos.add(parent_faces_uids[l]);
2199
2200 // Les noeuds de la face sont toujours les noeuds l et l+1
2201 // car on utilise la même exploration pour les deux cas.
2202 for (Integer nc = l; nc < l + 2; nc++) {
2203 faces_infos.add(parent_nodes_uids[nc % m_num_mng->nbNodeByCell()]);
2204 }
2205 total_nb_faces++;
2206
2207 if ((!mask_face_if_cell_left[l]) && is_cell_around_parent_cell_exist_and_different_owner(1, 0)) {
2208 parent_face_owner = owner_cells_around_parent_cell(1, 0);
2209 }
2210 else if ((!mask_face_if_cell_bottom[l]) && is_cell_around_parent_cell_exist_and_different_owner(0, 1)) {
2211 parent_face_owner = owner_cells_around_parent_cell(0, 1);
2212 }
2213 else {
2214 parent_face_owner = owner_cells_around_parent_cell(1, 1);
2215 }
2216 face_uid_to_owner[parent_faces_uids[l]] = parent_face_owner;
2217 debug() << "Parent face (create face) -- parent_cell_uid : " << parent_cell_uid
2218 << " -- level : " << -1
2219 << " -- face : " << l
2220 << " -- uid_face : " << parent_faces_uids[l]
2221 << " -- owner : " << parent_face_owner;
2222 }
2223 }
2224
2225 // Partie Node.
2226 // Cette partie est assez ressemblante à la partie face, mis à part le fait qu'il peut y avoir
2227 // plus de propriétaires possibles.
2228 for (Integer l = 0; l < m_num_mng->nbNodeByCell(); ++l) {
2229 Integer parent_node_owner = -1;
2230 if (
2231 (mask_node_if_cell_left[l] || is_cell_around_parent_cell_different_owner(1, 0) || is_not_in_subdomain_cells_around_parent_cell(1, 0)) &&
2232 (mask_node_if_cell_bottom[l] || is_cell_around_parent_cell_different_owner(0, 1) || is_not_in_subdomain_cells_around_parent_cell(0, 1))) {
2233 nodes_infos.add(parent_nodes_uids[l]);
2234 total_nb_nodes++;
2235
2236 if ((!mask_node_if_cell_left[l])) {
2237 if ((!mask_node_if_cell_bottom[l])) {
2238 if (is_cell_around_parent_cell_exist_and_different_owner(0, 0)) {
2239 parent_node_owner = owner_cells_around_parent_cell(0, 0);
2240 }
2241 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 1)) {
2242 parent_node_owner = owner_cells_around_parent_cell(0, 1);
2243 }
2244 else if (is_cell_around_parent_cell_exist_and_different_owner(1, 0)) {
2245 parent_node_owner = owner_cells_around_parent_cell(1, 0);
2246 }
2247 else {
2248 parent_node_owner = owner_cells_around_parent_cell(1, 1);
2249 }
2250 }
2251 else {
2252 if (is_cell_around_parent_cell_exist_and_different_owner(1, 0)) {
2253 parent_node_owner = owner_cells_around_parent_cell(1, 0);
2254 }
2255 else {
2256 parent_node_owner = owner_cells_around_parent_cell(1, 1);
2257 }
2258 }
2259 }
2260 else {
2261 if ((!mask_node_if_cell_bottom[l])) {
2262 if (is_cell_around_parent_cell_exist_and_different_owner(0, 1)) {
2263 parent_node_owner = owner_cells_around_parent_cell(0, 1);
2264 }
2265 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 2)) {
2266 parent_node_owner = owner_cells_around_parent_cell(0, 2);
2267 }
2268 else {
2269 parent_node_owner = owner_cells_around_parent_cell(1, 1);
2270 }
2271 }
2272 else {
2273 parent_node_owner = owner_cells_around_parent_cell(1, 1);
2274 }
2275 }
2276
2277 node_uid_to_owner[parent_nodes_uids[l]] = parent_node_owner;
2278 debug() << "Parent node (create node) -- parent_cell_uid : " << parent_cell_uid
2279 << " -- level : " << -1
2280 << " -- node : " << l
2281 << " -- uid_node : " << parent_nodes_uids[l]
2282 << " -- owner : " << parent_node_owner;
2283 }
2284 }
2285 }
2286 }
2287 else if (m_mesh->dimension() == 3) {
2288
2289 // Masques permettant de savoir si on doit créer une faces/noeuds (true)
2290 // ou si on doit regarder la maille d'à côté avant (false).
2291 const bool mask_node_if_cell_left[] = { false, true, true, false, false, true, true, false };
2292 const bool mask_node_if_cell_bottom[] = { false, false, true, true, false, false, true, true };
2293 const bool mask_node_if_cell_rear[] = { false, false, false, false, true, true, true, true };
2294
2295 const bool mask_face_if_cell_left[] = { true, false, true, true, true, true };
2296 const bool mask_face_if_cell_bottom[] = { true, true, false, true, true, true };
2297 const bool mask_face_if_cell_rear[] = { false, true, true, true, true, true };
2298
2299 // Petite différence par rapport au 2D. Pour le 2D, la position des noeuds des faces
2300 // dans le tableau "parent_nodes_uids" est toujours pareil (l et l+1, voir le 2D).
2301 // Pour le 3D, ce n'est pas le cas donc on a des tableaux pour avoir une correspondance
2302 // entre les noeuds de chaque face et la position des noeuds dans le tableau "parent_nodes_uids".
2303 // (Exemple : pour la face 1 (même ordre d'énumération qu'Arcane), on doit prendre le
2304 // tableau "nodes_in_face_1" et donc les noeuds "parent_nodes_uids[0]", "parent_nodes_uids[3]",
2305 // "parent_nodes_uids[7]" et "parent_nodes_uids[4]").
2306 const Integer nodes_in_face_0[] = { 0, 1, 2, 3 };
2307 const Integer nodes_in_face_1[] = { 0, 3, 7, 4 };
2308 const Integer nodes_in_face_2[] = { 0, 1, 5, 4 };
2309 const Integer nodes_in_face_3[] = { 4, 5, 6, 7 };
2310 const Integer nodes_in_face_4[] = { 1, 2, 6, 5 };
2311 const Integer nodes_in_face_5[] = { 3, 2, 6, 7 };
2312
2313 const Integer nb_nodes_in_face = 4;
2314
2315 // Pour le raffinement, on parcourait les mailles parents existantes.
2316 // Ici, les mailles parents n'existent pas encore, donc on parcours les uid.
2317 for (Int64 parent_cell_uid : cell_uid_to_create) {
2318
2319 UniqueArray<Int64> cells_uid_around(27);
2320 m_num_mng->cellUniqueIdsAroundCell(cells_uid_around, parent_cell_uid, -1);
2321
2322 UniqueArray<Int32> owner_cells_around_parent_cell_1d(27);
2323 UniqueArray<bool> is_not_in_subdomain_cells_around_parent_cell_1d(27);
2324
2325 ConstArray3View owner_cells_around_parent_cell(owner_cells_around_parent_cell_1d.data(), 3, 3, 3);
2326 // Attention au "not" dans le nom de la variable.
2327 ConstArray3View is_not_in_subdomain_cells_around_parent_cell(is_not_in_subdomain_cells_around_parent_cell_1d.data(), 3, 3, 3);
2328
2329 for (Integer i = 0; i < 27; ++i) {
2330 Int64 uid_cell = cells_uid_around[i];
2331 // Si uid_cell != -1 alors il y a peut-être une maille (mais on ne sait pas si elle est bien présente).
2332 // Si around_parent_cells_uid_to_owner[uid_cell] != -1 alors il y a bien une maille.
2333 if (uid_cell != -1 && around_parent_cells_uid_to_owner[uid_cell] != -1) {
2334 owner_cells_around_parent_cell_1d[i] = around_parent_cells_uid_to_owner[uid_cell];
2335 is_not_in_subdomain_cells_around_parent_cell_1d[i] = !around_parent_cells_uid_is_in_subdomain[uid_cell];
2336 }
2337 else {
2338 cells_uid_around[i] = -1;
2339 owner_cells_around_parent_cell_1d[i] = -1;
2340 is_not_in_subdomain_cells_around_parent_cell_1d[i] = true;
2341 }
2342 }
2343
2344 // Ces deux lambdas sont différentes.
2345 // Quand une parent_cell n'existe pas, il y a -1 dans le tableau adéquat,
2346 // la première lambda répondra donc forcément true alors que la seconde false.
2347 auto is_cell_around_parent_cell_different_owner = [&](Integer z, Integer y, Integer x) {
2348 return (owner_cells_around_parent_cell(z, y, x) != owner_cells_around_parent_cell(1, 1, 1));
2349 };
2350
2351 auto is_cell_around_parent_cell_exist_and_different_owner = [&](Integer z, Integer y, Integer x) {
2352 return (owner_cells_around_parent_cell(z, y, x) != -1 && (owner_cells_around_parent_cell(z, y, x) != owner_cells_around_parent_cell(1, 1, 1)));
2353 };
2354
2355 total_nb_cells++;
2356 debug() << "Parent"
2357 << " -- x : " << m_num_mng->cellUniqueIdToCoordX(parent_cell_uid, -1)
2358 << " -- y : " << m_num_mng->cellUniqueIdToCoordY(parent_cell_uid, -1)
2359 << " -- z : " << m_num_mng->cellUniqueIdToCoordZ(parent_cell_uid, -1)
2360 << " -- level : " << -1
2361 << " -- uid : " << parent_cell_uid;
2362
2363 // On récupère les uniqueIds des nodes et faces à créer.
2364 m_num_mng->cellNodeUniqueIds(parent_nodes_uids, -1, parent_cell_uid);
2365 m_num_mng->cellFaceUniqueIds(parent_faces_uids, -1, parent_cell_uid);
2366
2367 const Integer type_cell = IT_Hexaedron8;
2368 const Integer type_face = IT_Quad4;
2369
2370 // Partie Cell.
2371 cells_infos.add(type_cell);
2372 cells_infos.add(parent_cell_uid);
2373 for (Integer nc = 0; nc < m_num_mng->nbNodeByCell(); nc++) {
2374 cells_infos.add(parent_nodes_uids[nc]);
2375 }
2376
2377 // Partie Face.
2378 for (Integer l = 0; l < m_num_mng->nbFaceByCell(); ++l) {
2379 Integer parent_face_owner = -1;
2380
2381 // On regarde si l'on doit traiter la face.
2382 // Si mask_face_if_cell_left[l] == false, on doit regarder si la maille à gauche est à nous ou non
2383 // ou si la maille à gauche est dans notre sous-domaine ou non.
2384 // Si cette maille n'est pas à nous et/ou n'est pas sur notre sous-domaine,
2385 // on doit créer la face en tant que face fantôme.
2386 if (
2387 (mask_face_if_cell_left[l] || is_cell_around_parent_cell_different_owner(1, 1, 0) || is_not_in_subdomain_cells_around_parent_cell(1, 1, 0)) &&
2388 (mask_face_if_cell_bottom[l] || is_cell_around_parent_cell_different_owner(1, 0, 1) || is_not_in_subdomain_cells_around_parent_cell(1, 0, 1)) &&
2389 (mask_face_if_cell_rear[l] || is_cell_around_parent_cell_different_owner(0, 1, 1) || is_not_in_subdomain_cells_around_parent_cell(0, 1, 1))) {
2390 faces_infos.add(type_face);
2391 faces_infos.add(parent_faces_uids[l]);
2392
2393 // On récupère la position des noeuds de la face dans le tableau "ua_node_uid".
2394 ConstArrayView<Integer> nodes_in_face_l;
2395 switch (l) {
2396 case 0:
2397 nodes_in_face_l = ConstArrayView<Integer>::create(nodes_in_face_0, nb_nodes_in_face);
2398 break;
2399 case 1:
2400 nodes_in_face_l = ConstArrayView<Integer>::create(nodes_in_face_1, nb_nodes_in_face);
2401 break;
2402 case 2:
2403 nodes_in_face_l = ConstArrayView<Integer>::create(nodes_in_face_2, nb_nodes_in_face);
2404 break;
2405 case 3:
2406 nodes_in_face_l = ConstArrayView<Integer>::create(nodes_in_face_3, nb_nodes_in_face);
2407 break;
2408 case 4:
2409 nodes_in_face_l = ConstArrayView<Integer>::create(nodes_in_face_4, nb_nodes_in_face);
2410 break;
2411 case 5:
2412 nodes_in_face_l = ConstArrayView<Integer>::create(nodes_in_face_5, nb_nodes_in_face);
2413 break;
2414 default:
2415 ARCANE_FATAL("Bizarre...");
2416 }
2417 for (Integer nc : nodes_in_face_l) {
2418 faces_infos.add(parent_nodes_uids[nc]);
2419 }
2420 total_nb_faces++;
2421
2422 if ((!mask_face_if_cell_left[l]) && is_cell_around_parent_cell_exist_and_different_owner(1, 1, 0)) {
2423 parent_face_owner = owner_cells_around_parent_cell(1, 1, 0);
2424 }
2425 else if ((!mask_face_if_cell_bottom[l]) && is_cell_around_parent_cell_exist_and_different_owner(1, 0, 1)) {
2426 parent_face_owner = owner_cells_around_parent_cell(1, 0, 1);
2427 }
2428 else if ((!mask_face_if_cell_rear[l]) && is_cell_around_parent_cell_exist_and_different_owner(0, 1, 1)) {
2429 parent_face_owner = owner_cells_around_parent_cell(0, 1, 1);
2430 }
2431 else {
2432 parent_face_owner = owner_cells_around_parent_cell(1, 1, 1);
2433 }
2434 face_uid_to_owner[parent_faces_uids[l]] = parent_face_owner;
2435 debug() << "Parent face (create face) -- parent_cell_uid : " << parent_cell_uid
2436 << " -- level : " << -1
2437 << " -- face : " << l
2438 << " -- uid_face : " << parent_faces_uids[l]
2439 << " -- owner : " << parent_face_owner;
2440 }
2441 }
2442
2443 // Partie Node.
2444 // Cette partie est assez ressemblante à la partie face, mis à part le fait qu'il peut y avoir
2445 // plus de propriétaires possibles.
2446 for (Integer l = 0; l < m_num_mng->nbNodeByCell(); ++l) {
2447 Integer parent_node_owner = -1;
2448 if (
2449 (mask_node_if_cell_left[l] || is_cell_around_parent_cell_different_owner(1, 1, 0) || is_not_in_subdomain_cells_around_parent_cell(1, 1, 0)) &&
2450 (mask_node_if_cell_bottom[l] || is_cell_around_parent_cell_different_owner(1, 0, 1) || is_not_in_subdomain_cells_around_parent_cell(1, 0, 1)) &&
2451 (mask_node_if_cell_rear[l] || is_cell_around_parent_cell_different_owner(0, 1, 1) || is_not_in_subdomain_cells_around_parent_cell(0, 1, 1))) {
2452 nodes_infos.add(parent_nodes_uids[l]);
2453 total_nb_nodes++;
2454
2455 if ((!mask_node_if_cell_left[l])) {
2456 if ((!mask_node_if_cell_bottom[l])) {
2457 if ((!mask_node_if_cell_rear[l])) {
2458
2459 if (is_cell_around_parent_cell_exist_and_different_owner(0, 0, 0)) {
2460 parent_node_owner = owner_cells_around_parent_cell(0, 0, 0);
2461 }
2462 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 0, 1)) {
2463 parent_node_owner = owner_cells_around_parent_cell(0, 0, 1);
2464 }
2465 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 1, 0)) {
2466 parent_node_owner = owner_cells_around_parent_cell(0, 1, 0);
2467 }
2468 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 1, 1)) {
2469 parent_node_owner = owner_cells_around_parent_cell(0, 1, 1);
2470 }
2471 else if (is_cell_around_parent_cell_exist_and_different_owner(1, 0, 0)) {
2472 parent_node_owner = owner_cells_around_parent_cell(1, 0, 0);
2473 }
2474 else if (is_cell_around_parent_cell_exist_and_different_owner(1, 0, 1)) {
2475 parent_node_owner = owner_cells_around_parent_cell(1, 0, 1);
2476 }
2477 else if (is_cell_around_parent_cell_exist_and_different_owner(1, 1, 0)) {
2478 parent_node_owner = owner_cells_around_parent_cell(1, 1, 0);
2479 }
2480 else {
2481 parent_node_owner = owner_cells_around_parent_cell(1, 1, 1);
2482 }
2483 }
2484 else {
2485 if (is_cell_around_parent_cell_exist_and_different_owner(1, 0, 0)) {
2486 parent_node_owner = owner_cells_around_parent_cell(1, 0, 0);
2487 }
2488 else if (is_cell_around_parent_cell_exist_and_different_owner(1, 0, 1)) {
2489 parent_node_owner = owner_cells_around_parent_cell(1, 0, 1);
2490 }
2491 else if (is_cell_around_parent_cell_exist_and_different_owner(1, 1, 0)) {
2492 parent_node_owner = owner_cells_around_parent_cell(1, 1, 0);
2493 }
2494 else {
2495 parent_node_owner = owner_cells_around_parent_cell(1, 1, 1);
2496 }
2497 }
2498 }
2499 else {
2500 if ((!mask_node_if_cell_rear[l])) {
2501 if (is_cell_around_parent_cell_exist_and_different_owner(0, 1, 0)) {
2502 parent_node_owner = owner_cells_around_parent_cell(0, 1, 0);
2503 }
2504 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 1, 1)) {
2505 parent_node_owner = owner_cells_around_parent_cell(0, 1, 1);
2506 }
2507 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 2, 0)) {
2508 parent_node_owner = owner_cells_around_parent_cell(0, 2, 0);
2509 }
2510 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 2, 1)) {
2511 parent_node_owner = owner_cells_around_parent_cell(0, 2, 1);
2512 }
2513 else if (is_cell_around_parent_cell_exist_and_different_owner(1, 1, 0)) {
2514 parent_node_owner = owner_cells_around_parent_cell(1, 1, 0);
2515 }
2516 else {
2517 parent_node_owner = owner_cells_around_parent_cell(1, 1, 1);
2518 }
2519 }
2520 else {
2521 if (is_cell_around_parent_cell_exist_and_different_owner(1, 1, 0)) {
2522 parent_node_owner = owner_cells_around_parent_cell(1, 1, 0);
2523 }
2524 else {
2525 parent_node_owner = owner_cells_around_parent_cell(1, 1, 1);
2526 }
2527 }
2528 }
2529 }
2530 else {
2531 if ((!mask_node_if_cell_bottom[l])) {
2532 if ((!mask_node_if_cell_rear[l])) {
2533 if (is_cell_around_parent_cell_exist_and_different_owner(0, 0, 1)) {
2534 parent_node_owner = owner_cells_around_parent_cell(0, 0, 1);
2535 }
2536 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 0, 2)) {
2537 parent_node_owner = owner_cells_around_parent_cell(0, 0, 2);
2538 }
2539 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 1, 1)) {
2540 parent_node_owner = owner_cells_around_parent_cell(0, 1, 1);
2541 }
2542 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 1, 2)) {
2543 parent_node_owner = owner_cells_around_parent_cell(0, 1, 2);
2544 }
2545 else if (is_cell_around_parent_cell_exist_and_different_owner(1, 0, 1)) {
2546 parent_node_owner = owner_cells_around_parent_cell(1, 0, 1);
2547 }
2548 else if (is_cell_around_parent_cell_exist_and_different_owner(1, 0, 2)) {
2549 parent_node_owner = owner_cells_around_parent_cell(1, 0, 2);
2550 }
2551 else {
2552 parent_node_owner = owner_cells_around_parent_cell(1, 1, 1);
2553 }
2554 }
2555 else {
2556 if (is_cell_around_parent_cell_exist_and_different_owner(1, 0, 1)) {
2557 parent_node_owner = owner_cells_around_parent_cell(1, 0, 1);
2558 }
2559 else if (is_cell_around_parent_cell_exist_and_different_owner(1, 0, 2)) {
2560 parent_node_owner = owner_cells_around_parent_cell(1, 0, 2);
2561 }
2562 else {
2563 parent_node_owner = owner_cells_around_parent_cell(1, 1, 1);
2564 }
2565 }
2566 }
2567 else {
2568 if ((!mask_node_if_cell_rear[l])) {
2569 if (is_cell_around_parent_cell_exist_and_different_owner(0, 1, 1)) {
2570 parent_node_owner = owner_cells_around_parent_cell(0, 1, 1);
2571 }
2572 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 1, 2)) {
2573 parent_node_owner = owner_cells_around_parent_cell(0, 1, 2);
2574 }
2575 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 2, 1)) {
2576 parent_node_owner = owner_cells_around_parent_cell(0, 2, 1);
2577 }
2578 else if (is_cell_around_parent_cell_exist_and_different_owner(0, 2, 2)) {
2579 parent_node_owner = owner_cells_around_parent_cell(0, 2, 2);
2580 }
2581 else {
2582 parent_node_owner = owner_cells_around_parent_cell(1, 1, 1);
2583 }
2584 }
2585 else {
2586 parent_node_owner = owner_cells_around_parent_cell(1, 1, 1);
2587 }
2588 }
2589 }
2590
2591 node_uid_to_owner[parent_nodes_uids[l]] = parent_node_owner;
2592 debug() << "Parent node (create node) -- parent_cell_uid : " << parent_cell_uid
2593 << " -- level : " << -1
2594 << " -- node : " << l
2595 << " -- uid_node : " << parent_nodes_uids[l]
2596 << " -- owner : " << parent_node_owner;
2597 }
2598 }
2599 }
2600 }
2601 else {
2602 ARCANE_FATAL("Bad dimension");
2603 }
2604
2605 // Nodes
2606 {
2607 debug() << "Nb new nodes in patch : " << total_nb_nodes;
2608 {
2609 // Ce tableau contiendra les localIds des nouveaux noeuds.
2610 UniqueArray<Int32> nodes_lid(total_nb_nodes);
2611
2612 // On crée les noeuds. On met les localIds des nouveaux noeuds au début du tableau.
2613 m_mesh->modifier()->addNodes(nodes_infos, nodes_lid);
2614
2615 UniqueArray<Int64> uid_child_nodes(total_nb_nodes);
2616 UniqueArray<Int32> lid_child_nodes(total_nb_nodes);
2617 Integer index = 0;
2618
2619 // On attribue les bons propriétaires aux noeuds.
2620 ENUMERATE_ (Node, inode, m_mesh->nodeFamily()->view(nodes_lid)) {
2621 Node node = *inode;
2622
2623 ARCANE_ASSERT((node_uid_to_owner.find(node.uniqueId()) != node_uid_to_owner.end()), ("No owner found for node"));
2624 ARCANE_ASSERT((node_uid_to_owner[node.uniqueId()] < nb_rank && node_uid_to_owner[node.uniqueId()] >= 0), ("Bad owner found for node"));
2625
2626 node.mutableItemBase().setOwner(node_uid_to_owner[node.uniqueId()], my_rank);
2627
2628 if (node_uid_to_owner[node.uniqueId()] == my_rank) {
2629 node.mutableItemBase().addFlags(ItemFlags::II_Own);
2630 }
2631
2632 uid_child_nodes[index++] = m_num_mng->childNodeUniqueIdOfNode(node.uniqueId(), -1);
2633 }
2634 m_mesh->nodeFamily()->itemsUniqueIdToLocalId(lid_child_nodes, uid_child_nodes, false);
2635 NodeInfoListView nodes(m_mesh->nodeFamily());
2636
2637 index = 0;
2638 ENUMERATE_ (Node, inode, m_mesh->nodeFamily()->view(nodes_lid)) {
2639 const Int32 child_lid = lid_child_nodes[index++];
2640 if (child_lid == NULL_ITEM_ID) {
2641 continue;
2642 }
2643
2644 Node child = nodes[child_lid];
2645 Node parent = *inode;
2646
2647 m_mesh->modifier()->addParentNodeToNode(child, parent);
2648 m_mesh->modifier()->addChildNodeToNode(parent, child);
2649 }
2650 }
2651
2652 m_mesh->nodeFamily()->notifyItemsOwnerChanged();
2653 }
2654
2655 // Faces
2656 {
2657 debug() << "Nb new faces in patch : " << total_nb_faces;
2658 {
2659 Integer nb_child = (m_mesh->dimension() == 2 ? 2 : 4);
2660 UniqueArray<Int32> faces_lid(total_nb_faces);
2661
2662 m_mesh->modifier()->addFaces(total_nb_faces, faces_infos, faces_lid);
2663
2664 UniqueArray<Int64> uid_child_faces(total_nb_faces * m_num_mng->nbFaceByCell());
2665 UniqueArray<Int32> lid_child_faces(total_nb_faces * m_num_mng->nbFaceByCell());
2666 Integer index = 0;
2667
2668 // On attribue les bons propriétaires aux faces.
2669 ENUMERATE_ (Face, iface, m_mesh->faceFamily()->view(faces_lid)) {
2670 Face face = *iface;
2671
2672 ARCANE_ASSERT((face_uid_to_owner.find(face.uniqueId()) != face_uid_to_owner.end()), ("No owner found for face"));
2673 ARCANE_ASSERT((face_uid_to_owner[face.uniqueId()] < nb_rank && face_uid_to_owner[face.uniqueId()] >= 0), ("Bad owner found for face"));
2674
2675 face.mutableItemBase().setOwner(face_uid_to_owner[face.uniqueId()], my_rank);
2676
2677 if (face_uid_to_owner[face.uniqueId()] == my_rank) {
2678 face.mutableItemBase().addFlags(ItemFlags::II_Own);
2679 }
2680
2681 for (Integer i = 0; i < nb_child; ++i) {
2682 uid_child_faces[index++] = m_num_mng->childFaceUniqueIdOfFace(face.uniqueId(), -1, i);
2683 }
2684 }
2685
2686 m_mesh->faceFamily()->itemsUniqueIdToLocalId(lid_child_faces, uid_child_faces, false);
2687 FaceInfoListView faces(m_mesh->faceFamily());
2688
2689 index = 0;
2690 ENUMERATE_ (Face, iface, m_mesh->faceFamily()->view(faces_lid)) {
2691 for (Integer i = 0; i < nb_child; ++i) {
2692 const Int32 child_lid = lid_child_faces[index++];
2693 if (child_lid == NULL_ITEM_ID) {
2694 continue;
2695 }
2696
2697 Face child = faces[child_lid];
2698 Face parent = *iface;
2699
2700 m_mesh->modifier()->addParentFaceToFace(child, parent);
2701 m_mesh->modifier()->addChildFaceToFace(parent, child);
2702 }
2703 }
2704 }
2705
2706 m_mesh->faceFamily()->notifyItemsOwnerChanged();
2707 }
2708
2709 // Cells
2710 UniqueArray<Int32> cells_lid(total_nb_cells);
2711 {
2712 debug() << "Nb new cells in patch : " << total_nb_cells;
2713
2714 m_mesh->modifier()->addCells(total_nb_cells, cells_infos, cells_lid);
2715
2716 // Itération sur les nouvelles mailles.
2717 CellInfoListView cells(m_mesh->cellFamily());
2718 for (Integer i = 0; i < total_nb_cells; ++i) {
2719 Cell parent = cells[cells_lid[i]];
2720
2721 parent.mutableItemBase().setOwner(around_parent_cells_uid_to_owner[parent.uniqueId()], my_rank);
2722
2723 parent.mutableItemBase().addFlags(ItemFlags::II_JustAdded);
2724 parent.mutableItemBase().addFlags(ItemFlags::II_JustCoarsened);
2725 parent.mutableItemBase().addFlags(ItemFlags::II_Inactive);
2726
2727 if (around_parent_cells_uid_to_owner[parent.uniqueId()] == my_rank) {
2728 parent.mutableItemBase().addFlags(ItemFlags::II_Own);
2729 }
2730 if (parent_to_child_cells[parent.uniqueId()][0].itemBase().flags() & ItemFlags::II_Shared) {
2731 parent.mutableItemBase().addFlags(ItemFlags::II_Shared);
2732 }
2733 for (Cell child : parent_to_child_cells[parent.uniqueId()]) {
2734 m_mesh->modifier()->addParentCellToCell(child, parent);
2735 m_mesh->modifier()->addChildCellToCell(parent, child);
2736 }
2737 }
2738 m_mesh->cellFamily()->notifyItemsOwnerChanged();
2739 }
2740
2741 m_mesh->modifier()->endUpdate();
2742 m_num_mng->updateFirstLevel();
2743
2744 // On positionne les noeuds dans l'espace.
2745 CellInfoListView cells(m_mesh->cellFamily());
2746 for (Integer i = 0; i < total_nb_cells; ++i) {
2747 Cell parent_cell = cells[cells_lid[i]];
2748 m_num_mng->setParentNodeCoordinates(parent_cell);
2749
2750 // On ajoute le flag "II_Shared" aux noeuds et aux faces des mailles partagées.
2751 if (parent_cell.mutableItemBase().flags() & ItemFlags::II_Shared) {
2752 for (Node node : parent_cell.nodes()) {
2753 if (node.mutableItemBase().flags() & ItemFlags::II_Own) {
2754 node.mutableItemBase().addFlags(ItemFlags::II_Shared);
2755 }
2756 }
2757 for (Face face : parent_cell.faces()) {
2758 if (face.mutableItemBase().flags() & ItemFlags::II_Own) {
2759 face.mutableItemBase().addFlags(ItemFlags::II_Shared);
2760 }
2761 }
2762 }
2763 }
2764
2765 //! Créé le patch avec les mailles filles
2766 {
2767 CellGroup parent_cells = m_mesh->allLevelCells(0);
2768 m_cmesh->_internalApi()->addPatchFromExistingChildren(parent_cells.view().localIds());
2769 }
2770
2771 // Recalcule les informations de synchronisation
2772 // Cela n'est pas nécessaire pour l'AMR car ces informations seront recalculées
2773 // lors du raffinement mais comme on ne sais pas si on va faire du raffinement
2774 // après il est préférable de calculer ces informations dans tous les cas.
2775 m_mesh->computeSynchronizeInfos();
2776
2777 // Il faut recalculer les nouvelles directions après les modifications
2778 // et l'ajout de patch.
2779 m_cmesh->computeDirections();
2780
2781 // ENUMERATE_(Cell, icell, m_mesh->allCells()){
2782 // debug() << "\t" << *icell;
2783 // for(Node node : icell->nodes()){
2784 // debug() << "\t\t" << node;
2785 // }
2786 // for(Face face : icell->faces()){
2787 // debug() << "\t\t\t" << face;
2788 // }
2789 // }
2790 // info() << "Résumé :";
2791 // ENUMERATE_ (Cell, icell, m_mesh->allCells()) {
2792 // debug() << "\tCell uniqueId : " << icell->uniqueId() << " -- level : " << icell->level() << " -- nbChildren : " << icell->nbHChildren();
2793 // for (Integer i = 0; i < icell->nbHChildren(); ++i) {
2794 // debug() << "\t\tChild uniqueId : " << icell->hChild(i).uniqueId() << " -- level : " << icell->hChild(i).level() << " -- nbChildren : " << icell->hChild(i).nbHChildren();
2795 // }
2796 // }
2797 // info() << "Résumé node:";
2798 // ENUMERATE_ (Node, inode, m_mesh->allNodes()) {
2799 // debug() << "\tNode uniqueId : " << inode->uniqueId() << " -- level : " << inode->level() << " -- nbChildren : " << inode->nbHChildren();
2800 // for (Integer i = 0; i < inode->nbHChildren(); ++i) {
2801 // debug() << "\t\tNode Child uniqueId : " << inode->hChild(i).uniqueId() << " -- level : " << inode->hChild(i).level() << " -- nbChildren : " << inode->hChild(i).nbHChildren();
2802 // }
2803 // }
2804 //
2805 // info() << "Résumé face:";
2806 // ENUMERATE_ (Face, iface, m_mesh->allFaces()) {
2807 // debug() << "\tFace uniqueId : " << iface->uniqueId() << " -- level : " << iface->level() << " -- nbChildren : " << iface->nbHChildren();
2808 // for (Integer i = 0; i < iface->nbHChildren(); ++i) {
2809 // debug() << "\t\tChild uniqueId : " << iface->hChild(i).uniqueId() << " -- level : " << iface->hChild(i).level() << " -- nbChildren : " << iface->hChild(i).nbHChildren();
2810 // }
2811 // }
2812}
2813
2814/*---------------------------------------------------------------------------*/
2815/*---------------------------------------------------------------------------*/
2816
2817} // End namespace Arcane
2818
2819/*---------------------------------------------------------------------------*/
2820/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
Vue sur les informations des mailles.
Maille d'un maillage.
Definition Item.h:1178
FaceConnectedListViewType faces() const
Liste des faces de la maille.
Definition Item.h:1258
Cell hChild(Int32 i) const
i-ème enfant AMR
Definition Item.h:1296
Int32 level() const
Definition Item.h:1328
Vue sur les informations des faces.
Face d'une maille.
Definition Item.h:932
virtual void setBuilderVersion(Integer n)=0
Positionne la version du constructeur de mailles fantômes. Pour l'instant (version 3....
virtual Integer nbGhostLayer() const =0
Nombre de couches fantômes.
virtual Integer builderVersion() const =0
Version du constructeur de mailles fantômes.
virtual void setNbGhostLayer(Integer n)=0
Positionne le nombre de couches fantômes.
Interface de modification du maillage.
virtual void updateGhostLayers()=0
Mise à jour de la couche fantôme.
virtual void setDynamic(bool v)=0
Positionne la propriété indiquant si le maillage peut évoluer.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual void allGatherVariable(ConstArrayView< char > send_buf, Array< char > &recv_buf)=0
Effectue un regroupement sur tous les processeurs.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual void allGather(ConstArrayView< char > send_buf, ArrayView< char > recv_buf)=0
Effectue un regroupement sur tous les processeurs. Il s'agit d'une opération collective....
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
Int32 flags() const
Flags de l'entité
ItemVectorView view() const
Vue sur les entités du groupe.
Definition ItemGroup.cc:582
ItemGroupImplInternal * _internalApi() const
API interne à Arcane.
Definition ItemGroup.cc:645
Vue sur une liste pour obtenir des informations sur les entités.
Int32ConstArrayView localIds() const
Tableau des numéros locaux des entités.
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Definition Item.h:771
Classe de base d'un élément de maillage.
Definition Item.h:83
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
Definition Item.h:365
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
Definition Item.h:229
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:216
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:354
void setOwner(Integer suid, Int32 current_sub_domain)
Positionne le numéro du sous-domaine propriétaire de l'entité.
void setFlags(Int32 f)
Positionne les flags de l'entité
void addFlags(Int32 added_flags)
Ajoute les flags \added_flags à ceux de l'entité
void removeFlags(Int32 removed_flags)
Supprime les flags \added_flags de ceux de l'entité
Vue sur les informations des noeuds.
Noeud d'un maillage.
Definition Dom.h:204
Paramètres nécessaires à la construction d'une variable.
Classe gérant un vecteur de dimension 2 de type T.
Definition Vector2.h:36
bool contains(ConstReferenceType v) const
Vrai si le tableau contient l'élément de valeur v.
Integer size() const
Nombre d'éléments du vecteur.
Vue modifiable d'un tableau d'un type T.
const T * data() const
Accès à la racine du tableau hors toute protection.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
ArrayView< T > subView(Int64 abegin, Integer asize)
Sous-vue à partir de l'élément abegin et contenant asize éléments.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Vue constante d'un tableau de type T.
Vecteur 1D de données avec sémantique par valeur (style STL).
MeshVariableScalarRefT< Cell, Integer > VariableCellInteger
Grandeur au centre des mailles de type entier.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Espace de nom de Arccore.
Definition ArcaneTypes.h:24