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