Arcane  v3.16.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
CartesianMeshNumberingMng.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/* CartesianMeshNumberingMng.cc (C) 2000-2025 */
9/* */
10/* Gestionnaire de numérotation de maillage cartesian. La numérotation */
11/* utilisée ici est la même que celle utilisée dans la renumérotation V2. */
12/*---------------------------------------------------------------------------*/
13/*---------------------------------------------------------------------------*/
14
15#include "CartesianMeshNumberingMng.h"
16
17#include "arcane/utils/Vector2.h"
18
19#include "arcane/core/IMesh.h"
20#include "arcane/core/IParallelMng.h"
21#include "arcane/core/VariableTypes.h"
22#include "arcane/core/ICartesianMeshGenerationInfo.h"
23
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27namespace Arcane
28{
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33CartesianMeshNumberingMng::
34CartesianMeshNumberingMng(IMesh* mesh)
35: TraceAccessor(mesh->traceMng())
36, m_mesh(mesh)
37, m_dimension(mesh->dimension())
38, m_pattern(2)
39, m_max_level(0)
40, m_min_level(0)
41, m_converting_numbering_face(true)
42, m_ori_level(0)
43{
44 const auto* m_generation_info = ICartesianMeshGenerationInfo::getReference(m_mesh, true);
45
46 Int64ConstArrayView global_nb_cells_by_direction = m_generation_info->globalNbCells();
47 m_nb_cell.x = global_nb_cells_by_direction[MD_DirX];
48 m_nb_cell.y = global_nb_cells_by_direction[MD_DirY];
49 m_nb_cell.z = ((m_dimension == 2) ? 1 : global_nb_cells_by_direction[MD_DirZ]);
50
51 if (m_nb_cell.x <= 0)
52 ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirX] (should be >0)", m_nb_cell.x);
53 if (m_nb_cell.y <= 0)
54 ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirY] (should be >0)", m_nb_cell.y);
55 if (m_nb_cell.z <= 0)
56 ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirZ] (should be >0)", m_nb_cell.z);
57
58 m_p_to_l_level.add(0);
59
60 if (m_dimension == 2) {
61 m_latest_cell_uid = m_nb_cell.x * m_nb_cell.y;
62 m_latest_node_uid = (m_nb_cell.x + 1) * (m_nb_cell.y + 1);
63 m_latest_face_uid = (m_nb_cell.x * m_nb_cell.y) * 2 + m_nb_cell.x * 2 + m_nb_cell.y;
64 }
65 else {
66 m_latest_cell_uid = m_nb_cell.x * m_nb_cell.y * m_nb_cell.z;
67 m_latest_node_uid = (m_nb_cell.x + 1) * (m_nb_cell.y + 1) * (m_nb_cell.z + 1);
68 m_latest_face_uid = (m_nb_cell.z + 1) * m_nb_cell.x * m_nb_cell.y + (m_nb_cell.x + 1) * m_nb_cell.y * m_nb_cell.z + (m_nb_cell.y + 1) * m_nb_cell.z * m_nb_cell.x;
69 }
70
71 m_first_cell_uid_level.add(0);
72 m_first_node_uid_level.add(0);
73 m_first_face_uid_level.add(0);
74
75 // Tant qu'on utilise la numérotation d'origine pour le niveau 0, on doit utiliser
76 // une conversion de la numérotation d'origine vers la nouvelle.
77 // TODO AH : Ça risque de pas très bien se passer en cas de repartitionnement...
78 if (m_converting_numbering_face) {
79 UniqueArray<Int64> face_uid(CartesianMeshNumberingMng::nbFaceByCell());
80 ENUMERATE_ (Cell, icell, m_mesh->allLevelCells(0)) {
81 CartesianMeshNumberingMng::cellFaceUniqueIds(face_uid, 0, icell->uniqueId());
82 for (Integer i = 0; i < CartesianMeshNumberingMng::nbFaceByCell(); ++i) {
83 m_face_ori_numbering_to_new[icell->face(i).uniqueId()] = face_uid[i];
84 m_face_new_numbering_to_ori[face_uid[i]] = icell->face(i).uniqueId();
85 // debug() << "Face Ori <-> New -- Ori : " << icell->face(i).uniqueId() << " -- New : " << face_uid[i];
86 }
87 }
88 }
89}
90
91/*---------------------------------------------------------------------------*/
92/*---------------------------------------------------------------------------*/
93
94void CartesianMeshNumberingMng::
95prepareLevel(Int32 level)
96{
97 if (level <= m_max_level && level >= m_min_level)
98 return;
99 if (level == m_max_level + 1) {
100 m_max_level++;
101 }
102 else if (level == m_min_level - 1) {
103 m_min_level--;
104 }
105 else {
106 ARCANE_FATAL("Level error : {0}", level);
107 }
108 m_p_to_l_level.add(level);
109
110 m_first_cell_uid_level.add(m_latest_cell_uid);
111 m_first_node_uid_level.add(m_latest_node_uid);
112 m_first_face_uid_level.add(m_latest_face_uid);
113
114 m_latest_cell_uid += nbCellInLevel(level);
115 m_latest_node_uid += nbNodeInLevel(level);
116 m_latest_face_uid += nbFaceInLevel(level);
117}
118
119/*---------------------------------------------------------------------------*/
120/*---------------------------------------------------------------------------*/
121
122void CartesianMeshNumberingMng::
123updateFirstLevel()
124{
125 Int32 nb_levels_to_add = -m_min_level;
126 m_ori_level += nb_levels_to_add;
127
128 if (nb_levels_to_add == 0) {
129 return;
130 }
131
132 m_max_level += nb_levels_to_add;
133 m_min_level += nb_levels_to_add;
134
135 for (Int32& i : m_p_to_l_level) {
136 i += nb_levels_to_add;
137 }
138
139 m_nb_cell /= (m_pattern * nb_levels_to_add);
140
141 // ----------
142 // CartesianMeshCoarsening2::_recomputeMeshGenerationInfo()
143 // Recalcule les informations sur le nombre de mailles par direction.
144 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh, false);
145 if (!cmgi)
146 return;
147
148 {
149 ConstArrayView<Int64> v = cmgi->ownCellOffsets();
150 cmgi->setOwnCellOffsets(v[0] / m_pattern, v[1] / m_pattern, v[2] / m_pattern);
151 }
152 {
153 ConstArrayView<Int64> v = cmgi->globalNbCells();
154 cmgi->setGlobalNbCells(v[0] / m_pattern, v[1] / m_pattern, v[2] / m_pattern);
155 }
156 {
157 ConstArrayView<Int32> v = cmgi->ownNbCells();
158 cmgi->setOwnNbCells(v[0] / m_pattern, v[1] / m_pattern, v[2] / m_pattern);
159 }
160 cmgi->setFirstOwnCellUniqueId(firstCellUniqueId(0));
161 // CartesianMeshCoarsening2::_recomputeMeshGenerationInfo()
162 // ----------
163}
164
165/*---------------------------------------------------------------------------*/
166/*---------------------------------------------------------------------------*/
167
168Int64 CartesianMeshNumberingMng::
169firstCellUniqueId(Integer level)
170{
171 auto pos = m_p_to_l_level.span().findFirst(level);
172 if (pos.has_value()) {
173 return m_first_cell_uid_level[pos.value()];
174 }
175 else {
176 ARCANE_FATAL("Bad level : {0}", level);
177 }
178}
179
180/*---------------------------------------------------------------------------*/
181/*---------------------------------------------------------------------------*/
182
183Int64 CartesianMeshNumberingMng::
184firstNodeUniqueId(Integer level)
185{
186 auto pos = m_p_to_l_level.span().findFirst(level);
187 if (pos.has_value()) {
188 return m_first_node_uid_level[pos.value()];
189 }
190 else {
191 ARCANE_FATAL("Bad level : {0}", level);
192 }
193}
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
197
198Int64 CartesianMeshNumberingMng::
199firstFaceUniqueId(Integer level)
200{
201 auto pos = m_p_to_l_level.span().findFirst(level);
202 if (pos.has_value()) {
203 return m_first_face_uid_level[pos.value()];
204 }
205 else {
206 ARCANE_FATAL("Bad level : {0}", level);
207 }
208}
209
210/*---------------------------------------------------------------------------*/
211/*---------------------------------------------------------------------------*/
212
213Int64 CartesianMeshNumberingMng::
214globalNbCellsX(Integer level) const
215{
216 return static_cast<Int64>(static_cast<Real>(m_nb_cell.x) * std::pow(m_pattern, level));
217}
218
219/*---------------------------------------------------------------------------*/
220/*---------------------------------------------------------------------------*/
221
222Int64 CartesianMeshNumberingMng::
223globalNbCellsY(Integer level) const
224{
225 return static_cast<Int64>(static_cast<Real>(m_nb_cell.y) * std::pow(m_pattern, level));
226}
227
228/*---------------------------------------------------------------------------*/
229/*---------------------------------------------------------------------------*/
230
231Int64 CartesianMeshNumberingMng::
232globalNbCellsZ(Integer level) const
233{
234 return static_cast<Int64>(static_cast<Real>(m_nb_cell.z) * std::pow(m_pattern, level));
235}
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
239
240Int64 CartesianMeshNumberingMng::
241globalNbNodesX(Integer level) const
242{
243 return globalNbCellsX(level) + 1;
244}
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
248
249Int64 CartesianMeshNumberingMng::
250globalNbNodesY(Integer level) const
251{
252 return globalNbCellsY(level) + 1;
253}
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257
258Int64 CartesianMeshNumberingMng::
259globalNbNodesZ(Integer level) const
260{
261 return globalNbCellsZ(level) + 1;
262}
263
264/*---------------------------------------------------------------------------*/
265/*---------------------------------------------------------------------------*/
266
267Int64 CartesianMeshNumberingMng::
268globalNbFacesX(Integer level) const
269{
270 return globalNbCellsX(level) + 1;
271}
272
273/*---------------------------------------------------------------------------*/
274/*---------------------------------------------------------------------------*/
275
276Int64 CartesianMeshNumberingMng::
277globalNbFacesY(Integer level) const
278{
279 return globalNbCellsY(level) + 1;
280}
281
282/*---------------------------------------------------------------------------*/
283/*---------------------------------------------------------------------------*/
284
285Int64 CartesianMeshNumberingMng::
286globalNbFacesZ(Integer level) const
287{
288 return globalNbCellsZ(level) + 1;
289}
290
291/*---------------------------------------------------------------------------*/
292/*---------------------------------------------------------------------------*/
293
294Int64 CartesianMeshNumberingMng::
295globalNbFacesXCartesianView(Integer level) const
296{
297 return (globalNbCellsX(level) * 2) + 1;
298}
299
300/*---------------------------------------------------------------------------*/
301/*---------------------------------------------------------------------------*/
302
303Int64 CartesianMeshNumberingMng::
304globalNbFacesYCartesianView(Integer level) const
305{
306 return (globalNbCellsY(level) * 2) + 1;
307}
308
309/*---------------------------------------------------------------------------*/
310/*---------------------------------------------------------------------------*/
311
312Int64 CartesianMeshNumberingMng::
313globalNbFacesZCartesianView(Integer level) const
314{
315 return (globalNbCellsZ(level) * 2) + 1;
316}
317
318/*---------------------------------------------------------------------------*/
319/*---------------------------------------------------------------------------*/
320
321Int64 CartesianMeshNumberingMng::
322nbCellInLevel(Integer level) const
323{
324 if (m_dimension == 2) {
325 const Int64x2 nb_cell(globalNbCellsX(level), globalNbCellsY(level));
326 return nb_cell.x * nb_cell.y;
327 }
328
329 const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level));
330 return nb_cell.x * nb_cell.y * nb_cell.z;
331}
332
333/*---------------------------------------------------------------------------*/
334/*---------------------------------------------------------------------------*/
335
336Int64 CartesianMeshNumberingMng::
337nbNodeInLevel(Integer level) const
338{
339 if (m_dimension == 2) {
340 const Int64x2 nb_cell(globalNbCellsX(level), globalNbCellsY(level));
341 return (nb_cell.x + 1) * (nb_cell.y + 1);
342 }
343
344 const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level));
345 return (nb_cell.x + 1) * (nb_cell.y + 1) * (nb_cell.z + 1);
346}
347
348/*---------------------------------------------------------------------------*/
349/*---------------------------------------------------------------------------*/
350
351Int64 CartesianMeshNumberingMng::
352nbFaceInLevel(Integer level) const
353{
354 if (m_dimension == 2) {
355 const Int64x2 nb_cell(globalNbCellsX(level), globalNbCellsY(level));
356 return (nb_cell.x * nb_cell.y) * 2 + nb_cell.x * 2 + nb_cell.y;
357 }
358
359 const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level));
360 return (nb_cell.z + 1) * nb_cell.x * nb_cell.y + (nb_cell.x + 1) * nb_cell.y * nb_cell.z + (nb_cell.y + 1) * nb_cell.z * nb_cell.x;
361}
362
363/*---------------------------------------------------------------------------*/
364/*---------------------------------------------------------------------------*/
365
366Integer CartesianMeshNumberingMng::
367pattern() const
368{
369 return m_pattern;
370}
371
372/*---------------------------------------------------------------------------*/
373/*---------------------------------------------------------------------------*/
374
375Int32 CartesianMeshNumberingMng::
376cellLevel(Int64 uid) const
377{
378 Integer pos = 0;
379
380 while (pos < m_first_cell_uid_level.size() && m_first_cell_uid_level[pos] <= uid) {
381 pos++;
382 }
383 pos--;
384
385 return m_p_to_l_level[pos];
386}
387
388/*---------------------------------------------------------------------------*/
389/*---------------------------------------------------------------------------*/
390
391Int32 CartesianMeshNumberingMng::
392nodeLevel(Int64 uid) const
393{
394 Integer pos = 0;
395
396 while (pos < m_first_node_uid_level.size() && m_first_node_uid_level[pos] <= uid) {
397 pos++;
398 }
399 pos--;
400
401 return m_p_to_l_level[pos];
402}
403
404/*---------------------------------------------------------------------------*/
405/*---------------------------------------------------------------------------*/
406
407Int32 CartesianMeshNumberingMng::
408faceLevel(Int64 uid) const
409{
410 Integer pos = 0;
411
412 while (pos < m_first_face_uid_level.size() && m_first_face_uid_level[pos] <= uid) {
413 pos++;
414 }
415 pos--;
416
417 return m_p_to_l_level[pos];
418}
419
420/*---------------------------------------------------------------------------*/
421/*---------------------------------------------------------------------------*/
422
423// Tant que l'on a un unique "pattern" pour x, y, z, pas besoin de trois méthodes.
424Int64 CartesianMeshNumberingMng::
425offsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const
426{
427 if (level_from == level_to) {
428 return coord;
429 }
430 else if (level_from < level_to) {
431 return coord * m_pattern * (level_to - level_from);
432 }
433 else {
434 return coord / (m_pattern * (level_from - level_to));
435 }
436}
437
438/*---------------------------------------------------------------------------*/
439/*---------------------------------------------------------------------------*/
440
441// Tant que l'on a un unique "pattern" pour x, y, z, pas besoin de trois méthodes.
442Int64 CartesianMeshNumberingMng::
443faceOffsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const
444{
445 // Admettons que l'on ai les faces suivantes :
446 // ┌─0──┬──2─┐
447 // 4│ 6│ 8│
448 // ├─5──┼─7──┤
449 // 9│ 11│ 13│
450 // └─10─┴─12─┘
451
452 // Pour la position d'une face, on considère cette disposition :
453 // ┌──┬──┬──┬──┬──┐
454 // │ │ 0│ │ 2│ │
455 // ├──┼──┼──┼──┼──┤
456 // │ 4│ │ 6│ │ 8│
457 // ├──┼──┼──┼──┼──┤
458 // │ │ 5│ │ 7│ │
459 // ├──┼──┼──┼──┼──┤
460 // │ 9│ │11│ │13│
461 // ├──┼──┼──┼──┼──┤
462 // │ │10│ │12│ │
463 // └──┴──┴──┴──┴──┘
464
465 if (level_from == level_to) {
466 return coord;
467 }
468 else if (level_from < level_to) {
469 const Integer pattern = m_pattern * (level_to - level_from);
470 if (coord % 2 == 0) {
471 return coord * pattern;
472 }
473 else {
474 return ((coord - 1) * pattern) + 1;
475 }
476 }
477 else {
478 const Integer pattern = m_pattern * (level_from - level_to);
479 if (coord % 2 == 0) {
480 if (coord % (pattern * 2) == 0) {
481 return coord / pattern;
482 }
483 else {
484 return -1;
485 }
486 }
487 else {
488 // auto a = coord - 1;
489 // auto b = a % (pattern * 2);
490 // auto c = a / (pattern * 2);
491 // auto d = c * (2 * (pattern - 1));
492 // auto e = d + b;
493 // auto f = coord - e;
494 // return f;
495
496 return coord - ((Int64((coord - 1) / (pattern * 2)) * (2 * (pattern - 1))) + ((coord - 1) % (pattern * 2)));
497 }
498 }
499}
500
501/*---------------------------------------------------------------------------*/
502/*---------------------------------------------------------------------------*/
503
504Int64 CartesianMeshNumberingMng::
505cellUniqueIdToCoordX(Int64 uid, Integer level)
506{
507 const Int64 nb_cell_x = globalNbCellsX(level);
508 const Int64 nb_cell_y = globalNbCellsY(level);
509 const Int64 first_cell_uid = firstCellUniqueId(level);
510
511 uid -= first_cell_uid;
512
513 const Int64 to2d = uid % (nb_cell_x * nb_cell_y);
514 return to2d % nb_cell_x;
515}
516
517/*---------------------------------------------------------------------------*/
518/*---------------------------------------------------------------------------*/
519
520Int64 CartesianMeshNumberingMng::
521cellUniqueIdToCoordX(Cell cell)
522{
523 return cellUniqueIdToCoordX(cell.uniqueId(), cell.level());
524}
525
526/*---------------------------------------------------------------------------*/
527/*---------------------------------------------------------------------------*/
528
529Int64 CartesianMeshNumberingMng::
530cellUniqueIdToCoordY(Int64 uid, Integer level)
531{
532 const Int64 nb_cell_x = globalNbCellsX(level);
533 const Int64 nb_cell_y = globalNbCellsY(level);
534 const Int64 first_cell_uid = firstCellUniqueId(level);
535
536 uid -= first_cell_uid;
537
538 const Int64 to2d = uid % (nb_cell_x * nb_cell_y);
539 return to2d / nb_cell_x;
540}
541
542/*---------------------------------------------------------------------------*/
543/*---------------------------------------------------------------------------*/
544
545Int64 CartesianMeshNumberingMng::
546cellUniqueIdToCoordY(Cell cell)
547{
548 return cellUniqueIdToCoordY(cell.uniqueId(), cell.level());
549}
550
551/*---------------------------------------------------------------------------*/
552/*---------------------------------------------------------------------------*/
553
554Int64 CartesianMeshNumberingMng::
555cellUniqueIdToCoordZ(Int64 uid, Integer level)
556{
557 const Int64 nb_cell_x = globalNbCellsX(level);
558 const Int64 nb_cell_y = globalNbCellsY(level);
559 const Int64 first_cell_uid = firstCellUniqueId(level);
560
561 uid -= first_cell_uid;
562
563 return uid / (nb_cell_x * nb_cell_y);
564}
565
566/*---------------------------------------------------------------------------*/
567/*---------------------------------------------------------------------------*/
568
569Int64 CartesianMeshNumberingMng::
570cellUniqueIdToCoordZ(Cell cell)
571{
572 return cellUniqueIdToCoordZ(cell.uniqueId(), cell.level());
573}
574
575/*---------------------------------------------------------------------------*/
576/*---------------------------------------------------------------------------*/
577
578Int64 CartesianMeshNumberingMng::
579nodeUniqueIdToCoordX(Int64 uid, Integer level)
580{
581 const Int64 nb_node_x = globalNbNodesX(level);
582 const Int64 nb_node_y = globalNbNodesY(level);
583 const Int64 first_node_uid = firstNodeUniqueId(level);
584
585 uid -= first_node_uid;
586
587 const Int64 to2d = uid % (nb_node_x * nb_node_y);
588 return to2d % nb_node_x;
589}
590
591/*---------------------------------------------------------------------------*/
592/*---------------------------------------------------------------------------*/
593
594Int64 CartesianMeshNumberingMng::
595nodeUniqueIdToCoordX(Node node)
596{
597 const Int64 uid = node.uniqueId();
598 return nodeUniqueIdToCoordX(uid, nodeLevel(uid));
599}
600
601/*---------------------------------------------------------------------------*/
602/*---------------------------------------------------------------------------*/
603
604Int64 CartesianMeshNumberingMng::
605nodeUniqueIdToCoordY(Int64 uid, Integer level)
606{
607 const Int64 nb_node_x = globalNbNodesX(level);
608 const Int64 nb_node_y = globalNbNodesY(level);
609 const Int64 first_node_uid = firstNodeUniqueId(level);
610
611 uid -= first_node_uid;
612
613 const Int64 to2d = uid % (nb_node_x * nb_node_y);
614 return to2d / nb_node_x;
615}
616
617/*---------------------------------------------------------------------------*/
618/*---------------------------------------------------------------------------*/
619
620Int64 CartesianMeshNumberingMng::
621nodeUniqueIdToCoordY(Node node)
622{
623 const Int64 uid = node.uniqueId();
624 return nodeUniqueIdToCoordY(uid, nodeLevel(uid));
625}
626
627/*---------------------------------------------------------------------------*/
628/*---------------------------------------------------------------------------*/
629
630Int64 CartesianMeshNumberingMng::
631nodeUniqueIdToCoordZ(Int64 uid, Integer level)
632{
633 const Int64 nb_node_x = globalNbNodesX(level);
634 const Int64 nb_node_y = globalNbNodesY(level);
635 const Int64 first_node_uid = firstNodeUniqueId(level);
636
637 uid -= first_node_uid;
638
639 return uid / (nb_node_x * nb_node_y);
640}
641
642/*---------------------------------------------------------------------------*/
643/*---------------------------------------------------------------------------*/
644
645Int64 CartesianMeshNumberingMng::
646nodeUniqueIdToCoordZ(Node node)
647{
648 const Int64 uid = node.uniqueId();
649 return nodeUniqueIdToCoordZ(uid, nodeLevel(uid));
650}
651
652/*---------------------------------------------------------------------------*/
653/*---------------------------------------------------------------------------*/
654
655Int64 CartesianMeshNumberingMng::
656faceUniqueIdToCoordX(Int64 uid, Integer level)
657{
658 if (m_dimension == 2) {
659
660 const Int64 nb_face_x = globalNbFacesXCartesianView(level);
661 const Int64 first_face_uid = firstFaceUniqueId(level);
662
663 uid -= first_face_uid;
664 uid += 1;
665
666 // Le +1 nous permet d'avoir le niveau (imaginaire) -1 commençant à 0 :
667 //
668 // x = 0 1 2 3 4
669 // ┌──┬──┬──┬──┬──┐
670 // y = -1 │ 0│ │ 2│ │ 4│
671 // ┌──┬──┬──┬──┬──┐
672 // y = 0 │ │ 1│ │ 3│ │
673 // ├──┼──┼──┼──┼──┤
674 // y = 1 │ 5│ │ 7│ │ 9│
675 // ├──┼──┼──┼──┼──┤
676 // y = 2 │ │ 6│ │ 8│ │
677 // ├──┼──┼──┼──┼──┤
678 // y = 3 │10│ │12│ │14│
679 // ├──┼──┼──┼──┼──┤
680 // y = 4 │ │11│ │13│ │
681 // └──┴──┴──┴──┴──┘
682 //
683 // Si on fait "tomber" les faces (tetris), on obtient une numérotation
684 // cartésienne classique.
685
686 return uid % nb_face_x;
687 }
688 else {
689 const Int64 nb_face_x = globalNbFacesX(level);
690 const Int64 nb_cell_x = globalNbCellsX(level);
691 const Int64 first_face_uid = firstFaceUniqueId(level);
692
693 // Int64 initial_uid = uid;
694
695 uid -= first_face_uid;
696
697 Int64x3 three_parts_numbering = face3DNumberingThreeParts(level);
698
699 // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 :
700 // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4
701 // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4
702 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐
703 // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │
704 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
705 // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │
706 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
707 // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │
708 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
709 // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │
710 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
711 // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │
712 // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘
713 // │ │ │ │
714 //
715 // On peut remarquer 3 "sortes de disposition" : les faces ayant les uid [0, 11],
716 // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35].
717 // On récupère ces intervalles avec la méthode face3DNumberingThreeParts().
718
719 // Pour l'intervalle [0, 11], on remarque que l'origine en X est toujours 1 et que les mailles
720 // contenant une face sont sur les X impairs.
721 // Enfin, on a "nb_cell_x" faces en X.
722 if (uid < three_parts_numbering.x) {
723 // debug() << "faceUniqueIdToCoordX (1)"
724 // << " -- true uid : " << initial_uid
725 // << " -- uid : " << uid
726 // << " -- level : " << level
727 // << " -- three_parts_numbering : " << three_parts_numbering
728 // << " -- nb_cell_x : " << nb_cell_x
729 // << " -- return : " << ((uid % nb_cell_x) * 2 + 1);
730
731 return (uid % nb_cell_x) * 2 + 1;
732 }
733
734 // Pour l'intervalle [12, 23], on remarque que l'origine en X est toujours 0 et que les mailles
735 // contenant une face sont sur les X pairs.
736 // Enfin, on a "nb_face_x" faces en X.
737 else if (uid < three_parts_numbering.x + three_parts_numbering.y) {
738 uid -= three_parts_numbering.x;
739
740 // debug() << "faceUniqueIdToCoordX (2)"
741 // << " -- true uid : " << initial_uid
742 // << " -- uid : " << uid
743 // << " -- level : " << level
744 // << " -- three_parts_numbering : " << three_parts_numbering
745 // << " -- nb_face_x : " << nb_face_x
746 // << " -- return : " << ((uid % nb_face_x) * 2);
747
748 return (uid % nb_face_x) * 2;
749 }
750
751 // Pour l'intervalle [24, 35], on remarque que l'origine en X est toujours 1 et que les mailles
752 // contenant une face sont sur les X impairs.
753 // Enfin, on a "nb_cell_x" faces en X.
754 else {
755 uid -= three_parts_numbering.x + three_parts_numbering.y;
756
757 // debug() << "faceUniqueIdToCoordX (3)"
758 // << " -- true uid : " << initial_uid
759 // << " -- uid : " << uid
760 // << " -- level : " << level
761 // << " -- three_parts_numbering : " << three_parts_numbering
762 // << " -- nb_cell_x : " << nb_cell_x
763 // << " -- return : " << ((uid % nb_cell_x) * 2 + 1);
764
765 return (uid % nb_cell_x) * 2 + 1;
766 }
767 }
768}
769
770/*---------------------------------------------------------------------------*/
771/*---------------------------------------------------------------------------*/
772
773Int64 CartesianMeshNumberingMng::
774faceUniqueIdToCoordX(Face face)
775{
776 const Int64 uid = face.uniqueId();
777 return faceUniqueIdToCoordX(uid, faceLevel(uid));
778}
779
780/*---------------------------------------------------------------------------*/
781/*---------------------------------------------------------------------------*/
782
783Int64 CartesianMeshNumberingMng::
784faceUniqueIdToCoordY(Int64 uid, Integer level)
785{
786 if (m_dimension == 2) {
787 const Int64 nb_face_x = globalNbFacesXCartesianView(level);
788 const Int64 first_face_uid = firstFaceUniqueId(level);
789
790 uid -= first_face_uid;
791 uid += 1;
792
793 // Le +1 nous permet d'avoir le niveau (imaginaire) -1 commençant à 0 :
794 //
795 // x = 0 1 2 3 4
796 // ┌──┬──┬──┬──┬──┐
797 // y = -1 │ 0│ │ 2│ │ 4│
798 // ┌──┬──┬──┬──┬──┐
799 // y = 0 │ │ 1│ │ 3│ │
800 // ├──┼──┼──┼──┼──┤
801 // y = 1 │ 5│ │ 7│ │ 9│
802 // ├──┼──┼──┼──┼──┤
803 // y = 2 │ │ 6│ │ 8│ │
804 // ├──┼──┼──┼──┼──┤
805 // y = 3 │10│ │12│ │14│
806 // ├──┼──┼──┼──┼──┤
807 // y = 4 │ │11│ │13│ │
808 // └──┴──┴──┴──┴──┘
809 //
810 // Si, en plus, on fait y+1, on simplifie le problème puisque si on fait
811 // "tomber" les faces (tetris), on obtient une numérotation cartesienne classique.
812
813 const Int64 flat_pos = uid / nb_face_x;
814 return (flat_pos * 2) + (flat_pos % 2 == uid % 2 ? 0 : 1) - 1; // Le -1 pour "retirer" le niveau imaginaire.
815 }
816 else {
817 const Int64 nb_face_x = globalNbFacesX(level);
818 const Int64 nb_face_y = globalNbFacesY(level);
819 const Int64 nb_cell_x = globalNbCellsX(level);
820 const Int64 nb_cell_y = globalNbCellsY(level);
821 const Int64 first_face_uid = firstFaceUniqueId(level);
822
823 // Int64 initial_uid = uid;
824
825 uid -= first_face_uid;
826
827 Int64x3 three_parts_numbering = face3DNumberingThreeParts(level);
828
829 // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 :
830 // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4
831 // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4
832 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐
833 // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │
834 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
835 // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │
836 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
837 // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │
838 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
839 // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │
840 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
841 // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │
842 // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘
843 // │ │ │ │
844 //
845 // On peut remarquer 3 "sortes de disposition" : les faces ayant les uid [0, 11],
846 // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35].
847 // On récupère ces intervalles avec la méthode face3DNumberingThreeParts().
848
849 // Pour l'intervalle [0, 11], on remarque que l'origine en Y est toujours 1 et que les mailles
850 // contenant une face sont sur les Y impairs.
851 // Enfin, on a "nb_cell_y" faces en Y.
852 if (uid < three_parts_numbering.x) {
853 uid %= nb_cell_x * nb_cell_y;
854
855 // debug() << "faceUniqueIdToCoordY (1)"
856 // << " -- true uid : " << initial_uid
857 // << " -- uid : " << uid
858 // << " -- level : " << level
859 // << " -- three_parts_numbering : " << three_parts_numbering
860 // << " -- nb_cell_x : " << nb_cell_x
861 // << " -- nb_cell_y : " << nb_cell_y
862 // << " -- return : " << ((uid / nb_cell_x) * 2 + 1);
863
864 return (uid / nb_cell_x) * 2 + 1;
865 }
866
867 // Pour l'intervalle [12, 23], on remarque que l'origine en Y est toujours 1 et que les mailles
868 // contenant une face sont sur les Y impairs.
869 // Enfin, on a "nb_cell_y" faces en Y.
870 else if (uid < three_parts_numbering.x + three_parts_numbering.y) {
871 uid -= three_parts_numbering.x;
872 uid %= nb_face_x * nb_cell_y;
873
874 // debug() << "faceUniqueIdToCoordY (2)"
875 // << " -- true uid : " << initial_uid
876 // << " -- uid : " << uid
877 // << " -- level : " << level
878 // << " -- three_parts_numbering : " << three_parts_numbering
879 // << " -- nb_face_x : " << nb_face_x
880 // << " -- nb_cell_y : " << nb_cell_y
881 // << " -- return : " << ((uid / nb_face_x) * 2 + 1);
882
883 return (uid / nb_face_x) * 2 + 1;
884 }
885
886 // Pour l'intervalle [24, 35], on remarque que l'origine en Y est toujours 0 et que les mailles
887 // contenant une face sont sur les Y pairs.
888 // Enfin, on a "nb_face_y" faces en Y.
889 else {
890 uid -= three_parts_numbering.x + three_parts_numbering.y;
891 uid %= nb_cell_x * nb_face_y;
892
893 // debug() << "faceUniqueIdToCoordY (3)"
894 // << " -- true uid : " << initial_uid
895 // << " -- uid : " << uid
896 // << " -- level : " << level
897 // << " -- three_parts_numbering : " << three_parts_numbering
898 // << " -- nb_cell_x : " << nb_cell_x
899 // << " -- nb_face_y : " << nb_face_y
900 // << " -- return : " << ((uid / nb_cell_x) * 2);
901
902 return (uid / nb_cell_x) * 2;
903 }
904 }
905}
906
907/*---------------------------------------------------------------------------*/
908/*---------------------------------------------------------------------------*/
909
910Int64 CartesianMeshNumberingMng::
911faceUniqueIdToCoordY(Face face)
912{
913 const Int64 uid = face.uniqueId();
914 return faceUniqueIdToCoordY(uid, faceLevel(uid));
915}
916
917/*---------------------------------------------------------------------------*/
918/*---------------------------------------------------------------------------*/
919
920Int64 CartesianMeshNumberingMng::
921faceUniqueIdToCoordZ(Int64 uid, Integer level)
922{
923 const Int64 nb_face_x = globalNbFacesX(level);
924 const Int64 nb_face_y = globalNbFacesY(level);
925 const Int64 nb_cell_x = globalNbCellsX(level);
926 const Int64 nb_cell_y = globalNbCellsY(level);
927 const Int64 first_face_uid = firstFaceUniqueId(level);
928
929 // Int64 initial_uid = uid;
930
931 uid -= first_face_uid;
932
933 Int64x3 three_parts_numbering = face3DNumberingThreeParts(level);
934
935 // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 :
936 // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4
937 // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4
938 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐
939 // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │
940 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
941 // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │
942 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
943 // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │
944 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
945 // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │
946 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
947 // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │
948 // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘
949 // │ │ │ │
950 //
951 // On peut remarquer 3 "sortes de disposition" : les faces ayant les uid [0, 11],
952 // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35].
953 // On récupère ces intervalles avec la méthode face3DNumberingThreeParts().
954
955 // Pour l'intervalle [0, 11], on remarque que l'origine en Z est toujours 0 et que les mailles
956 // contenant une face sont sur les Z pairs.
957 // Enfin, on a "nb_face_z" faces en Z.
958 if (uid < three_parts_numbering.x) {
959
960 // debug() << "faceUniqueIdToCoordZ (1)"
961 // << " -- true uid : " << initial_uid
962 // << " -- uid : " << uid
963 // << " -- level : " << level
964 // << " -- three_parts_numbering : " << three_parts_numbering
965 // << " -- nb_cell_x : " << nb_cell_x
966 // << " -- nb_cell_y : " << nb_cell_y
967 // << " -- return : " << ((uid / (nb_cell_x * nb_cell_y)) * 2);
968
969 return (uid / (nb_cell_x * nb_cell_y)) * 2;
970 }
971
972 // Pour l'intervalle [12, 23], on remarque que l'origine en Z est toujours 1 et que les mailles
973 // contenant une face sont sur les Z impairs.
974 // Enfin, on a "nb_cell_z" faces en Z.
975 else if (uid < three_parts_numbering.x + three_parts_numbering.y) {
976 uid -= three_parts_numbering.x;
977
978 // debug() << "faceUniqueIdToCoordZ (2)"
979 // << " -- true uid : " << initial_uid
980 // << " -- uid : " << uid
981 // << " -- level : " << level
982 // << " -- three_parts_numbering : " << three_parts_numbering
983 // << " -- nb_face_x : " << nb_face_x
984 // << " -- nb_cell_y : " << nb_cell_y
985 // << " -- return : " << ((uid / (nb_face_x * nb_cell_y)) * 2 + 1);
986
987 return (uid / (nb_face_x * nb_cell_y)) * 2 + 1;
988 }
989
990 // Pour l'intervalle [24, 35], on remarque que l'origine en Z est toujours 1 et que les mailles
991 // contenant une face sont sur les Z impairs.
992 // Enfin, on a "nb_cell_z" faces en Z.
993 else {
994 uid -= three_parts_numbering.x + three_parts_numbering.y;
995
996 // debug() << "faceUniqueIdToCoordZ (3)"
997 // << " -- true uid : " << initial_uid
998 // << " -- uid : " << uid
999 // << " -- level : " << level
1000 // << " -- three_parts_numbering : " << three_parts_numbering
1001 // << " -- nb_cell_x : " << nb_cell_x
1002 // << " -- nb_face_y : " << nb_face_y
1003 // << " -- return : " << ((uid / (nb_cell_x * nb_face_y)) * 2 + 1);
1004
1005 return (uid / (nb_cell_x * nb_face_y)) * 2 + 1;
1006 }
1007}
1008
1009/*---------------------------------------------------------------------------*/
1010/*---------------------------------------------------------------------------*/
1011
1012Int64 CartesianMeshNumberingMng::
1013faceUniqueIdToCoordZ(Face face)
1014{
1015 const Int64 uid = face.uniqueId();
1016 return faceUniqueIdToCoordZ(uid, faceLevel(uid));
1017}
1018
1019/*---------------------------------------------------------------------------*/
1020/*---------------------------------------------------------------------------*/
1021
1022Int64 CartesianMeshNumberingMng::
1023cellUniqueId(Integer level, Int64x3 cell_coord)
1024{
1025 const Int64 nb_cell_x = globalNbCellsX(level);
1026 const Int64 nb_cell_y = globalNbCellsY(level);
1027 const Int64 first_cell_uid = firstCellUniqueId(level);
1028
1029 return (cell_coord.x + cell_coord.y * nb_cell_x + cell_coord.z * nb_cell_x * nb_cell_y) + first_cell_uid;
1030}
1031
1032/*---------------------------------------------------------------------------*/
1033/*---------------------------------------------------------------------------*/
1034
1035Int64 CartesianMeshNumberingMng::
1036cellUniqueId(Integer level, Int64x2 cell_coord)
1037{
1038 const Int64 nb_cell_x = globalNbCellsX(level);
1039 const Int64 first_cell_uid = firstCellUniqueId(level);
1040
1041 return (cell_coord.x + cell_coord.y * nb_cell_x) + first_cell_uid;
1042}
1043
1044/*---------------------------------------------------------------------------*/
1045/*---------------------------------------------------------------------------*/
1046
1047Int64 CartesianMeshNumberingMng::
1048nodeUniqueId(Integer level, Int64x3 node_coord)
1049{
1050 const Int64 nb_node_x = globalNbNodesX(level);
1051 const Int64 nb_node_y = globalNbNodesY(level);
1052 const Int64 first_node_uid = firstNodeUniqueId(level);
1053
1054 return (node_coord.x + node_coord.y * nb_node_x + node_coord.z * nb_node_x * nb_node_y) + first_node_uid;
1055}
1056
1057/*---------------------------------------------------------------------------*/
1058/*---------------------------------------------------------------------------*/
1059
1060Int64 CartesianMeshNumberingMng::
1061nodeUniqueId(Integer level, Int64x2 node_coord)
1062{
1063 const Int64 nb_node_x = globalNbNodesX(level);
1064 const Int64 first_node_uid = firstNodeUniqueId(level);
1065
1066 return (node_coord.x + node_coord.y * nb_node_x) + first_node_uid;
1067}
1068
1069/*---------------------------------------------------------------------------*/
1070/*---------------------------------------------------------------------------*/
1071
1072Int64 CartesianMeshNumberingMng::
1073faceUniqueId(Integer level, Int64x3 face_coord)
1074{
1075 const Int64 nb_face_x = globalNbFacesX(level);
1076 const Int64 nb_face_y = globalNbFacesY(level);
1077 const Int64 nb_cell_x = globalNbCellsX(level);
1078 const Int64 nb_cell_y = globalNbCellsY(level);
1079
1080 Int64x3 three_parts_numbering = face3DNumberingThreeParts(level);
1081 Int64 uid = firstFaceUniqueId(level);
1082
1083 // Prenons la vue des faces en grille cartésienne d'un maillage 2x2x2 :
1084 // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4
1085 // x = 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4 │ 0 1 2 3 4
1086 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐
1087 // y = 0 │ │ │ │ │ │ │ │ │24│ │25│ │ │ │ │ │ │ │ │ │ │ │30│ │31│ │ │ │ │ │ │ │ │
1088 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1089 // y = 1 │ │ 0│ │ 1│ │ │ │12│ │13│ │14│ │ │ │ 4│ │ 5│ │ │ │18│ │19│ │20│ │ │ │ 8│ │ 9│ │
1090 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1091 // y = 2 │ │ │ │ │ │ │ │ │26│ │27│ │ │ │ │ │ │ │ │ │ │ │32│ │33│ │ │ │ │ │ │ │ │
1092 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1093 // y = 3 │ │ 2│ │ 3│ │ │ │15│ │16│ │17│ │ │ │ 6│ │ 7│ │ │ │21│ │22│ │23│ │ │ │10│ │11│ │
1094 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1095 // y = 4 │ │ │ │ │ │ │ │ │28│ │29│ │ │ │ │ │ │ │ │ │ │ │34│ │35│ │ │ │ │ │ │ │ │
1096 // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘
1097 // │ │ │ │
1098 //
1099 // On peut remarquer 3 "sortes de disposition" : les faces ayant les uid [0, 11],
1100 // les faces ayant les uid [12, 23] et les faces ayant les uid [24, 35].
1101 // Ici, on veut faire l'inverse : passer des coordonnées x,y,z à un uid.
1102 // Pour identifier les trois intervalles, on regarde quelle coordonnée est pair.
1103 // En effet, pour l'intervalle [0, 11], on s'aperçoit que seule la coordonnée z est pair.
1104 // Pour l'intervalle [12, 23], seule la coordonnée x est pair et pour l'intervalle [24, 35],
1105 // seule la coordonnée y est pair.
1106
1107 // Intervalle [0, 11].
1108 if (face_coord.z % 2 == 0) {
1109 // Ici, on place les mailles à l'origine 0*0*0 et on les met côte-à-côte.
1110 face_coord.x -= 1;
1111 face_coord.y -= 1;
1112
1113 face_coord /= 2;
1114
1115 // On est, à présent et pour cet intervalle, dans une vue cartésienne de
1116 // taille nb_cell_x * nb_cell_y * nb_face_z.
1117 uid += face_coord.x + (face_coord.y * nb_cell_x) + (face_coord.z * nb_cell_x * nb_cell_y);
1118 }
1119
1120 // Intervalle [12, 23].
1121 else if (face_coord.x % 2 == 0) {
1122 uid += three_parts_numbering.x;
1123
1124 // Ici, on place les mailles à l'origine 0*0*0 et on les met côte-à-côte.
1125 face_coord.y -= 1;
1126 face_coord.z -= 1;
1127
1128 face_coord /= 2;
1129
1130 // On est, à présent et pour cet intervalle, dans une vue cartésienne de
1131 // taille nb_face_x * nb_cell_y * nb_cell_z.
1132 uid += face_coord.x + (face_coord.y * nb_face_x) + (face_coord.z * nb_face_x * nb_cell_y);
1133 }
1134
1135 // Intervalle [24, 35].
1136 else if (face_coord.y % 2 == 0) {
1137 uid += three_parts_numbering.x + three_parts_numbering.y;
1138
1139 // Ici, on place les mailles à l'origine 0*0*0 et on les met côte-à-côte.
1140 face_coord.x -= 1;
1141 face_coord.z -= 1;
1142
1143 face_coord /= 2;
1144
1145 // On est, à présent et pour cet intervalle, dans une vue cartésienne de
1146 // taille nb_cell_x * nb_face_y * nb_cell_z.
1147 uid += face_coord.x + (face_coord.y * nb_cell_x) + (face_coord.z * nb_cell_x * nb_face_y);
1148 }
1149 else {
1150 ARCANE_FATAL("Bizarre -- x : {0} -- y : {1} -- z : {2}", face_coord.x, face_coord.y, face_coord.z);
1151 }
1152
1153 return uid;
1154}
1155
1156/*---------------------------------------------------------------------------*/
1157/*---------------------------------------------------------------------------*/
1158
1159Int64 CartesianMeshNumberingMng::
1160faceUniqueId(Integer level, Int64x2 face_coord)
1161{
1162 const Int64 nb_face_x = globalNbFacesXCartesianView(level);
1163 const Int64 first_face_uid = firstFaceUniqueId(level);
1164
1165 // On considère que l'on a un niveau imaginaire -1 et que
1166 // l'on obtiendra uid+1 (dans la numérotation utilisée normalement,
1167 // la face à la position (1, 0) a un uid = 0).
1168 //
1169 // x = 0 1 2 3 4
1170 // ┌──┬──┬──┬──┬──┐
1171 // y = -1 │ 0│ │ 2│ │ 4│
1172 // ┌──┬──┬──┬──┬──┐
1173 // y = 0 │ │ 1│ │ 3│ │
1174 // ├──┼──┼──┼──┼──┤
1175 // y = 1 │ 5│ │ 7│ │ 9│
1176 // ├──┼──┼──┼──┼──┤
1177 // y = 2 │ │ 6│ │ 8│ │
1178 // ├──┼──┼──┼──┼──┤
1179 // y = 3 │10│ │12│ │14│
1180 // ├──┼──┼──┼──┼──┤
1181 // y = 4 │ │11│ │13│ │
1182 // └──┴──┴──┴──┴──┘
1183 //
1184
1185 face_coord.y += 1;
1186
1187 const Int64 a = (face_coord.y / 2) * nb_face_x;
1188
1189 return (face_coord.x + a - 1) + first_face_uid; // Le -1 est pour revenir à la numérotation normale.
1190}
1191
1192/*---------------------------------------------------------------------------*/
1193/*---------------------------------------------------------------------------*/
1194
1195Integer CartesianMeshNumberingMng::
1196nbNodeByCell()
1197{
1198 return static_cast<Integer>(std::pow(m_pattern, m_mesh->dimension()));
1199}
1200
1201/*---------------------------------------------------------------------------*/
1202/*---------------------------------------------------------------------------*/
1203
1204void CartesianMeshNumberingMng::
1205cellNodeUniqueIds(ArrayView<Int64> uid, Integer level, Int64x3 cell_coord)
1206{
1207 if (uid.size() != nbNodeByCell())
1208 ARCANE_FATAL("Bad size of arrayview");
1209
1210 const Int64 nb_node_x = globalNbNodesX(level);
1211 const Int64 nb_node_y = globalNbNodesY(level);
1212 const Int64 first_node_uid = firstNodeUniqueId(level);
1213
1214 uid[0] = (cell_coord.x + 0) + ((cell_coord.y + 0) * nb_node_x) + ((cell_coord.z + 0) * nb_node_x * nb_node_y) + first_node_uid;
1215 uid[1] = (cell_coord.x + 1) + ((cell_coord.y + 0) * nb_node_x) + ((cell_coord.z + 0) * nb_node_x * nb_node_y) + first_node_uid;
1216 uid[2] = (cell_coord.x + 1) + ((cell_coord.y + 1) * nb_node_x) + ((cell_coord.z + 0) * nb_node_x * nb_node_y) + first_node_uid;
1217 uid[3] = (cell_coord.x + 0) + ((cell_coord.y + 1) * nb_node_x) + ((cell_coord.z + 0) * nb_node_x * nb_node_y) + first_node_uid;
1218
1219 uid[4] = (cell_coord.x + 0) + ((cell_coord.y + 0) * nb_node_x) + ((cell_coord.z + 1) * nb_node_x * nb_node_y) + first_node_uid;
1220 uid[5] = (cell_coord.x + 1) + ((cell_coord.y + 0) * nb_node_x) + ((cell_coord.z + 1) * nb_node_x * nb_node_y) + first_node_uid;
1221 uid[6] = (cell_coord.x + 1) + ((cell_coord.y + 1) * nb_node_x) + ((cell_coord.z + 1) * nb_node_x * nb_node_y) + first_node_uid;
1222 uid[7] = (cell_coord.x + 0) + ((cell_coord.y + 1) * nb_node_x) + ((cell_coord.z + 1) * nb_node_x * nb_node_y) + first_node_uid;
1223}
1224
1225/*---------------------------------------------------------------------------*/
1226/*---------------------------------------------------------------------------*/
1227
1228void CartesianMeshNumberingMng::
1229cellNodeUniqueIds(ArrayView<Int64> uid, Integer level, Int64x2 cell_coord)
1230{
1231 if (uid.size() != nbNodeByCell())
1232 ARCANE_FATAL("Bad size of arrayview");
1233
1234 const Int64 nb_node_x = globalNbNodesX(level);
1235 const Int64 first_node_uid = firstNodeUniqueId(level);
1236
1237 uid[0] = (cell_coord.x + 0) + ((cell_coord.y + 0) * nb_node_x) + first_node_uid;
1238 uid[1] = (cell_coord.x + 1) + ((cell_coord.y + 0) * nb_node_x) + first_node_uid;
1239 uid[2] = (cell_coord.x + 1) + ((cell_coord.y + 1) * nb_node_x) + first_node_uid;
1240 uid[3] = (cell_coord.x + 0) + ((cell_coord.y + 1) * nb_node_x) + first_node_uid;
1241}
1242
1243/*---------------------------------------------------------------------------*/
1244/*---------------------------------------------------------------------------*/
1245
1246void CartesianMeshNumberingMng::
1247cellNodeUniqueIds(ArrayView<Int64> uid, Integer level, Int64 cell_uid)
1248{
1249 if (m_dimension == 2) {
1250 const Int64x2 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level));
1251 cellNodeUniqueIds(uid, level, cell_coord);
1252 }
1253 else {
1254 const Int64x3 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level), cellUniqueIdToCoordZ(cell_uid, level));
1255 cellNodeUniqueIds(uid, level, cell_coord);
1256 }
1257}
1258
1259/*---------------------------------------------------------------------------*/
1260/*---------------------------------------------------------------------------*/
1261
1262Integer CartesianMeshNumberingMng::
1263nbFaceByCell()
1264{
1265 return m_pattern * m_dimension;
1266}
1267
1268/*---------------------------------------------------------------------------*/
1269/*---------------------------------------------------------------------------*/
1270
1271void CartesianMeshNumberingMng::
1272cellFaceUniqueIds(ArrayView<Int64> uid, Integer level, Int64x3 cell_coord)
1273{
1274 if (uid.size() != nbFaceByCell())
1275 ARCANE_FATAL("Bad size of arrayview");
1276
1277 const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level));
1278 const Int64x3 nb_face(nb_cell + 1);
1279
1280 const Int64 first_face_uid = firstFaceUniqueId(level);
1281
1282 // Numérote les faces
1283 // Cet algo n'est pas basé sur l'algo 2D.
1284 // Les UniqueIDs générés sont contigües.
1285 // Il est aussi possible de retrouver les UniqueIDs des faces
1286 // à l'aide de la position de la cellule et la taille du maillage.
1287 // De plus, l'ordre des UniqueIDs des faces d'une cellule est toujours le
1288 // même (en notation localId Arcane (cell.face(i)) : 0, 3, 1, 4, 2, 5).
1289 // Les UniqueIDs générés sont donc les mêmes quelque soit le découpage.
1290 /*
1291 x z
1292 ┌──► │ ┌──►
1293 │ │ │
1294 y▼12 13 14 │y▼ ┌────┬────┐
1295 │ 26 │ 27 │ │ │ 24 │ 25 │
1296 └────┴────┘ │ 0 4 8
1297 15 16 17 │
1298 │ 28 │ 29 │ │ │ │ │
1299 └────┴────┘ │ 2 6 10
1300 z=0 │ x=0
1301 - - - - - - - - - - - - - - - - - -
1302 z=1 │ x=1
1303 18 19 20 │ ┌────┬────┐
1304 │ 32 │ 33 │ │ │ 30 │ 31 │
1305 └────┴────┘ │ 1 5 9
1306 21 22 23 │
1307 │ 34 │ 35 │ │ │ │ │
1308 └────┴────┘ │ 3 7 11
1309
1310 */
1311 // On a un cube décomposé en huit cellules (2x2x2).
1312 // Le schéma au-dessus représente les faces des cellules de ce cube avec
1313 // les uniqueIDs que l'algorithme génèrera (sans face_adder).
1314 // Pour cet algo, on commence par les faces "xy".
1315 // On énumère d'abord en x, puis en y, puis en z.
1316 // Une fois les faces "xy" numérotées, on fait les faces "yz".
1317 // Toujours le même ordre de numérotation.
1318 // On termine avec les faces "zx", encore dans le même ordre.
1319 //
1320 // Dans l'implémentation ci-dessous, on fait la numérotation
1321 // maille par maille.
1322
1323 const Int64 total_face_xy = nb_face.z * nb_cell.x * nb_cell.y;
1324 const Int64 total_face_xy_yz = total_face_xy + nb_face.x * nb_cell.y * nb_cell.z;
1325
1326 const Int64 nb_cell_before_j = cell_coord.y * nb_cell.x;
1327
1328 uid[0] = (cell_coord.z * nb_cell.x * nb_cell.y) + nb_cell_before_j + (cell_coord.x);
1329
1330 uid[3] = uid[0] + nb_cell.x * nb_cell.y;
1331
1332 uid[1] = (cell_coord.z * nb_face.x * nb_cell.y) + (cell_coord.y * nb_face.x) + (cell_coord.x) + total_face_xy;
1333
1334 uid[4] = uid[1] + 1;
1335
1336 uid[2] = (cell_coord.z * nb_cell.x * nb_face.y) + nb_cell_before_j + (cell_coord.x) + total_face_xy_yz;
1337
1338 uid[5] = uid[2] + nb_cell.x;
1339
1340 uid[0] += first_face_uid;
1341 uid[1] += first_face_uid;
1342 uid[2] += first_face_uid;
1343 uid[3] += first_face_uid;
1344 uid[4] += first_face_uid;
1345 uid[5] += first_face_uid;
1346}
1347
1348/*---------------------------------------------------------------------------*/
1349/*---------------------------------------------------------------------------*/
1350
1351void CartesianMeshNumberingMng::
1352cellFaceUniqueIds(ArrayView<Int64> uid, Integer level, Int64x2 cell_coord)
1353{
1354 if (uid.size() != nbFaceByCell())
1355 ARCANE_FATAL("Bad size of arrayview");
1356
1357 const Int64 nb_cell_x = globalNbCellsX(level);
1358 const Int64 nb_face_x = nb_cell_x + 1;
1359 const Int64 first_face_uid = firstFaceUniqueId(level);
1360
1361 // Numérote les faces
1362 // ┌─0──┬──2─┐
1363 // 4│ 6│ 8│
1364 // ├─5──┼─7──┤
1365 // 9│ 11│ 13│
1366 // └─10─┴─12─┘
1367 //
1368 // Avec cette numérotation, HAUT < GAUCHE < BAS < DROITE
1369 // Mis à part les uniqueIds de la première ligne de face, tous
1370 // les uniqueIds sont contigües.
1371
1372 // HAUT
1373 // - "(current_level_nb_face_x + current_level_nb_cell_x)" :
1374 // le nombre de faces GAUCHE BAS DROITE au dessus.
1375 // - "cell_coord.y * (current_level_nb_face_x + current_level_nb_cell_x)" :
1376 // le nombre total de faces GAUCHE BAS DROITE au dessus.
1377 // - "cell_coord.x * 2"
1378 // on avance deux à deux sur les faces d'un même "coté".
1379 uid[0] = cell_coord.x * 2 + cell_coord.y * (nb_face_x + nb_cell_x);
1380
1381 // BAS
1382 // Pour BAS, c'est comme HAUT mais avec un "nombre de face du dessus" en plus.
1383 uid[2] = uid[0] + (nb_face_x + nb_cell_x);
1384 // GAUCHE
1385 // Pour GAUCHE, c'est l'UID de BAS -1.
1386 uid[3] = uid[2] - 1;
1387 // DROITE
1388 // Pour DROITE, c'est l'UID de BAS +1.
1389 uid[1] = uid[2] + 1;
1390
1391 uid[0] += first_face_uid;
1392 uid[1] += first_face_uid;
1393 uid[2] += first_face_uid;
1394 uid[3] += first_face_uid;
1395}
1396
1397/*---------------------------------------------------------------------------*/
1398/*---------------------------------------------------------------------------*/
1399
1400void CartesianMeshNumberingMng::
1401cellFaceUniqueIds(ArrayView<Int64> uid, Integer level, Int64 cell_uid)
1402{
1403 if (m_dimension == 2) {
1404 const Int64x2 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level));
1405 cellFaceUniqueIds(uid, level, cell_coord);
1406 }
1407 else {
1408 const Int64x3 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level), cellUniqueIdToCoordZ(cell_uid, level));
1409 cellFaceUniqueIds(uid, level, cell_coord);
1410 }
1411}
1412
1413/*---------------------------------------------------------------------------*/
1414/*---------------------------------------------------------------------------*/
1415
1416void CartesianMeshNumberingMng::
1417cellUniqueIdsAroundCell(ArrayView<Int64> uid, Cell cell)
1418{
1419 cellUniqueIdsAroundCell(uid, cell.uniqueId(), cell.level());
1420}
1421
1422/*---------------------------------------------------------------------------*/
1423/*---------------------------------------------------------------------------*/
1424
1425void CartesianMeshNumberingMng::
1426cellUniqueIdsAroundCell(ArrayView<Int64> uid, Int64 cell_uid, Int32 level)
1427{
1428 uid.fill(-1);
1429
1430 const Int64 coord_cell_x = cellUniqueIdToCoordX(cell_uid, level);
1431 const Int64 coord_cell_y = cellUniqueIdToCoordY(cell_uid, level);
1432
1433 const Int64 nb_cells_x = globalNbCellsX(level);
1434 const Int64 nb_cells_y = globalNbCellsY(level);
1435
1436 if (m_dimension == 2) {
1437 ARCANE_ASSERT((uid.size() == 9), ("Size of uid array != 9"));
1438
1439 for (Integer j = -1; j < 2; ++j) {
1440 const Int64 coord_around_cell_y = coord_cell_y + j;
1441 if (coord_around_cell_y >= 0 && coord_around_cell_y < nb_cells_y) {
1442
1443 for (Integer i = -1; i < 2; ++i) {
1444 const Int64 coord_around_cell_x = coord_cell_x + i;
1445 if (coord_around_cell_x >= 0 && coord_around_cell_x < nb_cells_x) {
1446 uid[(i + 1) + ((j + 1) * 3)] = cellUniqueId(level, Int64x2(coord_around_cell_x, coord_around_cell_y));
1447 }
1448 }
1449 }
1450 }
1451 }
1452
1453 else {
1454 ARCANE_ASSERT((uid.size() == 27), ("Size of uid array != 27"));
1455
1456 const Int64 coord_cell_z = cellUniqueIdToCoordZ(cell_uid, level);
1457 const Int64 nb_cells_z = globalNbCellsZ(level);
1458
1459 for (Integer k = -1; k < 2; ++k) {
1460 const Int64 coord_around_cell_z = coord_cell_z + k;
1461 if (coord_around_cell_z >= 0 && coord_around_cell_z < nb_cells_z) {
1462
1463 for (Integer j = -1; j < 2; ++j) {
1464 const Int64 coord_around_cell_y = coord_cell_y + j;
1465 if (coord_around_cell_y >= 0 && coord_around_cell_y < nb_cells_y) {
1466
1467 for (Integer i = -1; i < 2; ++i) {
1468 const Int64 coord_around_cell_x = coord_cell_x + i;
1469 if (coord_around_cell_x >= 0 && coord_around_cell_x < nb_cells_x) {
1470 uid[(i + 1) + ((j + 1) * 3) + ((k + 1) * 9)] = cellUniqueId(level, Int64x3(coord_around_cell_x, coord_around_cell_y, coord_around_cell_z));
1471 }
1472 }
1473 }
1474 }
1475 }
1476 }
1477 }
1478}
1479
1480/*---------------------------------------------------------------------------*/
1481/*---------------------------------------------------------------------------*/
1482
1483void CartesianMeshNumberingMng::
1484setChildNodeCoordinates(Cell parent_cell)
1485{
1486 if (!(parent_cell.itemBase().flags() & ItemFlags::II_JustRefined)) {
1487 ARCANE_FATAL("Cell not II_JustRefined");
1488 }
1489
1490 VariableNodeReal3& nodes_coords = m_mesh->nodesCoordinates();
1491
1492 const Real3& node0(nodes_coords[parent_cell.node(0)]);
1493 const Real3& node1(nodes_coords[parent_cell.node(1)]);
1494 const Real3& node2(nodes_coords[parent_cell.node(2)]);
1495 const Real3& node3(nodes_coords[parent_cell.node(3)]);
1496
1497 if (m_dimension == 2) {
1498
1499 /*
1500 =
1501 ┌─────────────────────►= y3
1502 │ = ▲ l
1503 ▼ = ▼
1504 X───────────────X◄────►= y2
1505 /▲ /▲ =
1506 / │ / │ =
1507 / │ / │ =
1508 / │ / │ =
1509 / │ / │ =
1510 / │ / │ =
1511 / │ / │ =
1512 / │ / │ =
1513 X───────────────X◄───────│─────►= y1
1514 ▲ │ ▲ │ = ▲ k
1515 │ │ │ │ = ▼
1516 ├──────────────────────────────►= y0
1517 │ │ │ │ =
1518 │ │ │ │ =
1519 ▼ ▼ ▼ ▼
1520 ==============================
1521 x0 ◄───► x3 x1 ◄───► x2
1522 i j
1523 */
1524 /*!
1525 * \brief Lambda permettant de déterminer la position d'un noeud enfant
1526 * dans une maille parent.
1527 */
1528 auto txty = [&](Integer pos_x, Integer pos_y) -> Real3 {
1529 const Real x = (Real)pos_x / (Real)m_pattern;
1530 const Real y = (Real)pos_y / (Real)m_pattern;
1531
1532 const Real i = (node3.x - node0.x) * y + node0.x;
1533 const Real j = (node2.x - node1.x) * y + node1.x;
1534
1535 const Real k = (node1.y - node0.y) * x + node0.y;
1536 const Real l = (node2.y - node3.y) * x + node3.y;
1537
1538 const Real tx = (j - i) * x + i;
1539 const Real ty = (l - k) * y + k;
1540
1541 /*
1542 info() << "[txty]"
1543 << " x : " << x
1544 << " -- y : " << y
1545 << " -- node0 : " << node0
1546 << " -- node1 : " << node1
1547 << " -- node2 : " << node2
1548 << " -- node3 : " << node3
1549 << " -- i : " << i
1550 << " -- j : " << j
1551 << " -- k : " << k
1552 << " -- l : " << l
1553 << " -- tx : " << tx
1554 << " -- ty : " << ty;
1555 */
1556 return { tx, ty, 0 };
1557 };
1558
1559 const Integer node_1d_2d_x[] = { 0, 1, 1, 0 };
1560 const Integer node_1d_2d_y[] = { 0, 0, 1, 1 };
1561
1562 for (Integer j = 0; j < m_pattern; ++j) {
1563 for (Integer i = 0; i < m_pattern; ++i) {
1564
1565 Integer begin = (i == 0 && j == 0 ? 0 : j == 0 ? 1
1566 : 2);
1567 Integer end = (i == 0 ? nbNodeByCell() : nbNodeByCell() - 1);
1568 Cell child = childCellOfCell(parent_cell, Int64x2(i, j));
1569
1570 for (Integer inode = begin; inode < end; ++inode) {
1571 nodes_coords[child.node(inode)] = txty(i + node_1d_2d_x[inode], j + node_1d_2d_y[inode]);
1572 // Real3 pos = txty(i + node_1d_2d_x[inode], j + node_1d_2d_y[inode]);
1573 // nodes_coords[child.node(inode)] = pos;
1574 // info() << "Node uid : " << child.node(inode).uniqueId()
1575 // << " -- nodeX : " << (i + node_1d_2d_x[inode])
1576 // << " -- nodeY : " << (j + node_1d_2d_y[inode])
1577 // << " -- Pos : " << pos;
1578 }
1579 }
1580 }
1581 }
1582
1583 else {
1584 const Real3& node4(nodes_coords[parent_cell.node(4)]);
1585 const Real3& node5(nodes_coords[parent_cell.node(5)]);
1586 const Real3& node6(nodes_coords[parent_cell.node(6)]);
1587 const Real3& node7(nodes_coords[parent_cell.node(7)]);
1588
1589 /*!
1590 * \brief Lambda permettant de déterminer la position d'un noeud enfant
1591 * dans une maille parent.
1592 */
1593 auto txtytz = [&](Integer pos_x, Integer pos_y, Integer pos_z) -> Real3 {
1594 const Real x = (Real)pos_x / (Real)m_pattern;
1595 const Real y = (Real)pos_y / (Real)m_pattern;
1596 const Real z = (Real)pos_z / (Real)m_pattern;
1597
1598 // Face (m, n, o, p) entre les faces (node0, node1, node2, node3) et (node4, node5, node6, node7).
1599 const Real3 m = (node4 - node0) * z + node0;
1600 const Real3 n = (node5 - node1) * z + node1;
1601 const Real3 o = (node6 - node2) * z + node2;
1602 const Real3 p = (node7 - node3) * z + node3;
1603
1604 // On calcule tx et ty comme en 2D mais sur la face (m, n, o, p).
1605 const Real i = (p.x - m.x) * y + m.x;
1606 const Real j = (o.x - n.x) * y + n.x;
1607
1608 const Real tx = (j - i) * x + i;
1609
1610 const Real k = (n.y - m.y) * x + m.y;
1611 const Real l = (o.y - p.y) * x + p.y;
1612
1613 const Real ty = (l - k) * y + k;
1614
1615 const Real q = (p.z - m.z) * y + m.z;
1616 const Real r = (o.z - n.z) * y + n.z;
1617
1618 const Real s = (n.z - m.z) * x + m.z;
1619 const Real t = (o.z - p.z) * x + p.z;
1620
1621 const Real tz = (((r - q) * x + q) + ((t - s) * y + s)) * 0.5;
1622
1623 /*
1624 info() << "[txtytz]"
1625 << " x : " << x
1626 << " -- y : " << y
1627 << " -- z : " << z
1628 << " -- node0 : " << node0
1629 << " -- node1 : " << node1
1630 << " -- node2 : " << node2
1631 << " -- node3 : " << node3
1632 << " -- node4 : " << node4
1633 << " -- node5 : " << node5
1634 << " -- node6 : " << node6
1635 << " -- node7 : " << node7
1636 << " -- m : " << m
1637 << " -- n : " << n
1638 << " -- o : " << o
1639 << " -- p : " << p
1640 << " -- j : " << j
1641 << " -- k : " << k
1642 << " -- l : " << l
1643 << " -- q : " << q
1644 << " -- r : " << r
1645 << " -- s : " << s
1646 << " -- t : " << t
1647 << " -- tx : " << tx
1648 << " -- ty : " << ty
1649 << " -- tz : " << tz;
1650 */
1651 return { tx, ty, tz };
1652 };
1653
1654 const Integer node_1d_3d_x[] = { 0, 1, 1, 0, 0, 1, 1, 0 };
1655 const Integer node_1d_3d_y[] = { 0, 0, 1, 1, 0, 0, 1, 1 };
1656 const Integer node_1d_3d_z[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
1657
1658 for (Integer k = 0; k < m_pattern; ++k) {
1659 for (Integer j = 0; j < m_pattern; ++j) {
1660 for (Integer i = 0; i < m_pattern; ++i) {
1661
1662 // TODO : éviter les multiples appels pour un même noeud.
1663 Integer begin = 0;
1664 Integer end = nbNodeByCell();
1665 Cell child = childCellOfCell(parent_cell, Int64x3(i, j, k));
1666
1667 for (Integer inode = begin; inode < end; ++inode) {
1668 nodes_coords[child.node(inode)] = txtytz(i + node_1d_3d_x[inode], j + node_1d_3d_y[inode], k + node_1d_3d_z[inode]);
1669 // Real3 pos = txtytz(i + node_1d_3d_x[inode], j + node_1d_3d_y[inode], k + node_1d_3d_z[inode]);
1670 // nodes_coords[child.node(inode)] = pos;
1671 // info() << "Node uid : " << child.node(inode).uniqueId()
1672 // << " -- nodeX : " << (i + node_1d_3d_x[inode])
1673 // << " -- nodeY : " << (j + node_1d_3d_y[inode])
1674 // << " -- nodeZ : " << (k + node_1d_3d_z[inode])
1675 // << " -- Pos : " << pos;
1676 }
1677 }
1678 }
1679 }
1680 }
1681}
1682
1683/*---------------------------------------------------------------------------*/
1684/*---------------------------------------------------------------------------*/
1685
1686void CartesianMeshNumberingMng::
1687setParentNodeCoordinates(Cell parent_cell)
1688{
1689 if (!(parent_cell.itemBase().flags() & ItemFlags::II_JustAdded)) {
1690 ARCANE_FATAL("Cell not II_JustAdded");
1691 }
1692
1693 VariableNodeReal3& nodes_coords = m_mesh->nodesCoordinates();
1694
1695 if (m_dimension == 2) {
1696 nodes_coords[parent_cell.node(0)] = nodes_coords[childCellOfCell(parent_cell, Int64x2(0, 0)).node(0)];
1697 nodes_coords[parent_cell.node(1)] = nodes_coords[childCellOfCell(parent_cell, Int64x2(m_pattern - 1, 0)).node(1)];
1698 nodes_coords[parent_cell.node(2)] = nodes_coords[childCellOfCell(parent_cell, Int64x2(m_pattern - 1, m_pattern - 1)).node(2)];
1699 nodes_coords[parent_cell.node(3)] = nodes_coords[childCellOfCell(parent_cell, Int64x2(0, m_pattern - 1)).node(3)];
1700 }
1701
1702 else {
1703 nodes_coords[parent_cell.node(0)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(0, 0, 0)).node(0)];
1704 nodes_coords[parent_cell.node(1)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(m_pattern - 1, 0, 0)).node(1)];
1705 nodes_coords[parent_cell.node(2)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(m_pattern - 1, m_pattern - 1, 0)).node(2)];
1706 nodes_coords[parent_cell.node(3)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(0, m_pattern - 1, 0)).node(3)];
1707
1708 nodes_coords[parent_cell.node(4)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(0, 0, m_pattern - 1)).node(4)];
1709 nodes_coords[parent_cell.node(5)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(m_pattern - 1, 0, m_pattern - 1)).node(5)];
1710 nodes_coords[parent_cell.node(6)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(m_pattern - 1, m_pattern - 1, m_pattern - 1)).node(6)];
1711 nodes_coords[parent_cell.node(7)] = nodes_coords[childCellOfCell(parent_cell, Int64x3(0, m_pattern - 1, m_pattern - 1)).node(7)];
1712 }
1713}
1714
1715/*---------------------------------------------------------------------------*/
1716/*---------------------------------------------------------------------------*/
1717
1718Int64 CartesianMeshNumberingMng::
1719parentCellUniqueIdOfCell(Int64 uid, Integer level, bool do_fatal)
1720{
1721 // Pour avoir la face parent d'une maille, on passe d'abord de l'uid vers les
1722 // coordonnées de la maille,
1723 // puis on détermine les coordonnées du parent grâce au m_pattern,
1724 // et enfin, on repasse des coordonnées du parent vers son uid.
1725
1726 if (globalNbCellsX(level - 1) == 0) {
1727 if (do_fatal) {
1728 ARCANE_FATAL("Level {0} do not exist", (level - 1));
1729 }
1730 return NULL_ITEM_UNIQUE_ID;
1731 }
1732
1733 if (m_dimension == 2) {
1734 return cellUniqueId(level - 1,
1735 Int64x2(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level - 1),
1736 offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level - 1)));
1737 }
1738 else {
1739 return cellUniqueId(level - 1,
1740 Int64x3(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level - 1),
1741 offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level - 1),
1742 offsetLevelToLevel(cellUniqueIdToCoordZ(uid, level), level, level - 1)));
1743 }
1744}
1745
1746/*---------------------------------------------------------------------------*/
1747/*---------------------------------------------------------------------------*/
1748
1749Int64 CartesianMeshNumberingMng::
1750parentCellUniqueIdOfCell(Cell cell, bool do_fatal)
1751{
1752 return parentCellUniqueIdOfCell(cell.uniqueId(), cell.level(), do_fatal);
1753}
1754
1755/*---------------------------------------------------------------------------*/
1756/*---------------------------------------------------------------------------*/
1757
1758Int64 CartesianMeshNumberingMng::
1759childCellUniqueIdOfCell(Cell cell, Int64x3 child_coord_in_parent)
1760{
1761 ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x"))
1762 ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y"))
1763 ARCANE_ASSERT((child_coord_in_parent.z < m_pattern && child_coord_in_parent.z >= 0), ("Bad child_coord_in_parent.z"))
1764
1765 const Int64 uid = cell.uniqueId();
1766 const Int32 level = cell.level();
1767
1768 return cellUniqueId(level + 1,
1769 Int64x3(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level + 1) + child_coord_in_parent.x,
1770 offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level + 1) + child_coord_in_parent.y,
1771 offsetLevelToLevel(cellUniqueIdToCoordZ(uid, level), level, level + 1) + child_coord_in_parent.z));
1772}
1773
1774/*---------------------------------------------------------------------------*/
1775/*---------------------------------------------------------------------------*/
1776
1777Int64 CartesianMeshNumberingMng::
1778childCellUniqueIdOfCell(Cell cell, Int64x2 child_coord_in_parent)
1779{
1780 ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x"))
1781 ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y"))
1782
1783 const Int64 uid = cell.uniqueId();
1784 const Int32 level = cell.level();
1785
1786 return cellUniqueId(level + 1,
1787 Int64x2(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level + 1) + child_coord_in_parent.x,
1788 offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level + 1) + child_coord_in_parent.y));
1789}
1790
1791/*---------------------------------------------------------------------------*/
1792/*---------------------------------------------------------------------------*/
1793
1794Int64 CartesianMeshNumberingMng::
1795childCellUniqueIdOfCell(Cell cell, Int64 child_index_in_parent)
1796{
1797 if (m_dimension == 2) {
1798 ARCANE_ASSERT((child_index_in_parent < m_pattern * m_pattern && child_index_in_parent >= 0), ("Bad child_index_in_parent"))
1799
1800 return childCellUniqueIdOfCell(cell,
1801 Int64x2(
1802 child_index_in_parent % m_pattern,
1803 child_index_in_parent / m_pattern));
1804 }
1805
1806 else {
1807 ARCANE_ASSERT((child_index_in_parent < m_pattern * m_pattern * m_pattern && child_index_in_parent >= 0), ("Bad child_index_in_parent"))
1808
1809 const Int64 to_2d = child_index_in_parent % (m_pattern * m_pattern);
1810 return childCellUniqueIdOfCell(cell,
1811 Int64x3(
1812 to_2d % m_pattern,
1813 to_2d / m_pattern,
1814 child_index_in_parent / (m_pattern * m_pattern)));
1815 }
1816}
1817
1818/*---------------------------------------------------------------------------*/
1819/*---------------------------------------------------------------------------*/
1820
1821Cell CartesianMeshNumberingMng::
1822childCellOfCell(Cell cell, Int64x3 child_coord_in_parent)
1823{
1824 ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x"))
1825 ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y"))
1826
1827 Cell child = cell.hChild((Int32)child_coord_in_parent.x + ((Int32)child_coord_in_parent.y * m_pattern) + ((Int32)child_coord_in_parent.z * m_pattern * m_pattern));
1828 const Int64 uid = childCellUniqueIdOfCell(cell, child_coord_in_parent);
1829
1830 // Si jamais la maille à l'index calculé ne correspond pas à l'uniqueId
1831 // recherché, on recherche parmi les autres mailles enfants.
1832 if (child.uniqueId() != uid) {
1833 const Int32 nb_children = cell.nbHChildren();
1834 for (Integer i = 0; i < nb_children; ++i) {
1835 if (cell.hChild(i).uniqueId() == uid) {
1836 return cell.hChild(i);
1837 }
1838 }
1839 ARCANE_FATAL("Unknown cell uid -- uid : {0} -- parent_uid : {1}", uid, cell.uniqueId());
1840 }
1841 return child;
1842}
1843
1844/*---------------------------------------------------------------------------*/
1845/*---------------------------------------------------------------------------*/
1846
1847Cell CartesianMeshNumberingMng::
1848childCellOfCell(Cell cell, Int64x2 child_coord_in_parent)
1849{
1850 ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x"))
1851 ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y"))
1852
1853 Cell child = cell.hChild((Int32)child_coord_in_parent.x + ((Int32)child_coord_in_parent.y * m_pattern));
1854 const Int64 uid = childCellUniqueIdOfCell(cell, child_coord_in_parent);
1855
1856 // Si jamais la maille à l'index calculé ne correspond pas à l'uniqueId
1857 // recherché, on recherche parmi les autres mailles enfants.
1858 if (child.uniqueId() != uid) {
1859 const Int32 nb_children = cell.nbHChildren();
1860 for (Integer i = 0; i < nb_children; ++i) {
1861 if (cell.hChild(i).uniqueId() == uid) {
1862 return cell.hChild(i);
1863 }
1864 }
1865 ARCANE_FATAL("Unknown cell uid -- uid : {0} -- parent_uid : {1}", uid, cell.uniqueId());
1866 }
1867 return child;
1868}
1869
1870/*---------------------------------------------------------------------------*/
1871/*---------------------------------------------------------------------------*/
1872
1873Int64 CartesianMeshNumberingMng::
1874parentNodeUniqueIdOfNode(Int64 uid, Integer level, bool do_fatal)
1875{
1876 // Pour avoir le noeud parent d'un noeud, on passe d'abord de l'uid vers les
1877 // coordonnées du noeud, puis on détermine les coordonnées du parent grâce au m_pattern,
1878 // et enfin, on repasse des coordonnées du parent vers son uid.
1879
1880 const Int64 coord_x = nodeUniqueIdToCoordX(uid, level);
1881 const Int64 coord_y = nodeUniqueIdToCoordY(uid, level);
1882
1883 if (coord_x % m_pattern != 0 || coord_y % m_pattern != 0) {
1884 if (do_fatal) {
1885 ARCANE_FATAL("Node uid={0} do not have parent", uid);
1886 }
1887 return NULL_ITEM_UNIQUE_ID;
1888 }
1889
1890 if (m_dimension == 2) {
1891 return nodeUniqueId(level - 1,
1892 Int64x2(offsetLevelToLevel(coord_x, level, level - 1),
1893 offsetLevelToLevel(coord_y, level, level - 1)));
1894 }
1895 else {
1896 const Int64 coord_z = nodeUniqueIdToCoordZ(uid, level);
1897
1898 if (coord_z % m_pattern != 0) {
1899 if (do_fatal) {
1900 ARCANE_FATAL("Node uid={0} do not have parent", uid);
1901 }
1902 return NULL_ITEM_UNIQUE_ID;
1903 }
1904 return nodeUniqueId(level - 1,
1905 Int64x3(offsetLevelToLevel(coord_x, level, level - 1),
1906 offsetLevelToLevel(coord_y, level, level - 1),
1907 offsetLevelToLevel(coord_z, level, level - 1)));
1908 }
1909}
1910
1911/*---------------------------------------------------------------------------*/
1912/*---------------------------------------------------------------------------*/
1913
1914Int64 CartesianMeshNumberingMng::
1915parentNodeUniqueIdOfNode(Node node, bool do_fatal)
1916{
1917 const Int64 uid = node.uniqueId();
1918 return parentNodeUniqueIdOfNode(uid, nodeLevel(uid), do_fatal);
1919}
1920
1921/*---------------------------------------------------------------------------*/
1922/*---------------------------------------------------------------------------*/
1923
1924Int64 CartesianMeshNumberingMng::
1925childNodeUniqueIdOfNode(Int64 uid, Integer level)
1926{
1927 if (m_dimension == 2) {
1928 return nodeUniqueId(level + 1,
1929 Int64x2(offsetLevelToLevel(nodeUniqueIdToCoordX(uid, level), level, level + 1),
1930 offsetLevelToLevel(nodeUniqueIdToCoordY(uid, level), level, level + 1)));
1931 }
1932
1933 else {
1934 return nodeUniqueId(level + 1,
1935 Int64x3(offsetLevelToLevel(nodeUniqueIdToCoordX(uid, level), level, level + 1),
1936 offsetLevelToLevel(nodeUniqueIdToCoordY(uid, level), level, level + 1),
1937 offsetLevelToLevel(nodeUniqueIdToCoordZ(uid, level), level, level + 1)));
1938 }
1939}
1940
1941/*---------------------------------------------------------------------------*/
1942/*---------------------------------------------------------------------------*/
1943
1944Int64 CartesianMeshNumberingMng::
1945childNodeUniqueIdOfNode(Node node)
1946{
1947 const Int64 uid = node.uniqueId();
1948 return childNodeUniqueIdOfNode(uid, nodeLevel(uid));
1949}
1950
1951/*---------------------------------------------------------------------------*/
1952/*---------------------------------------------------------------------------*/
1953
1954Int64 CartesianMeshNumberingMng::
1955parentFaceUniqueIdOfFace(Int64 uid, Integer level, bool do_fatal)
1956{
1957 if (m_converting_numbering_face && level == m_ori_level) {
1958 uid = m_face_ori_numbering_to_new[uid];
1959 }
1960
1961 // Pour avoir la face parent d'une face, on passe d'abord de l'uid vers les
1962 // coordonnées de la face en "vue cartésienne",
1963 // puis on détermine les coordonnées du parent grâce au m_pattern,
1964 // et enfin, on repasse des coordonnées du parent vers son uid.
1965
1966 const Int64 coord_x = faceUniqueIdToCoordX(uid, level);
1967 const Int64 coord_y = faceUniqueIdToCoordY(uid, level);
1968
1969 ARCANE_ASSERT((coord_x < globalNbFacesXCartesianView(level) && coord_x >= 0), ("Bad coord_x"))
1970 ARCANE_ASSERT((coord_y < globalNbFacesYCartesianView(level) && coord_y >= 0), ("Bad coord_y"))
1971
1972 const Int64 parent_coord_x = faceOffsetLevelToLevel(coord_x, level, level - 1);
1973 const Int64 parent_coord_y = faceOffsetLevelToLevel(coord_y, level, level - 1);
1974
1975 if (parent_coord_x == -1 || parent_coord_y == -1) {
1976 if (do_fatal) {
1977 ARCANE_FATAL("Face uid={0} do not have parent", uid);
1978 }
1979 return NULL_ITEM_UNIQUE_ID;
1980 }
1981
1982 ARCANE_ASSERT((parent_coord_x < globalNbFacesXCartesianView(level - 1) && parent_coord_x >= 0), ("Bad parent_coord_x"))
1983 ARCANE_ASSERT((parent_coord_y < globalNbFacesYCartesianView(level - 1) && parent_coord_y >= 0), ("Bad parent_coord_y"))
1984
1985 if (m_dimension == 2) {
1986 if (m_converting_numbering_face && level - 1 == m_ori_level) {
1987 return m_face_new_numbering_to_ori[faceUniqueId(level - 1, Int64x2(parent_coord_x, parent_coord_y))];
1988 }
1989 return faceUniqueId(level - 1, Int64x2(parent_coord_x, parent_coord_y));
1990 }
1991 else {
1992 const Int64 coord_z = faceUniqueIdToCoordZ(uid, level);
1993 ARCANE_ASSERT((coord_z < globalNbFacesZCartesianView(level) && coord_z >= 0), ("Bad coord_z"))
1994
1995 const Int64 parent_coord_z = faceOffsetLevelToLevel(coord_z, level, level - 1);
1996
1997 if (parent_coord_z == -1) {
1998 if (do_fatal) {
1999 ARCANE_FATAL("Face uid={0} do not have parent", uid);
2000 }
2001 return NULL_ITEM_UNIQUE_ID;
2002 }
2003
2004 ARCANE_ASSERT((parent_coord_z < globalNbFacesZCartesianView(level - 1) && parent_coord_z >= 0), ("Bad parent_coord_z"))
2005
2006 // debug() << "Uid : " << uid << " -- CoordX : " << coord_x << " -- CoordY : " << coord_y << " -- CoordZ : " << coord_z;
2007
2008 if (m_converting_numbering_face && level - 1 == m_ori_level) {
2009 return m_face_new_numbering_to_ori[faceUniqueId(level - 1, Int64x3(parent_coord_x, parent_coord_y, parent_coord_z))];
2010 }
2011
2012 return faceUniqueId(level - 1, Int64x3(parent_coord_x, parent_coord_y, parent_coord_z));
2013 }
2014}
2015
2016/*---------------------------------------------------------------------------*/
2017/*---------------------------------------------------------------------------*/
2018
2019Int64 CartesianMeshNumberingMng::
2020parentFaceUniqueIdOfFace(Face face, bool do_fatal)
2021{
2022 const Int64 uid = face.uniqueId();
2023 return parentFaceUniqueIdOfFace(uid, faceLevel(uid), do_fatal);
2024}
2025
2026/*---------------------------------------------------------------------------*/
2027/*---------------------------------------------------------------------------*/
2028
2029Int64 CartesianMeshNumberingMng::
2030childFaceUniqueIdOfFace(Int64 uid, Integer level, Int64 child_index_in_parent)
2031{
2032 if (m_converting_numbering_face && level == m_ori_level) {
2033 uid = m_face_ori_numbering_to_new[uid];
2034 }
2035
2036 const Int64 coord_x = faceUniqueIdToCoordX(uid, level);
2037 const Int64 coord_y = faceUniqueIdToCoordY(uid, level);
2038
2039 ARCANE_ASSERT((coord_x < globalNbFacesXCartesianView(level) && coord_x >= 0), ("Bad coord_x"))
2040 ARCANE_ASSERT((coord_y < globalNbFacesYCartesianView(level) && coord_y >= 0), ("Bad coord_y"))
2041
2042 Int64 first_child_coord_x = faceOffsetLevelToLevel(coord_x, level, level + 1);
2043 Int64 first_child_coord_y = faceOffsetLevelToLevel(coord_y, level, level + 1);
2044
2045 ARCANE_ASSERT((first_child_coord_x < globalNbFacesXCartesianView(level + 1) && first_child_coord_x >= 0), ("Bad first_child_coord_x"))
2046 ARCANE_ASSERT((first_child_coord_y < globalNbFacesYCartesianView(level + 1) && first_child_coord_y >= 0), ("Bad first_child_coord_y"))
2047
2048 if (m_dimension == 2) {
2049 ARCANE_ASSERT((child_index_in_parent < m_pattern && child_index_in_parent >= 0), ("Invalid child_index_in_parent"))
2050
2051 if (coord_y % 2 == 0) {
2052 first_child_coord_x += child_index_in_parent * 2;
2053 }
2054 else if (coord_x % 2 == 0) {
2055 first_child_coord_y += child_index_in_parent * globalNbFacesY(level + 1);
2056 }
2057 else {
2058 ARCANE_FATAL("Impossible normalement");
2059 }
2060
2061 if (m_converting_numbering_face && level + 1 == m_ori_level) {
2062 return m_face_new_numbering_to_ori[faceUniqueId(level + 1, Int64x2(first_child_coord_x, first_child_coord_y))];
2063 }
2064
2065 return faceUniqueId(level + 1, Int64x2(first_child_coord_x, first_child_coord_y));
2066 }
2067
2068 else {
2069 ARCANE_ASSERT((child_index_in_parent < m_pattern * m_pattern && child_index_in_parent >= 0), ("Invalid child_index_in_parent"))
2070
2071 const Int64 coord_z = faceUniqueIdToCoordZ(uid, level);
2072 ARCANE_ASSERT((coord_z < globalNbFacesZCartesianView(level) && coord_z >= 0), ("Bad coord_z"))
2073
2074 Int64 first_child_coord_z = faceOffsetLevelToLevel(coord_z, level, level + 1);
2075 ARCANE_ASSERT((first_child_coord_z < globalNbFacesZCartesianView(level + 1) && first_child_coord_z >= 0), ("Bad first_child_coord_z"))
2076
2077 Int64 child_x = child_index_in_parent % m_pattern;
2078 Int64 child_y = child_index_in_parent / m_pattern;
2079
2080 Int64x3 three_parts_numbering = face3DNumberingThreeParts(level);
2081
2082 if (uid < three_parts_numbering.x) {
2083 first_child_coord_x += child_x * 2;
2084 first_child_coord_y += child_y * 2;
2085 }
2086 else if (uid < three_parts_numbering.x + three_parts_numbering.y) {
2087 first_child_coord_y += child_x * 2;
2088 first_child_coord_z += child_y * 2;
2089 }
2090 else {
2091 first_child_coord_x += child_x * 2;
2092 first_child_coord_z += child_y * 2;
2093 }
2094
2095 if (m_converting_numbering_face && level + 1 == m_ori_level) {
2096 return m_face_new_numbering_to_ori[faceUniqueId(level + 1, Int64x3(first_child_coord_x, first_child_coord_y, first_child_coord_z))];
2097 }
2098
2099 return faceUniqueId(level + 1, Int64x3(first_child_coord_x, first_child_coord_y, first_child_coord_z));
2100 }
2101}
2102
2103/*---------------------------------------------------------------------------*/
2104/*---------------------------------------------------------------------------*/
2105
2106Int64 CartesianMeshNumberingMng::
2107childFaceUniqueIdOfFace(Face face, Int64 child_index_in_parent)
2108{
2109 const Int64 uid = face.uniqueId();
2110 return childFaceUniqueIdOfFace(uid, faceLevel(uid), child_index_in_parent);
2111}
2112
2113/*---------------------------------------------------------------------------*/
2114/*---------------------------------------------------------------------------*/
2115
2116Int64x3 CartesianMeshNumberingMng::
2117face3DNumberingThreeParts(Integer level) const
2118{
2119 const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level));
2120 return { (nb_cell.z + 1) * nb_cell.x * nb_cell.y, (nb_cell.x + 1) * nb_cell.y * nb_cell.z, (nb_cell.y + 1) * nb_cell.z * nb_cell.x };
2121}
2122
2123/*---------------------------------------------------------------------------*/
2124/*---------------------------------------------------------------------------*/
2125
2126} // End namespace Arcane
2127
2128/*---------------------------------------------------------------------------*/
2129/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
Vue modifiable d'un tableau d'un type T.
void fill(const T &o) noexcept
Remplit le tableau avec la valeur o.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
Int64 parentCellUniqueIdOfCell(Int64 uid, Integer level, bool do_fatal) override
Méthode permettant de récupérer l'uniqueId du parent d'une maille.
Int32 nodeLevel(Int64 uid) const override
Méthode permettant de récupérer le niveau d'un noeud avec son uid.
Int64 parentNodeUniqueIdOfNode(Int64 uid, Integer level, bool do_fatal) override
Méthode permettant de récupérer l'uniqueId du parent d'un noeud.
Int64 globalNbNodesX(Integer level) const override
Méthode permettant de récupérer le nombre de noeuds global en X d'un niveau.
Int64 nbFaceInLevel(Integer level) const override
Méthode permettant de récupérer le nombre de faces total dans un niveau.
Int64 faceUniqueId(Integer level, Int64x3 face_coord) override
Méthode permettant de récupérer l'uniqueId d'une face à partir de sa position et de son niveau.
Int64 faceUniqueIdToCoordY(Int64 uid, Integer level) override
Méthode permettant de récupérer la coordonnée en Y d'une face grâce à son uniqueId.
void cellFaceUniqueIds(ArrayView< Int64 > uid, Integer level, Int64x3 cell_coord) override
Méthode permettant de récupérer les uniqueIds des faces d'une maille à partir de ses coordonnées.
Int64 cellUniqueIdToCoordY(Int64 uid, Integer level) override
Méthode permettant de récupérer la coordonnée en Y d'une maille grâce à son uniqueId.
Int64 firstFaceUniqueId(Integer level) override
Méthode permettant de récupérer le premier unique id utilisé par les faces d'un niveau....
Int64 nbNodeInLevel(Integer level) const override
Méthode permettant de récupérer le nombre de noeuds total dans un niveau.
Integer nbNodeByCell() override
Méthode permettant de récupérer le nombre de noeuds dans une maille.
Int64 nodeUniqueId(Integer level, Int64x3 node_coord) override
Méthode permettant de récupérer l'uniqueId d'un noeud à partir de sa position et de son niveau.
Int64 globalNbCellsX(Integer level) const override
Méthode permettant de récupérer le nombre de mailles global en X d'un niveau.
void cellUniqueIdsAroundCell(ArrayView< Int64 > uid, Int64 cell_uid, Int32 level) override
Méthode permettant de récupérer les uniqueIds des mailles autour de la maille passée en paramètre.
Integer pattern() const override
Méthode permettant de récupérer le pattern de raffinement utilisé dans chaque maille....
Int64 faceUniqueIdToCoordX(Int64 uid, Integer level) override
Méthode permettant de récupérer la coordonnée en X d'une face grâce à son uniqueId.
Int64 nodeUniqueIdToCoordX(Int64 uid, Integer level) override
Méthode permettant de récupérer la coordonnée en X d'un noeud grâce à son uniqueId.
Int64 globalNbFacesX(Integer level) const override
Méthode permettant de récupérer le nombre de faces global en X d'un niveau.
Int64 faceOffsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const override
Méthode permettant d'obtenir la position de la première face enfant à partir de la position de la fac...
Int64 globalNbNodesY(Integer level) const override
Méthode permettant de récupérer le nombre de noeuds global en Y d'un niveau.
Int64 cellUniqueIdToCoordX(Int64 uid, Integer level) override
Méthode permettant de récupérer la coordonnée en X d'une maille grâce à son uniqueId.
Int64 nodeUniqueIdToCoordZ(Int64 uid, Integer level) override
Méthode permettant de récupérer la coordonnée en Z d'un noeud grâce à son uniqueId.
Int64 cellUniqueId(Integer level, Int64x3 cell_coord) override
Méthode permettant de récupérer l'uniqueId d'une maille à partir de sa position et de son niveau.
Int64 offsetLevelToLevel(Int64 coord, Integer level_from, Integer level_to) const override
Méthode permettant d'obtenir la position du premier noeud/maille fille à partir de la position du noe...
Integer nbFaceByCell() override
Méthode permettant de récupérer le nombre de faces dans une maille.
Int64 globalNbCellsZ(Integer level) const override
Méthode permettant de récupérer le nombre de mailles global en Z d'un niveau.
Int64 childNodeUniqueIdOfNode(Int64 uid, Integer level) override
Méthode permettant de récupérer l'uniqueId d'un noeud enfant d'un noeud parent.
Int64 cellUniqueIdToCoordZ(Int64 uid, Integer level) override
Méthode permettant de récupérer la coordonnée en Z d'une maille grâce à son uniqueId.
Int64 nodeUniqueIdToCoordY(Int64 uid, Integer level) override
Méthode permettant de récupérer la coordonnée en Y d'un noeud grâce à son uniqueId.
void cellNodeUniqueIds(ArrayView< Int64 > uid, Integer level, Int64x3 cell_coord) override
Méthode permettant de récupérer les uniqueIds des noeuds d'une maille à partir de ses coordonnées.
Int64 firstNodeUniqueId(Integer level) override
Méthode permettant de récupérer le premier unique id utilisé par les noeuds d'un niveau....
Cell childCellOfCell(Cell cell, Int64x3 child_coord_in_parent) override
Méthode permettant de récupérer une maille enfant d'une maille parent à partir de la position de la m...
Int64 childCellUniqueIdOfCell(Cell cell, Int64x3 child_coord_in_parent) override
Méthode permettant de récupérer l'uniqueId d'une maille enfant d'une maille parent à partir de la pos...
Int64 nbCellInLevel(Integer level) const override
Méthode permettant de récupérer le nombre de mailles total dans un niveau.
Int64 globalNbFacesY(Integer level) const override
Méthode permettant de récupérer le nombre de faces global en Y d'un niveau.
Int64 childFaceUniqueIdOfFace(Int64 uid, Integer level, Int64 child_index_in_parent) override
Méthode permettant de récupérer l'uniqueId d'une face enfant d'une face parent à partir de l'index de...
Int64 faceUniqueIdToCoordZ(Int64 uid, Integer level) override
Méthode permettant de récupérer la coordonnée en Z d'une face grâce à son uniqueId.
Int32 faceLevel(Int64 uid) const override
Méthode permettant de récupérer le niveau d'une face avec son uid.
Int64 globalNbCellsY(Integer level) const override
Méthode permettant de récupérer le nombre de mailles global en Y d'un niveau.
Int64 parentFaceUniqueIdOfFace(Int64 uid, Integer level, bool do_fatal) override
Méthode permettant de récupérer l'uniqueId du parent d'une face.
Int64 globalNbFacesYCartesianView(Integer level) const override
Méthode permettant de récupérer la taille de la vue "grille cartésienne" contenant les noeuds.
Int64 globalNbFacesXCartesianView(Integer level) const override
Méthode permettant de récupérer la taille de la vue "grille cartésienne" contenant les noeuds.
Int64 firstCellUniqueId(Integer level) override
Méthode permettant de récupérer le premier unique id utilisé par les mailles d'un niveau....
Int64 globalNbFacesZCartesianView(Integer level) const override
Méthode permettant de récupérer la taille de la vue "grille cartésienne" contenant les noeuds.
Maille d'un maillage.
Definition Item.h:1191
Int32 nbHChildren() const
Nombre d'enfants pour l'AMR.
Definition Item.h:1307
Cell hChild(Int32 i) const
i-ème enfant AMR
Definition Item.h:1310
Int32 level() const
Definition Item.h:1342
Vue constante d'un tableau de type T.
Face d'une maille.
Definition Item.h:944
Int32 flags() const
Flags de l'entité
@ II_JustAdded
L'entité vient d'être ajoutée.
Definition ItemFlags.h:54
@ II_JustRefined
L'entité vient d'être raffinée.
Definition ItemFlags.h:64
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:779
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:363
Noeud d'un maillage.
Definition Item.h:573
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
-*- 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.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:567
@ MD_DirZ
Direction Z.
@ MD_DirY
Direction Y.
@ MD_DirX
Direction X.
double Real
Type représentant un réel.
std::int32_t Int32
Type entier signé sur 32 bits.
Real y
deuxième composante du triplet
Definition Real3.h:36
Real z
troisième composante du triplet
Definition Real3.h:37
Real x
première composante du triplet
Definition Real3.h:35