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