Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
CartesianMeshNumberingMngInternal.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* CartesianMeshNumberingMngInternal.cc (C) 2000-2026 */
9/* */
10/* Cartesian mesh numbering manager. Cell and node numbering is quite */
11/* standard, face numbering is explained (among others) in the methods */
12/* 'faceUniqueId()' and 'cellFaceUniqueIds()'. */
13/*---------------------------------------------------------------------------*/
14/*---------------------------------------------------------------------------*/
15
16#include "arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h"
17
18#include "arcane/utils/Vector2.h"
19#include "arcane/utils/ITraceMng.h"
20
21#include "arcane/core/IMesh.h"
22#include "arcane/core/IParallelMng.h"
23#include "arcane/core/VariableTypes.h"
24#include "arcane/core/ICartesianMeshGenerationInfo.h"
25#include "arcane/core/IItemFamily.h"
26#include "arcane/core/IMeshModifier.h"
27#include "arcane/core/Properties.h"
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32namespace Arcane
33{
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38CartesianMeshNumberingMngInternal::
39CartesianMeshNumberingMngInternal(IMesh* mesh)
40: TraceAccessor(mesh->traceMng())
41, m_mesh(mesh)
42, m_dimension(mesh->dimension())
43, m_pattern(2)
44, m_max_level(0)
45, m_min_level(0)
46, m_converting_numbering_face(true)
47, m_ori_level(0)
48{
49 {
50 const auto* m_generation_info = ICartesianMeshGenerationInfo::getReference(m_mesh, true);
51 ConstArrayView<Int64> global_nb_cells_by_direction = m_generation_info->globalNbCells();
52
53 const Int64x3 nb_cell_ground = {
54 global_nb_cells_by_direction[MD_DirX],
55 global_nb_cells_by_direction[MD_DirY],
56 ((m_dimension == 2) ? 1 : global_nb_cells_by_direction[MD_DirZ])
57 };
58
59 m_nb_cell_ground.x = static_cast<CartCoord>(nb_cell_ground.x);
60 m_nb_cell_ground.y = static_cast<CartCoord>(nb_cell_ground.y);
61 m_nb_cell_ground.z = static_cast<CartCoord>(nb_cell_ground.z);
62
63 if (nb_cell_ground.x <= 0)
64 ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirX] (should be >0)", nb_cell_ground.x);
65 if (nb_cell_ground.y <= 0)
66 ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirY] (should be >0)", nb_cell_ground.y);
67 if (nb_cell_ground.z <= 0)
68 ARCANE_FATAL("Bad value '{0}' for globalNbCells()[MD_DirZ] (should be >0)", nb_cell_ground.z);
69
70 if (m_dimension == 2) {
71 m_latest_cell_uid = nb_cell_ground.x * nb_cell_ground.y;
72 m_latest_node_uid = (nb_cell_ground.x + 1) * (nb_cell_ground.y + 1);
73 m_latest_face_uid = (nb_cell_ground.x * nb_cell_ground.y) * 2 + nb_cell_ground.x * 2 + nb_cell_ground.y;
74 }
75 else {
76 m_latest_cell_uid = nb_cell_ground.x * nb_cell_ground.y * nb_cell_ground.z;
77 m_latest_node_uid = (nb_cell_ground.x + 1) * (nb_cell_ground.y + 1) * (nb_cell_ground.z + 1);
78 m_latest_face_uid = (nb_cell_ground.x + 1) * nb_cell_ground.y * nb_cell_ground.z + (nb_cell_ground.y + 1) * nb_cell_ground.z * nb_cell_ground.x + (nb_cell_ground.z + 1) * nb_cell_ground.x * nb_cell_ground.y;
79 }
80 }
81
82 m_first_cell_uid_level.add(0);
83 m_first_node_uid_level.add(0);
84 m_first_face_uid_level.add(0);
85
86 // As long as we use the original numbering for level 0, we must use
87 // a conversion from the original numbering to the new one.
88 // TODO AH: This might not work well in case of repartitioning...
89 if (m_converting_numbering_face) {
90 UniqueArray<Int64> face_uid(CartesianMeshNumberingMngInternal::nbFaceByCell());
91 ENUMERATE_ (Cell, icell, m_mesh->allLevelCells(0)) {
92 CartesianMeshNumberingMngInternal::cellFaceUniqueIds(icell->uniqueId(), 0, face_uid);
93 for (Integer i = 0; i < CartesianMeshNumberingMngInternal::nbFaceByCell(); ++i) {
94 m_face_ori_numbering_to_new[icell->face(i).uniqueId()] = face_uid[i];
95 m_face_new_numbering_to_ori[face_uid[i]] = icell->face(i).uniqueId();
96 // debug() << "Face Ori <-> New -- Ori : " << icell->face(i).uniqueId() << " -- New : " << face_uid[i];
97 }
98 }
99 }
100}
101
102/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
104
105void CartesianMeshNumberingMngInternal::
106build()
107{
108 m_properties = makeRef(new Properties(*(m_mesh->properties()), "CartesianMeshNumberingMngInternal"));
109}
110
111/*---------------------------------------------------------------------------*/
112/*---------------------------------------------------------------------------*/
113
114void CartesianMeshNumberingMngInternal::
115saveInfosInProperties()
116{
117 m_properties->set("Version", 1);
118 m_properties->set("FirstCellUIDByLevel", m_first_cell_uid_level);
119
120 // See how to recalculate upon restart.
121 m_properties->set("FirstNodeUIDByLevel", m_first_node_uid_level);
122 m_properties->set("FirstFaceUIDByLevel", m_first_face_uid_level);
123
124 m_properties->set("OriginalGroundLevelForConverting", m_ori_level);
125}
126
127/*---------------------------------------------------------------------------*/
128/*---------------------------------------------------------------------------*/
129
130void CartesianMeshNumberingMngInternal::
131recreateFromDump()
132{
133 Int32 v = m_properties->getInt32("Version");
134 if (v != 1)
135 ARCANE_FATAL("Bad numbering mng version: trying to read from incompatible checkpoint v={0} expected={1}", v, 1);
136
137 m_properties->get("FirstCellUIDByLevel", m_first_cell_uid_level);
138 m_properties->get("FirstNodeUIDByLevel", m_first_node_uid_level);
139 m_properties->get("FirstFaceUIDByLevel", m_first_face_uid_level);
140
141 m_properties->get("OriginalGroundLevelForConverting", m_ori_level);
142 if (m_ori_level == -1) {
143 m_converting_numbering_face = false;
144 m_face_ori_numbering_to_new.clear();
145 m_face_new_numbering_to_ori.clear();
146 }
147
148 m_nb_cell_ground = { globalNbCellsX(0), globalNbCellsY(0), globalNbCellsZ(0) };
149
150 m_max_level = m_first_cell_uid_level.size() - 1;
151
152 {
153 Integer pos = 0;
154 Int64 max = 0;
155 Integer iter = 0;
156 for (const Int64 elem : m_first_cell_uid_level) {
157 if (elem > max) {
158 max = elem;
159 pos = iter;
160 }
161 iter++;
162 }
163 m_latest_cell_uid = m_first_cell_uid_level[pos] + nbCellInLevel(pos);
164 m_latest_node_uid = m_first_node_uid_level[pos] + nbNodeInLevel(pos);
165 m_latest_face_uid = m_first_face_uid_level[pos] + nbFaceInLevel(pos);
166 }
167}
168
169/*---------------------------------------------------------------------------*/
170/*---------------------------------------------------------------------------*/
171
172void CartesianMeshNumberingMngInternal::
173renumberingFacesLevel0FromOriginalArcaneNumbering()
174{
175 if (!m_converting_numbering_face)
176 return;
177
178 info() << "Renumbering faces of level 0...";
179
181 ENUMERATE_ (Cell, icell, m_mesh->allLevelCells(m_ori_level)) {
182 cellFaceUniqueIds(icell->uniqueId(), m_ori_level, face_uid);
183 for (Integer i = 0; i < nbFaceByCell(); ++i) {
184 // debug() << "Face Ori <-> New -- Ori : " << icell->face(i).uniqueId() << " -- New : " << face_uid[i];
185 icell->face(i).mutableItemBase().setUniqueId(face_uid[i]);
186 }
187 }
188 m_mesh->faceFamily()->notifyItemsUniqueIdChanged();
189 m_mesh->modifier()->endUpdate();
190 m_mesh->checkValidMesh();
191
192 m_converting_numbering_face = false;
193 m_ori_level = -1;
194 m_face_ori_numbering_to_new.clear();
195 m_face_new_numbering_to_ori.clear();
196}
197
198/*---------------------------------------------------------------------------*/
199/*---------------------------------------------------------------------------*/
200
201void CartesianMeshNumberingMngInternal::
202printStatus()
203{
204 ITraceMng* tm = m_mesh->traceMng();
205 Trace::Setter _(tm, "CartesianMeshNumberingMngInternal");
206
207 tm->info() << "CartesianMeshNumberingMngInternal status :";
208
209 // tm->info() << "FirstCellUIDByLevel : " << m_first_cell_uid_level;
210 // tm->info() << "FirstNodeUIDByLevel : " << m_first_node_uid_level;
211 // tm->info() << "FirstFaceUIDByLevel : " << m_first_face_uid_level;
212
213 tm->info() << "LatestCellUID : " << m_latest_cell_uid;
214 tm->info() << "LatestNodeUID : " << m_latest_node_uid;
215 tm->info() << "LatestFaceUID : " << m_latest_face_uid;
216
217 tm->info() << "MinLevel : " << m_min_level;
218 tm->info() << "MaxLevel : " << m_max_level;
219
220 tm->info() << "GroundLevelNbCells : " << m_nb_cell_ground;
221
222 if (m_ori_level == -1) {
223 tm->info() << "Ground Level is renumbered";
224 }
225 else {
226 tm->info() << "Ground Level is not renumbered -- OriginalGroundLevel : " << m_ori_level;
227 }
228
229 for (Integer i = m_min_level; i <= m_max_level; ++i) {
230 tm->info() << "Level " << i << " : ";
231 tm->info() << "\tUID Cells : [" << firstCellUniqueId(i) << ", " << (firstCellUniqueId(i) + nbCellInLevel(i)) << "[";
232 tm->info() << "\tUID Nodes : [" << firstNodeUniqueId(i) << ", " << (firstNodeUniqueId(i) + nbNodeInLevel(i)) << "[";
233 tm->info() << "\tUID Faces : [" << firstFaceUniqueId(i) << ", " << (firstFaceUniqueId(i) + nbFaceInLevel(i)) << "[";
234 }
235
236 const auto* m_generation_info = ICartesianMeshGenerationInfo::getReference(m_mesh, true);
237
238 Int64ConstArrayView global_nb_cells_by_direction = m_generation_info->globalNbCells();
239 tm->info() << "global_nb_cells_by_direction.x : " << global_nb_cells_by_direction[MD_DirX];
240 tm->info() << "global_nb_cells_by_direction.y : " << global_nb_cells_by_direction[MD_DirY];
241 tm->info() << "global_nb_cells_by_direction.z : " << global_nb_cells_by_direction[MD_DirZ];
242}
243
244/*---------------------------------------------------------------------------*/
245/*---------------------------------------------------------------------------*/
246
247void CartesianMeshNumberingMngInternal::
248prepareLevel(Int32 level)
249{
250 if (level <= m_max_level && level >= m_min_level)
251 return;
252 if (level == m_max_level + 1) {
253 m_max_level++;
254 m_first_cell_uid_level.add(m_latest_cell_uid);
255 m_first_node_uid_level.add(m_latest_node_uid);
256 m_first_face_uid_level.add(m_latest_face_uid);
257 }
258 else if (level == m_min_level - 1) {
259 m_min_level--;
260 _pushFront(m_first_cell_uid_level, m_latest_cell_uid);
261 _pushFront(m_first_node_uid_level, m_latest_node_uid);
262 _pushFront(m_first_face_uid_level, m_latest_face_uid);
263 }
264 else {
265 ARCANE_FATAL("Level error : {0}", level);
266 }
267
268 m_latest_cell_uid += nbCellInLevel(level);
269 m_latest_node_uid += nbNodeInLevel(level);
270 m_latest_face_uid += nbFaceInLevel(level);
271}
272
273/*---------------------------------------------------------------------------*/
274/*---------------------------------------------------------------------------*/
275
276void CartesianMeshNumberingMngInternal::
277updateFirstLevel()
278{
279 const Int32 nb_levels_to_add = -m_min_level;
280 m_ori_level += nb_levels_to_add;
281
282 if (nb_levels_to_add == 0) {
283 return;
284 }
285
286 m_max_level += nb_levels_to_add;
287 m_min_level += nb_levels_to_add;
288
289 const Integer to_div = m_pattern * nb_levels_to_add;
290 if (m_dimension == 2) {
291 m_nb_cell_ground.x /= to_div;
292 m_nb_cell_ground.y /= to_div;
293 // z remains 1.
294 }
295 else {
296 m_nb_cell_ground /= to_div;
297 }
298
299 // ----------
300 // CartesianMeshCoarsening2::_recomputeMeshGenerationInfo()
301 // Recalculate the mesh cell count information per direction.
302 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh, false);
303 if (!cmgi)
304 return;
305
306 {
307 ConstArrayView<Int64> v = cmgi->ownCellOffsets();
308 cmgi->setOwnCellOffsets(v[0] / to_div, v[1] / to_div, v[2] / to_div);
309 }
310 {
311 ConstArrayView<Int64> v = cmgi->globalNbCells();
312 cmgi->setGlobalNbCells(v[0] / to_div, v[1] / to_div, v[2] / to_div);
313 }
314 {
315 ConstArrayView<Int32> v = cmgi->ownNbCells();
316 cmgi->setOwnNbCells(v[0] / to_div, v[1] / to_div, v[2] / to_div);
317 }
318 cmgi->setFirstOwnCellUniqueId(firstCellUniqueId(0));
319 // CartesianMeshCoarsening2::_recomputeMeshGenerationInfo()
320 // ----------
321}
322
323/*---------------------------------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
325
326Int64 CartesianMeshNumberingMngInternal::
327firstCellUniqueId(Int32 level) const
328{
329 return m_first_cell_uid_level[level - m_min_level];
330}
331
332/*---------------------------------------------------------------------------*/
333/*---------------------------------------------------------------------------*/
334
335Int64 CartesianMeshNumberingMngInternal::
336firstNodeUniqueId(Int32 level) const
337{
338 return m_first_node_uid_level[level - m_min_level];
339}
340
341/*---------------------------------------------------------------------------*/
342/*---------------------------------------------------------------------------*/
343
344Int64 CartesianMeshNumberingMngInternal::
345firstFaceUniqueId(Int32 level) const
346{
347 return m_first_face_uid_level[level - m_min_level];
348}
349
350/*---------------------------------------------------------------------------*/
351/*---------------------------------------------------------------------------*/
352
353CartCoord CartesianMeshNumberingMngInternal::
354globalNbCellsX(Int32 level) const
355{
356 return static_cast<CartCoord>(static_cast<Real>(m_nb_cell_ground.x) * std::pow(m_pattern, level));
357}
358
359/*---------------------------------------------------------------------------*/
360/*---------------------------------------------------------------------------*/
361
362CartCoord CartesianMeshNumberingMngInternal::
363globalNbCellsY(Int32 level) const
364{
365 return static_cast<CartCoord>(static_cast<Real>(m_nb_cell_ground.y) * std::pow(m_pattern, level));
366}
367
368/*---------------------------------------------------------------------------*/
369/*---------------------------------------------------------------------------*/
370
371CartCoord CartesianMeshNumberingMngInternal::
372globalNbCellsZ(Int32 level) const
373{
374 return static_cast<CartCoord>(static_cast<Real>(m_nb_cell_ground.z) * std::pow(m_pattern, level));
375}
376
377/*---------------------------------------------------------------------------*/
378/*---------------------------------------------------------------------------*/
379
380CartCoord CartesianMeshNumberingMngInternal::
381globalNbNodesX(Int32 level) const
382{
383 return globalNbCellsX(level) + 1;
384}
385
386/*---------------------------------------------------------------------------*/
387/*---------------------------------------------------------------------------*/
388
389CartCoord CartesianMeshNumberingMngInternal::
390globalNbNodesY(Int32 level) const
391{
392 return globalNbCellsY(level) + 1;
393}
394
395/*---------------------------------------------------------------------------*/
396/*---------------------------------------------------------------------------*/
397
398CartCoord CartesianMeshNumberingMngInternal::
399globalNbNodesZ(Int32 level) const
400{
401 return globalNbCellsZ(level) + 1;
402}
403
404/*---------------------------------------------------------------------------*/
405/*---------------------------------------------------------------------------*/
406
407CartCoord CartesianMeshNumberingMngInternal::
408globalNbFacesX(Int32 level) const
409{
410 return globalNbCellsX(level) + 1;
411}
412
413/*---------------------------------------------------------------------------*/
414/*---------------------------------------------------------------------------*/
415
416CartCoord CartesianMeshNumberingMngInternal::
417globalNbFacesY(Int32 level) const
418{
419 return globalNbCellsY(level) + 1;
420}
421
422/*---------------------------------------------------------------------------*/
423/*---------------------------------------------------------------------------*/
424
425CartCoord CartesianMeshNumberingMngInternal::
426globalNbFacesZ(Int32 level) const
427{
428 return globalNbCellsZ(level) + 1;
429}
430
431/*---------------------------------------------------------------------------*/
432/*---------------------------------------------------------------------------*/
433
434CartCoord CartesianMeshNumberingMngInternal::
435globalNbFacesXCartesianView(Int32 level) const
436{
437 return (globalNbCellsX(level) * 2) + 1;
438}
439
440/*---------------------------------------------------------------------------*/
441/*---------------------------------------------------------------------------*/
442
443CartCoord CartesianMeshNumberingMngInternal::
444globalNbFacesYCartesianView(Int32 level) const
445{
446 return (globalNbCellsY(level) * 2) + 1;
447}
448
449/*---------------------------------------------------------------------------*/
450/*---------------------------------------------------------------------------*/
451
452CartCoord CartesianMeshNumberingMngInternal::
453globalNbFacesZCartesianView(Int32 level) const
454{
455 return (globalNbCellsZ(level) * 2) + 1;
456}
457
458/*---------------------------------------------------------------------------*/
459/*---------------------------------------------------------------------------*/
460
461Int64 CartesianMeshNumberingMngInternal::
462nbCellInLevel(Int32 level) const
463{
464 if (m_dimension == 2) {
465 const Int64x2 nb_cell(globalNbCellsX(level), globalNbCellsY(level));
466 return nb_cell.x * nb_cell.y;
467 }
468
469 const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level));
470 return nb_cell.x * nb_cell.y * nb_cell.z;
471}
472
473/*---------------------------------------------------------------------------*/
474/*---------------------------------------------------------------------------*/
475
476Int64 CartesianMeshNumberingMngInternal::
477nbNodeInLevel(Int32 level) const
478{
479 if (m_dimension == 2) {
480 const Int64x2 nb_cell(globalNbCellsX(level), globalNbCellsY(level));
481 return (nb_cell.x + 1) * (nb_cell.y + 1);
482 }
483
484 const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level));
485 return (nb_cell.x + 1) * (nb_cell.y + 1) * (nb_cell.z + 1);
486}
487
488/*---------------------------------------------------------------------------*/
489/*---------------------------------------------------------------------------*/
490
491Int64 CartesianMeshNumberingMngInternal::
492nbFaceInLevel(Int32 level) const
493{
494 if (m_dimension == 2) {
495 const Int64x2 nb_cell(globalNbCellsX(level), globalNbCellsY(level));
496 return (nb_cell.x * nb_cell.y) * 2 + nb_cell.x * 2 + nb_cell.y;
497 }
498
499 const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level));
500 return (nb_cell.x + 1) * nb_cell.y * nb_cell.z + (nb_cell.y + 1) * nb_cell.z * nb_cell.x + (nb_cell.z + 1) * nb_cell.x * nb_cell.y;
501}
502
503/*---------------------------------------------------------------------------*/
504/*---------------------------------------------------------------------------*/
505
506Int32 CartesianMeshNumberingMngInternal::
507pattern() const
508{
509 return m_pattern;
510}
511
512/*---------------------------------------------------------------------------*/
513/*---------------------------------------------------------------------------*/
514
515Int32 CartesianMeshNumberingMngInternal::
516cellLevel(Int64 uid) const
517{
518 Int32 pos = -1;
519 Int64 max = -1;
520
521 for (Int32 i = m_min_level; i <= m_max_level; ++i) {
522 const Int64 first_uid = firstCellUniqueId(i);
523 if (first_uid <= uid && first_uid > max) {
524 pos = i;
525 max = first_uid;
526 }
527 }
528#ifdef ARCANE_CHECK
529 if (max == -1) {
530 ARCANE_FATAL("CellUID is not in any patch (UID too low)");
531 }
532 if (uid >= firstCellUniqueId(pos) + nbCellInLevel(pos)) {
533 ARCANE_FATAL("CellUID is not in any patch (UID too high)");
534 }
535#endif
536 return pos;
537}
538
539/*---------------------------------------------------------------------------*/
540/*---------------------------------------------------------------------------*/
541
542Int32 CartesianMeshNumberingMngInternal::
543nodeLevel(Int64 uid) const
544{
545 Int32 pos = -1;
546 Int64 max = -1;
547
548 for (Int32 i = m_min_level; i <= m_max_level; ++i) {
549 const Int64 first_uid = firstNodeUniqueId(i);
550 if (first_uid <= uid && first_uid > max) {
551 pos = i;
552 max = first_uid;
553 }
554 }
555#ifdef ARCANE_CHECK
556 if (max == -1) {
557 ARCANE_FATAL("NodeUID is not in any patch (UID too low)");
558 }
559 if (uid >= firstNodeUniqueId(pos) + nbNodeInLevel(pos)) {
560 ARCANE_FATAL("NodeUID is not in any patch (UID too high)");
561 }
562#endif
563 return pos;
564}
565
566/*---------------------------------------------------------------------------*/
567/*---------------------------------------------------------------------------*/
568
569Int32 CartesianMeshNumberingMngInternal::
570faceLevel(Int64 uid) const
571{
572 Int32 pos = -1;
573 Int64 max = -1;
574
575 for (Int32 i = m_min_level; i <= m_max_level; ++i) {
576 const Int64 first_uid = firstFaceUniqueId(i);
577 if (first_uid <= uid && first_uid > max) {
578 pos = i;
579 max = first_uid;
580 }
581 }
582#ifdef ARCANE_CHECK
583 if (max == -1) {
584 ARCANE_FATAL("FaceUID is not in any patch (UID too low)");
585 }
586 if (uid >= firstFaceUniqueId(pos) + nbFaceInLevel(pos)) {
587 ARCANE_FATAL("FaceUID is not in any patch (UID too high)");
588 }
589#endif
590 return pos;
591}
592
593/*---------------------------------------------------------------------------*/
594/*---------------------------------------------------------------------------*/
595
596// As long as we have a unique "pattern" for x, y, z, three methods are not needed.
597CartCoord CartesianMeshNumberingMngInternal::
598offsetLevelToLevel(CartCoord coord, Int32 level_from, Int32 level_to) const
599{
600 if (level_from == level_to) {
601 return coord;
602 }
603 if (level_from < level_to) {
604 return coord * static_cast<CartCoord>(std::pow(m_pattern, (level_to - level_from)));
605 }
606 return coord / static_cast<CartCoord>(std::pow(m_pattern, (level_from - level_to)));
607}
608
609/*---------------------------------------------------------------------------*/
610/*---------------------------------------------------------------------------*/
611
612CartCoord3 CartesianMeshNumberingMngInternal::
613offsetLevelToLevel(CartCoord3 coord, Int32 level_from, Int32 level_to) const
614{
615 if (level_from == level_to) {
616 return coord;
617 }
618 if (level_from < level_to) {
619 return coord * static_cast<CartCoord>(std::pow(m_pattern, (level_to - level_from)));
620 }
621 return coord / static_cast<CartCoord>(std::pow(m_pattern, (level_from - level_to)));
622}
623
624/*---------------------------------------------------------------------------*/
625/*---------------------------------------------------------------------------*/
626
627// As long as we have a unique "pattern" for x, y, z, three methods are not needed.
628CartCoord CartesianMeshNumberingMngInternal::
629faceOffsetLevelToLevel(CartCoord coord, Int32 level_from, Int32 level_to) const
630{
631 // Let's assume we have the following faces:
632 // ┌─0──┬──2─┐
633 // 4│ 6│ 8│
634 // ├─5──┼─7──┤
635 // 9│ 11│ 13│
636 // └─10─┴─12─┘
637
638 // For the position of a face, we consider this arrangement:
639 // ┌──┬──┬──┬──┬──┐
640 // │ │ 0│ │ 2│ │
641 // ├──┼──┼──┼──┼──┤
642 // │ 4│ │ 6│ │ 8│
643 // ├──┼──┼──┼──┼──┤
644 // │ │ 5│ │ 7│ │
645 // ├──┼──┼──┼──┼──┤
646 // │ 9│ │11│ │13│
647 // ├──┼──┼──┼──┼──┤
648 // │ │10│ │12│ │
649 // └──┴──┴──┴──┴──┘
650
651 if (level_from == level_to) {
652 return coord;
653 }
654
655 if (level_from < level_to) {
656 const Int32 pattern = m_pattern * (level_to - level_from);
657 if (coord % 2 == 0) {
658 return coord * pattern;
659 }
660 return ((coord - 1) * pattern) + 1;
661 }
662
663 const Int32 pattern = m_pattern * (level_from - level_to);
664 if (coord % 2 == 0) {
665 if (coord % (pattern * 2) == 0) {
666 return coord / pattern;
667 }
668 return -1;
669 }
670
671 // auto a = coord - 1;
672 // auto b = a % (pattern * 2);
673 // auto c = a / (pattern * 2);
674 // auto d = c * (2 * (pattern - 1));
675 // auto e = d + b;
676 // auto f = coord - e;
677 // return f;
678
679 return coord - (((coord - 1) / (pattern * 2) * (2 * (pattern - 1))) + ((coord - 1) % (pattern * 2)));
680}
681
682/*---------------------------------------------------------------------------*/
683/*---------------------------------------------------------------------------*/
684
685CartCoord3 CartesianMeshNumberingMngInternal::
686cellUniqueIdToCoord(Int64 uid, Int32 level)
687{
688 const Int64 nb_cell_x = globalNbCellsX(level);
689 const Int64 nb_cell_y = globalNbCellsY(level);
690 const Int64 first_cell_uid = firstCellUniqueId(level);
691
692 uid -= first_cell_uid;
693
694 const Int64 to2d = uid % (nb_cell_x * nb_cell_y);
695
696 return { static_cast<CartCoord>(to2d % nb_cell_x), static_cast<CartCoord>(to2d / nb_cell_x), static_cast<CartCoord>(uid / (nb_cell_x * nb_cell_y)) };
697}
698
699/*---------------------------------------------------------------------------*/
700/*---------------------------------------------------------------------------*/
701
702CartCoord3 CartesianMeshNumberingMngInternal::
703cellUniqueIdToCoord(Cell cell)
704{
705 return cellUniqueIdToCoord(cell.uniqueId().asInt64(), cell.level());
706}
707
708/*---------------------------------------------------------------------------*/
709/*---------------------------------------------------------------------------*/
710
711CartCoord CartesianMeshNumberingMngInternal::
712cellUniqueIdToCoordX(Int64 uid, Int32 level)
713{
714 const Int64 nb_cell_x = globalNbCellsX(level);
715 const Int64 nb_cell_y = globalNbCellsY(level);
716 const Int64 first_cell_uid = firstCellUniqueId(level);
717
718 uid -= first_cell_uid;
719
720 const Int64 to2d = uid % (nb_cell_x * nb_cell_y);
721 return static_cast<CartCoord>(to2d % nb_cell_x);
722}
723
724/*---------------------------------------------------------------------------*/
725/*---------------------------------------------------------------------------*/
726
727CartCoord CartesianMeshNumberingMngInternal::
728cellUniqueIdToCoordX(Cell cell)
729{
730 return cellUniqueIdToCoordX(cell.uniqueId(), cell.level());
731}
732
733/*---------------------------------------------------------------------------*/
734/*---------------------------------------------------------------------------*/
735
736CartCoord CartesianMeshNumberingMngInternal::
737cellUniqueIdToCoordY(Int64 uid, Int32 level)
738{
739 const Int64 nb_cell_x = globalNbCellsX(level);
740 const Int64 nb_cell_y = globalNbCellsY(level);
741 const Int64 first_cell_uid = firstCellUniqueId(level);
742
743 uid -= first_cell_uid;
744
745 const Int64 to2d = uid % (nb_cell_x * nb_cell_y);
746 return static_cast<CartCoord>(to2d / nb_cell_x);
747}
748
749/*---------------------------------------------------------------------------*/
750/*---------------------------------------------------------------------------*/
751
752CartCoord CartesianMeshNumberingMngInternal::
753cellUniqueIdToCoordY(Cell cell)
754{
755 return cellUniqueIdToCoordY(cell.uniqueId(), cell.level());
756}
757
758/*---------------------------------------------------------------------------*/
759/*---------------------------------------------------------------------------*/
760
761CartCoord CartesianMeshNumberingMngInternal::
762cellUniqueIdToCoordZ(Int64 uid, Int32 level)
763{
764 const Int64 nb_cell_x = globalNbCellsX(level);
765 const Int64 nb_cell_y = globalNbCellsY(level);
766 const Int64 first_cell_uid = firstCellUniqueId(level);
767
768 uid -= first_cell_uid;
769
770 return static_cast<CartCoord>(uid / (nb_cell_x * nb_cell_y));
771}
772
773/*---------------------------------------------------------------------------*/
774/*---------------------------------------------------------------------------*/
775
776CartCoord CartesianMeshNumberingMngInternal::
777cellUniqueIdToCoordZ(Cell cell)
778{
779 return cellUniqueIdToCoordZ(cell.uniqueId(), cell.level());
780}
781
782/*---------------------------------------------------------------------------*/
783/*---------------------------------------------------------------------------*/
784
785CartCoord CartesianMeshNumberingMngInternal::
786nodeUniqueIdToCoordX(Int64 uid, Int32 level)
787{
788 const Int64 nb_node_x = globalNbNodesX(level);
789 const Int64 nb_node_y = globalNbNodesY(level);
790 const Int64 first_node_uid = firstNodeUniqueId(level);
791
792 uid -= first_node_uid;
793
794 const Int64 to2d = uid % (nb_node_x * nb_node_y);
795 return static_cast<CartCoord>(to2d % nb_node_x);
796}
797
798/*---------------------------------------------------------------------------*/
799/*---------------------------------------------------------------------------*/
800
801CartCoord CartesianMeshNumberingMngInternal::
802nodeUniqueIdToCoordX(Node node)
803{
804 const Int64 uid = node.uniqueId().asInt64();
805 return nodeUniqueIdToCoordX(uid, nodeLevel(uid));
806}
807
808/*---------------------------------------------------------------------------*/
809/*---------------------------------------------------------------------------*/
810
811CartCoord CartesianMeshNumberingMngInternal::
812nodeUniqueIdToCoordY(Int64 uid, Int32 level)
813{
814 const Int64 nb_node_x = globalNbNodesX(level);
815 const Int64 nb_node_y = globalNbNodesY(level);
816 const Int64 first_node_uid = firstNodeUniqueId(level);
817
818 uid -= first_node_uid;
819
820 const Int64 to2d = uid % (nb_node_x * nb_node_y);
821 return static_cast<CartCoord>(to2d / nb_node_x);
822}
823
824/*---------------------------------------------------------------------------*/
825/*---------------------------------------------------------------------------*/
826
827CartCoord CartesianMeshNumberingMngInternal::
828nodeUniqueIdToCoordY(Node node)
829{
830 const Int64 uid = node.uniqueId().asInt64();
831 return nodeUniqueIdToCoordY(uid, nodeLevel(uid));
832}
833
834/*---------------------------------------------------------------------------*/
835/*---------------------------------------------------------------------------*/
836
837CartCoord CartesianMeshNumberingMngInternal::
838nodeUniqueIdToCoordZ(Int64 uid, Int32 level)
839{
840 const Int64 nb_node_x = globalNbNodesX(level);
841 const Int64 nb_node_y = globalNbNodesY(level);
842 const Int64 first_node_uid = firstNodeUniqueId(level);
843
844 uid -= first_node_uid;
845
846 return static_cast<CartCoord>(uid / (nb_node_x * nb_node_y));
847}
848
849/*---------------------------------------------------------------------------*/
850/*---------------------------------------------------------------------------*/
851
852CartCoord CartesianMeshNumberingMngInternal::
853nodeUniqueIdToCoordZ(Node node)
854{
855 const Int64 uid = node.uniqueId().asInt64();
856 return nodeUniqueIdToCoordZ(uid, nodeLevel(uid));
857}
858
859/*---------------------------------------------------------------------------*/
860/*---------------------------------------------------------------------------*/
861
862CartCoord CartesianMeshNumberingMngInternal::
863faceUniqueIdToCoordX(Int64 uid, Int32 level)
864{
865 if (m_dimension == 2) {
866
867 const Int64 nb_face_x = globalNbFacesXCartesianView(level);
868 const Int64 first_face_uid = firstFaceUniqueId(level);
869
870 uid -= first_face_uid;
871 uid += 1;
872
873 // The +1 allows the (imaginary) level -1 to start at 0:
874 //
875 // x = 0 1 2 3 4
876 // ┌──┬──┬──┬──┬──┐
877 // y = -1 │ 0│ │ 2│ │ 4│
878 // ┌──┬──┬──┬──┬──┐
879 // y = 0 │ │ 1│ │ 3│ │
880 // ├──┼──┼──┼──┼──┤
881 // y = 1 │ 5│ │ 7│ │ 9│
882 // ├──┼──┼──┼──┼──┤
883 // y = 2 │ │ 6│ │ 8│ │
884 // ├──┼──┼──┼──┼──┤
885 // y = 3 │10│ │12│ │14│
886 // ├──┼──┼──┼──┼──┤
887 // y = 4 │ │11│ │13│ │
888 // └──┴──┴──┴──┴──┘
889 //
890 // If we "drop" the faces (tetris), we get a classic Cartesian numbering.
891
892 return static_cast<CartCoord>(uid % nb_face_x);
893 }
894
895 const Int64 nb_face_x = globalNbFacesX(level);
896 const Int64 nb_cell_x = globalNbCellsX(level);
897 const Int64 first_face_uid = firstFaceUniqueId(level);
898
899 // Int64 initial_uid = uid;
900
901 uid -= first_face_uid;
902
903 Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level);
904
905 // Take the view of the faces in a Cartesian grid of a 2x2x2 mesh:
906 // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4
907 // 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
908 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐
909 // y = 0 │ │ │ │ │ │ │ │ │12│ │13│ │ │ │ │ │ │ │ │ │ │ │18│ │19│ │ │ │ │ │ │ │ │
910 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
911 // y = 1 │ │24│ │25│ │ │ │ 0│ │ 1│ │ 2│ │ │ │28│ │29│ │ │ │ 6│ │ 7│ │ 8│ │ │ │32│ │33│ │
912 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
913 // y = 2 │ │ │ │ │ │ │ │ │14│ │15│ │ │ │ │ │ │ │ │ │ │ │20│ │21│ │ │ │ │ │ │ │ │
914 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
915 // y = 3 │ │26│ │27│ │ │ │ 3│ │ 4│ │ 5│ │ │ │30│ │31│ │ │ │ 9│ │10│ │11│ │ │ │34│ │35│ │
916 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
917 // y = 4 │ │ │ │ │ │ │ │ │16│ │17│ │ │ │ │ │ │ │ │ │ │ │22│ │23│ │ │ │ │ │ │ │ │
918 // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘
919 // │ │ │ │
920 //
921 // We can notice 3 "types of arrangement": faces with uids [0, 11],
922 // faces with uids [12, 23], and faces with uids [24, 35].
923 // We retrieve these intervals using the face3DNumberingThreeParts() method.
924
925 // For the interval [0, 11], we notice that the origin in X is always 0 and that the cells
926 // containing a face are on even X coordinates.
927 // Finally, we have "nb_face_x" faces in X.
928 if (uid < three_parts_numbering.x) {
929
930 // debug() << "faceUniqueIdToCoordX (2)"
931 // << " -- true uid : " << initial_uid
932 // << " -- uid : " << uid
933 // << " -- level : " << level
934 // << " -- three_parts_numbering : " << three_parts_numbering
935 // << " -- nb_face_x : " << nb_face_x
936 // << " -- return : " << ((uid % nb_face_x) * 2);
937
938 return static_cast<CartCoord>((uid % nb_face_x) * 2);
939 }
940
941 // For the interval [12, 23], we notice that the origin in X is always 1 and that the cells
942 // containing a face are on odd X coordinates.
943 // Finally, we have "nb_cell_x" faces in X.
944 if (uid < three_parts_numbering.x + three_parts_numbering.y) {
945 uid -= three_parts_numbering.x;
946 // debug() << "faceUniqueIdToCoordX (3)"
947 // << " -- true uid : " << initial_uid
948 // << " -- uid : " << uid
949 // << " -- level : " << level
950 // << " -- three_parts_numbering : " << three_parts_numbering
951 // << " -- nb_cell_x : " << nb_cell_x
952 // << " -- return : " << ((uid % nb_cell_x) * 2 + 1);
953
954 return static_cast<CartCoord>((uid % nb_cell_x) * 2 + 1);
955 }
956
957 // For the interval [24, 35], we notice that the origin in X is always 1 and that the cells
958 // containing a face are on odd X coordinates.
959 // Finally, we have "nb_cell_x" faces in X.
960 uid -= three_parts_numbering.x + three_parts_numbering.y;
961 // debug() << "faceUniqueIdToCoordX (1)"
962 // << " -- true uid : " << initial_uid
963 // << " -- uid : " << uid
964 // << " -- level : " << level
965 // << " -- three_parts_numbering : " << three_parts_numbering
966 // << " -- nb_cell_x : " << nb_cell_x
967 // << " -- return : " << ((uid % nb_cell_x) * 2 + 1);
968
969 return static_cast<CartCoord>((uid % nb_cell_x) * 2 + 1);
970}
971
972/*---------------------------------------------------------------------------*/
973/*---------------------------------------------------------------------------*/
974
975CartCoord CartesianMeshNumberingMngInternal::
976faceUniqueIdToCoordX(Face face)
977{
978 const Int64 uid = face.uniqueId().asInt64();
979 return faceUniqueIdToCoordX(uid, faceLevel(uid));
980}
981
982/*---------------------------------------------------------------------------*/
983/*---------------------------------------------------------------------------*/
984
985CartCoord CartesianMeshNumberingMngInternal::
986faceUniqueIdToCoordY(Int64 uid, Int32 level)
987{
988 if (m_dimension == 2) {
989 const Int64 nb_face_x = globalNbFacesXCartesianView(level);
990 const Int64 first_face_uid = firstFaceUniqueId(level);
991
992 uid -= first_face_uid;
993 uid += 1;
994
995 // The +1 allows us to have the (imaginary) level -1 starting at 0:
996 //
997 // x = 0 1 2 3 4
998 // ┌──┬──┬──┬──┬──┐
999 // y = -1 │ 0│ │ 2│ │ 4│
1000 // ┌──┬──┬──┬──┬──┐
1001 // y = 0 │ │ 1│ │ 3│ │
1002 // ├──┼──┼──┼──┼──┤
1003 // y = 1 │ 5│ │ 7│ │ 9│
1004 // ├──┼──┼──┼──┼──┤
1005 // y = 2 │ │ 6│ │ 8│ │
1006 // ├──┼──┼──┼──┼──┤
1007 // y = 3 │10│ │12│ │14│
1008 // ├──┼──┼──┼──┼──┤
1009 // y = 4 │ │11│ │13│ │
1010 // └──┴──┴──┴──┴──┘
1011 //
1012 // If, furthermore, we do y+1, we simplify the problem because if we
1013 // "drop" the faces (tetris), we get a classic Cartesian numbering.
1014
1015 const Int64 flat_pos = uid / nb_face_x;
1016 return static_cast<CartCoord>((flat_pos * 2) + (flat_pos % 2 == uid % 2 ? 0 : 1) - 1); // The -1 to "remove" the imaginary level.
1017 }
1018 const Int64 nb_face_x = globalNbFacesX(level);
1019 const Int64 nb_face_y = globalNbFacesY(level);
1020 const Int64 nb_cell_x = globalNbCellsX(level);
1021 const Int64 nb_cell_y = globalNbCellsY(level);
1022 const Int64 first_face_uid = firstFaceUniqueId(level);
1023
1024 // Int64 initial_uid = uid;
1025
1026 uid -= first_face_uid;
1027
1028 Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level);
1029
1030 // Let's take the view of the faces in a Cartesian grid of a 2x2x2 mesh:
1031 // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4
1032 // 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
1033 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐
1034 // y = 0 │ │ │ │ │ │ │ │ │12│ │13│ │ │ │ │ │ │ │ │ │ │ │18│ │19│ │ │ │ │ │ │ │ │
1035 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1036 // y = 1 │ │24│ │25│ │ │ │ 0│ │ 1│ │ 2│ │ │ │28│ │29│ │ │ │ 6│ │ 7│ │ 8│ │ │ │32│ │33│ │
1037 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1038 // y = 2 │ │ │ │ │ │ │ │ │14│ │15│ │ │ │ │ │ │ │ │ │ │ │20│ │21│ │ │ │ │ │ │ │ │
1039 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1040 // y = 3 │ │26│ │27│ │ │ │ 3│ │ 4│ │ 5│ │ │ │30│ │31│ │ │ │ 9│ │10│ │11│ │ │ │34│ │35│ │
1041 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1042 // y = 4 │ │ │ │ │ │ │ │ │16│ │17│ │ │ │ │ │ │ │ │ │ │ │22│ │23│ │ │ │ │ │ │ │ │
1043 // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘
1044 // │ │ │ │
1045 //
1046 // We can notice 3 "types of arrangement": the faces having uids [0, 11],
1047 // the faces having uids [12, 23] and the faces having uids [24, 35].
1048 // We retrieve these intervals using the face3DNumberingThreeParts() method.
1049
1050 // For the interval [0, 1], we notice that the origin in Y is always 1 and that the cells
1051 // containing a face are on odd Ys.
1052 // Finally, we have "nb_cell_y" faces in Y.
1053 if (uid < three_parts_numbering.x) {
1054 uid %= nb_face_x * nb_cell_y;
1055
1056 // debug() << "faceUniqueIdToCoordY (2)"
1057 // << " -- true uid : " << initial_uid
1058 // << " -- uid : " << uid
1059 // << " -- level : " << level
1060 // << " -- three_parts_numbering : " << three_parts_numbering
1061 // << " -- nb_face_x : " << nb_face_x
1062 // << " -- nb_cell_y : " << nb_cell_y
1063 // << " -- return : " << ((uid / nb_face_x) * 2 + 1);
1064
1065 return static_cast<CartCoord>((uid / nb_face_x) * 2 + 1);
1066 }
1067
1068 // For the interval [12, 23], we notice that the origin in Y is always 0 and that the cells
1069 // containing a face are on even Ys.
1070 // Finally, we have "nb_face_y" faces in Y.
1071 if (uid < three_parts_numbering.x + three_parts_numbering.y) {
1072 uid -= three_parts_numbering.x;
1073 uid %= nb_cell_x * nb_face_y;
1074
1075 // debug() << "faceUniqueIdToCoordY (3)"
1076 // << " -- true uid : " << initial_uid
1077 // << " -- uid : " << uid
1078 // << " -- level : " << level
1079 // << " -- three_parts_numbering : " << three_parts_numbering
1080 // << " -- nb_cell_x : " << nb_cell_x
1081 // << " -- nb_face_y : " << nb_face_y
1082 // << " -- return : " << ((uid / nb_cell_x) * 2);
1083
1084 return static_cast<CartCoord>((uid / nb_cell_x) * 2);
1085 }
1086
1087 // For the interval [24, 35], we notice that the origin in Y is always 1 and that the cells
1088 // containing a face are on odd Ys.
1089 // Finally, we have "nb_cell_y" faces in Y.
1090 uid -= three_parts_numbering.x + three_parts_numbering.y;
1091 uid %= nb_cell_x * nb_cell_y;
1092
1093 // debug() << "faceUniqueIdToCoordY (1)"
1094 // << " -- true uid : " << initial_uid
1095 // << " -- uid : " << uid
1096 // << " -- level : " << level
1097 // << " -- three_parts_numbering : " << three_parts_numbering
1098 // << " -- nb_cell_x : " << nb_cell_x
1099 // << " -- nb_cell_y : " << nb_cell_y
1100 // << " -- return : " << ((uid / nb_cell_x) * 2 + 1);
1101
1102 return static_cast<CartCoord>((uid / nb_cell_x) * 2 + 1);
1103}
1104
1105/*---------------------------------------------------------------------------*/
1106/*---------------------------------------------------------------------------*/
1107
1108CartCoord CartesianMeshNumberingMngInternal::
1109faceUniqueIdToCoordY(Face face)
1110{
1111 const Int64 uid = face.uniqueId().asInt64();
1112 return faceUniqueIdToCoordY(uid, faceLevel(uid));
1113}
1114
1115/*---------------------------------------------------------------------------*/
1116/*---------------------------------------------------------------------------*/
1117
1118CartCoord CartesianMeshNumberingMngInternal::
1119faceUniqueIdToCoordZ(Int64 uid, Int32 level)
1120{
1121 const Int64 nb_face_x = globalNbFacesX(level);
1122 const Int64 nb_face_y = globalNbFacesY(level);
1123 const Int64 nb_cell_x = globalNbCellsX(level);
1124 const Int64 nb_cell_y = globalNbCellsY(level);
1125 const Int64 first_face_uid = firstFaceUniqueId(level);
1126
1127 // Int64 initial_uid = uid;
1128
1129 uid -= first_face_uid;
1130
1131 Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level);
1132
1133 // Let's take the view of the faces in a Cartesian grid of a 2x2x2 mesh:
1134 // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4
1135 // 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
1136 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐
1137 // y = 0 │ │ │ │ │ │ │ │ │12│ │13│ │ │ │ │ │ │ │ │ │ │ │18│ │19│ │ │ │ │ │ │ │ │
1138 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1139 // y = 1 │ │24│ │25│ │ │ │ 0│ │ 1│ │ 2│ │ │ │28│ │29│ │ │ │ 6│ │ 7│ │ 8│ │ │ │32│ │33│ │
1140 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1141 // y = 2 │ │ │ │ │ │ │ │ │14│ │15│ │ │ │ │ │ │ │ │ │ │ │20│ │21│ │ │ │ │ │ │ │ │
1142 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1143 // y = 3 │ │26│ │27│ │ │ │ 3│ │ 4│ │ 5│ │ │ │30│ │31│ │ │ │ 9│ │10│ │11│ │ │ │34│ │35│ │
1144 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1145 // y = 4 │ │ │ │ │ │ │ │ │16│ │17│ │ │ │ │ │ │ │ │ │ │ │22│ │23│ │ │ │ │ │ │ │ │
1146 // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘
1147 // │ │ │ │
1148 //
1149 // We can notice 3 "types of arrangement": the faces having uids [0, 11],
1150 // the faces having uids [12, 23] and the faces having uids [24, 35].
1151 // We retrieve these intervals using the face3DNumberingThreeParts() method.
1152
1153 // For the interval [0, 11], we notice that the origin in Z is always 1 and that the cells
1154 // containing a face are on odd Zs.
1155 // Finally, we have "nb_cell_z" faces in Z.
1156 if (uid < three_parts_numbering.x) {
1157
1158 // debug() << "faceUniqueIdToCoordZ (2)"
1159 // << " -- true uid : " << initial_uid
1160 // << " -- uid : " << uid
1161 // << " -- level : " << level
1162 // << " -- three_parts_numbering : " << three_parts_numbering
1163 // << " -- nb_face_x : " << nb_face_x
1164 // << " -- nb_cell_y : " << nb_cell_y
1165 // << " -- return : " << ((uid / (nb_face_x * nb_cell_y)) * 2 + 1);
1166
1167 return static_cast<CartCoord>((uid / (nb_face_x * nb_cell_y)) * 2 + 1);
1168 }
1169
1170 // For the interval [12, 23], we notice that the origin in Z is always 1 and that the cells
1171 // containing a face are on odd Zs.
1172 // Finally, we have "nb_cell_z" faces in Z.
1173 if (uid < three_parts_numbering.x + three_parts_numbering.y) {
1174 uid -= three_parts_numbering.x;
1175
1176 // debug() << "faceUniqueIdToCoordZ (3)"
1177 // << " -- true uid : " << initial_uid
1178 // << " -- uid : " << uid
1179 // << " -- level : " << level
1180 // << " -- three_parts_numbering : " << three_parts_numbering
1181 // << " -- nb_cell_x : " << nb_cell_x
1182 // << " -- nb_face_y : " << nb_face_y
1183 // << " -- return : " << ((uid / (nb_cell_x * nb_face_y)) * 2 + 1);
1184
1185 return static_cast<CartCoord>((uid / (nb_cell_x * nb_face_y)) * 2 + 1);
1186 }
1187
1188 // For the interval [24, 35], we notice that the origin in Z is always 0 and that the cells
1189 // containing a face are on even Zs.
1190 // Finally, we have "nb_face_z" faces in Z.
1191 uid -= three_parts_numbering.x + three_parts_numbering.y;
1192
1193 // debug() << "faceUniqueIdToCoordZ (1)"
1194 // << " -- true uid : " << initial_uid
1195 // << " -- uid : " << uid
1196 // << " -- level : " << level
1197 // << " -- three_parts_numbering : " << three_parts_numbering
1198 // << " -- nb_cell_x : " << nb_cell_x
1199 // << " -- nb_cell_y : " << nb_cell_y
1200 // << " -- return : " << ((uid / (nb_cell_x * nb_cell_y)) * 2);
1201
1202 return static_cast<CartCoord>((uid / (nb_cell_x * nb_cell_y)) * 2);
1203}
1204
1205/*---------------------------------------------------------------------------*/
1206/*---------------------------------------------------------------------------*/
1207
1208CartCoord CartesianMeshNumberingMngInternal::
1209faceUniqueIdToCoordZ(Face face)
1210{
1211 const Int64 uid = face.uniqueId().asInt64();
1212 return faceUniqueIdToCoordZ(uid, faceLevel(uid));
1213}
1214
1215/*---------------------------------------------------------------------------*/
1216/*---------------------------------------------------------------------------*/
1217
1218Int64 CartesianMeshNumberingMngInternal::
1219cellUniqueId(CartCoord3 cell_coord, Int32 level)
1220{
1221 const Int64 nb_cell_x = globalNbCellsX(level);
1222 const Int64 nb_cell_y = globalNbCellsY(level);
1223 const Int64 first_cell_uid = firstCellUniqueId(level);
1224
1225 return (cell_coord.x + cell_coord.y * nb_cell_x + cell_coord.z * nb_cell_x * nb_cell_y) + first_cell_uid;
1226}
1227
1228/*---------------------------------------------------------------------------*/
1229/*---------------------------------------------------------------------------*/
1230
1231Int64 CartesianMeshNumberingMngInternal::
1232cellUniqueId(CartCoord2 cell_coord, Int32 level)
1233{
1234 const Int64 nb_cell_x = globalNbCellsX(level);
1235 const Int64 first_cell_uid = firstCellUniqueId(level);
1236
1237 return (cell_coord.x + cell_coord.y * nb_cell_x) + first_cell_uid;
1238}
1239
1240/*---------------------------------------------------------------------------*/
1241/*---------------------------------------------------------------------------*/
1242
1243Int64 CartesianMeshNumberingMngInternal::
1244nodeUniqueId(CartCoord3 node_coord, Int32 level)
1245{
1246 const Int64 nb_node_x = globalNbNodesX(level);
1247 const Int64 nb_node_y = globalNbNodesY(level);
1248 const Int64 first_node_uid = firstNodeUniqueId(level);
1249
1250 return (node_coord.x + node_coord.y * nb_node_x + node_coord.z * nb_node_x * nb_node_y) + first_node_uid;
1251}
1252
1253/*---------------------------------------------------------------------------*/
1254/*---------------------------------------------------------------------------*/
1255
1256Int64 CartesianMeshNumberingMngInternal::
1257nodeUniqueId(CartCoord2 node_coord, Int32 level)
1258{
1259 const Int64 nb_node_x = globalNbNodesX(level);
1260 const Int64 first_node_uid = firstNodeUniqueId(level);
1261
1262 return (node_coord.x + node_coord.y * nb_node_x) + first_node_uid;
1263}
1264
1265/*---------------------------------------------------------------------------*/
1266/*---------------------------------------------------------------------------*/
1267
1268Int64 CartesianMeshNumberingMngInternal::
1269faceUniqueId(CartCoord3 face_coord, Int32 level)
1270{
1271 const Int64 nb_face_x = globalNbFacesX(level);
1272 const Int64 nb_face_y = globalNbFacesY(level);
1273 const Int64 nb_cell_x = globalNbCellsX(level);
1274 const Int64 nb_cell_y = globalNbCellsY(level);
1275
1276 Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level);
1277 Int64 uid = firstFaceUniqueId(level);
1278
1279 // Let's take the view of the faces in a Cartesian grid of a 2x2x2 mesh:
1280 // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4
1281 // 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
1282 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐
1283 // y = 0 │ │ │ │ │ │ │ │ │12│ │13│ │ │ │ │ │ │ │ │ │ │ │18│ │19│ │ │ │ │ │ │ │ │
1284 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1285 // y = 1 │ │24│ │25│ │ │ │ 0│ │ 1│ │ 2│ │ │ │28│ │29│ │ │ │ 6│ │ 7│ │ 8│ │ │ │32│ │33│ │
1286 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1287 // y = 2 │ │ │ │ │ │ │ │ │14│ │15│ │ │ │ │ │ │ │ │ │ │ │20│ │21│ │ │ │ │ │ │ │ │
1288 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1289 // y = 3 │ │26│ │27│ │ │ │ 3│ │ 4│ │ 5│ │ │ │30│ │31│ │ │ │ 9│ │10│ │11│ │ │ │34│ │35│ │
1290 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1291 // y = 4 │ │ │ │ │ │ │ │ │16│ │17│ │ │ │ │ │ │ │ │ │ │ │22│ │23│ │ │ │ │ │ │ │ │
1292 // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘
1293 // │ │ │ │
1294 //
1295 // We can notice 3 "types of arrangement": the faces having uids [0, 11],
1296 // the faces having uids [12, 23] and the faces having uids [24, 35].
1297 // Here, we want to do the reverse: go from x,y,z coordinates to a uid.
1298 // To identify the three intervals, we look at which coordinate is even.
1299 // Indeed, for the interval [0, 11], we notice that only the z coordinate is even.
1300 // For the interval [12, 23], only the x coordinate is even, and for the interval [24, 35],
1301 // only the y coordinate is even.
1302
1303 // Interval [0, 11].
1304 if (face_coord.x % 2 == 0) {
1305
1306 // Here, we place the cells at the origin 0*0*0 and put them side by side.
1307 face_coord.y -= 1;
1308 face_coord.z -= 1;
1309
1310 face_coord /= 2;
1311
1312 // We are now, and for this interval, in a Cartesian view of
1313 // size nb_face_x * nb_cell_y * nb_cell_z.
1314 uid += face_coord.x + (face_coord.y * nb_face_x) + (face_coord.z * nb_face_x * nb_cell_y);
1315 }
1316
1317 // Interval [12, 23].
1318 else if (face_coord.y % 2 == 0) {
1319 uid += three_parts_numbering.x;
1320
1321 // Here, we place the cells at the origin 0*0*0 and put them side by side.
1322 face_coord.x -= 1;
1323 face_coord.z -= 1;
1324
1325 face_coord /= 2;
1326
1327 // We are now, and for this interval, in a Cartesian view of
1328 // size nb_cell_x * nb_face_y * nb_cell_z.
1329 uid += face_coord.x + (face_coord.y * nb_cell_x) + (face_coord.z * nb_cell_x * nb_face_y);
1330 }
1331
1332 // Interval [24, 35].
1333 else if (face_coord.z % 2 == 0) {
1334 uid += three_parts_numbering.x + three_parts_numbering.y;
1335
1336 // Here, we place the cells at the origin 0*0*0 and put them side by side.
1337 face_coord.x -= 1;
1338 face_coord.y -= 1;
1339
1340 face_coord /= 2;
1341
1342 // We are now, and for this interval, in a Cartesian view of
1343 // size nb_cell_x * nb_cell_y * nb_face_z.
1344 uid += face_coord.x + (face_coord.y * nb_cell_x) + (face_coord.z * nb_cell_x * nb_cell_y);
1345 }
1346 else {
1347 ARCANE_FATAL("Bizarre -- x : {0} -- y : {1} -- z : {2}", face_coord.x, face_coord.y, face_coord.z);
1348 }
1349
1350 return uid;
1351}
1352
1353/*---------------------------------------------------------------------------*/
1354/*---------------------------------------------------------------------------*/
1355
1356Int64 CartesianMeshNumberingMngInternal::
1357faceUniqueId(CartCoord2 face_coord, Int32 level)
1358{
1359 const Int64 nb_face_x = globalNbFacesXCartesianView(level);
1360 const Int64 first_face_uid = firstFaceUniqueId(level);
1361
1362 // We consider that we have an imaginary level -1 and that
1363 // we will get uid+1 (in the normally used numbering,
1364 // the face at position (1, 0) has a uid = 0).
1365 //
1366 // x = 0 1 2 3 4
1367 // ┌──┬──┬──┬──┬──┐
1368 // y = -1 │ 0│ │ 2│ │ 4│
1369 // ┌──┬──┬──┬──┬──┐
1370 // y = 0 │ │ 1│ │ 3│ │
1371 // ├──┼──┼──┼──┼──┤
1372 // y = 1 │ 5│ │ 7│ │ 9│
1373 // ├──┼──┼──┼──┼──┤
1374 // y = 2 │ │ 6│ │ 8│ │
1375 // ├──┼──┼──┼──┼──┤
1376 // y = 3 │10│ │12│ │14│
1377 // ├──┼──┼──┼──┼──┤
1378 // y = 4 │ │11│ │13│ │
1379 // └──┴──┴──┴──┴──┘
1380 //
1381
1382 face_coord.y += 1;
1383
1384 const Int64 a = (face_coord.y / 2) * nb_face_x;
1385
1386 return (face_coord.x + a - 1) + first_face_uid; // The -1 is to return to the normal numbering.
1387}
1388
1389/*---------------------------------------------------------------------------*/
1390/*---------------------------------------------------------------------------*/
1391
1392Int32 CartesianMeshNumberingMngInternal::
1393nbNodeByCell()
1394{
1395 return (m_dimension == 2 ? 4 : 8);
1396}
1397
1398/*---------------------------------------------------------------------------*/
1399/*---------------------------------------------------------------------------*/
1400
1401void CartesianMeshNumberingMngInternal::
1402cellNodeUniqueIds(CartCoord3 cell_coord, Int32 level, ArrayView<Int64> uid)
1403{
1404 if (uid.size() != nbNodeByCell())
1405 ARCANE_FATAL("Bad size of arrayview");
1406
1407 const Int64 nb_node_x = globalNbNodesX(level);
1408 const Int64 nb_node_y = globalNbNodesY(level);
1409 const Int64 first_node_uid = firstNodeUniqueId(level);
1410
1411 const Int64 x0 = cell_coord.x + 0;
1412 const Int64 x1 = cell_coord.x + 1;
1413
1414 const Int64 y0 = (cell_coord.y + 0) * nb_node_x;
1415 const Int64 y1 = (cell_coord.y + 1) * nb_node_x;
1416
1417 const Int64 z0 = (cell_coord.z + 0) * nb_node_x * nb_node_y;
1418 const Int64 z1 = (cell_coord.z + 1) * nb_node_x * nb_node_y;
1419
1420 uid[0] = x0 + y0 + z0 + first_node_uid;
1421 uid[1] = x1 + y0 + z0 + first_node_uid;
1422 uid[2] = x1 + y1 + z0 + first_node_uid;
1423 uid[3] = x0 + y1 + z0 + first_node_uid;
1424
1425 uid[4] = x0 + y0 + z1 + first_node_uid;
1426 uid[5] = x1 + y0 + z1 + first_node_uid;
1427 uid[6] = x1 + y1 + z1 + first_node_uid;
1428 uid[7] = x0 + y1 + z1 + first_node_uid;
1429}
1430
1431/*---------------------------------------------------------------------------*/
1432/*---------------------------------------------------------------------------*/
1433
1434void CartesianMeshNumberingMngInternal::
1435cellNodeUniqueIds(CartCoord2 cell_coord, Int32 level, ArrayView<Int64> uid)
1436{
1437 if (uid.size() != nbNodeByCell())
1438 ARCANE_FATAL("Bad size of arrayview");
1439
1440 const Int64 nb_node_x = globalNbNodesX(level);
1441 const Int64 first_node_uid = firstNodeUniqueId(level);
1442
1443 const Int64 x0 = cell_coord.x + 0;
1444 const Int64 x1 = cell_coord.x + 1;
1445
1446 const Int64 y0 = (cell_coord.y + 0) * nb_node_x;
1447 const Int64 y1 = (cell_coord.y + 1) * nb_node_x;
1448
1449 uid[0] = x0 + y0 + first_node_uid;
1450 uid[1] = x1 + y0 + first_node_uid;
1451 uid[2] = x1 + y1 + first_node_uid;
1452 uid[3] = x0 + y1 + first_node_uid;
1453}
1454
1455/*---------------------------------------------------------------------------*/
1456/*---------------------------------------------------------------------------*/
1457
1458void CartesianMeshNumberingMngInternal::
1459cellNodeUniqueIds(Int64 cell_uid, Int32 level, ArrayView<Int64> uid)
1460{
1461 if (m_dimension == 2) {
1462 const CartCoord2 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level));
1463 cellNodeUniqueIds(cell_coord, level, uid);
1464 }
1465 else {
1466 const CartCoord3 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level), cellUniqueIdToCoordZ(cell_uid, level));
1467 cellNodeUniqueIds(cell_coord, level, uid);
1468 }
1469}
1470
1471/*---------------------------------------------------------------------------*/
1472/*---------------------------------------------------------------------------*/
1473
1474void CartesianMeshNumberingMngInternal::
1475cellNodeUniqueIds(Cell cell, ArrayView<Int64> uid)
1476{
1477 cellNodeUniqueIds(cell.uniqueId().asInt64(), cell.level(), uid);
1478}
1479
1480/*---------------------------------------------------------------------------*/
1481/*---------------------------------------------------------------------------*/
1482
1483Int32 CartesianMeshNumberingMngInternal::
1484nbFaceByCell()
1485{
1486 return (m_dimension == 2 ? 4 : 6);
1487}
1488
1489/*---------------------------------------------------------------------------*/
1490/*---------------------------------------------------------------------------*/
1491
1492void CartesianMeshNumberingMngInternal::
1493cellFaceUniqueIds(CartCoord3 cell_coord, Int32 level, ArrayView<Int64> uid)
1494{
1495 if (uid.size() != nbFaceByCell())
1496 ARCANE_FATAL("Bad size of arrayview");
1497
1498 const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level));
1499 const Int64x3 nb_face(nb_cell + 1);
1500
1501 const Int64 first_face_uid = firstFaceUniqueId(level);
1502
1503 // Number the faces
1504 // This algorithm is not based on the 2D algorithm.
1505 // The generated UniqueIDs are contiguous.
1506 // It is also possible to find the UniqueIDs of the faces
1507 // using the cell position and the mesh size.
1508 // Furthermore, the order of the face UniqueIDs of a cell is always the
1509 // same (in Arcane localId notation (cell.face(i)) : 1, 4, 2, 5, 0, 3).
1510 // The generated UniqueIDs are therefore the same regardless of the subdivision.
1511 //
1512 // Let's take the view of the faces in a Cartesian grid of a 2x2x2 mesh:
1513 // z = 0 │ z = 1 │ z = 2 │ z = 3 │ z = 4
1514 // 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
1515 // ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐ │ ┌──┬──┬──┬──┬──┐
1516 // y = 0 │ │ │ │ │ │ │ │ │12│ │13│ │ │ │ │ │ │ │ │ │ │ │18│ │19│ │ │ │ │ │ │ │ │
1517 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1518 // y = 1 │ │24│ │25│ │ │ │ 0│ │ 1│ │ 2│ │ │ │28│ │29│ │ │ │ 6│ │ 7│ │ 8│ │ │ │32│ │33│ │
1519 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1520 // y = 2 │ │ │ │ │ │ │ │ │14│ │15│ │ │ │ │ │ │ │ │ │ │ │20│ │21│ │ │ │ │ │ │ │ │
1521 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1522 // y = 3 │ │26│ │27│ │ │ │ 3│ │ 4│ │ 5│ │ │ │30│ │31│ │ │ │ 9│ │10│ │11│ │ │ │34│ │35│ │
1523 // ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤ │ ├──┼──┼──┼──┼──┤
1524 // y = 4 │ │ │ │ │ │ │ │ │16│ │17│ │ │ │ │ │ │ │ │ │ │ │22│ │23│ │ │ │ │ │ │ │ │
1525 // └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘ │ └──┴──┴──┴──┴──┘
1526 // │ │ │ │
1527 //
1528 // (in this view, the cells are located at odd X, Y, and Z coordinates
1529 // (so here, [1, 1, 1], [3, 1, 1], [1, 3, 1], etc)).
1530 //
1531 // We have a cube decomposed into eight cells (2x2x2).
1532 // The diagram above represents the faces of the cells of this cube with
1533 // the uniqueIDs that the algorithm will generate (without face_adder).
1534 // For this algorithm, we start with the "yz" faces (X direction).
1535 // We enumerate first by x, then by y, then by z.
1536 // Once the "yz" faces are numbered, we do the "zx" faces (Y direction).
1537 // Always the same numbering order.
1538 // We finish with the "xy" faces (Z direction), still in the same order.
1539 //
1540 // In the implementation below, we perform the numbering
1541 // cell by cell.
1542
1543 const Int64 total_face_yz = nb_face.x * nb_cell.y * nb_cell.z;
1544 const Int64 total_face_yz_zx = total_face_yz + nb_face.y * nb_cell.z * nb_cell.x;
1545
1546 const Int64 nb_cell_before_j = cell_coord.y * nb_cell.x;
1547
1548 uid[0] = (cell_coord.z * nb_cell.x * nb_cell.y) + nb_cell_before_j + cell_coord.x + total_face_yz_zx;
1549
1550 uid[3] = uid[0] + nb_cell.x * nb_cell.y;
1551
1552 uid[1] = (cell_coord.z * nb_face.x * nb_cell.y) + (cell_coord.y * nb_face.x) + cell_coord.x;
1553
1554 uid[4] = uid[1] + 1;
1555
1556 uid[2] = (cell_coord.z * nb_cell.x * nb_face.y) + nb_cell_before_j + cell_coord.x + total_face_yz;
1557
1558 uid[5] = uid[2] + nb_cell.x;
1559
1560 uid[0] += first_face_uid;
1561 uid[1] += first_face_uid;
1562 uid[2] += first_face_uid;
1563 uid[3] += first_face_uid;
1564 uid[4] += first_face_uid;
1565 uid[5] += first_face_uid;
1566
1567 // debug() << "Coord : " << cell_coord << " -- UIDs : " << uid;
1568}
1569
1570/*---------------------------------------------------------------------------*/
1571/*---------------------------------------------------------------------------*/
1572
1573void CartesianMeshNumberingMngInternal::
1574cellFaceUniqueIds(CartCoord2 cell_coord, Int32 level, ArrayView<Int64> uid)
1575{
1576 if (uid.size() != nbFaceByCell())
1577 ARCANE_FATAL("Bad size of arrayview");
1578
1579 const Int64 nb_cell_x = globalNbCellsX(level);
1580 const Int64 nb_face_x = nb_cell_x + 1;
1581 const Int64 first_face_uid = firstFaceUniqueId(level);
1582
1583 // Number the faces
1584 // ┌─0──┬──2─┐
1585 // 4│ 6│ 8│
1586 // ├─5──┼─7──┤
1587 // 9│ 11│ 13│
1588 // └─10─┴─12─┘
1589 //
1590 // With this numbering, TOP < LEFT < BOTTOM < RIGHT
1591 // Aside from the uniqueIds of the first row of faces, all
1592 // uniqueIds are contiguous.
1593
1594 // TOP
1595 // - "(current_level_nb_face_x + current_level_nb_cell_x)" :
1596 // the number of RIGHT BOTTOM on top.
1597 // - "cell_coord.y * (current_level_nb_face_x + current_level_nb_cell_x)" :
1598 // the total number of RIGHT BOTTOM on top.
1599 // - "cell_coord.x * 2"
1600 // we advance two by two on the faces of the same "side".
1601 uid[0] = cell_coord.x * 2 + cell_coord.y * (nb_face_x + nb_cell_x);
1602
1603 // BOTTOM
1604 // For BOTTOM, it is like TOP but with an additional "number of face on top".
1605 uid[2] = uid[0] + (nb_face_x + nb_cell_x);
1606 // LEFT
1607 // For LEFT, it is the UID of BOTTOM - 1.
1608 uid[3] = uid[2] - 1;
1609 // RIGHT
1610 // For RIGHT, it is the UID of BOTTOM + 1.
1611 uid[1] = uid[2] + 1;
1612
1613 uid[0] += first_face_uid;
1614 uid[1] += first_face_uid;
1615 uid[2] += first_face_uid;
1616 uid[3] += first_face_uid;
1617}
1618
1619/*---------------------------------------------------------------------------*/
1620/*---------------------------------------------------------------------------*/
1621
1622void CartesianMeshNumberingMngInternal::
1623cellFaceUniqueIds(Int64 cell_uid, Int32 level, ArrayView<Int64> uid)
1624{
1625 if (m_dimension == 2) {
1626 const CartCoord2 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level));
1627 cellFaceUniqueIds(cell_coord, level, uid);
1628 }
1629 else {
1630 const CartCoord3 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level), cellUniqueIdToCoordZ(cell_uid, level));
1631 cellFaceUniqueIds(cell_coord, level, uid);
1632 }
1633}
1634
1635/*---------------------------------------------------------------------------*/
1636/*---------------------------------------------------------------------------*/
1637
1638void CartesianMeshNumberingMngInternal::
1639cellFaceUniqueIds(Cell cell, ArrayView<Int64> uid)
1640{
1641 cellFaceUniqueIds(cell.uniqueId().asInt64(), cell.level(), uid);
1642}
1643
1644/*---------------------------------------------------------------------------*/
1645/*---------------------------------------------------------------------------*/
1646
1647void CartesianMeshNumberingMngInternal::
1648cellUniqueIdsAroundCell(CartCoord3 cell_coord, Int32 level, ArrayView<Int64> uid)
1649{
1650 ARCANE_ASSERT((uid.size() == 27), ("Size of uid array != 27"));
1651
1652 uid.fill(-1);
1653
1654 const CartCoord nb_cells_x = globalNbCellsX(level);
1655 const CartCoord nb_cells_y = globalNbCellsY(level);
1656 const CartCoord nb_cells_z = globalNbCellsZ(level);
1657
1658 for (CartCoord k = -1; k < 2; ++k) {
1659 const CartCoord coord_around_cell_z = cell_coord.z + k;
1660 if (coord_around_cell_z >= 0 && coord_around_cell_z < nb_cells_z) {
1661 for (CartCoord j = -1; j < 2; ++j) {
1662 const CartCoord coord_around_cell_y = cell_coord.y + j;
1663
1664 if (coord_around_cell_y >= 0 && coord_around_cell_y < nb_cells_y) {
1665 for (CartCoord i = -1; i < 2; ++i) {
1666 const CartCoord coord_around_cell_x = cell_coord.x + i;
1667
1668 if (coord_around_cell_x >= 0 && coord_around_cell_x < nb_cells_x) {
1669 uid[(i + 1) + ((j + 1) * 3) + ((k + 1) * 9)] = cellUniqueId(CartCoord3{ coord_around_cell_x, coord_around_cell_y, coord_around_cell_z }, level);
1670 }
1671 }
1672 }
1673 }
1674 }
1675 }
1676}
1677
1678/*---------------------------------------------------------------------------*/
1679/*---------------------------------------------------------------------------*/
1680
1681void CartesianMeshNumberingMngInternal::
1682cellUniqueIdsAroundCell(CartCoord2 cell_coord, Int32 level, ArrayView<Int64> uid)
1683{
1684 ARCANE_ASSERT((uid.size() == 9), ("Size of uid array != 9"));
1685
1686 uid.fill(-1);
1687
1688 const CartCoord nb_cells_x = globalNbCellsX(level);
1689 const CartCoord nb_cells_y = globalNbCellsY(level);
1690
1691 for (CartCoord j = -1; j < 2; ++j) {
1692 const CartCoord coord_around_cell_y = cell_coord.y + j;
1693 if (coord_around_cell_y >= 0 && coord_around_cell_y < nb_cells_y) {
1694
1695 for (CartCoord i = -1; i < 2; ++i) {
1696 const CartCoord coord_around_cell_x = cell_coord.x + i;
1697 if (coord_around_cell_x >= 0 && coord_around_cell_x < nb_cells_x) {
1698 uid[(i + 1) + ((j + 1) * 3)] = cellUniqueId(CartCoord2{ coord_around_cell_x, coord_around_cell_y }, level);
1699 }
1700 }
1701 }
1702 }
1703}
1704
1705/*---------------------------------------------------------------------------*/
1706/*---------------------------------------------------------------------------*/
1707
1708void CartesianMeshNumberingMngInternal::
1709cellUniqueIdsAroundCell(Int64 cell_uid, Int32 level, ArrayView<Int64> uid)
1710{
1711 if (m_dimension == 2) {
1712 const CartCoord2 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level));
1713 cellUniqueIdsAroundCell(cell_coord, level, uid);
1714 }
1715 else {
1716 const CartCoord3 cell_coord(cellUniqueIdToCoordX(cell_uid, level), cellUniqueIdToCoordY(cell_uid, level), cellUniqueIdToCoordZ(cell_uid, level));
1717 cellUniqueIdsAroundCell(cell_coord, level, uid);
1718 }
1719}
1720
1721/*---------------------------------------------------------------------------*/
1722/*---------------------------------------------------------------------------*/
1723
1724void CartesianMeshNumberingMngInternal::
1725cellUniqueIdsAroundCell(Cell cell, ArrayView<Int64> uid)
1726{
1727 cellUniqueIdsAroundCell(cell.uniqueId().asInt64(), cell.level(), uid);
1728}
1729
1730/*---------------------------------------------------------------------------*/
1731/*---------------------------------------------------------------------------*/
1732
1733void CartesianMeshNumberingMngInternal::
1734cellUniqueIdsAroundNode(CartCoord3 node_coord, Int32 level, ArrayView<Int64> uid)
1735{
1736 ARCANE_ASSERT((uid.size() == 8), ("Size of uid array != 8"));
1737
1738 uid.fill(-1);
1739
1740 const CartCoord nb_cells_x = globalNbCellsX(level);
1741 const CartCoord nb_cells_y = globalNbCellsY(level);
1742 const CartCoord nb_cells_z = globalNbCellsZ(level);
1743
1744 for (CartCoord k = -1; k < 1; ++k) {
1745 const CartCoord coord_cell_z = node_coord.z + k;
1746 if (coord_cell_z >= 0 && coord_cell_z < nb_cells_z) {
1747
1748 for (CartCoord j = -1; j < 1; ++j) {
1749 const CartCoord coord_cell_y = node_coord.y + j;
1750 if (coord_cell_y >= 0 && coord_cell_y < nb_cells_y) {
1751
1752 for (CartCoord i = -1; i < 1; ++i) {
1753 const CartCoord coord_cell_x = node_coord.x + i;
1754 if (coord_cell_x >= 0 && coord_cell_x < nb_cells_x) {
1755 uid[(i + 1) + ((j + 1) * 2) + ((k + 1) * 4)] = cellUniqueId(CartCoord3{ coord_cell_x, coord_cell_y, coord_cell_z }, level);
1756 }
1757 }
1758 }
1759 }
1760 }
1761 }
1762}
1763
1764/*---------------------------------------------------------------------------*/
1765/*---------------------------------------------------------------------------*/
1766
1767void CartesianMeshNumberingMngInternal::
1768cellUniqueIdsAroundNode(CartCoord2 node_coord, Int32 level, ArrayView<Int64> uid)
1769{
1770 ARCANE_ASSERT((uid.size() == 4), ("Size of uid array != 4"));
1771
1772 uid.fill(-1);
1773
1774 const CartCoord nb_cells_x = globalNbCellsX(level);
1775 const CartCoord nb_cells_y = globalNbCellsY(level);
1776
1777 for (CartCoord j = -1; j < 1; ++j) {
1778 const CartCoord coord_cell_y = node_coord.y + j;
1779 if (coord_cell_y >= 0 && coord_cell_y < nb_cells_y) {
1780
1781 for (CartCoord i = -1; i < 1; ++i) {
1782 const CartCoord coord_cell_x = node_coord.x + i;
1783 if (coord_cell_x >= 0 && coord_cell_x < nb_cells_x) {
1784 uid[(i + 1) + ((j + 1) * 2)] = cellUniqueId(CartCoord2{ coord_cell_x, coord_cell_y }, level);
1785 }
1786 }
1787 }
1788 }
1789}
1790
1791/*---------------------------------------------------------------------------*/
1792/*---------------------------------------------------------------------------*/
1793
1794void CartesianMeshNumberingMngInternal::
1795cellUniqueIdsAroundNode(Int64 node_uid, Int32 level, ArrayView<Int64> uid)
1796{
1797 if (m_dimension == 2) {
1798 const CartCoord2 node_coord{ nodeUniqueIdToCoordX(node_uid, level), nodeUniqueIdToCoordY(node_uid, level) };
1799 cellUniqueIdsAroundNode(node_coord, level, uid);
1800 }
1801 else {
1802 const CartCoord3 node_coord{ nodeUniqueIdToCoordX(node_uid, level), nodeUniqueIdToCoordY(node_uid, level), nodeUniqueIdToCoordZ(node_uid, level) };
1803 cellUniqueIdsAroundNode(node_coord, level, uid);
1804 }
1805}
1806
1807/*---------------------------------------------------------------------------*/
1808/*---------------------------------------------------------------------------*/
1809
1810void CartesianMeshNumberingMngInternal::
1811cellUniqueIdsAroundNode(Node node, ArrayView<Int64> uid)
1812{
1813 cellUniqueIdsAroundNode(node.uniqueId().asInt64(), nodeLevel(node.uniqueId().asInt64()), uid);
1814}
1815
1816/*---------------------------------------------------------------------------*/
1817/*---------------------------------------------------------------------------*/
1818
1819void CartesianMeshNumberingMngInternal::
1820setChildNodeCoordinates(Cell parent_cell)
1821{
1822 if (!(parent_cell.itemBase().flags() & ItemFlags::II_JustRefined)) {
1823 ARCANE_FATAL("Cell not II_JustRefined");
1824 }
1825
1826 VariableNodeReal3& nodes_coords = m_mesh->nodesCoordinates();
1827
1828 const Real3& node0(nodes_coords[parent_cell.node(0)]);
1829 const Real3& node1(nodes_coords[parent_cell.node(1)]);
1830 const Real3& node2(nodes_coords[parent_cell.node(2)]);
1831 const Real3& node3(nodes_coords[parent_cell.node(3)]);
1832
1833 if (m_dimension == 2) {
1834
1835 /*
1836 =
1837 ┌─────────────────────►= y3
1838 │ = ▲ l
1839 ▼ = ▼
1840 X───────────────X◄────►= y2
1841 /▲ /▲ =
1842 / │ / │ =
1843 / │ / │ =
1844 / │ / │ =
1845 / │ / │ =
1846 / │ / │ =
1847 / │ / │ =
1848 / │ / │ =
1849 X───────────────X◄───────│─────►= y1
1850 ▲ │ ▲ │ = ▲ k
1851 │ │ │ │ = ▼
1852 ├──────────────────────────────►= y0
1853 │ │ │ │ =
1854 │ │ │ │ =
1855 ▼ ▼ ▼ ▼
1856 ==============================
1857 x0 ◄───► x3 x1 ◄───► x2
1858 i j
1859 */
1864 auto txty = [&](CartCoord pos_x, CartCoord pos_y) -> Real3 {
1865 const Real x = static_cast<Real>(pos_x) / static_cast<Real>(m_pattern);
1866 const Real y = static_cast<Real>(pos_y) / static_cast<Real>(m_pattern);
1867
1868 const Real i = (node3.x - node0.x) * y + node0.x;
1869 const Real j = (node2.x - node1.x) * y + node1.x;
1870
1871 const Real k = (node1.y - node0.y) * x + node0.y;
1872 const Real l = (node2.y - node3.y) * x + node3.y;
1873
1874 const Real tx = (j - i) * x + i;
1875 const Real ty = (l - k) * y + k;
1876
1877 /*
1878 info() << "[txty]"
1879 << " x : " << x
1880 << " -- y : " << y
1881 << " -- node0 : " << node0
1882 << " -- node1 : " << node1
1883 << " -- node2 : " << node2
1884 << " -- node3 : " << node3
1885 << " -- i : " << i
1886 << " -- j : " << j
1887 << " -- k : " << k
1888 << " -- l : " << l
1889 << " -- tx : " << tx
1890 << " -- ty : " << ty;
1891 */
1892 return { tx, ty, 0 };
1893 };
1894
1895 constexpr CartCoord node_1d_2d_x[] = { 0, 1, 1, 0 };
1896 constexpr CartCoord node_1d_2d_y[] = { 0, 0, 1, 1 };
1897
1898 for (CartCoord j = 0; j < m_pattern; ++j) {
1899 for (CartCoord i = 0; i < m_pattern; ++i) {
1900
1901 Int32 begin = (i == 0 && j == 0 ? 0 : j == 0 ? 1
1902 : 2);
1903 Int32 end = (i == 0 ? nbNodeByCell() : nbNodeByCell() - 1);
1904 Cell child = childCellOfCell(parent_cell, CartCoord2(i, j));
1905
1906 for (Int32 inode = begin; inode < end; ++inode) {
1907 nodes_coords[child.node(inode)] = txty(i + node_1d_2d_x[inode], j + node_1d_2d_y[inode]);
1908 // Real3 pos = txty(i + node_1d_2d_x[inode], j + node_1d_2d_y[inode]);
1909 // nodes_coords[child.node(inode)] = pos;
1910 // info() << "Node uid : " << child.node(inode).uniqueId()
1911 // << " -- nodeX : " << (i + node_1d_2d_x[inode])
1912 // << " -- nodeY : " << (j + node_1d_2d_y[inode])
1913 // << " -- Pos : " << pos;
1914 }
1915 }
1916 }
1917 }
1918
1919 else {
1920 const Real3& node4(nodes_coords[parent_cell.node(4)]);
1921 const Real3& node5(nodes_coords[parent_cell.node(5)]);
1922 const Real3& node6(nodes_coords[parent_cell.node(6)]);
1923 const Real3& node7(nodes_coords[parent_cell.node(7)]);
1924
1929 auto txtytz = [&](CartCoord pos_x, CartCoord pos_y, CartCoord pos_z) -> Real3 {
1930 const Real x = static_cast<Real>(pos_x) / static_cast<Real>(m_pattern);
1931 const Real y = static_cast<Real>(pos_y) / static_cast<Real>(m_pattern);
1932 const Real z = static_cast<Real>(pos_z) / static_cast<Real>(m_pattern);
1933
1934 // Face (m, n, o, p) between faces (node0, node1, node2, node3) and (node4, node5, node6, node7).
1935 const Real3 m = (node4 - node0) * z + node0;
1936 const Real3 n = (node5 - node1) * z + node1;
1937 const Real3 o = (node6 - node2) * z + node2;
1938 const Real3 p = (node7 - node3) * z + node3;
1939
1940 // We calculate tx and ty as in 2D but on the face (m, n, o, p).
1941 const Real i = (p.x - m.x) * y + m.x;
1942 const Real j = (o.x - n.x) * y + n.x;
1943
1944 const Real tx = (j - i) * x + i;
1945
1946 const Real k = (n.y - m.y) * x + m.y;
1947 const Real l = (o.y - p.y) * x + p.y;
1948
1949 const Real ty = (l - k) * y + k;
1950
1951 const Real q = (p.z - m.z) * y + m.z;
1952 const Real r = (o.z - n.z) * y + n.z;
1953
1954 const Real s = (n.z - m.z) * x + m.z;
1955 const Real t = (o.z - p.z) * x + p.z;
1956
1957 const Real tz = (((r - q) * x + q) + ((t - s) * y + s)) * 0.5;
1958
1959 /*
1960 info() << "[txtytz]"
1961 << " x : " << x
1962 << " -- y : " << y
1963 << " -- z : " << z
1964 << " -- node0 : " << node0
1965 << " -- node1 : " << node1
1966 << " -- node2 : " << node2
1967 << " -- node3 : " << node3
1968 << " -- node4 : " << node4
1969 << " -- node5 : " << node5
1970 << " -- node6 : " << node6
1971 << " -- node7 : " << node7
1972 << " -- m : " << m
1973 << " -- n : " << n
1974 << " -- o : " << o
1975 << " -- p : " << p
1976 << " -- j : " << j
1977 << " -- k : " << k
1978 << " -- l : " << l
1979 << " -- q : " << q
1980 << " -- r : " << r
1981 << " -- s : " << s
1982 << " -- t : " << t
1983 << " -- tx : " << tx
1984 << " -- ty : " << ty
1985 << " -- tz : " << tz;
1986 */
1987 return { tx, ty, tz };
1988 };
1989
1990 constexpr CartCoord node_1d_3d_x[] = { 0, 1, 1, 0, 0, 1, 1, 0 };
1991 constexpr CartCoord node_1d_3d_y[] = { 0, 0, 1, 1, 0, 0, 1, 1 };
1992 constexpr CartCoord node_1d_3d_z[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
1993
1994 for (CartCoord k = 0; k < m_pattern; ++k) {
1995 for (CartCoord j = 0; j < m_pattern; ++j) {
1996 for (CartCoord i = 0; i < m_pattern; ++i) {
1997
1998 // TODO : avoid multiple calls for the same node.
1999 Int32 begin = 0;
2000 Int32 end = nbNodeByCell();
2001 Cell child = childCellOfCell(parent_cell, CartCoord3(i, j, k));
2002
2003 for (Int32 inode = begin; inode < end; ++inode) {
2004 nodes_coords[child.node(inode)] = txtytz(i + node_1d_3d_x[inode], j + node_1d_3d_y[inode], k + node_1d_3d_z[inode]);
2005 // Real3 pos = txtytz(i + node_1d_3d_x[inode], j + node_1d_3d_y[inode], k + node_1d_3d_z[inode]);
2006 // nodes_coords[child.node(inode)] = pos;
2007 // info() << "Node uid : " << child.node(inode).uniqueId()
2008 // << " -- nodeX : " << (i + node_1d_3d_x[inode])
2009 // << " -- nodeY : " << (j + node_1d_3d_y[inode])
2010 // << " -- nodeZ : " << (k + node_1d_3d_z[inode])
2011 // << " -- Pos : " << pos;
2012 }
2013 }
2014 }
2015 }
2016 }
2017}
2018
2019/*---------------------------------------------------------------------------*/
2020/*---------------------------------------------------------------------------*/
2021
2022void CartesianMeshNumberingMngInternal::
2023setParentNodeCoordinates(Cell parent_cell)
2024{
2025 if (!(parent_cell.itemBase().flags() & ItemFlags::II_JustAdded)) {
2026 ARCANE_FATAL("Cell not II_JustAdded");
2027 }
2028
2029 VariableNodeReal3& nodes_coords = m_mesh->nodesCoordinates();
2030
2031 if (m_dimension == 2) {
2032 nodes_coords[parent_cell.node(0)] = nodes_coords[childCellOfCell(parent_cell, CartCoord2(0, 0)).node(0)];
2033 nodes_coords[parent_cell.node(1)] = nodes_coords[childCellOfCell(parent_cell, CartCoord2(m_pattern - 1, 0)).node(1)];
2034 nodes_coords[parent_cell.node(2)] = nodes_coords[childCellOfCell(parent_cell, CartCoord2(m_pattern - 1, m_pattern - 1)).node(2)];
2035 nodes_coords[parent_cell.node(3)] = nodes_coords[childCellOfCell(parent_cell, CartCoord2(0, m_pattern - 1)).node(3)];
2036 }
2037
2038 else {
2039 nodes_coords[parent_cell.node(0)] = nodes_coords[childCellOfCell(parent_cell, CartCoord3(0, 0, 0)).node(0)];
2040 nodes_coords[parent_cell.node(1)] = nodes_coords[childCellOfCell(parent_cell, CartCoord3(m_pattern - 1, 0, 0)).node(1)];
2041 nodes_coords[parent_cell.node(2)] = nodes_coords[childCellOfCell(parent_cell, CartCoord3(m_pattern - 1, m_pattern - 1, 0)).node(2)];
2042 nodes_coords[parent_cell.node(3)] = nodes_coords[childCellOfCell(parent_cell, CartCoord3(0, m_pattern - 1, 0)).node(3)];
2043
2044 nodes_coords[parent_cell.node(4)] = nodes_coords[childCellOfCell(parent_cell, CartCoord3(0, 0, m_pattern - 1)).node(4)];
2045 nodes_coords[parent_cell.node(5)] = nodes_coords[childCellOfCell(parent_cell, CartCoord3(m_pattern - 1, 0, m_pattern - 1)).node(5)];
2046 nodes_coords[parent_cell.node(6)] = nodes_coords[childCellOfCell(parent_cell, CartCoord3(m_pattern - 1, m_pattern - 1, m_pattern - 1)).node(6)];
2047 nodes_coords[parent_cell.node(7)] = nodes_coords[childCellOfCell(parent_cell, CartCoord3(0, m_pattern - 1, m_pattern - 1)).node(7)];
2048 }
2049}
2050
2051/*---------------------------------------------------------------------------*/
2052/*---------------------------------------------------------------------------*/
2053
2054Int64 CartesianMeshNumberingMngInternal::
2055parentCellUniqueIdOfCell(Int64 uid, Int32 level, bool do_fatal)
2056{
2057 // To get the parent face of a cell, we first go from the uid to the
2058 // cell coordinates,
2059 // then we determine the parent coordinates using m_pattern,
2060 // and finally, we go from the parent coordinates back to its uid.
2061
2062 if (globalNbCellsX(level - 1) == 0) {
2063 if (do_fatal) {
2064 ARCANE_FATAL("Level {0} do not exist", (level - 1));
2065 }
2066 return NULL_ITEM_UNIQUE_ID;
2067 }
2068
2069 if (m_dimension == 2) {
2070 return cellUniqueId(CartCoord2(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level - 1),
2071 offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level - 1)),
2072 level - 1);
2073 }
2074
2075 return cellUniqueId(CartCoord3(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level - 1),
2076 offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level - 1),
2077 offsetLevelToLevel(cellUniqueIdToCoordZ(uid, level), level, level - 1)),
2078 level - 1);
2079}
2080
2081/*---------------------------------------------------------------------------*/
2082/*---------------------------------------------------------------------------*/
2083
2084Int64 CartesianMeshNumberingMngInternal::
2085parentCellUniqueIdOfCell(Cell cell, bool do_fatal)
2086{
2087 return parentCellUniqueIdOfCell(cell.uniqueId(), cell.level(), do_fatal);
2088}
2089
2090/*---------------------------------------------------------------------------*/
2091/*---------------------------------------------------------------------------*/
2092
2093Int64 CartesianMeshNumberingMngInternal::
2094childCellUniqueIdOfCell(Cell cell, CartCoord3 child_coord_in_parent)
2095{
2096 ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x"))
2097 ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y"))
2098 ARCANE_ASSERT((child_coord_in_parent.z < m_pattern && child_coord_in_parent.z >= 0), ("Bad child_coord_in_parent.z"))
2099
2100 const Int64 uid = cell.uniqueId();
2101 const Int32 level = cell.level();
2102
2103 return cellUniqueId(CartCoord3(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level + 1) + child_coord_in_parent.x,
2104 offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level + 1) + child_coord_in_parent.y,
2105 offsetLevelToLevel(cellUniqueIdToCoordZ(uid, level), level, level + 1) + child_coord_in_parent.z),
2106 level + 1);
2107}
2108
2109/*---------------------------------------------------------------------------*/
2110/*---------------------------------------------------------------------------*/
2111
2112Int64 CartesianMeshNumberingMngInternal::
2113childCellUniqueIdOfCell(Cell cell, CartCoord2 child_coord_in_parent)
2114{
2115 ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x"))
2116 ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y"))
2117
2118 const Int64 uid = cell.uniqueId();
2119 const Int32 level = cell.level();
2120
2121 return cellUniqueId(CartCoord2(offsetLevelToLevel(cellUniqueIdToCoordX(uid, level), level, level + 1) + child_coord_in_parent.x,
2122 offsetLevelToLevel(cellUniqueIdToCoordY(uid, level), level, level + 1) + child_coord_in_parent.y),
2123 level + 1);
2124}
2125
2126/*---------------------------------------------------------------------------*/
2127/*---------------------------------------------------------------------------*/
2128
2129Int64 CartesianMeshNumberingMngInternal::
2130childCellUniqueIdOfCell(Cell cell, Int32 child_index_in_parent)
2131{
2132 if (m_dimension == 2) {
2133 ARCANE_ASSERT((child_index_in_parent < m_pattern * m_pattern && child_index_in_parent >= 0), ("Bad child_index_in_parent"))
2134
2135 return childCellUniqueIdOfCell(cell,
2136 CartCoord2(
2137 child_index_in_parent % m_pattern,
2138 child_index_in_parent / m_pattern));
2139 }
2140
2141 ARCANE_ASSERT((child_index_in_parent < m_pattern * m_pattern * m_pattern && child_index_in_parent >= 0), ("Bad child_index_in_parent"))
2142
2143 const CartCoord to_2d = child_index_in_parent % (m_pattern * m_pattern);
2144 return childCellUniqueIdOfCell(cell,
2145 CartCoord3(
2146 to_2d % m_pattern,
2147 to_2d / m_pattern,
2148 child_index_in_parent / (m_pattern * m_pattern)));
2149}
2150
2151/*---------------------------------------------------------------------------*/
2152/*---------------------------------------------------------------------------*/
2153
2154Cell CartesianMeshNumberingMngInternal::
2155childCellOfCell(Cell cell, CartCoord3 child_coord_in_parent)
2156{
2157 ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x"))
2158 ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y"))
2159
2160 Cell child = cell.hChild(child_coord_in_parent.x + (child_coord_in_parent.y * m_pattern) + (child_coord_in_parent.z * m_pattern * m_pattern));
2161 const Int64 uid = childCellUniqueIdOfCell(cell, child_coord_in_parent);
2162
2163 // If the cell at the calculated index does not match the sought uniqueId,
2164 // we search among the other child cells.
2165 if (child.uniqueId() != uid) {
2166 const Int32 nb_children = cell.nbHChildren();
2167 for (Integer i = 0; i < nb_children; ++i) {
2168 if (cell.hChild(i).uniqueId() == uid) {
2169 return cell.hChild(i);
2170 }
2171 }
2172 ARCANE_FATAL("Unknown cell uid -- uid : {0} -- parent_uid : {1}", uid, cell.uniqueId());
2173 }
2174 return child;
2175}
2176
2177/*---------------------------------------------------------------------------*/
2178/*---------------------------------------------------------------------------*/
2179
2180Cell CartesianMeshNumberingMngInternal::
2181childCellOfCell(Cell cell, CartCoord2 child_coord_in_parent)
2182{
2183 ARCANE_ASSERT((child_coord_in_parent.x < m_pattern && child_coord_in_parent.x >= 0), ("Bad child_coord_in_parent.x"))
2184 ARCANE_ASSERT((child_coord_in_parent.y < m_pattern && child_coord_in_parent.y >= 0), ("Bad child_coord_in_parent.y"))
2185
2186 Cell child = cell.hChild(child_coord_in_parent.x + (child_coord_in_parent.y * m_pattern));
2187 const Int64 uid = childCellUniqueIdOfCell(cell, child_coord_in_parent);
2188
2189 // If the cell at the calculated index does not match the sought uniqueId,
2190 // we search among the other child cells.
2191 if (child.uniqueId() != uid) {
2192 const Int32 nb_children = cell.nbHChildren();
2193 for (Integer i = 0; i < nb_children; ++i) {
2194 if (cell.hChild(i).uniqueId() == uid) {
2195 return cell.hChild(i);
2196 }
2197 }
2198 ARCANE_FATAL("Unknown cell uid -- uid : {0} -- parent_uid : {1}", uid, cell.uniqueId());
2199 }
2200 return child;
2201}
2202
2203/*---------------------------------------------------------------------------*/
2204/*---------------------------------------------------------------------------*/
2205
2206Int64 CartesianMeshNumberingMngInternal::
2207parentNodeUniqueIdOfNode(Int64 uid, Int32 level, bool do_fatal)
2208{
2209 // To get the parent node of a node, we first go from the uid to the
2210 // node coordinates, then we determine the parent coordinates using m_pattern,
2211 // and finally, we go from the parent coordinates back to its uid.
2212
2213 const CartCoord coord_x = nodeUniqueIdToCoordX(uid, level);
2214 const CartCoord coord_y = nodeUniqueIdToCoordY(uid, level);
2215
2216 if (coord_x % m_pattern != 0 || coord_y % m_pattern != 0) {
2217 if (do_fatal) {
2218 ARCANE_FATAL("Node uid={0} do not have parent", uid);
2219 }
2220 return NULL_ITEM_UNIQUE_ID;
2221 }
2222
2223 if (m_dimension == 2) {
2224 return nodeUniqueId(CartCoord2(offsetLevelToLevel(coord_x, level, level - 1),
2225 offsetLevelToLevel(coord_y, level, level - 1)),
2226 level - 1);
2227 }
2228
2229 const CartCoord coord_z = nodeUniqueIdToCoordZ(uid, level);
2230
2231 if (coord_z % m_pattern != 0) {
2232 if (do_fatal) {
2233 ARCANE_FATAL("Node uid={0} do not have parent", uid);
2234 }
2235 return NULL_ITEM_UNIQUE_ID;
2236 }
2237 return nodeUniqueId(CartCoord3(offsetLevelToLevel(coord_x, level, level - 1),
2238 offsetLevelToLevel(coord_y, level, level - 1),
2239 offsetLevelToLevel(coord_z, level, level - 1)),
2240 level - 1);
2241}
2242
2243/*---------------------------------------------------------------------------*/
2244/*---------------------------------------------------------------------------*/
2245
2246Int64 CartesianMeshNumberingMngInternal::
2247parentNodeUniqueIdOfNode(Node node, bool do_fatal)
2248{
2249 const Int64 uid = node.uniqueId().asInt64();
2250 return parentNodeUniqueIdOfNode(uid, nodeLevel(uid), do_fatal);
2251}
2252
2253/*---------------------------------------------------------------------------*/
2254/*---------------------------------------------------------------------------*/
2255
2256Int64 CartesianMeshNumberingMngInternal::
2257childNodeUniqueIdOfNode(Int64 uid, Int32 level)
2258{
2259 if (m_dimension == 2) {
2260 return nodeUniqueId(CartCoord2(offsetLevelToLevel(nodeUniqueIdToCoordX(uid, level), level, level + 1),
2261 offsetLevelToLevel(nodeUniqueIdToCoordY(uid, level), level, level + 1)),
2262 level + 1);
2263 }
2264
2265 return nodeUniqueId(CartCoord3(offsetLevelToLevel(nodeUniqueIdToCoordX(uid, level), level, level + 1),
2266 offsetLevelToLevel(nodeUniqueIdToCoordY(uid, level), level, level + 1),
2267 offsetLevelToLevel(nodeUniqueIdToCoordZ(uid, level), level, level + 1)),
2268 level + 1);
2269}
2270
2271/*---------------------------------------------------------------------------*/
2272/*---------------------------------------------------------------------------*/
2273
2274Int64 CartesianMeshNumberingMngInternal::
2275childNodeUniqueIdOfNode(Node node)
2276{
2277 const Int64 uid = node.uniqueId().asInt64();
2278 return childNodeUniqueIdOfNode(uid, nodeLevel(uid));
2279}
2280
2281/*---------------------------------------------------------------------------*/
2282/*---------------------------------------------------------------------------*/
2283
2284Int64 CartesianMeshNumberingMngInternal::
2285parentFaceUniqueIdOfFace(Int64 uid, Int32 level, bool do_fatal)
2286{
2287 if (m_converting_numbering_face && level == m_ori_level) {
2288 uid = m_face_ori_numbering_to_new[uid];
2289 }
2290
2291 // To get the parent face of a face, we first go from the uid to the
2292 // face coordinates in "Cartesian view",
2293 // then we determine the parent coordinates using m_pattern,
2294 // and finally, we go from the parent coordinates back to its uid.
2295
2296 const CartCoord coord_x = faceUniqueIdToCoordX(uid, level);
2297 const CartCoord coord_y = faceUniqueIdToCoordY(uid, level);
2298
2299 ARCANE_ASSERT((coord_x < globalNbFacesXCartesianView(level) && coord_x >= 0), ("Bad coord_x"))
2300 ARCANE_ASSERT((coord_y < globalNbFacesYCartesianView(level) && coord_y >= 0), ("Bad coord_y"))
2301
2302 const CartCoord parent_coord_x = faceOffsetLevelToLevel(coord_x, level, level - 1);
2303 const CartCoord parent_coord_y = faceOffsetLevelToLevel(coord_y, level, level - 1);
2304
2305 if (parent_coord_x == -1 || parent_coord_y == -1) {
2306 if (do_fatal) {
2307 ARCANE_FATAL("Face uid={0} do not have parent", uid);
2308 }
2309 return NULL_ITEM_UNIQUE_ID;
2310 }
2311
2312 ARCANE_ASSERT((parent_coord_x < globalNbFacesXCartesianView(level - 1) && parent_coord_x >= 0), ("Bad parent_coord_x"))
2313 ARCANE_ASSERT((parent_coord_y < globalNbFacesYCartesianView(level - 1) && parent_coord_y >= 0), ("Bad parent_coord_y"))
2314
2315 if (m_dimension == 2) {
2316 if (m_converting_numbering_face && level - 1 == m_ori_level) {
2317 return m_face_new_numbering_to_ori[faceUniqueId(CartCoord2(parent_coord_x, parent_coord_y), level - 1)];
2318 }
2319 return faceUniqueId(CartCoord2(parent_coord_x, parent_coord_y), level - 1);
2320 }
2321
2322 const CartCoord coord_z = faceUniqueIdToCoordZ(uid, level);
2323 ARCANE_ASSERT((coord_z < globalNbFacesZCartesianView(level) && coord_z >= 0), ("Bad coord_z"))
2324
2325 const CartCoord parent_coord_z = faceOffsetLevelToLevel(coord_z, level, level - 1);
2326
2327 if (parent_coord_z == -1) {
2328 if (do_fatal) {
2329 ARCANE_FATAL("Face uid={0} do not have parent", uid);
2330 }
2331 return NULL_ITEM_UNIQUE_ID;
2332 }
2333
2334 ARCANE_ASSERT((parent_coord_z < globalNbFacesZCartesianView(level - 1) && parent_coord_z >= 0), ("Bad parent_coord_z"))
2335
2336 // debug() << "Uid : " << uid << " -- CoordX : " << coord_x << " -- CoordY : " << coord_y << " -- CoordZ : " << coord_z;
2337
2338 if (m_converting_numbering_face && level - 1 == m_ori_level) {
2339 return m_face_new_numbering_to_ori[faceUniqueId(CartCoord3(parent_coord_x, parent_coord_y, parent_coord_z), level - 1)];
2340 }
2341
2342 return faceUniqueId(CartCoord3(parent_coord_x, parent_coord_y, parent_coord_z), level - 1);
2343}
2344
2345/*---------------------------------------------------------------------------*/
2346/*---------------------------------------------------------------------------*/
2347
2348Int64 CartesianMeshNumberingMngInternal::
2349parentFaceUniqueIdOfFace(Face face, bool do_fatal)
2350{
2351 const Int64 uid = face.uniqueId().asInt64();
2352 return parentFaceUniqueIdOfFace(uid, faceLevel(uid), do_fatal);
2353}
2354
2355/*---------------------------------------------------------------------------*/
2356/*---------------------------------------------------------------------------*/
2357
2358Int64 CartesianMeshNumberingMngInternal::
2359childFaceUniqueIdOfFace(Int64 uid, Int32 level, Int32 child_index_in_parent)
2360{
2361 if (m_converting_numbering_face && level == m_ori_level) {
2362 uid = m_face_ori_numbering_to_new[uid];
2363 }
2364
2365 const CartCoord coord_x = faceUniqueIdToCoordX(uid, level);
2366 const CartCoord coord_y = faceUniqueIdToCoordY(uid, level);
2367
2368 ARCANE_ASSERT((coord_x < globalNbFacesXCartesianView(level) && coord_x >= 0), ("Bad coord_x"))
2369 ARCANE_ASSERT((coord_y < globalNbFacesYCartesianView(level) && coord_y >= 0), ("Bad coord_y"))
2370
2371 CartCoord first_child_coord_x = faceOffsetLevelToLevel(coord_x, level, level + 1);
2372 CartCoord first_child_coord_y = faceOffsetLevelToLevel(coord_y, level, level + 1);
2373
2374 ARCANE_ASSERT((first_child_coord_x < globalNbFacesXCartesianView(level + 1) && first_child_coord_x >= 0), ("Bad first_child_coord_x"))
2375 ARCANE_ASSERT((first_child_coord_y < globalNbFacesYCartesianView(level + 1) && first_child_coord_y >= 0), ("Bad first_child_coord_y"))
2376
2377 if (m_dimension == 2) {
2378 ARCANE_ASSERT((child_index_in_parent < m_pattern && child_index_in_parent >= 0), ("Invalid child_index_in_parent"))
2379
2380 if (coord_y % 2 == 0) {
2381 first_child_coord_x += child_index_in_parent * 2;
2382 }
2383 else if (coord_x % 2 == 0) {
2384 first_child_coord_y += child_index_in_parent * globalNbFacesY(level + 1);
2385 }
2386 else {
2387 ARCANE_FATAL("Impossible normally");
2388 }
2389
2390 if (m_converting_numbering_face && level + 1 == m_ori_level) {
2391 return m_face_new_numbering_to_ori[faceUniqueId(CartCoord2(first_child_coord_x, first_child_coord_y), level + 1)];
2392 }
2393
2394 return faceUniqueId(CartCoord2(first_child_coord_x, first_child_coord_y), level + 1);
2395 }
2396
2397 ARCANE_ASSERT((child_index_in_parent < m_pattern * m_pattern && child_index_in_parent >= 0), ("Invalid child_index_in_parent"))
2398
2399 const CartCoord coord_z = faceUniqueIdToCoordZ(uid, level);
2400 ARCANE_ASSERT((coord_z < globalNbFacesZCartesianView(level) && coord_z >= 0), ("Bad coord_z"))
2401
2402 CartCoord first_child_coord_z = faceOffsetLevelToLevel(coord_z, level, level + 1);
2403 ARCANE_ASSERT((first_child_coord_z < globalNbFacesZCartesianView(level + 1) && first_child_coord_z >= 0), ("Bad first_child_coord_z"))
2404
2405 const CartCoord child_x = child_index_in_parent % m_pattern;
2406 const CartCoord child_y = child_index_in_parent / m_pattern;
2407
2408 Int64x3 three_parts_numbering = _face3DNumberingThreeParts(level);
2409
2410 if (uid < three_parts_numbering.x) {
2411 first_child_coord_y += child_x * 2;
2412 first_child_coord_z += child_y * 2;
2413 }
2414 else if (uid < three_parts_numbering.x + three_parts_numbering.y) {
2415 first_child_coord_x += child_x * 2;
2416 first_child_coord_z += child_y * 2;
2417 }
2418 else {
2419 first_child_coord_x += child_x * 2;
2420 first_child_coord_y += child_y * 2;
2421 }
2422
2423 if (m_converting_numbering_face && level + 1 == m_ori_level) {
2424 return m_face_new_numbering_to_ori[faceUniqueId(CartCoord3(first_child_coord_x, first_child_coord_y, first_child_coord_z), level + 1)];
2425 }
2426
2427 return faceUniqueId(CartCoord3(first_child_coord_x, first_child_coord_y, first_child_coord_z), level + 1);
2428}
2429
2430/*---------------------------------------------------------------------------*/
2431/*---------------------------------------------------------------------------*/
2432
2433Int64 CartesianMeshNumberingMngInternal::
2434childFaceUniqueIdOfFace(Face face, Int32 child_index_in_parent)
2435{
2436 const Int64 uid = face.uniqueId().asInt64();
2437 return childFaceUniqueIdOfFace(uid, faceLevel(uid), child_index_in_parent);
2438}
2439
2440/*---------------------------------------------------------------------------*/
2441/*---------------------------------------------------------------------------*/
2442
2443Int64x3 CartesianMeshNumberingMngInternal::
2444_face3DNumberingThreeParts(Int32 level) const
2445{
2446 const Int64x3 nb_cell(globalNbCellsX(level), globalNbCellsY(level), globalNbCellsZ(level));
2447 return { (nb_cell.x + 1) * nb_cell.y * nb_cell.z, (nb_cell.y + 1) * nb_cell.z * nb_cell.x, (nb_cell.z + 1) * nb_cell.x * nb_cell.y };
2448}
2449
2450/*---------------------------------------------------------------------------*/
2451/*---------------------------------------------------------------------------*/
2452
2453void CartesianMeshNumberingMngInternal::
2454_pushFront(UniqueArray<Int64>& array, const Int64 elem)
2455{
2456 array.resize(array.size() + 1);
2457 array.back() = elem;
2458 for (Integer i = array.size() - 2; i >= 0; --i) {
2459 std::swap(array[i], array[i + 1]);
2460 }
2461}
2462
2463/*---------------------------------------------------------------------------*/
2464/*---------------------------------------------------------------------------*/
2465
2466} // End namespace Arcane
2467
2468/*---------------------------------------------------------------------------*/
2469/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ENUMERATE_(type, name, group)
Generic enumerator for an entity group.
Integer size() const
Number of elements in the vector.
Modifiable view of an array of type T.
void fill(const T &o) noexcept
Fills the array with the value o.
constexpr Integer size() const noexcept
Returns the size of the array.
void resize(Int64 s)
Changes the number of elements in the array to s.
T & back()
Last element of the array.
CartCoord globalNbFacesXCartesianView(Int32 level) const override
Method allowing the retrieval of the size of the "Cartesian grid" view containing the faces.
Int32 pattern() const override
Method allowing the retrieval of the refinement pattern used in each cell. For example,...
Int64 childNodeUniqueIdOfNode(Int64 uid, Int32 level) override
Method to retrieve the uniqueId of a child node of a parent node.
Int64x3 _face3DNumberingThreeParts(Int32 level) const
Method to retrieve the number of faces for the three parts of the numbering.
Int64 nbNodeInLevel(Int32 level) const override
Method allowing the retrieval of the total number of nodes in a level.
Cell childCellOfCell(Cell cell, CartCoord3 child_coord_in_parent) override
Method to retrieve a child cell of a parent cell based on the position of the child cell within the p...
Int64 nbCellInLevel(Int32 level) const override
Method allowing the retrieval of the total number of cells in a level.
CartCoord faceUniqueIdToCoordX(Int64 uid, Int32 level) override
Method to retrieve the X coordinate of a face using its uniqueId.
void cellFaceUniqueIds(CartCoord3 cell_coord, Int32 level, ArrayView< Int64 > uid) override
Method to retrieve the uniqueIds of a cell's faces based on its coordinates.
CartCoord cellUniqueIdToCoordX(Int64 uid, Int32 level) override
Method to retrieve the X coordinate of a cell using its uniqueId.
Int64 childFaceUniqueIdOfFace(Int64 uid, Int32 level, Int32 child_index_in_parent) override
Method to retrieve the uniqueId of a child face of a parent face based on the index of the child face...
void cellUniqueIdsAroundCell(CartCoord3 cell_coord, Int32 level, ArrayView< Int64 > uid) override
Method to retrieve the uniqueIds of cells around a cell.
CartCoord3 cellUniqueIdToCoord(Int64 uid, Int32 level) override
Method to retrieve the coordinates of a cell using its uniqueId.
CartCoord offsetLevelToLevel(CartCoord coord, Int32 level_from, Int32 level_to) const override
Method allowing the retrieval of the position of the first child node/cell from the position of the p...
void cellUniqueIdsAroundNode(CartCoord3 node_coord, Int32 level, ArrayView< Int64 > uid) override
Method to retrieve the uniqueIds of cells around a node.
CartCoord nodeUniqueIdToCoordX(Int64 uid, Int32 level) override
Method to retrieve the X coordinate of a node using its uniqueId.
CartCoord globalNbFacesYCartesianView(Int32 level) const override
Method allowing the retrieval of the size of the "Cartesian grid" view containing the faces.
Int64 parentFaceUniqueIdOfFace(Int64 uid, Int32 level, bool do_fatal) override
Method to retrieve the uniqueId of a face's parent.
Int64 firstFaceUniqueId(Int32 level) const override
Method allowing the retrieval of the first unique ID used by the faces of a level....
Int64 nbFaceInLevel(Int32 level) const override
Method allowing the retrieval of the total number of faces in a level.
CartCoord nodeUniqueIdToCoordY(Int64 uid, Int32 level) override
Method to retrieve the Y coordinate of a node using its uniqueId.
Int32 faceLevel(Int64 uid) const override
Method allowing the retrieval of the level of a face with its UID.
CartCoord faceOffsetLevelToLevel(CartCoord coord, Int32 level_from, Int32 level_to) const override
Method to obtain the position of the first child face from the position of the parent face.
CartCoord globalNbCellsZ(Int32 level) const override
Method allowing the retrieval of the global number of cells in Z for a level.
CartCoord nodeUniqueIdToCoordZ(Int64 uid, Int32 level) override
Method to retrieve the Z coordinate of a node using its uniqueId.
Int64 firstCellUniqueId(Int32 level) const override
Method allowing the retrieval of the first unique ID used by the cells of a level....
Int64 parentNodeUniqueIdOfNode(Int64 uid, Int32 level, bool do_fatal) override
Method to retrieve the uniqueId of a node's parent.
CartCoord globalNbFacesZCartesianView(Int32 level) const override
Method allowing the retrieval of the size of the "Cartesian grid" view containing the faces.
Int32 nbNodeByCell() override
Method to retrieve the number of nodes in a cell.
CartCoord globalNbNodesX(Int32 level) const override
Method allowing the retrieval of the global number of nodes in X for a level.
CartCoord cellUniqueIdToCoordZ(Int64 uid, Int32 level) override
Method to retrieve the Z coordinate of a cell using its uniqueId.
Int32 nbFaceByCell() override
Method to retrieve the number of faces in a cell.
void cellNodeUniqueIds(CartCoord3 cell_coord, Int32 level, ArrayView< Int64 > uid) override
Method to retrieve the uniqueIds of the nodes of a cell from its coordinates.
CartCoord faceUniqueIdToCoordZ(Int64 uid, Int32 level) override
Method to retrieve the Z coordinate of a face using its uniqueId.
CartCoord faceUniqueIdToCoordY(Int64 uid, Int32 level) override
Method to retrieve the Y coordinate of a face using its uniqueId.
Int64 cellUniqueId(CartCoord3 cell_coord, Int32 level) override
Method to retrieve the uniqueId of a cell from its position and level.
CartCoord globalNbCellsX(Int32 level) const override
Method allowing the retrieval of the global number of cells in X for a level.
Int64 nodeUniqueId(CartCoord3 node_coord, Int32 level) override
Method to retrieve the uniqueId of a node from its position and level.
CartCoord globalNbCellsY(Int32 level) const override
Method allowing the retrieval of the global number of cells in Y for a level.
Int64 firstNodeUniqueId(Int32 level) const override
Method allowing the retrieval of the first unique ID used by the nodes of a level....
CartCoord globalNbNodesY(Int32 level) const override
Method allowing the retrieval of the global number of nodes in Y for a level.
Int64 faceUniqueId(CartCoord3 face_coord, Int32 level) override
Method to retrieve the uniqueId of a face from its position and level.
CartCoord globalNbFacesY(Int32 level) const override
Method allowing the retrieval of the global number of faces in Y for a level.
Int32 nodeLevel(Int64 uid) const override
Method allowing the retrieval of the level of a node with its UID.
Int64 childCellUniqueIdOfCell(Cell cell, CartCoord3 child_coord_in_parent) override
Method to retrieve the uniqueId of a child cell of a parent cell based on the position of the child c...
CartCoord globalNbFacesX(Int32 level) const override
Method allowing the retrieval of the global number of faces in X for a level.
CartCoord cellUniqueIdToCoordY(Int64 uid, Int32 level) override
Method to retrieve the Y coordinate of a cell using its uniqueId.
Int64 parentCellUniqueIdOfCell(Int64 uid, Int32 level, bool do_fatal) override
Method to retrieve the uniqueId of a cell's parent.
Cell of a mesh.
Definition Item.h:1300
Int32 nbHChildren() const
Number of children for AMR.
Definition Item.h:1438
Cell hChild(Int32 i) const
i-th AMR child
Definition Item.h:1441
Int32 level() const
Definition Item.h:1473
Constant view of an array of type T.
Face of a cell.
Definition Item.h:1032
virtual TraceMessage info()=0
Stream for an information message.
Int32 flags() const
Flags of the entity.
@ II_JustAdded
The entity has just been added.
Definition ItemFlags.h:62
@ II_JustRefined
The entity has just been refined.
Definition ItemFlags.h:78
Node node(Int32 i) const
i-th node of the entity
Definition Item.h:840
ItemUniqueId uniqueId() const
Unique identifier across all domains.
Definition Item.h:239
impl::ItemBase itemBase() const
Internal part of the entity.
Definition Item.h:383
Node of a mesh.
Definition Item.h:598
Class managing a 3-dimensional real vector.
Definition Real3.h:132
TraceMessage info() const
Flow for an information message.
1D data vector with value semantics (STL style).
T max(const T &a, const T &b, const T &c)
Returns the maximum of three elements.
Definition MathUtils.h:407
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 CartCoord
Represents a coordinate of an element in the Cartesian grid (in X or Y or Z).
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:480
@ MD_DirZ
Z Direction.
@ MD_DirY
Y Direction.
@ MD_DirX
X Direction.
double Real
Type representing a real number.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
Int32x2 CartCoord2
Represents the 2D coordinates of an element in the Cartesian grid {x, y}.
std::int32_t Int32
Signed integer type of 32 bits.
Int32x3 CartCoord3
Represents the 3D coordinates of an element in the Cartesian grid {x, y, z}.
Real y
second component of the triplet
Definition Real3.h:36
Real z
third component of the triplet
Definition Real3.h:37
Real x
first component of the triplet
Definition Real3.h:35