Arcane  v4.1.3.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
CartesianMesh.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/* CartesianMesh.cc (C) 2000-2026 */
9/* */
10/* Maillage cartésien. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/TraceAccessor.h"
15#include "arcane/utils/NotImplementedException.h"
16#include "arcane/utils/AutoDestroyUserData.h"
17#include "arcane/utils/IUserDataList.h"
18#include "arcane/utils/Ref.h"
19#include "arcane/utils/ScopedPtr.h"
20#include "arcane/utils/PlatformUtils.h"
21#include "arcane/utils/Event.h"
22
23#include "arcane/core/IMesh.h"
24#include "arcane/core/ItemPrinter.h"
25#include "arcane/core/IItemFamily.h"
26#include "arcane/core/IParallelMng.h"
27#include "arcane/core/VariableTypes.h"
28#include "arcane/core/Properties.h"
29#include "arcane/core/IMeshModifier.h"
30#include "arcane/core/MeshStats.h"
31#include "arcane/core/ICartesianMeshGenerationInfo.h"
32#include "arcane/core/MeshEvents.h"
33#include "arcane/core/MeshKind.h"
34#include "arcane/core/internal/IMeshInternal.h"
35
36#include "arcane/cartesianmesh/internal/CartesianPatchGroup.h"
37#include "arcane/cartesianmesh/ICartesianMesh.h"
38#include "arcane/cartesianmesh/AMRZonePosition.h"
39#include "arcane/cartesianmesh/CartesianConnectivity.h"
40#include "arcane/cartesianmesh/CartesianMeshRenumberingInfo.h"
41#include "arcane/cartesianmesh/CartesianMeshCoarsening.h"
42#include "arcane/cartesianmesh/CartesianMeshCoarsening2.h"
43#include "arcane/cartesianmesh/CartesianMeshPatchListView.h"
44#include "arcane/cartesianmesh/internal/CartesianMeshPatch.h"
45#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
46
47#include "arcane/cartesianmesh/internal/CartesianMeshUniqueIdRenumbering.h"
48#include "arcane/cartesianmesh/v2/CartesianMeshUniqueIdRenumberingV2.h"
49#include "arcane/cartesianmesh/CartesianMeshNumberingMng.h"
50
51#include "arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h"
52#include "arcane/core/IGhostLayerMng.h"
53#include "arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h"
54
55#include <set>
56
57/*---------------------------------------------------------------------------*/
58/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67/*---------------------------------------------------------------------------*/
68
69namespace Arcane
70{
71
72/*---------------------------------------------------------------------------*/
73/*---------------------------------------------------------------------------*/
77class CartesianMeshImpl
78: public TraceAccessor
79, public ICartesianMesh
80{
81 class InternalApi
83 {
84 public:
85
86 explicit InternalApi(CartesianMeshImpl* cartesian_mesh)
87 : m_cartesian_mesh(cartesian_mesh)
88 {
89 }
90
91 public:
92
94 {
95 return m_cartesian_mesh->_createCartesianMeshCoarsening2();
96 }
97 void addPatchFromExistingChildren(ConstArrayView<Int32> parent_cells_local_id) override
98 {
99 m_cartesian_mesh->_addPatchFromExistingChildren(parent_cells_local_id);
100 }
102 {
103 if (m_numbering_mng.isNull()) {
105 }
106 if (m_amr_mng.isNull()) {
107 m_amr_mng = makeRef(new CartesianMeshAMRPatchMng(m_cartesian_mesh, m_numbering_mng.get()));
108 }
109 }
111 {
112 return m_amr_mng;
113 }
115 {
116 if (m_numbering_mng.isNull()) {
117 m_numbering_mng = makeRef(new CartesianMeshNumberingMngInternal(m_cartesian_mesh->mesh()));
118 }
119 }
121 {
122 return m_numbering_mng;
123 }
124 CartesianPatchGroup& cartesianPatchGroup() override { return m_cartesian_mesh->_cartesianPatchGroup(); }
125
126 private:
127
128 CartesianMeshImpl* m_cartesian_mesh = nullptr;
131 };
132
133 public:
134
135 explicit CartesianMeshImpl(IMesh* mesh);
136
137 public:
138
139 void build() override;
140
142 IMesh* mesh() const override { return m_mesh; }
143
145 ITraceMng* traceMng() const override { return TraceAccessor::traceMng(); }
146
148 {
149 return m_all_items_direction_info->cellDirection(dir);
150 }
151
153 {
154 return m_all_items_direction_info->cellDirection(idir);
155 }
156
158 {
159 return m_all_items_direction_info->faceDirection(dir);
160 }
161
163 {
164 return m_all_items_direction_info->faceDirection(idir);
165 }
166
168 {
169 return m_all_items_direction_info->nodeDirection(dir);
170 }
171
173 {
174 return m_all_items_direction_info->nodeDirection(idir);
175 }
176
177 void computeDirections() override;
178
179 void recreateFromDump() override;
180
182 {
183 return m_connectivity;
184 }
185
186 Int32 nbPatch() const override { return m_patch_group.nbPatch(); }
187 ICartesianMeshPatch* patch(Int32 index) const override { return m_patch_group.patch(index).get(); }
188 CartesianPatch amrPatch(Int32 index) const override { return CartesianPatch(m_patch_group.patch(index).get()); }
189 CartesianMeshPatchListView patches() const override { return m_patch_group.patchListView(); }
190
191 void refinePatch2D(Real2 position,Real2 length) override;
192 void refinePatch3D(Real3 position,Real3 length) override;
193 void refinePatch(const AMRZonePosition& position) override;
194
195 void coarseZone2D(Real2 position, Real2 length) override;
196 void coarseZone3D(Real3 position, Real3 length) override;
197 void coarseZone(const AMRZonePosition& position) override;
198
199 Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) override;
200
202
203 void checkValid() const override;
204
206
208 ICartesianMeshInternal* _internalApi() override { return &m_internal_api; }
209
210 void computeDirectionsPatchV2(Integer index) override;
211
212 private:
213
214 // Implémentation de 'ICartesianMeshInternal'
215 Ref<CartesianMeshCoarsening2> _createCartesianMeshCoarsening2();
216 void _addPatchFromExistingChildren(ConstArrayView<Int32> parent_cells_local_id);
217 CartesianPatchGroup& _cartesianPatchGroup() { return m_patch_group; }
218 void _computeDirectionsV2();
219
220 private:
221
222 InternalApi m_internal_api;
224 // la direction X, Y ou Z
225 Int32 m_local_face_direction[3] = { -1, -1, -1 };
226 IMesh* m_mesh = nullptr;
227 Ref<CartesianMeshPatch> m_all_items_direction_info;
228 CartesianConnectivity m_connectivity;
229 UniqueArray<CartesianConnectivity::Index> m_nodes_to_cell_storage;
230 UniqueArray<CartesianConnectivity::Index> m_cells_to_node_storage;
232 bool m_is_amr = false;
235 ScopedPtrT<Properties> m_properties;
236
237 EventObserverPool m_event_pool;
238 bool m_is_mesh_event_added = false;
239 Int64 m_mesh_timestamp = 0;
240 eMeshAMRKind m_amr_type;
241
242 private:
243
244 void _computeMeshDirection(CartesianMeshPatch& cdi,eMeshDirection dir,
245 VariableCellReal3& cells_center,
246 VariableFaceReal3& faces_center,CellGroup all_cells,
247 NodeGroup all_nodes);
248
249 void _computeMeshDirectionV2(CartesianMeshPatch& cdi, eMeshDirection dir,
250 CellGroup all_cells,
251 CellGroup in_patch_cells,
252 CellGroup overlap_cells,
253 NodeGroup all_nodes);
254
255 void _applyRefine(const AMRZonePosition &position);
256 void _applyCoarse(const AMRZonePosition& zone_position);
257 void _addPatch(ConstArrayView<Int32> parent_cells);
258 void _saveInfosInProperties();
259
260 std::tuple<CellGroup, NodeGroup>
261 _buildPatchGroups(const CellGroup& cells, Integer patch_level);
262 void _checkNeedComputeDirections();
263 void _checkAddObservableMeshChanged();
264};
265
266/*---------------------------------------------------------------------------*/
267/*---------------------------------------------------------------------------*/
268
269extern "C++" ICartesianMesh*
271{
272 auto* cm = new CartesianMeshImpl(mesh);
273 cm->build();
274 return cm;
275}
276
277/*---------------------------------------------------------------------------*/
278/*---------------------------------------------------------------------------*/
279
280CartesianMeshImpl::
281CartesianMeshImpl(IMesh* mesh)
282: TraceAccessor(mesh->traceMng())
283, m_internal_api(this)
284, m_mesh(mesh)
285, m_nodes_to_cell_storage(platform::getDefaultDataAllocator())
286, m_cells_to_node_storage(platform::getDefaultDataAllocator())
287, m_permutation_storage(platform::getDefaultDataAllocator())
288, m_patch_group(this)
289, m_amr_type(mesh->meshKind().meshAMRKind())
290{
291 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
292 m_internal_api.initCartesianMeshNumberingMngInternal();
293 m_internal_api.initCartesianMeshAMRPatchMng();
294 }
295 m_all_items_direction_info = m_patch_group.groundPatch();
296}
297
298/*---------------------------------------------------------------------------*/
299/*---------------------------------------------------------------------------*/
300
301void CartesianMeshImpl::
302build()
303{
304 m_properties = new Properties(*(mesh()->properties()),"CartesianMesh");
305 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
306 m_internal_api.cartesianMeshNumberingMngInternal()->build();
307 }
308 m_patch_group.build();
309}
310
311namespace
312{
313const Int32 SERIALIZE_VERSION = 1;
314}
315
316/*---------------------------------------------------------------------------*/
317/*---------------------------------------------------------------------------*/
318
319void CartesianMeshImpl::
320_checkNeedComputeDirections()
321{
322 Int64 new_timestamp = mesh()->timestamp();
323 if (m_mesh_timestamp!=new_timestamp){
324 info() << "Mesh timestamp has changed (old=" << m_mesh_timestamp << " new=" << new_timestamp << ")";
325 computeDirections();
326 }
327}
328
329/*---------------------------------------------------------------------------*/
330/*---------------------------------------------------------------------------*/
331
332void CartesianMeshImpl::
333_saveInfosInProperties()
334{
335 // Sauve le numéro de version pour être sur que c'est OK en reprise
336 m_properties->set("Version",SERIALIZE_VERSION);
337
338 m_patch_group.saveInfosInProperties();
339
340 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
341 m_internal_api.cartesianMeshNumberingMngInternal()->saveInfosInProperties();
342 //m_internal_api.cartesianMeshNumberingMngInternal()->printStatus();
343 }
344}
345
346/*---------------------------------------------------------------------------*/
347/*---------------------------------------------------------------------------*/
348
349void CartesianMeshImpl::
350recreateFromDump()
351{
352 info() << "Creating 'CartesianMesh' infos from dump";
353
354 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
355 m_internal_api.cartesianMeshNumberingMngInternal()->recreateFromDump();
356 m_internal_api.cartesianMeshNumberingMngInternal()->printStatus();
357 }
358
359 // Sauve le numéro de version pour être sur que c'est OK en reprise
360 Int32 v = m_properties->getInt32("Version");
361 if (v!=SERIALIZE_VERSION)
362 ARCANE_FATAL("Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}",
363 v,SERIALIZE_VERSION);
364
365 m_patch_group.recreateFromDump();
366
367 m_all_items_direction_info = m_patch_group.groundPatch();
368
370}
371
372/*---------------------------------------------------------------------------*/
373/*---------------------------------------------------------------------------*/
374
375void CartesianMeshImpl::
376_checkAddObservableMeshChanged()
377{
378 if (m_is_mesh_event_added)
379 return;
380 m_is_mesh_event_added = true;
381 // Pour appeler automatiquement 'computeDirections()' après un appel à
382 // IMesh::prepareForDump().
383 auto f1 = [&](const MeshEventArgs&){ this->_checkNeedComputeDirections(); };
384 mesh()->eventObservable(eMeshEventType::EndPrepareDump).attach(m_event_pool,f1);
385}
386
387/*---------------------------------------------------------------------------*/
388/*---------------------------------------------------------------------------*/
389
390void CartesianMeshImpl::
391computeDirections()
392{
393 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
394 // TODO : Voir où mettre la renumérotation.
395 m_internal_api.cartesianMeshNumberingMngInternal()->renumberingFacesLevel0FromOriginalArcaneNumbering();
396 _computeDirectionsV2();
397 return;
398 }
399 info() << "CartesianMesh: computeDirections()";
400
401 m_mesh_timestamp = mesh()->timestamp();
402 _checkAddObservableMeshChanged();
403
404 m_is_amr = m_mesh->isAmrActivated();
405
406 VariableCellReal3 cells_center(VariableBuildInfo(m_mesh,"TemporaryCartesianMeshCellCenter"));
407 VariableFaceReal3 faces_center(VariableBuildInfo(m_mesh,"TemporaryCartesianMeshFaceCenter"));
408
409 // Calcule les coordonnées du centre des mailles.
410 VariableNodeReal3& nodes_coord = m_mesh->nodesCoordinates();
411 ENUMERATE_CELL(icell,m_mesh->allCells()){
412 Cell cell = *icell;
413 Real3 center;
414 for( NodeLocalId inode : cell.nodeIds() )
415 center += nodes_coord[inode];
416 center /= cell.nbNode();
417 cells_center[icell] = center;
418 }
419 ENUMERATE_FACE(iface,m_mesh->allFaces()){
420 Face face = *iface;
421 Real3 center;
422 for( NodeLocalId inode : face.nodeIds() )
423 center += nodes_coord[inode];
424 center /= face.nbNode();
425 faces_center[iface] = center;
426 }
427
428 IItemFamily* cell_family = m_mesh->cellFamily();
429 IItemFamily* node_family = m_mesh->nodeFamily();
430 Int32 next_face_x = -1;
431 Int32 next_face_y = -1;
432 Int32 next_face_z = -1;
433
434 CellVectorView cell_view = cell_family->allItems().view();
435 Cell cell0 = cell_view[0];
436 Integer nb_face = cell0.nbFace();
437 Integer nb_node = cell0.nbNode();
438 Real3 cell_center = cells_center[cell0];
439
440 info(4) << "sizeof(CellDirectionMng)=" << sizeof(CellDirectionMng)
441 << " sizeof(FaceDirectionMng)=" << sizeof(FaceDirectionMng)
442 << " sizeof(NodelDirectionMng)=" << sizeof(NodeDirectionMng);
443 info(4) << "sizeof(IndexedItemConnectivityViewBase)=" << sizeof(IndexedItemConnectivityViewBase)
444 << " sizeof(CellInfoListView)=" << sizeof(CellInfoListView);
445 info(4) << "Cartesian mesh compute directions is_amr=" << m_is_amr;
446
447 for( Integer i=0; i<nb_node; ++i ){
448 Node node = cell0.node(i);
449 info(4) << "Node I=" << i << " node=" << ItemPrinter(node) << " pos=" << nodes_coord[node];
450 }
451
452 bool is_3d = m_mesh->dimension() == 3;
453
454 // On suppose que toutes les mailles ont le même sens de numérotation dans le maillage.
455 // Par exemple, pour toutes les mailles, la face d'indice 0 est celle du haut, celle
456 // d'indice 1 celle de droite.
457 if (is_3d) {
458 Real max_x = -1;
459 Real max_y = -1;
460 Real max_z = -1;
461
462 for (Integer i = 0; i < nb_face; ++i) {
463 Face f = cell0.face(i);
464
465 Real3 next_center = faces_center[f];
466
467 Real diff_x = next_center.x - cell_center.x;
468 Real diff_y = next_center.y - cell_center.y;
469 Real diff_z = next_center.z - cell_center.z;
470
471 info(4) << "NEXT_FACE=" << ItemPrinter(f) << " center=" << next_center << " diff=" << Real3(diff_x, diff_y, diff_z);
472
473 if (diff_x > max_x) {
474 max_x = diff_x;
475 next_face_x = i;
476 }
477
478 if (diff_y > max_y) {
479 max_y = diff_y;
480 next_face_y = i;
481 }
482
483 if (diff_z > max_z) {
484 max_z = diff_z;
485 next_face_z = i;
486 }
487 }
488 info(4) << "Advance in direction X -> " << next_face_x;
489 info(4) << "Advance in direction Y -> " << next_face_y;
490 info(4) << "Advance in direction Z -> " << next_face_z;
491 }
492 else {
493 Real max_x = -1;
494 Real max_y = -1;
495
496 for (Integer i = 0; i < nb_face; ++i) {
497 Face f = cell0.face(i);
498
499 Real3 next_center = faces_center[f];
500
501 Real diff_x = next_center.x - cell_center.x;
502 Real diff_y = next_center.y - cell_center.y;
503
504 info(4) << "NEXT_FACE=" << ItemPrinter(f) << " center=" << next_center << " diff=" << Real2(diff_x, diff_y);
505
506 if (diff_x > max_x) {
507 max_x = diff_x;
508 next_face_x = i;
509 }
510
511 if (diff_y > max_y) {
512 max_y = diff_y;
513 next_face_y = i;
514 }
515 }
516 info(4) << "Advance in direction X -> " << next_face_x;
517 info(4) << "Advance in direction Y -> " << next_face_y;
518 }
519 m_all_items_direction_info->_internalComputeNodeCellInformations(cell0,cells_center[cell0],nodes_coord);
520
521 info() << "Informations from IMesh properties:";
522
523 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,true);
524
525 info() << "GlobalNbCell = " << cmgi->globalNbCells();
526 info() << "OwnNbCell: " << cmgi->ownNbCells();
527 info() << "SubDomainOffset: " << cmgi->subDomainOffsets();
528 info() << "OwnCellOffset: " << cmgi->ownCellOffsets();
529
530 CellGroup all_cells = cell_family->allItems();
531 NodeGroup all_nodes = node_family->allItems();
532 if (m_is_amr){
533 auto x = _buildPatchGroups(mesh()->allLevelCells(0),0);
534 all_cells = std::get<0>(x);
535 all_nodes = std::get<1>(x);
536 }
537
538 if (next_face_x!=(-1)){
539 m_local_face_direction[MD_DirX] = next_face_x;
540 _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirX, cells_center, faces_center, all_cells, all_nodes);
541 }
542 if (next_face_y!=(-1)){
543 m_local_face_direction[MD_DirY] = next_face_y;
544 _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirY, cells_center, faces_center, all_cells, all_nodes);
545 }
546 if (next_face_z != (-1)) {
547 m_local_face_direction[MD_DirZ] = next_face_z;
548 _computeMeshDirection(*m_all_items_direction_info.get(), MD_DirZ, cells_center, faces_center, all_cells, all_nodes);
549 }
550
551 // Positionne les informations par direction
552 for( Integer idir=0, nb_dir=mesh()->dimension(); idir<nb_dir; ++idir ){
553 CellDirectionMng& cdm = m_all_items_direction_info->cellDirection(idir);
554 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
555 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
556 }
557
558 info() << "Compute cartesian connectivity";
559
560 m_permutation_storage.resize(1);
561 m_permutation_storage[0].compute();
562 m_nodes_to_cell_storage.resize(mesh()->nodeFamily()->maxLocalId());
563 m_cells_to_node_storage.resize(mesh()->cellFamily()->maxLocalId());
564 m_connectivity._setStorage(m_nodes_to_cell_storage,m_cells_to_node_storage,&m_permutation_storage[0]);
565 m_connectivity._computeInfos(mesh(),nodes_coord,cells_center);
566
567 // Ajoute informations de connectivités pour les patchs AMR
568 // TODO: supporter plusieurs appels à cette méthode ?
569 for (Integer patch_index = 1; patch_index < m_patch_group.nbPatch(); ++patch_index) {
570 CellGroup cells = m_patch_group.allCells(patch_index);
571 Ref<CartesianMeshPatch> patch = m_patch_group.patch(patch_index);
572 info() << "AMR Patch name=" << cells.name() << " size=" << cells.size() << " index=" << patch_index << " nbPatch=" << m_patch_group.nbPatch();
573 patch->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
574 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
575 _computeMeshDirection(*patch.get(), MD_DirX, cells_center, faces_center, patch_cells, patch_nodes);
576 _computeMeshDirection(*patch.get(), MD_DirY, cells_center, faces_center, patch_cells, patch_nodes);
577 if (is_3d)
578 _computeMeshDirection(*patch.get(), MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes);
579 }
580
581 if (arcaneIsCheck())
582 checkValid();
583
584 _saveInfosInProperties();
585}
586
587/*---------------------------------------------------------------------------*/
588/*---------------------------------------------------------------------------*/
589
590std::tuple<CellGroup,NodeGroup> CartesianMeshImpl::
591_buildPatchGroups(const CellGroup& cells,Integer patch_level)
592{
593 // On créé un groupe pour chaque patch en garantissant que l'ordre de parcours
594 // est celui des uniqueId() des entités
595 // TODO: à terme, il faudrait que l'ordre de parcours soit le même que
596 // celui du maillage cartésien. Pour cela, il faut soit que les uniqueId()
597 // des mailles/noeuds créés soient dans le même ordre que le maillage cartésien,
598 // soit que la fonction de tri soit spécifique à ce type de maillage.
599 NodeGroup nodes = cells.nodeGroup();
600 IItemFamily* cell_family = cells.itemFamily();
601 IItemFamily* node_family = nodes.itemFamily();
602
603 String cell_group_name = String("AMRPatchCells") + patch_level;
604 CellGroup patch_cells = cell_family->createGroup(cell_group_name,Int32ConstArrayView(),true);
605 // Met les mêmes mailles que \a cells mais force le tri
606 patch_cells.setItems(cells.view().localIds(),true);
607
608 String node_group_name = String("AMRPatchNodes") + patch_level;
609 NodeGroup patch_nodes = node_family->createGroup(node_group_name,Int32ConstArrayView(),true);
610 // Met les mêmes noeuds que \a nodes mais force le tri
611 patch_nodes.setItems(nodes.view().localIds(),true);
612 info(4) << "PATCH_CELLS name=" << patch_cells.name() << " size=" << patch_cells.size();
613 info(4) << "PATCH_NODES name=" << patch_nodes.name() << " size=" << patch_nodes.size();
614 return { patch_cells, patch_nodes };
615}
616
617/*---------------------------------------------------------------------------*/
618/*---------------------------------------------------------------------------*/
619
620void CartesianMeshImpl::
621_computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, VariableCellReal3& cells_center,
622 VariableFaceReal3& faces_center, CellGroup all_cells, NodeGroup all_nodes)
623{
624 IItemFamily* cell_family = m_mesh->cellFamily();
625 IItemFamily* face_family = m_mesh->faceFamily();
626 IItemFamily* node_family = m_mesh->nodeFamily();
627
628 Int32 max_cell_id = cell_family->maxLocalId();
629 Int32 max_face_id = face_family->maxLocalId();
630 Int32 max_node_id = node_family->maxLocalId();
631
632 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
633 cell_dm._internalResizeInfos(max_cell_id);
634
635 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
636 face_dm._internalResizeInfos(max_face_id);
637
638 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
639 node_dm._internalResizeInfos(max_node_id);
640
641 //TODO: attention à remettre à jour après changement de maillage.
642 info(4) << "COMPUTE DIRECTION dir=" << dir;
643
644 Int32 prev_local_face = -1;
645 Int32 next_local_face = m_local_face_direction[dir];
646 Integer mesh_dim = m_mesh->dimension();
647 // Calcul le numero local de face oppose à la face suivante.
648 if (mesh_dim==2)
649 prev_local_face = (next_local_face + 2) % 4;
650 else if (mesh_dim==3)
651 prev_local_face = (next_local_face + 3) % 6;
652
653 cell_dm._internalSetLocalFaceIndex(next_local_face,prev_local_face);
654
655 // Positionne pour chaque maille les faces avant et après dans la direction.
656 // On s'assure que ces entités sont dans le groupe des entités de la direction correspondante
657 std::set<Int32> cells_set;
658 ENUMERATE_CELL(icell,all_cells){
659 cells_set.insert(icell.itemLocalId());
660 }
661
662 // Calcule les mailles devant/derrière. En cas de patch AMR, il faut que ces deux mailles
663 // soient de même niveau
664 ENUMERATE_CELL (icell, all_cells) {
665 Cell cell = *icell;
666 Int32 my_level = cell.level();
667 Face next_face = cell.face(next_local_face);
668 Cell next_cell = next_face.backCell()==cell ? next_face.frontCell() : next_face.backCell();
669 if (cells_set.find(next_cell.localId()) == cells_set.end())
670 next_cell = Cell();
671 else if (next_cell.level() != my_level)
672 next_cell = Cell();
673
674 Face prev_face = cell.face(prev_local_face);
675 Cell prev_cell = prev_face.backCell()==cell ? prev_face.frontCell() : prev_face.backCell();
676 if (cells_set.find(prev_cell.localId()) == cells_set.end())
677 prev_cell = Cell();
678 else if (prev_cell.level() != my_level)
679 prev_cell = Cell();
680 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
681 }
682 cell_dm._internalComputeInnerAndOuterItems(all_cells);
683 face_dm._internalComputeInfos(cell_dm,cells_center,faces_center);
684 node_dm._internalComputeInfos(cell_dm,all_nodes,cells_center);
685}
686
687/*---------------------------------------------------------------------------*/
688/*---------------------------------------------------------------------------*/
689
690void CartesianMeshImpl::
691_computeDirectionsV2()
692{
693 info() << "CartesianMesh: computeDirectionsV2()";
694
695 m_mesh_timestamp = mesh()->timestamp();
696 _checkAddObservableMeshChanged();
697
698 m_is_amr = m_mesh->isAmrActivated();
699
700 IItemFamily* cell_family = m_mesh->cellFamily();
701 IItemFamily* node_family = m_mesh->nodeFamily();
702
703 bool is_3d = m_mesh->dimension() == 3;
704
705 m_all_items_direction_info->_internalComputeNodeCellInformations();
706
707 info() << "Informations from IMesh properties:";
708
709 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh, true);
710
711 info() << "GlobalNbCell = " << cmgi->globalNbCells();
712 info() << "OwnNbCell: " << cmgi->ownNbCells();
713 info() << "SubDomainOffset: " << cmgi->subDomainOffsets();
714 info() << "OwnCellOffset: " << cmgi->ownCellOffsets();
715
716 CellGroup all_cells = cell_family->allItems();
717 NodeGroup all_nodes = node_family->allItems();
718 if (m_is_amr) {
719 auto x = _buildPatchGroups(mesh()->allLevelCells(0), 0);
720 all_cells = std::get<0>(x);
721 all_nodes = std::get<1>(x);
722 }
723 if (is_3d) {
724 m_local_face_direction[MD_DirX] = 4;
725 m_local_face_direction[MD_DirY] = 5;
726 m_local_face_direction[MD_DirZ] = 3;
727 }
728 else {
729 m_local_face_direction[MD_DirX] = 1;
730 m_local_face_direction[MD_DirY] = 2;
731 }
732
733 _computeMeshDirectionV2(*m_all_items_direction_info.get(), MD_DirX, all_cells, all_cells, CellGroup(), all_nodes);
734 _computeMeshDirectionV2(*m_all_items_direction_info.get(), MD_DirY, all_cells, all_cells, CellGroup(), all_nodes);
735 if (is_3d) {
736 _computeMeshDirectionV2(*m_all_items_direction_info.get(), MD_DirZ, all_cells, all_cells, CellGroup(), all_nodes);
737 }
738
739 // Positionne les informations par direction
740 for (Integer idir = 0, nb_dir = mesh()->dimension(); idir < nb_dir; ++idir) {
741 CellDirectionMng& cdm = m_all_items_direction_info->cellDirection(idir);
742 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
743 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
744 }
745
746 info() << "Compute cartesian connectivity";
747
748 m_permutation_storage.resize(1);
749 m_permutation_storage[0].compute();
750 m_nodes_to_cell_storage.resize(mesh()->nodeFamily()->maxLocalId());
751 m_cells_to_node_storage.resize(mesh()->cellFamily()->maxLocalId());
752 m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]);
753 m_connectivity._computeInfos(this);
754
755 // Ajoute informations de connectivités pour les patchs AMR
756 for (Integer patch_index = 1; patch_index < m_patch_group.nbPatch(); ++patch_index) {
757 computeDirectionsPatchV2(patch_index);
758 }
759
760 // TODO : Voir pour modifier cette méthode.
761 // if (arcaneIsCheck())
762 // checkValid();
763
764 _saveInfosInProperties();
765}
766
767/*---------------------------------------------------------------------------*/
768/*---------------------------------------------------------------------------*/
769
770void CartesianMeshImpl::
771computeDirectionsPatchV2(Integer patch_index)
772{
773 bool is_3d = m_mesh->dimension() == 3;
774
775 CellGroup cells = m_patch_group.allCells(patch_index);
776 Ref<CartesianMeshPatch> patch = m_patch_group.patch(patch_index);
777 info() << "AMR Patch name=" << cells.name() << " size=" << cells.size() << " index=" << patch_index << " nbPatch=" << m_patch_group.nbPatch();
778 {
779 const AMRPatchPosition position = patch->position();
780 info() << " position min=" << position.minPoint() << " max=" << position.maxPoint() << " level=" << position.level() << " overlapLayerSize=" << position.overlapLayerSize();
781 }
782 patch->_internalComputeNodeCellInformations();
783 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index); // TODO A suppr
784 _computeMeshDirectionV2(*patch.get(), MD_DirX, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overlapCells(patch_index), patch_nodes);
785 _computeMeshDirectionV2(*patch.get(), MD_DirY, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overlapCells(patch_index), patch_nodes);
786 if (is_3d)
787 _computeMeshDirectionV2(*patch.get(), MD_DirZ, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overlapCells(patch_index), patch_nodes);
788}
789
790/*---------------------------------------------------------------------------*/
791/*---------------------------------------------------------------------------*/
792
793void CartesianMeshImpl::
794_computeMeshDirectionV2(CartesianMeshPatch& cdi, eMeshDirection dir, CellGroup all_cells, CellGroup in_patch_cells, CellGroup overlap_cells, NodeGroup all_nodes)
795{
796 IItemFamily* cell_family = m_mesh->cellFamily();
797 IItemFamily* face_family = m_mesh->faceFamily();
798 IItemFamily* node_family = m_mesh->nodeFamily();
799
800 Int32 max_cell_id = cell_family->maxLocalId();
801 Int32 max_face_id = face_family->maxLocalId();
802 Int32 max_node_id = node_family->maxLocalId();
803
804 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
805 cell_dm._internalResizeInfos(max_cell_id);
806
807 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
808 face_dm._internalResizeInfos(max_face_id);
809
810 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
811 node_dm._internalResizeInfos(max_node_id);
812
813 //TODO: attention à remettre à jour après changement de maillage.
814 info(4) << "COMPUTE DIRECTION dir=" << dir;
815
816 Int32 prev_local_face = -1;
817 Int32 next_local_face = m_local_face_direction[dir];
818 Integer mesh_dim = m_mesh->dimension();
819 // Calcul le numero local de face oppose à la face suivante.
820 if (mesh_dim == 2)
821 prev_local_face = (next_local_face + 2) % 4;
822 else if (mesh_dim == 3)
823 prev_local_face = (next_local_face + 3) % 6;
824
825 cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face);
826
827 // Positionne pour chaque maille les faces avant et après dans la direction.
828 // On s'assure que ces entités sont dans le groupe des entités de la direction correspondante
829 std::set<Int32> cells_set;
830 ENUMERATE_ (Cell, icell, all_cells) {
831 cells_set.insert(icell.itemLocalId());
832 }
833
834 // Calcule les mailles devant/derrière. En cas de patch AMR, il faut que ces deux mailles
835 // soient de même niveau
836 ENUMERATE_ (Cell, icell, all_cells) {
837 Cell cell = *icell;
838 Int32 my_level = cell.level();
839 Face next_face = cell.face(next_local_face);
840 Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell();
841 if (!cells_set.contains(next_cell.localId()) || next_cell.level() != my_level) {
842 next_cell = Cell();
843 }
844
845 Face prev_face = cell.face(prev_local_face);
846 Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell();
847 if (!cells_set.contains(prev_cell.localId()) || prev_cell.level() != my_level) {
848 prev_cell = Cell();
849 }
850
851 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
852 }
853 cell_dm._internalComputeCellGroups(all_cells, in_patch_cells, overlap_cells);
854 face_dm._internalComputeInfos(cell_dm);
855 node_dm._internalComputeInfos(cell_dm, all_nodes);
856}
857
858/*---------------------------------------------------------------------------*/
859/*---------------------------------------------------------------------------*/
860
861void CartesianMeshImpl::
862refinePatch2D(Real2 position,Real2 length)
863{
864 info() << "REFINEMENT 2D position=" << position << " length=" << length;
865 refinePatch({ position, length });
866}
867
868/*---------------------------------------------------------------------------*/
869/*---------------------------------------------------------------------------*/
870
871void CartesianMeshImpl::
872refinePatch3D(Real3 position, Real3 length)
873{
874 info() << "REFINEMENT 3D position=" << position << " length=" << length;
875 refinePatch({ position, length });
876}
877
878/*---------------------------------------------------------------------------*/
879/*---------------------------------------------------------------------------*/
880
881void CartesianMeshImpl::
882refinePatch(const AMRZonePosition& position)
883{
884 _applyRefine(position);
885 _saveInfosInProperties();
886}
887
888/*---------------------------------------------------------------------------*/
889/*---------------------------------------------------------------------------*/
890
891void CartesianMeshImpl::
892coarseZone2D(Real2 position, Real2 length)
893{
894 info() << "COARSEN 2D position=" << position << " length=" << length;
895 coarseZone({ position, length });
896}
897
898/*---------------------------------------------------------------------------*/
899/*---------------------------------------------------------------------------*/
900
901void CartesianMeshImpl::
902coarseZone3D(Real3 position, Real3 length)
903{
904 info() << "COARSEN 3D position=" << position << " length=" << length;
905 coarseZone({ position, length });
906}
907
908/*---------------------------------------------------------------------------*/
909/*---------------------------------------------------------------------------*/
910
911void CartesianMeshImpl::
912coarseZone(const AMRZonePosition& position)
913{
914 _applyCoarse(position);
915 _saveInfosInProperties();
916}
917
918/*---------------------------------------------------------------------------*/
919/*---------------------------------------------------------------------------*/
920
921Integer CartesianMeshImpl::
922reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers)
923{
924 if (level < 1) {
925 ARCANE_FATAL("You cannot reduce number of ghost layer of level 0 with this method");
926 }
927
928 // Nombre de couche de maille fantôme max. Bof; à modifier.
929 const Int32 max_nb_layer = 128;
930 Int32 level_max = 0;
931
932 ENUMERATE_ (Cell, icell, m_mesh->allCells()) {
933 level_max = std::max(level_max, icell->level());
934 }
935
936 level_max = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, level_max);
937 //debug() << "Level max : " << level_max;
938
940
941 Integer level_0_nb_ghost_layer = m_mesh->ghostLayerMng()->nbGhostLayer();
942 //debug() << "NbGhostLayers level 0 : " << level_0_nb_ghost_layer;
943
944 if (level_0_nb_ghost_layer == 0) {
945 return 0;
946 }
947
948 Integer nb_ghost_layer = Convert::toInt32(level_0_nb_ghost_layer * pow(2, level));
949
950 //debug() << "NbGhostLayers level " << level << " : " << nb_ghost_layer;
951
952 // On considère qu'on a toujours 2*2 mailles filles (2*2*2 en 3D).
953 if (target_nb_ghost_layers % 2 != 0) {
954 target_nb_ghost_layers++;
955 }
956
957 if (target_nb_ghost_layers == nb_ghost_layer) {
958 return nb_ghost_layer;
959 }
960
961 //debug() << "TargetNbGhostLayers level " << level << " : " << target_nb_ghost_layers;
962
963 Integer parent_level = level - 1;
964 Integer parent_target_nb_ghost_layer = target_nb_ghost_layers / 2;
965
966 // TODO AH : On est forcé de dé-raffiner niveau par niveau. À changer.
967 UniqueArray<UniqueArray<Int32>> cell_lid2(level_max);
968
969 //UniqueArray<Int32> cell_lid;
970 std::function<void(Cell)> children_list;
971
972 children_list = [&cell_lid2, &children_list](Cell cell) -> void {
973 for (Integer i = 0; i < cell.nbHChildren(); ++i) {
974 //debug() << "child of lid=" << cell.localId() << " : lid=" << cell.hChild(i).localId() << " -- level : " << cell.level();
975 cell_lid2[cell.level()].add(cell.hChild(i).localId());
976 children_list(cell.hChild(i));
977 }
978 };
979
980 // Algorithme de numérotation des couches de mailles fantômes.
981 {
982 VariableNodeInt32 level_node{ VariableBuildInfo{ m_mesh, "LevelNode" } };
983 level_node.fill(-1);
984
985 VariableCellInt32 level_cell{ VariableBuildInfo{ m_mesh, "LevelCell" } };
986 level_cell.fill(-1);
987
988 ENUMERATE_ (Face, iface, m_mesh->allFaces()) {
989 Cell front_cell = iface->frontCell();
990 Cell back_cell = iface->backCell();
991 if (
992 ((front_cell.null() || (!front_cell.isOwn() && front_cell.level() == parent_level)) && ((!back_cell.null()) && (back_cell.isOwn() && back_cell.level() == parent_level))) ||
993 ((back_cell.null() || (!back_cell.isOwn() && back_cell.level() == parent_level)) && ((!front_cell.null()) && (front_cell.isOwn() && front_cell.level() == parent_level)))) {
994 for (Node node : iface->nodes()) {
995 level_node[node] = 0;
996 //debug() << "Node layer 0 : " << node.uniqueId();
997 }
998 }
999 }
1000
1001 bool is_modif = true;
1002 Int32 current_layer = 0;
1003 while (is_modif) {
1004 is_modif = false;
1005
1006 ENUMERATE_ (Cell, icell, m_mesh->allCells()) {
1007 if (icell->isOwn() || icell->level() != parent_level || level_cell[icell] != -1) {
1008 continue;
1009 }
1010
1011 Int32 min = max_nb_layer;
1012 Int32 max = -1;
1013
1014 for (Node node : icell->nodes()) {
1015 Int32 nlevel = level_node[node];
1016 if (nlevel != -1) {
1017 min = std::min(min, nlevel);
1018 max = std::max(max, nlevel);
1019 }
1020 }
1021
1022 // On fait couche par couche (voir pour enlever cette limitation).
1023 if (min != current_layer) {
1024 continue;
1025 }
1026
1027 // Maille n'ayant pas de nodes déjà traités.
1028 if (min == max_nb_layer && max == -1) {
1029 continue;
1030 }
1031
1032 Integer new_level = ((min == max) ? min + 1 : max);
1033
1034 for (Node node : icell->nodes()) {
1035 Int32 nlevel = level_node[node];
1036 if (nlevel == -1) {
1037 level_node[node] = new_level;
1038 //debug() << "Node layer " << new_level << " : " << node.uniqueId();
1039 is_modif = true;
1040 }
1041 }
1042
1043 level_cell[icell] = min;
1044
1045 //debug() << "Cell uid : " << icell->uniqueId()
1046 // << " -- Layer : " << min;
1047
1048 if (min >= parent_target_nb_ghost_layer) {
1049 children_list(*icell);
1050 }
1051 }
1052 current_layer++;
1053 if (current_layer >= max_nb_layer) {
1054 ARCANE_FATAL("Error in ghost layer counter algo. Report it plz.");
1055 }
1056 }
1057 }
1058
1059 for (Integer i = level_max - 1; i >= 0; --i) {
1060 // Une comm pour en éviter plein d'autres.
1061 if (m_mesh->parallelMng()->reduce(Parallel::ReduceMax, cell_lid2[i].size()) == 0) {
1062 continue;
1063 }
1064 //debug() << "Removing children of ghost cell (parent level=" << i << ") (children localIds) : " << cell_lid2[i];
1065
1066 m_mesh->modifier()->flagCellToCoarsen(cell_lid2[i]);
1067 m_mesh->modifier()->coarsenItemsV2(false);
1068 }
1069
1070 info() << "Nb ghost layer for level " << level << " : " << target_nb_ghost_layers;
1071
1072 return target_nb_ghost_layers;
1073}
1074
1075/*---------------------------------------------------------------------------*/
1076/*---------------------------------------------------------------------------*/
1077
1078void CartesianMeshImpl::
1079_addPatchFromExistingChildren(ConstArrayView<Int32> parent_cells_local_id)
1080{
1081 _addPatch(parent_cells_local_id);
1082}
1083
1084/*---------------------------------------------------------------------------*/
1085/*---------------------------------------------------------------------------*/
1089void CartesianMeshImpl::
1090_addPatch(ConstArrayView<Int32> parent_cells)
1091{
1092 // Créé le groupe contenant les mailles AMR
1093 // Il s'agit des mailles filles de \a parent_cells
1094
1095 UniqueArray<Int32> children_local_id;
1096 CellInfoListView cells(m_mesh->cellFamily());
1097 for (Int32 cell_local_id : parent_cells) {
1098 Cell c = cells[cell_local_id];
1099 for (Integer k = 0; k < c.nbHChildren(); ++k) {
1100 Cell child = c.hChild(k);
1101 children_local_id.add(child.localId());
1102 }
1103 }
1104
1105 m_patch_group.addPatch(children_local_id);
1106}
1107
1108/*---------------------------------------------------------------------------*/
1109/*---------------------------------------------------------------------------*/
1110
1111void CartesianMeshImpl::
1112_applyRefine(const AMRZonePosition& position)
1113{
1114 if (m_amr_type == eMeshAMRKind::Cell) {
1115 UniqueArray<Int32> cells_local_id;
1116 position.cellsInPatch(mesh(), cells_local_id);
1117
1118 Integer nb_cell = cells_local_id.size();
1119 info(4) << "Local_NbCellToRefine = " << nb_cell;
1120
1121 IParallelMng* pm = m_mesh->parallelMng();
1122 Int64 total_nb_cell = pm->reduce(Parallel::ReduceSum, nb_cell);
1123 info(4) << "Global_NbCellToRefine = " << total_nb_cell;
1124 if (total_nb_cell == 0)
1125 return;
1126
1127 debug() << "Refine with modifier() (for all mesh types)";
1128 m_mesh->modifier()->flagCellToRefine(cells_local_id);
1129 m_mesh->modifier()->adapt();
1130
1131 _addPatch(cells_local_id);
1132 }
1133
1134 else if(m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
1135 debug() << "Refine with specific refiner (for cartesian mesh only)";
1136 m_patch_group.addPatch(position);
1137 }
1138
1139 else if (m_amr_type == eMeshAMRKind::Patch) {
1140 ARCANE_FATAL("General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1141 }
1142 else{
1143 ARCANE_FATAL("AMR is not enabled");
1144 }
1145
1146 {
1147 MeshStats ms(traceMng(),m_mesh,m_mesh->parallelMng());
1148 ms.dumpStats();
1149 }
1150}
1151
1152/*---------------------------------------------------------------------------*/
1153/*---------------------------------------------------------------------------*/
1154
1155void CartesianMeshImpl::
1156_applyCoarse(const AMRZonePosition& zone_position)
1157{
1158 if (m_amr_type == eMeshAMRKind::Cell) {
1159 UniqueArray<Int32> cells_local_id;
1160
1161 zone_position.cellsInPatch(mesh(), cells_local_id);
1162
1163 Integer nb_cell = cells_local_id.size();
1164 info(4) << "Local_NbCellToCoarsen = " << nb_cell;
1165
1166 IParallelMng* pm = m_mesh->parallelMng();
1167 Int64 total_nb_cell = pm->reduce(Parallel::ReduceSum, nb_cell);
1168 info(4) << "Global_NbCellToCoarsen = " << total_nb_cell;
1169 if (total_nb_cell == 0)
1170 return;
1171
1172 debug() << "Coarse with modifier() (for all mesh types)";
1173 m_patch_group.removeCellsInAllPatches(cells_local_id);
1174 m_patch_group.applyPatchEdit(true);
1175
1176 m_mesh->modifier()->flagCellToCoarsen(cells_local_id);
1177 m_mesh->modifier()->coarsenItemsV2(true);
1178 }
1179
1180 else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
1181 debug() << "Coarsen with specific coarser (for cartesian mesh only)";
1182 m_patch_group.removeCellsInZone(zone_position);
1183 }
1184
1185 else if (m_amr_type == eMeshAMRKind::Patch) {
1186 ARCANE_FATAL("General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1187 }
1188 else {
1189 ARCANE_FATAL("AMR is not enabled");
1190 }
1191
1192 {
1193 MeshStats ms(traceMng(), m_mesh, m_mesh->parallelMng());
1194 ms.dumpStats();
1195 }
1196}
1197
1198/*---------------------------------------------------------------------------*/
1199/*---------------------------------------------------------------------------*/
1200
1201void CartesianMeshImpl::
1202checkValid() const
1203{
1204 info(4) << "Check valid CartesianMesh";
1205 Integer nb_patch = nbPatch();
1206 for( Integer i=0; i<nb_patch; ++i ){
1207 ICartesianMeshPatch* p = patch(i);
1208 p->checkValid();
1209 }
1210}
1211
1212/*---------------------------------------------------------------------------*/
1213/*---------------------------------------------------------------------------*/
1214
1215void CartesianMeshImpl::
1216renumberItemsUniqueId(const CartesianMeshRenumberingInfo& v)
1217{
1218 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,true);
1219
1220 // Regarde d'abord si on renumérote les faces
1221 Int32 face_method = v.renumberFaceMethod();
1222 if (face_method!=0 && face_method!=1)
1223 ARCANE_FATAL("Invalid value '{0}' for renumberFaceMethod(). Valid values are 0 or 1",
1224 face_method);
1225 if (face_method==1)
1226 ARCANE_THROW(NotImplementedException,"Method 1 for face renumbering");
1227
1228 // Regarde ensuite les patchs si demandé.
1229 Int32 patch_method = v.renumberPatchMethod();
1230 if (patch_method < 0 || patch_method > 4) {
1231 ARCANE_FATAL("Invalid value '{0}' for renumberPatchMethod(). Valid values are 0, 1, 2, 3 or 4",
1232 patch_method);
1233 }
1234 if (patch_method != 0 && m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
1235 ARCANE_FATAL("Mesh items renumbering is not compatible with this type of AMR");
1236 }
1237
1238 if (patch_method == 1 || patch_method == 3 || patch_method == 4) {
1239 CartesianMeshUniqueIdRenumbering renumberer(this, cmgi, v.parentPatch(), patch_method);
1240 renumberer.renumber();
1241 }
1242 else if (patch_method == 2) {
1243 warning() << "The patch method 2 is experimental!";
1244 CartesianMeshUniqueIdRenumberingV2 renumberer(this, cmgi);
1245 renumberer.renumber();
1246 }
1247
1248 // Termine par un tri éventuel.
1249 if (v.isSortAfterRenumbering()){
1250 info() << "Compacting and Sorting after renumbering";
1251 m_mesh->nodeFamily()->compactItems(true);
1252 m_mesh->faceFamily()->compactItems(true);
1253 m_mesh->cellFamily()->compactItems(true);
1255 }
1256}
1257
1258/*---------------------------------------------------------------------------*/
1259/*---------------------------------------------------------------------------*/
1260
1262createCartesianMeshCoarsening()
1263{
1264 return makeRef(new CartesianMeshCoarsening(this));
1265}
1266
1267/*---------------------------------------------------------------------------*/
1268/*---------------------------------------------------------------------------*/
1269
1270Ref<CartesianMeshCoarsening2> CartesianMeshImpl::
1271_createCartesianMeshCoarsening2()
1272{
1273 return makeRef(new CartesianMeshCoarsening2(this));
1274}
1275
1276/*---------------------------------------------------------------------------*/
1277/*---------------------------------------------------------------------------*/
1278
1279/*---------------------------------------------------------------------------*/
1280/*---------------------------------------------------------------------------*/
1281
1282ICartesianMesh* ICartesianMesh::
1283getReference(const MeshHandleOrMesh& mesh_handle_or_mesh,bool create)
1284{
1285 MeshHandle h = mesh_handle_or_mesh.handle();
1286 //TODO: faire lock pour multi-thread
1287 const char* name = "CartesianMesh";
1288 IUserDataList* udlist = h.meshUserDataList();
1289
1290 IUserData* ud = udlist->data(name,true);
1291 if (!ud){
1292 if (!create)
1293 return nullptr;
1294 IMesh* mesh = h.meshOrNull();
1295 if (!mesh)
1296 ARCANE_FATAL("The mesh {0} is not yet created",h.meshName());
1298 udlist->setData(name,new AutoDestroyUserData<ICartesianMesh>(cm));
1299
1300 // Indique que le maillage est cartésien
1301 MeshKind mk = mesh->meshKind();
1302 mk.setMeshStructure(eMeshStructure::Cartesian);
1303 mesh->_internalApi()->setMeshKind(mk);
1304
1305 return cm;
1306 }
1308 if (!adud)
1309 ARCANE_FATAL("Can not cast to ICartesianMesh*");
1310 return adud->data();
1311}
1312
1313/*---------------------------------------------------------------------------*/
1314/*---------------------------------------------------------------------------*/
1315
1316} // End namespace Arcane
1317
1318/*---------------------------------------------------------------------------*/
1319/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_FACE(name, group)
Enumérateur générique d'un groupe de faces.
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
Fichier contenant les mécanismes de gestion des évènements.
Classe permettant de définir une zone d'un maillage.
void cellsInPatch(IMesh *mesh, UniqueArray< Int32 > &cells_local_id) const
Méthode permettant de retrouver les mailles incluses dans la zone.
Integer size() const
Nombre d'éléments du vecteur.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
UserData s'auto-détruisant une fois détaché.
Informations de connectivité d'un maillage cartésien.
Déraffine un maillage cartésien par 2.
Déraffine un maillage cartésien par 2.
void initCartesianMeshNumberingMngInternal() override
Méthode permettant de créer une instance de CartesianMeshNumberingMngInternal.
Ref< ICartesianMeshNumberingMngInternal > cartesianMeshNumberingMngInternal() override
Méthode permettant de récupérer l'instance de CartesianMeshNumberingMngInternal.
void addPatchFromExistingChildren(ConstArrayView< Int32 > parent_cells_local_id) override
Créé un patch avec tous les enfants des mailles parent_cells_local_id.
Ref< ICartesianMeshAMRPatchMng > cartesianMeshAMRPatchMng() override
Méthode permettant de récupérer l'instance de CartesianMeshAMRPatchMng.
Ref< CartesianMeshCoarsening2 > createCartesianMeshCoarsening2() override
Créé une instance pour gérer le déraffinement du maillage (V2).
void initCartesianMeshAMRPatchMng() override
Méthode permettant de créer une instance de CartesianMeshAMRPatchMng.
CartesianPatchGroup & cartesianPatchGroup() override
Méthode permettant de récupérer le CartesianPatchGroup.
Infos spécifiques à un maillage cartésien.
void refinePatch3D(Real3 position, Real3 length) override
Raffine en 3D un bloc du maillage cartésien.
Int32 nbPatch() const override
Nombre de patchs du maillage.
Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) override
Méthode permettant de supprimer une ou plusieurs couches de mailles fantômes sur un niveau de raffine...
CartesianPatchGroup m_patch_group
Groupe de mailles pour chaque patch AMR.
void refinePatch(const AMRZonePosition &position) override
Raffine un bloc du maillage cartésien.
ITraceMng * traceMng() const override
Gestionnaire de trace associé.
CellDirectionMng cellDirection(Integer idir) override
Liste des mailles dans la direction dir (0, 1 ou 2)
void recreateFromDump() override
Recalcule les informations de cartésiennes après une reprise.
void computeDirections() override
Calcule les infos pour les accès par direction.
FaceDirectionMng faceDirection(Integer idir) override
Liste des faces dans la direction dir (0, 1 ou 2)
void coarseZone(const AMRZonePosition &position) override
Dé-raffine un bloc du maillage cartésien.
NodeDirectionMng nodeDirection(Integer idir) override
Liste des noeuds dans la direction dir (0, 1 ou 2)
Int32 m_local_face_direction[3]
Indice dans la numérotation locale de la maille, de la face dans.
void checkValid() const override
Effectue des vérifications sur la validité de l'instance.
IMesh * mesh() const override
Maillage associé à ce maillage cartésien.
FaceDirectionMng faceDirection(eMeshDirection dir) override
Liste des faces dans la direction dir.
NodeDirectionMng nodeDirection(eMeshDirection dir) override
Liste des noeuds dans la direction dir.
void refinePatch2D(Real2 position, Real2 length) override
Raffine en 2D un bloc du maillage cartésien.
ICartesianMeshPatch * patch(Int32 index) const override
Retourne le index-ième patch du maillage.
void coarseZone2D(Real2 position, Real2 length) override
Dé-raffine en 2D un bloc du maillage cartésien.
void renumberItemsUniqueId(const CartesianMeshRenumberingInfo &v) override
Renumérote les uniqueId() des entités.
ICartesianMeshInternal * _internalApi() override
API interne à Arcane.
void coarseZone3D(Real3 position, Real3 length) override
Dé-raffine en 3D un bloc du maillage cartésien.
Ref< CartesianMeshCoarsening > createCartesianMeshCoarsening() override
Créé une instance pour gérer le déraffinement du maillage.
CartesianPatch amrPatch(Int32 index) const override
Retourne le index-ième patch du maillage.
CellDirectionMng cellDirection(eMeshDirection dir) override
Liste des mailles dans la direction dir.
void _addPatch(ConstArrayView< Int32 > parent_cells)
Créé un patch avec tous les enfants du groupe parent_cells.
CartesianMeshPatchListView patches() const override
Vue sur la liste des patchs.
CartesianConnectivity connectivity() override
Informations sur la connectivité
Informations par direction pour chaque genre d'entité du maillage.
Renumérotation des uniqueId() pour les maillages cartésiens.
Renumérotation des uniqueId() pour les maillages cartésiens.
Patch AMR d'un maillage cartésien.
Infos sur les mailles d'une direction spécifique X,Y ou Z d'un maillage structuré.
Vue sur les informations des mailles.
Maille d'un maillage.
Definition Item.h:1214
Int32 nbHChildren() const
Nombre d'enfants pour l'AMR.
Definition Item.h:1333
Face face(Int32 i) const
i-ème face de la maille
Definition Item.h:1295
Int32 nbFace() const
Nombre de faces de la maille.
Definition Item.h:1292
Cell hChild(Int32 i) const
i-ème enfant AMR
Definition Item.h:1336
Int32 level() const
Definition Item.h:1368
Vue constante d'un tableau de type T.
Conserve des références d'observateurs.
Infos sur les face d'une direction spécifique X,Y ou Z d'un maillage structuré.
Face d'une maille.
Definition Item.h:964
Partie interne de ICartesianMesh.
Interface d'un patch AMR d'un maillage cartésien.
virtual void checkValid() const =0
Effectue des vérifications sur la validité de l'instance.
Interface d'un maillage cartésien.
virtual IMesh * mesh() const =0
Maillage associé à ce maillage cartésien.
Interface d'une famille d'entités.
Definition IItemFamily.h:84
virtual ItemGroup allItems() const =0
Groupe de toutes les entités.
virtual ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Créé un groupe d'entités de nom name contenant les entités local_ids.
virtual Int32 maxLocalId() const =0
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
Interface du gestionnaire de traces.
Interface d'une liste qui gère des données utilisateurs.
virtual void setData(const String &name, IUserData *ud)=0
Positionne le user-data associé au nom name.
virtual IUserData * data(const String &name, bool allow_null=false) const =0
Donnée associée à name.
Interface pour une donnée utilisateur attachée à un autre objet.
Definition IUserData.h:31
Classe de base d'une vue sur une connectivité non structurée.
NodeGroup nodeGroup() const
Groupe des noeuds des éléments de ce groupe.
Definition ItemGroup.cc:230
const String & name() const
Nom du groupe.
Definition ItemGroup.h:76
ItemVectorView view() const
Vue sur les entités du groupe.
Definition ItemGroup.cc:583
Integer size() const
Nombre d'éléments du groupe.
Definition ItemGroup.h:88
IItemFamily * itemFamily() const
Famille d'entité à laquelle appartient ce groupe (0 pour le group nul)
Definition ItemGroup.h:123
void setItems(Int32ConstArrayView items_local_id)
Positionne les entités du groupe.
Definition ItemGroup.cc:489
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:34
Int32ConstArrayView localIds() const
Tableau des numéros locaux des entités.
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:791
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:788
NodeLocalIdView nodeIds() const
Liste des noeuds de l'entité
Definition Item.h:797
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Definition Item.h:216
constexpr bool isOwn() const
true si l'entité est appartient au sous-domaine
Definition Item.h:253
Arguments des évènements sur le maillage.
Definition MeshEvents.h:43
Classe de compatibilité pour contenir un MeshHandle ou un IMesh*.
Definition MeshHandle.h:194
const MeshHandle & handle() const
handle associé.
Definition MeshHandle.h:217
Handle sur un maillage.
Definition MeshHandle.h:47
IMesh * meshOrNull() const
Retourne le maillage associé à cette instance.
IUserDataList * meshUserDataList() const
Données utilisateurs associées.
Definition MeshHandle.h:157
Caractéristiques d'un maillage.
Definition MeshKind.h:111
Infos sur les noeuds d'une direction spécifique X,Y ou Z d'un maillage structuré.
Noeud d'un maillage.
Definition Item.h:582
Exception lorsqu'une fonction n'est pas implémentée.
Classe gérant un vecteur de réel de dimension 2.
Definition Real2.h:121
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
Référence à une instance.
Encapsulation d'un pointeur qui se détruit automatiquement.
Definition ScopedPtr.h:44
Chaîne de caractères unicode.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage warning() const
Flot pour un message d'avertissement.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
Paramètres nécessaires à la construction d'une variable.
ItemGroupT< Cell > CellGroup
Groupe de mailles.
Definition ItemTypes.h:183
ItemVectorViewT< Cell > CellVectorView
Vue sur un vecteur de mailles.
Definition ItemTypes.h:304
ItemGroupT< Node > NodeGroup
Groupe de noeuds.
Definition ItemTypes.h:167
MeshVariableScalarRefT< Cell, Real3 > VariableCellReal3
Grandeur au centre des mailles de type coordonnées.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
MeshVariableScalarRefT< Node, Int32 > VariableNodeInt32
Grandeur au noeud de type entier 32 bits.
MeshVariableScalarRefT< Face, Real3 > VariableFaceReal3
Grandeur aux faces de type coordonnées.
MeshVariableScalarRefT< Cell, Int32 > VariableCellInt32
Grandeur au centre des mailles de type entier 32 bits.
Int32 toInt32(Real r)
Converti un Real en Int32.
@ ReduceSum
Somme des valeurs.
@ ReduceMax
Maximum des valeurs.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
bool arcaneIsCheck()
Vrai si on est en mode vérification.
Definition Misc.cc:68
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:482
@ Cartesian
Maillage cartésien.
Definition MeshKind.h:35
eMeshDirection
Type de la direction pour un maillage structuré
@ MD_DirZ
Direction Z.
@ MD_DirY
Direction Y.
@ MD_DirX
Direction X.
double Real
Type représentant un réel.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
ICartesianMesh * arcaneCreateCartesianMesh(IMesh *mesh)
eMeshAMRKind
Type de maillage AMR.
Definition MeshKind.h:48
@ Cell
Le maillage est AMR par maille.
Definition MeshKind.h:52
@ PatchCartesianMeshOnly
Le maillage est AMR par patch cartésien (rectangulaire)
Definition MeshKind.h:56
std::int32_t Int32
Type entier signé sur 32 bits.
Real y
deuxième composante du triplet
Definition Real3.h:36
Real z
troisième composante du triplet
Definition Real3.h:37
Real x
première composante du triplet
Definition Real3.h:35