Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
CartesianMesh.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* CartesianMesh.cc (C) 2000-2024 */
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/ICartesianMesh.h"
37#include "arcane/cartesianmesh/CartesianConnectivity.h"
38#include "arcane/cartesianmesh/CartesianMeshRenumberingInfo.h"
39#include "arcane/cartesianmesh/CartesianMeshCoarsening.h"
40#include "arcane/cartesianmesh/CartesianMeshCoarsening2.h"
41#include "arcane/cartesianmesh/CartesianMeshPatchListView.h"
42#include "arcane/cartesianmesh/internal/CartesianMeshPatch.h"
43#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
44
45#include "arcane/cartesianmesh/internal/CartesianMeshUniqueIdRenumbering.h"
46#include "arcane/cartesianmesh/v2/CartesianMeshUniqueIdRenumberingV2.h"
47
48#include "arcane/cartesianmesh/CartesianMeshAMRPatchMng.h"
49#include "arcane/core/IGhostLayerMng.h"
50
51#include <set>
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55/*!
56 * \defgroup ArcaneCartesianMesh Maillages cartésiens.
57 *
58 * Ensemble des classes assurant la gestion des maillage cartésiens.
59 *
60 * Pour plus de renseignements, se reporter à la page \ref arcanedoc_entities_cartesianmesh.
61 */
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
65namespace Arcane
66{
67
68/*---------------------------------------------------------------------------*/
69/*---------------------------------------------------------------------------*/
70/*!
71 * \brief Infos spécifiques à un maillage cartésien.
72 */
74: public TraceAccessor
75, public ICartesianMesh
76{
77 class InternalApi
78 : public ICartesianMeshInternal
79 {
80 public:
81
82 explicit InternalApi(CartesianMeshImpl* cartesian_mesh)
83 : m_cartesian_mesh(cartesian_mesh)
84 {
85 }
86
87 public:
88
89 Ref<CartesianMeshCoarsening2> createCartesianMeshCoarsening2() override
90 {
91 return m_cartesian_mesh->_createCartesianMeshCoarsening2();
92 }
93 void addPatchFromExistingChildren(ConstArrayView<Int32> parent_cells_local_id) override
94 {
95 m_cartesian_mesh->_addPatchFromExistingChildren(parent_cells_local_id);
96 }
97 void initCartesianMeshAMRPatchMng() override
98 {
99 m_amr_mng = makeRef(new CartesianMeshAMRPatchMng(m_cartesian_mesh));
100 }
101
102 Ref<ICartesianMeshAMRPatchMng> cartesianMeshAMRPatchMng() override
103 {
104 return m_amr_mng;
105 }
106
107 private:
108
109 CartesianMeshImpl* m_cartesian_mesh = nullptr;
110 Ref<ICartesianMeshAMRPatchMng> m_amr_mng;
111 };
112
113 public:
114
115 explicit CartesianMeshImpl(IMesh* mesh);
116
117 public:
118
119 void build() override;
120
121 //! Maillage associé à ce maillage cartésien
122 IMesh* mesh() const override { return m_mesh; }
123
124 //! Gestionnaire de trace associé.
125 ITraceMng* traceMng() const override { return TraceAccessor::traceMng(); }
126
128 {
129 return m_all_items_direction_info->cellDirection(dir);
130 }
131
132 CellDirectionMng cellDirection(Integer idir) override
133 {
134 return m_all_items_direction_info->cellDirection(idir);
135 }
136
138 {
139 return m_all_items_direction_info->faceDirection(dir);
140 }
141
142 FaceDirectionMng faceDirection(Integer idir) override
143 {
144 return m_all_items_direction_info->faceDirection(idir);
145 }
146
148 {
149 return m_all_items_direction_info->nodeDirection(dir);
150 }
151
152 NodeDirectionMng nodeDirection(Integer idir) override
153 {
154 return m_all_items_direction_info->nodeDirection(idir);
155 }
156
157 void computeDirections() override;
158
159 void recreateFromDump() override;
160
162 {
163 return m_connectivity;
164 }
165
166 Int32 nbPatch() const override { return m_amr_patches.size(); }
167 ICartesianMeshPatch* patch(Int32 index) const override { return m_amr_patches[index].get(); }
168 CartesianPatch amrPatch(Int32 index) const override { return CartesianPatch(m_amr_patches[index].get()); }
169 CartesianMeshPatchListView patches() const override { return CartesianMeshPatchListView(m_amr_patches_pointer); }
170
171 void refinePatch2D(Real2 position,Real2 length) override;
172 void refinePatch3D(Real3 position,Real3 length) override;
173
174 void coarseZone2D(Real2 position, Real2 length) override;
175 void coarseZone3D(Real3 position, Real3 length) override;
176
177 Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) override;
178
180
181 void checkValid() const override;
182
183 Ref<CartesianMeshCoarsening> createCartesianMeshCoarsening() override;
184
185 //! API interne à Arcane
186 ICartesianMeshInternal* _internalApi() override { return &m_internal_api; }
187
188 private:
189
190 // Implémentation de 'ICartesianMeshInternal'
191 Ref<CartesianMeshCoarsening2> _createCartesianMeshCoarsening2();
192 void _addPatchFromExistingChildren(ConstArrayView<Int32> parent_cells_local_id);
193
194 private:
195
196 InternalApi m_internal_api;
197 //! Indice dans la numérotation locale de la maille, de la face dans
198 // la direction X, Y ou Z
199 Int32 m_local_face_direction[3] = { -1, -1, -1 };
200 IMesh* m_mesh = nullptr;
201 Ref<CartesianMeshPatch> m_all_items_direction_info;
202 CartesianConnectivity m_connectivity;
203 UniqueArray<CartesianConnectivity::Index> m_nodes_to_cell_storage;
204 UniqueArray<CartesianConnectivity::Index> m_cells_to_node_storage;
205 UniqueArray<CartesianConnectivity::Permutation> m_permutation_storage;
206 bool m_is_amr = false;
207 //! Groupe de mailles pour chaque patch AMR.
208 UniqueArray<CellGroup> m_amr_patch_cell_groups;
209 UniqueArray<Ref<CartesianMeshPatch>> m_amr_patches;
210 UniqueArray<ICartesianMeshPatch*> m_amr_patches_pointer;
211 ScopedPtrT<Properties> m_properties;
212
213 EventObserverPool m_event_pool;
214 bool m_is_mesh_event_added = false;
215 Int64 m_mesh_timestamp = 0;
216 eMeshAMRKind m_amr_type;
217
218 private:
219
220 void _computeMeshDirection(CartesianMeshPatch& cdi,eMeshDirection dir,
221 VariableCellReal3& cells_center,
222 VariableFaceReal3& faces_center,CellGroup all_cells,
223 NodeGroup all_nodes);
224 void _applyRefine(ConstArrayView<Int32> cells_local_id);
225 void _removeCellsInPatches(ConstArrayView<Int32> const_array_view);
226 void _applyCoarse(ConstArrayView<Int32> cells_local_id);
227 void _addPatch(const CellGroup& parent_group);
228 void _saveInfosInProperties();
229
230 std::tuple<CellGroup, NodeGroup>
231 _buildPatchGroups(const CellGroup& cells, Integer patch_level);
232 void _refinePatch(Real3 position, Real3 length, bool is_3d);
233 void _coarseZone(Real3 position, Real3 length, bool is_3d);
234 void _cellsInZone(Real3 position, Real3 length, bool is_3d, UniqueArray<Int32>& cells_local_id);
235 void _checkNeedComputeDirections();
236 void _checkAddObservableMeshChanged();
237 void _addPatchInstance(const Ref<CartesianMeshPatch>& v)
238 {
239 m_amr_patches.add(v);
240 m_amr_patches_pointer.add(v.get());
241 }
242};
243
244/*---------------------------------------------------------------------------*/
245/*---------------------------------------------------------------------------*/
246
247extern "C++" ICartesianMesh*
248arcaneCreateCartesianMesh(IMesh* mesh)
249{
250 auto* cm = new CartesianMeshImpl(mesh);
251 cm->build();
252 return cm;
253}
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257
258CartesianMeshImpl::
259CartesianMeshImpl(IMesh* mesh)
260: TraceAccessor(mesh->traceMng())
261, m_internal_api(this)
262, m_mesh(mesh)
263, m_nodes_to_cell_storage(platform::getDefaultDataAllocator())
264, m_cells_to_node_storage(platform::getDefaultDataAllocator())
265, m_permutation_storage(platform::getDefaultDataAllocator())
266, m_amr_type(mesh->meshKind().meshAMRKind())
267{
268 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly)
269 m_internal_api.initCartesianMeshAMRPatchMng();
270
271 m_all_items_direction_info = makeRef(new CartesianMeshPatch(this,-1));
272 _addPatchInstance(m_all_items_direction_info);
273}
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
277
278void CartesianMeshImpl::
279build()
280{
281 m_properties = new Properties(*(mesh()->properties()),"CartesianMesh");
282}
283
284namespace
285{
286const Int32 SERIALIZE_VERSION = 1;
287}
288
289/*---------------------------------------------------------------------------*/
290/*---------------------------------------------------------------------------*/
291
292void CartesianMeshImpl::
293_checkNeedComputeDirections()
294{
295 Int64 new_timestamp = mesh()->timestamp();
296 if (m_mesh_timestamp!=new_timestamp){
297 info() << "Mesh timestamp has changed (old=" << m_mesh_timestamp << " new=" << new_timestamp << ")";
299 }
300}
301
302/*---------------------------------------------------------------------------*/
303/*---------------------------------------------------------------------------*/
304
305void CartesianMeshImpl::
306_saveInfosInProperties()
307{
308 // Sauve le numéro de version pour être sur que c'est OK en reprise
309 m_properties->set("Version",SERIALIZE_VERSION);
310
311 // Sauve les informations des patches
312 UniqueArray<String> patch_group_names;
313 for( const CellGroup& x : m_amr_patch_cell_groups ){
314 patch_group_names.add(x.name());
315 }
316 m_properties->set("PatchGroupNames",patch_group_names);
317}
318
319/*---------------------------------------------------------------------------*/
320/*---------------------------------------------------------------------------*/
321
324{
325 info() << "Creating 'CartesianMesh' infos from dump";
326
327 // Sauve le numéro de version pour être sur que c'est OK en reprise
328 Int32 v = m_properties->getInt32("Version");
329 if (v!=SERIALIZE_VERSION)
330 ARCANE_FATAL("Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}",
331 v,SERIALIZE_VERSION);
332
333 // Récupère les noms des groupes des patchs
334 UniqueArray<String> patch_group_names;
335 m_properties->get("PatchGroupNames",patch_group_names);
336 info(4) << "Found n=" << patch_group_names.size() << " patchs";
337 m_amr_patch_cell_groups.clear();
338 IItemFamily* cell_family = m_mesh->cellFamily();
339 for( const String& x : patch_group_names ){
340 CellGroup group = cell_family->findGroup(x);
341 if (group.null())
342 ARCANE_FATAL("Can not find cell group '{0}'",x);
343 m_amr_patch_cell_groups.add(group);
344 }
345
347}
348
349/*---------------------------------------------------------------------------*/
350/*---------------------------------------------------------------------------*/
351
352void CartesianMeshImpl::
353_checkAddObservableMeshChanged()
354{
355 if (m_is_mesh_event_added)
356 return;
357 m_is_mesh_event_added = true;
358 // Pour appeler automatiquement 'computeDirections()' après un appel à
359 // IMesh::prepareForDump().
360 auto f1 = [&](const MeshEventArgs&){ this->_checkNeedComputeDirections(); };
361 mesh()->eventObservable(eMeshEventType::EndPrepareDump).attach(m_event_pool,f1);
362}
363
364/*---------------------------------------------------------------------------*/
365/*---------------------------------------------------------------------------*/
366
369{
370 info() << "CartesianMesh: computeDirections()";
371
372 m_mesh_timestamp = mesh()->timestamp();
373 _checkAddObservableMeshChanged();
374
375 m_amr_patches.clear();
376 m_amr_patches_pointer.clear();
377 _addPatchInstance(m_all_items_direction_info);
378
379 m_is_amr = m_mesh->isAmrActivated();
380
381 VariableCellReal3 cells_center(VariableBuildInfo(m_mesh,"TemporaryCartesianMeshCellCenter"));
382 VariableFaceReal3 faces_center(VariableBuildInfo(m_mesh,"TemporaryCartesianMeshFaceCenter"));
383
384 // Calcule les coordonnées du centre des mailles.
385 VariableNodeReal3& nodes_coord = m_mesh->nodesCoordinates();
386 ENUMERATE_CELL(icell,m_mesh->allCells()){
387 Cell cell = *icell;
388 Real3 center;
389 for( NodeLocalId inode : cell.nodeIds() )
390 center += nodes_coord[inode];
391 center /= cell.nbNode();
392 cells_center[icell] = center;
393 }
394 ENUMERATE_FACE(iface,m_mesh->allFaces()){
395 Face face = *iface;
396 Real3 center;
397 for( NodeLocalId inode : face.nodeIds() )
398 center += nodes_coord[inode];
399 center /= face.nbNode();
400 faces_center[iface] = center;
401 }
402
403 IItemFamily* cell_family = m_mesh->cellFamily();
404 IItemFamily* node_family = m_mesh->nodeFamily();
405 Int32 next_face_x = -1;
406 Int32 next_face_y = -1;
407 Int32 next_face_z = -1;
408
409 CellVectorView cell_view = cell_family->allItems().view();
410 Cell cell0 = cell_view[0];
411 Integer nb_face = cell0.nbFace();
412 Integer nb_node = cell0.nbNode();
413 Real3 cell_center = cells_center[cell0];
414
415 info(4) << "sizeof(CellDirectionMng)=" << sizeof(CellDirectionMng)
416 << " sizeof(FaceDirectionMng)=" << sizeof(FaceDirectionMng)
417 << " sizeof(NodelDirectionMng)=" << sizeof(NodeDirectionMng);
418 info(4) << "sizeof(IndexedItemConnectivityViewBase)=" << sizeof(IndexedItemConnectivityViewBase)
419 << " sizeof(CellInfoListView)=" << sizeof(CellInfoListView);
420 info(4) << "Cartesian mesh compute directions is_amr=" << m_is_amr;
421
422 for( Integer i=0; i<nb_node; ++i ){
423 Node node = cell0.node(i);
424 info(4) << "Node I=" << i << " node=" << ItemPrinter(node) << " pos=" << nodes_coord[node];
425 }
426
427 bool is_3d = m_mesh->dimension() == 3;
428
429 // On suppose que toutes les mailles ont le même sens de numérotation dans le maillage.
430 // Par exemple, pour toutes les mailles, la face d'indice 0 est celle du haut, celle
431 // d'indice 1 celle de droite.
432 if (is_3d) {
433 for (Integer i = 0; i < nb_face; ++i) {
434 Face f = cell0.face(i);
435
436 Real3 next_center = faces_center[f];
437
438 info(4) << "NEXT_FACE=" << ItemPrinter(f) << " center=" << next_center;
439
440 Real diff_x = next_center.x - cell_center.x;
441 Real diff_y = next_center.y - cell_center.y;
442 Real diff_z = next_center.z - cell_center.z;
443
444 if (diff_x < 0)
445 diff_x = 0;
446 if (diff_y < 0)
447 diff_y = 0;
448 if (diff_z < 0)
449 diff_z = 0;
450
451 info(4) << "NEXT_FACE=" << ItemPrinter(f) << " diff=" << Real3(diff_x, diff_y, diff_z);
452
453 if (diff_x > diff_y && diff_x > diff_z) {
454 // INC X
455 next_face_x = i;
456 info(4) << "Advance in direction X -> " << next_face_x;
457 }
458 else if (diff_y > diff_x && diff_y > diff_z) {
459 // INC Y
460 next_face_y = i;
461 info(4) << "Advance in direction Y -> " << next_face_y;
462 }
463 else if (diff_z > diff_x && diff_z > diff_y) {
464 // INC Z
465 next_face_z = i;
466 info(4) << "Advance in direction Z -> " << next_face_z;
467 }
468 }
469 }
470 else {
471 for (Integer i = 0; i < nb_face; ++i) {
472 Face f = cell0.face(i);
473
474 Real3 next_center = faces_center[f];
475
476 info(4) << "NEXT_FACE=" << ItemPrinter(f) << " center=" << next_center;
477
478 Real diff_x = next_center.x - cell_center.x;
479 Real diff_y = next_center.y - cell_center.y;
480
481 if (diff_x < 0)
482 diff_x = 0;
483 if (diff_y < 0)
484 diff_y = 0;
485
486 info(4) << "NEXT_FACE=" << ItemPrinter(f) << " diff=" << Real2(diff_x, diff_y);
487
488 if (diff_x > diff_y) {
489 // INC X
490 next_face_x = i;
491 info(4) << "Advance in direction X -> " << next_face_x;
492 }
493 else if (diff_y > diff_x) {
494 // INC Y
495 next_face_y = i;
496 info(4) << "Advance in direction Y -> " << next_face_y;
497 }
498 }
499 }
500 m_all_items_direction_info->_internalComputeNodeCellInformations(cell0,cells_center[cell0],nodes_coord);
501
502 info() << "Informations from IMesh properties:";
503
504 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,true);
505
506 info() << "GlobalNbCell = " << cmgi->globalNbCells();
507 info() << "OwnNbCell: " << cmgi->ownNbCells();
508 info() << "SubDomainOffset: " << cmgi->subDomainOffsets();
509 info() << "OwnCellOffset: " << cmgi->ownCellOffsets();
510
511 CellGroup all_cells = cell_family->allItems();
512 NodeGroup all_nodes = node_family->allItems();
513 if (m_is_amr){
514 auto x = _buildPatchGroups(mesh()->allLevelCells(0),0);
515 all_cells = std::get<0>(x);
516 all_nodes = std::get<1>(x);
517 }
518
519 if (next_face_x!=(-1)){
520 m_local_face_direction[MD_DirX] = next_face_x;
521 _computeMeshDirection(*m_all_items_direction_info.get(),MD_DirX,cells_center,faces_center,all_cells,all_nodes);
522 }
523 if (next_face_y!=(-1)){
524 m_local_face_direction[MD_DirY] = next_face_y;
525 _computeMeshDirection(*m_all_items_direction_info.get(),MD_DirY,cells_center,faces_center,all_cells,all_nodes);
526 }
527 if (next_face_z != (-1)) {
528 m_local_face_direction[MD_DirZ] = next_face_z;
529 _computeMeshDirection(*m_all_items_direction_info.get(),MD_DirZ,cells_center,faces_center,all_cells,all_nodes);
530 }
531
532 // Positionne les informations par direction
533 for( Integer idir=0, nb_dir=mesh()->dimension(); idir<nb_dir; ++idir ){
534 CellDirectionMng& cdm = m_all_items_direction_info->cellDirection(idir);
535 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
536 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
537 }
538
539 info() << "Compute cartesian connectivity";
540
541 m_permutation_storage.resize(1);
542 m_permutation_storage[0].compute();
543 m_nodes_to_cell_storage.resize(mesh()->nodeFamily()->maxLocalId());
544 m_cells_to_node_storage.resize(mesh()->cellFamily()->maxLocalId());
545 m_connectivity._setStorage(m_nodes_to_cell_storage,m_cells_to_node_storage,&m_permutation_storage[0]);
546 m_connectivity._computeInfos(mesh(),nodes_coord,cells_center);
547
548 // Ajoute informations de connectivités pour les patchs AMR
549 // TODO: supporter plusieurs appels à cette méthode
550 for( const CellGroup& cells : m_amr_patch_cell_groups ){
551 Integer patch_index = m_amr_patches.size();
552 info() << "AMR Patch name=" << cells.name() << " size=" << cells.size() << " index=" << patch_index;
553 auto* cdi = new CartesianMeshPatch(this,patch_index);
554 _addPatchInstance(makeRef(cdi));
555 cdi->_internalComputeNodeCellInformations(cell0,cells_center[cell0],nodes_coord);
556 auto [ patch_cells, patch_nodes ] = _buildPatchGroups(cells,patch_index);
557 _computeMeshDirection(*cdi,MD_DirX,cells_center,faces_center,patch_cells,patch_nodes);
558 _computeMeshDirection(*cdi,MD_DirY,cells_center,faces_center,patch_cells,patch_nodes);
559 if (is_3d)
560 _computeMeshDirection(*cdi,MD_DirZ,cells_center,faces_center,patch_cells,patch_nodes);
561 }
562
563 if (arcaneIsCheck())
564 checkValid();
565
566 _saveInfosInProperties();
567}
568
569/*---------------------------------------------------------------------------*/
570/*---------------------------------------------------------------------------*/
571
572std::tuple<CellGroup,NodeGroup> CartesianMeshImpl::
573_buildPatchGroups(const CellGroup& cells,Integer patch_level)
574{
575 // On créé un groupe pour chaque patch en garantissant que l'ordre de parcours
576 // est celui des uniqueId() des entités
577 // TODO: à terme, il faudrait que l'ordre de parcours soit le même que
578 // celui du maillage cartésien. Pour cela, il faut soit que les uniqueId()
579 // des mailles/noeuds créés soient dans le même ordre que le maillage cartésien,
580 // soit que la fonction de tri soit spécifique à ce type de maillage.
581 NodeGroup nodes = cells.nodeGroup();
582 IItemFamily* cell_family = cells.itemFamily();
583 IItemFamily* node_family = nodes.itemFamily();
584
585 String cell_group_name = String("AMRPatchCells") + patch_level;
586 CellGroup patch_cells = cell_family->createGroup(cell_group_name,Int32ConstArrayView(),true);
587 // Met les mêmes mailles que \a cells mais force le tri
588 patch_cells.setItems(cells.view().localIds(),true);
589
590 String node_group_name = String("AMRPatchNodes") + patch_level;
591 NodeGroup patch_nodes = node_family->createGroup(node_group_name,Int32ConstArrayView(),true);
592 // Met les mêmes noeuds que \a nodes mais force le tri
593 patch_nodes.setItems(nodes.view().localIds(),true);
594 info(4) << "PATCH_CELLS name=" << patch_cells.name() << " size=" << patch_cells.size();
595 info(4) << "PATCH_NODES name=" << patch_nodes.name() << " size=" << patch_nodes.size();
596 return { patch_cells, patch_nodes };
597}
598
599/*---------------------------------------------------------------------------*/
600/*---------------------------------------------------------------------------*/
601
602void CartesianMeshImpl::
603_computeMeshDirection(CartesianMeshPatch& cdi,eMeshDirection dir,VariableCellReal3& cells_center,
604 VariableFaceReal3& faces_center,CellGroup all_cells,NodeGroup all_nodes)
605{
606 IItemFamily* cell_family = m_mesh->cellFamily();
607 IItemFamily* face_family = m_mesh->faceFamily();
608 IItemFamily* node_family = m_mesh->nodeFamily();
609
610 Int32 max_cell_id = cell_family->maxLocalId();
611 Int32 max_face_id = face_family->maxLocalId();
612 Int32 max_node_id = node_family->maxLocalId();
613
614 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
615 cell_dm._internalResizeInfos(max_cell_id);
616
617 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
618 face_dm._internalResizeInfos(max_face_id);
619
620 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
621 node_dm._internalResizeInfos(max_node_id);
622
623 //TODO: attention à remettre à jour après changement de maillage.
624 info(4) << "COMPUTE DIRECTION dir=" << dir;
625
626 Int32 prev_local_face = -1;
627 Int32 next_local_face = m_local_face_direction[dir];
628 Integer mesh_dim = m_mesh->dimension();
629 // Calcul le numero local de face oppose à la face suivante.
630 if (mesh_dim==2)
631 prev_local_face = (next_local_face + 2) % 4;
632 else if (mesh_dim==3)
633 prev_local_face = (next_local_face + 3) % 6;
634
635 cell_dm._internalSetLocalFaceIndex(next_local_face,prev_local_face);
636
637 // Positionne pour chaque maille les faces avant et après dans la direction.
638 // On s'assure que ces entités sont dans le groupe des entités de la direction correspondante
639 std::set<Int32> cells_set;
640 ENUMERATE_CELL(icell,all_cells){
641 cells_set.insert(icell.itemLocalId());
642 }
643
644 // Calcule les mailles devant/derrière. En cas de patch AMR, il faut que ces deux mailles
645 // soient de même niveau
646 ENUMERATE_CELL(icell,all_cells){
647 Cell cell = *icell;
648 Int32 my_level = cell.level();
649 Face next_face = cell.face(next_local_face);
650 Cell next_cell = next_face.backCell()==cell ? next_face.frontCell() : next_face.backCell();
651 if (cells_set.find(next_cell.localId())==cells_set.end())
652 next_cell = Cell();
653 else if (next_cell.level()!=my_level)
654 next_cell = Cell();
655
656 Face prev_face = cell.face(prev_local_face);
657 Cell prev_cell = prev_face.backCell()==cell ? prev_face.frontCell() : prev_face.backCell();
658 if (cells_set.find(prev_cell.localId())==cells_set.end())
659 prev_cell = Cell();
660 else if (prev_cell.level()!=my_level)
661 prev_cell = Cell();
662 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell,prev_cell);
663 }
664 cell_dm._internalComputeInnerAndOuterItems(all_cells);
665 face_dm._internalComputeInfos(cell_dm,cells_center,faces_center);
666 node_dm._internalComputeInfos(cell_dm,all_nodes,cells_center);
667}
668
669/*---------------------------------------------------------------------------*/
670/*---------------------------------------------------------------------------*/
671
672void CartesianMeshImpl::
673_refinePatch(Real3 position,Real3 length, bool is_3d)
674{
675 UniqueArray<Int32> cells_local_id;
676 _cellsInZone(position, length, is_3d, cells_local_id);
677
678 _applyRefine(cells_local_id);
679 _saveInfosInProperties();
680}
681
682/*---------------------------------------------------------------------------*/
683/*---------------------------------------------------------------------------*/
684
685void CartesianMeshImpl::
686_coarseZone(Real3 position, Real3 length, bool is_3d)
687{
688 UniqueArray<Int32> cells_local_id;
689 _cellsInZone(position, length, is_3d, cells_local_id);
690
691 _applyCoarse(cells_local_id);
692 _saveInfosInProperties();
693}
694
695/*---------------------------------------------------------------------------*/
696/*---------------------------------------------------------------------------*/
697
698void CartesianMeshImpl::
699_cellsInZone(Real3 position, Real3 length, bool is_3d, UniqueArray<Int32>& cells_local_id)
700{
701 VariableNodeReal3& nodes_coord = m_mesh->nodesCoordinates();
702 // Parcours les mailles actives et ajoute dans la liste des mailles
703 // à raffiner celles qui sont contenues dans la boîte englobante
704 // spécifiée dans le jeu de données.
705 Real3 min_pos = position;
706 Real3 max_pos = min_pos + length;
707 cells_local_id.clear();
708 ENUMERATE_CELL (icell, m_mesh->allActiveCells()) {
709 Cell cell = *icell;
710 Real3 center;
711 for (NodeLocalId inode : cell.nodeIds())
712 center += nodes_coord[inode];
713 center /= cell.nbNode();
714 bool is_inside_x = center.x > min_pos.x && center.x < max_pos.x;
715 bool is_inside_y = center.y > min_pos.y && center.y < max_pos.y;
716 bool is_inside_z = (center.z > min_pos.z && center.z < max_pos.z) || !is_3d;
717 if (is_inside_x && is_inside_y && is_inside_z) {
718 cells_local_id.add(icell.itemLocalId());
719 }
720 }
721}
722
723/*---------------------------------------------------------------------------*/
724/*---------------------------------------------------------------------------*/
725
727refinePatch2D(Real2 position,Real2 length)
728{
729 info() << "REFINEMENT 2D position=" << position << " length=" << length;
730 Real3 position_3d(position.x,position.y,0.0);
731 Real3 length_3d(length.x,length.y,0.0);
732 _refinePatch(position_3d,length_3d,false);
733}
734
735/*---------------------------------------------------------------------------*/
736/*---------------------------------------------------------------------------*/
737
739refinePatch3D(Real3 position,Real3 length)
740{
741 info() << "REFINEMENT 3D position=" << position << " length=" << length;
742 _refinePatch(position,length,true);
743}
744
745/*---------------------------------------------------------------------------*/
746/*---------------------------------------------------------------------------*/
747
749coarseZone2D(Real2 position, Real2 length)
750{
751 info() << "COARSEN 2D position=" << position << " length=" << length;
752 Real3 position_3d(position.x, position.y, 0.0);
753 Real3 length_3d(length.x, length.y, 0.0);
754 _coarseZone(position_3d, length_3d, false);
755}
756
757/*---------------------------------------------------------------------------*/
758/*---------------------------------------------------------------------------*/
759
761coarseZone3D(Real3 position, Real3 length)
762{
763 info() << "COARSEN 3D position=" << position << " length=" << length;
764 _coarseZone(position, length, true);
765}
766
767/*---------------------------------------------------------------------------*/
768/*---------------------------------------------------------------------------*/
769
771reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers)
772{
773 if (level < 1) {
774 ARCANE_FATAL("You cannot reduce number of ghost layer of level 0 with this method");
775 }
776
777 // Nombre de couche de maille fantôme max. Bof; à modifier.
778 const Int32 max_nb_layer = 128;
779 Int32 level_max = 0;
780
781 ENUMERATE_ (Cell, icell, m_mesh->allCells()) {
782 level_max = std::max(level_max, icell->level());
783 }
784
785 level_max = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, level_max);
786
788
789 Integer level_0_nb_ghost_layer = m_mesh->ghostLayerMng()->nbGhostLayer();
790 //info() << "NbGhostLayers : " << level_0_nb_ghost_layer;
791
792 if (level_0_nb_ghost_layer == 0) {
793 return 0;
794 }
795
796 Integer nb_ghost_layer = Convert::toInt32(level_0_nb_ghost_layer * pow(2, level));
797
798 // On considère qu'on a toujours 2*2 mailles filles (2*2*2 en 3D).
799 if (target_nb_ghost_layers % 2 != 0) {
800 target_nb_ghost_layers++;
801 }
802
803 if (target_nb_ghost_layers == nb_ghost_layer) {
804 return nb_ghost_layer;
805 }
806
807 Integer parent_level = level - 1;
808 Integer parent_target_nb_ghost_layer = target_nb_ghost_layers / 2;
809
810 // TODO AH : On est forcé de dé-raffiner niveau par niveau. À changer.
811 UniqueArray<UniqueArray<Int32>> cell_lid2(level_max);
812
813 //UniqueArray<Int32> cell_lid;
814 std::function<void(Cell)> children_list;
815
816 children_list = [&cell_lid2, &children_list](Cell cell) -> void {
817 for (Integer i = 0; i < cell.nbHChildren(); ++i) {
818 cell_lid2[cell.level()].add(cell.hChild(i).localId());
819 children_list(cell.hChild(i));
820 }
821 };
822
823 // Algorithme de numérotation des couches de mailles fantômes.
824 {
825 VariableNodeInt32 level_node{ VariableBuildInfo{ m_mesh, "LevelNode" } };
826 level_node.fill(-1);
827
828 VariableCellInt32 level_cell{ VariableBuildInfo{ m_mesh, "LevelCell" } };
829 level_cell.fill(-1);
830
831 ENUMERATE_ (Face, iface, m_mesh->allFaces()) {
832 Cell front_cell = iface->frontCell();
833 Cell back_cell = iface->backCell();
834 if (
835 ((front_cell.null() || (!front_cell.isOwn() && front_cell.level() == parent_level)) && ((!back_cell.null()) && (back_cell.isOwn() && back_cell.level() == parent_level))) ||
836 ((back_cell.null() || (!back_cell.isOwn() && back_cell.level() == parent_level)) && ((!front_cell.null()) && (front_cell.isOwn() && front_cell.level() == parent_level)))) {
837 for (Node node : iface->nodes()) {
838 level_node[node] = 0;
839 //debug() << "Node layer 0 : " << node.uniqueId();
840 }
841 }
842 }
843
844 bool is_modif = true;
845 Int32 current_layer = 0;
846 while (is_modif) {
847 is_modif = false;
848
849 ENUMERATE_ (Cell, icell, m_mesh->allCells()) {
850 if (icell->isOwn() || icell->level() != parent_level || level_cell[icell] != -1) {
851 continue;
852 }
853
854 Int32 min = max_nb_layer;
855 Int32 max = -1;
856
857 for (Node node : icell->nodes()) {
858 Int32 nlevel = level_node[node];
859 if (nlevel != -1) {
860 min = std::min(min, nlevel);
861 max = std::max(max, nlevel);
862 }
863 }
864
865 // On fait couche par couche (voir pour enlever cette limitation).
866 if (min != current_layer) {
867 continue;
868 }
869
870 // Maille n'ayant pas de nodes déjà traités.
871 if (min == 10 && max == -1) {
872 continue;
873 }
874
875 Integer new_level = ((min == max) ? min + 1 : max);
876
877 for (Node node : icell->nodes()) {
878 Int32 nlevel = level_node[node];
879 if (nlevel == -1) {
880 level_node[node] = new_level;
881 //debug() << "Node layer " << new_level << " : " << node.uniqueId();
882 is_modif = true;
883 }
884 }
885
886 level_cell[icell] = min;
887
888 //debug() << "Cell uid : " << icell->uniqueId()
889 // << " -- Layer : " << min;
890
891 if (min >= parent_target_nb_ghost_layer) {
892 children_list(*icell);
893 }
894 }
895 current_layer++;
896 if (current_layer >= max_nb_layer) {
897 ARCANE_FATAL("Error in ghost layer counter algo. Report it plz.");
898 }
899 }
900 }
901
902 for (Integer i = level_max - 1; i >= 0; --i) {
903 // Une comm pour en éviter plein d'autres.
904 if (m_mesh->parallelMng()->reduce(Parallel::ReduceMax, cell_lid2[i].size()) == 0) {
905 continue;
906 }
907 //debug() << "Ghost cells to remove (level=" << i << ") (localIds) : " << cell_lid2[i];
908
909 m_mesh->modifier()->flagCellToCoarsen(cell_lid2[i]);
910 m_mesh->modifier()->coarsenItemsV2(false);
911 }
912
913 info() << "Nb ghost layer for level " << level << " : " << target_nb_ghost_layers;
914
915 return target_nb_ghost_layers;
916}
917
918/*---------------------------------------------------------------------------*/
919/*---------------------------------------------------------------------------*/
920
921void CartesianMeshImpl::
922_addPatchFromExistingChildren(ConstArrayView<Int32> parent_cells_local_id)
923{
924 IItemFamily* cell_family = m_mesh->cellFamily();
925 Integer index = m_amr_patch_cell_groups.size();
926 String parent_group_name = String("CartesianMeshPatchParentCells")+index;
927 CellGroup parent_cells = cell_family->createGroup(parent_group_name,parent_cells_local_id,true);
928 _addPatch(parent_cells);
929}
930
931/*---------------------------------------------------------------------------*/
932/*---------------------------------------------------------------------------*/
933/*!
934 * \brief Créé un patch avec tous les enfants du groupe \a parent_cells.
935 */
936void CartesianMeshImpl::
937_addPatch(const CellGroup& parent_cells)
938{
939 Integer index = m_amr_patch_cell_groups.size();
940 // Créé le groupe contenant les mailles AMR
941 // Il s'agit des mailles filles de \a parent_cells
942 String children_group_name = String("CartesianMeshPatchCells")+index;
943 UniqueArray<Int32> children_local_id;
944 ENUMERATE_(Cell,icell,parent_cells){
945 Cell c = *icell;
946 for(Integer k=0; k<c.nbHChildren(); ++k ){
947 Cell child = c.hChild(k);
948 children_local_id.add(child.localId());
949 }
950 }
951 IItemFamily* cell_family = m_mesh->cellFamily();
952 CellGroup children_cells = cell_family->createGroup(children_group_name,children_local_id,true);
953 m_amr_patch_cell_groups.add(children_cells);
954}
955
956/*---------------------------------------------------------------------------*/
957/*---------------------------------------------------------------------------*/
958
959void CartesianMeshImpl::
960_removeCellsInPatches(ConstArrayView<Int32> const_array_view)
961{
962 for (CellGroup cells : m_amr_patch_cell_groups) {
963 cells.removeItems(const_array_view);
964 }
965
966 IParallelMng* pm = m_mesh->parallelMng();
967
968 auto new_end = std::remove_if(m_amr_patch_cell_groups.begin(), m_amr_patch_cell_groups.end(),
969 [&pm](const CellGroup& cells) { return pm->reduce(Parallel::ReduceMax, cells.size()) == 0; });
970
971 m_amr_patch_cell_groups.resize(new_end - m_amr_patch_cell_groups.begin());
972}
973
974/*---------------------------------------------------------------------------*/
975/*---------------------------------------------------------------------------*/
976
977void CartesianMeshImpl::
978_applyRefine(ConstArrayView<Int32> cells_local_id)
979{
980 IItemFamily* cell_family = m_mesh->cellFamily();
981 Integer nb_cell = cells_local_id.size();
982 info(4) << "Local_NbCellToRefine = " << nb_cell;
983 Integer index = m_amr_patch_cell_groups.size();
984 String parent_group_name = String("CartesianMeshPatchParentCells")+index;
985 CellGroup parent_cells = cell_family->createGroup(parent_group_name,cells_local_id,true);
986
987 IParallelMng* pm = m_mesh->parallelMng();
988 Int64 total_nb_cell = pm->reduce(Parallel::ReduceSum,nb_cell);
989 info(4) << "Global_NbCellToRefine = " << total_nb_cell;
990 if (total_nb_cell==0)
991 return;
992
993 if(m_amr_type == eMeshAMRKind::Cell) {
994 debug() << "Refine with modifier() (for all mesh types)";
995 m_mesh->modifier()->flagCellToRefine(cells_local_id);
996 m_mesh->modifier()->adapt();
997 }
998 else if(m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
999 debug() << "Refine with specific refiner (for cartesian mesh only)";
1001 m_internal_api.cartesianMeshAMRPatchMng()->flagCellToRefine(cells_local_id);
1002 m_internal_api.cartesianMeshAMRPatchMng()->refine();
1003 }
1004 else if(m_amr_type == eMeshAMRKind::Patch) {
1005 ARCANE_FATAL("General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1006 }
1007 else{
1008 ARCANE_FATAL("AMR is not enabled");
1009 }
1010
1011 {
1012 MeshStats ms(traceMng(),m_mesh,m_mesh->parallelMng());
1013 ms.dumpStats();
1014 }
1015 _addPatch(parent_cells);
1016}
1017
1018/*---------------------------------------------------------------------------*/
1019/*---------------------------------------------------------------------------*/
1020
1021void CartesianMeshImpl::
1022_applyCoarse(ConstArrayView<Int32> cells_local_id)
1023{
1024 Integer nb_cell = cells_local_id.size();
1025 info(4) << "Local_NbCellToCoarsen = " << nb_cell;
1026
1027 IParallelMng* pm = m_mesh->parallelMng();
1028 Int64 total_nb_cell = pm->reduce(Parallel::ReduceSum, nb_cell);
1029 info(4) << "Global_NbCellToCoarsen = " << total_nb_cell;
1030 if (total_nb_cell == 0)
1031 return;
1032
1033 _removeCellsInPatches(cells_local_id);
1034
1035 if (m_amr_type == eMeshAMRKind::Cell) {
1036 debug() << "Coarse with modifier() (for all mesh types)";
1037 m_mesh->modifier()->flagCellToCoarsen(cells_local_id);
1038 m_mesh->modifier()->coarsenItemsV2(true);
1039 }
1040 else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
1041 ARCANE_NOT_YET_IMPLEMENTED("Patch AMR for Cartesian only is not implemented yet");
1042 }
1043 else if (m_amr_type == eMeshAMRKind::Patch) {
1044 ARCANE_FATAL("General patch AMR is not implemented. Please use PatchCartesianMeshOnly (3)");
1045 }
1046 else {
1047 ARCANE_FATAL("AMR is not enabled");
1048 }
1049
1050 {
1051 MeshStats ms(traceMng(), m_mesh, m_mesh->parallelMng());
1052 ms.dumpStats();
1053 }
1054}
1055
1056/*---------------------------------------------------------------------------*/
1057/*---------------------------------------------------------------------------*/
1058
1060checkValid() const
1061{
1062 info(4) << "Check valid CartesianMesh";
1063 Integer nb_patch = nbPatch();
1064 for( Integer i=0; i<nb_patch; ++i ){
1065 ICartesianMeshPatch* p = patch(i);
1066 p->checkValid();
1067 }
1068}
1069
1070/*---------------------------------------------------------------------------*/
1071/*---------------------------------------------------------------------------*/
1072
1075{
1076 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,true);
1077
1078 // Regarde d'abord si on renumérote les faces
1079 Int32 face_method = v.renumberFaceMethod();
1080 if (face_method!=0 && face_method!=1)
1081 ARCANE_FATAL("Invalid value '{0}' for renumberFaceMethod(). Valid values are 0 or 1",
1082 face_method);
1083 if (face_method==1)
1084 ARCANE_THROW(NotImplementedException,"Method 1 for face renumbering");
1085
1086 // Regarde ensuite les patchs si demandé.
1087 Int32 patch_method = v.renumberPatchMethod();
1088 if (patch_method < 0 || patch_method > 4)
1089 ARCANE_FATAL("Invalid value '{0}' for renumberPatchMethod(). Valid values are 0, 1, 2, 3 or 4",
1090 patch_method);
1091
1092 else if (patch_method == 1 || patch_method == 3 || patch_method == 4){
1093 CartesianMeshUniqueIdRenumbering renumberer(this,cmgi,v.parentPatch(),patch_method);
1094 renumberer.renumber();
1095 }
1096 else if (patch_method == 2){
1097 warning() << "The patch method 2 is experimental!";
1098 CartesianMeshUniqueIdRenumberingV2 renumberer(this,cmgi);
1099 renumberer.renumber();
1100 }
1101
1102 // Termine par un tri éventuel.
1103 if (v.isSortAfterRenumbering()){
1104 info() << "Compacting and Sorting after renumbering";
1105 m_mesh->nodeFamily()->compactItems(true);
1106 m_mesh->faceFamily()->compactItems(true);
1107 m_mesh->cellFamily()->compactItems(true);
1109 }
1110}
1111
1112/*---------------------------------------------------------------------------*/
1113/*---------------------------------------------------------------------------*/
1114
1115Ref<CartesianMeshCoarsening> CartesianMeshImpl::
1117{
1118 return makeRef(new CartesianMeshCoarsening(this));
1119}
1120
1121/*---------------------------------------------------------------------------*/
1122/*---------------------------------------------------------------------------*/
1123
1124Ref<CartesianMeshCoarsening2> CartesianMeshImpl::
1125_createCartesianMeshCoarsening2()
1126{
1127 return makeRef(new CartesianMeshCoarsening2(this));
1128}
1129
1130/*---------------------------------------------------------------------------*/
1131/*---------------------------------------------------------------------------*/
1132
1133/*---------------------------------------------------------------------------*/
1134/*---------------------------------------------------------------------------*/
1135
1137getReference(const MeshHandleOrMesh& mesh_handle_or_mesh,bool create)
1138{
1139 MeshHandle h = mesh_handle_or_mesh.handle();
1140 //TODO: faire lock pour multi-thread
1141 const char* name = "CartesianMesh";
1142 IUserDataList* udlist = h.meshUserDataList();
1143
1144 IUserData* ud = udlist->data(name,true);
1145 if (!ud){
1146 if (!create)
1147 return nullptr;
1148 IMesh* mesh = h.meshOrNull();
1149 if (!mesh)
1150 ARCANE_FATAL("The mesh {0} is not yet created",h.meshName());
1151 ICartesianMesh* cm = arcaneCreateCartesianMesh(mesh);
1152 udlist->setData(name,new AutoDestroyUserData<ICartesianMesh>(cm));
1153
1154 // Indique que le maillage est cartésien
1155 MeshKind mk = mesh->meshKind();
1156 mk.setMeshStructure(eMeshStructure::Cartesian);
1157 mesh->_internalApi()->setMeshKind(mk);
1158
1159 return cm;
1160 }
1162 if (!adud)
1163 ARCANE_FATAL("Can not cast to ICartesianMesh*");
1164 return adud->data();
1165}
1166
1167/*---------------------------------------------------------------------------*/
1168/*---------------------------------------------------------------------------*/
1169
1170} // End namespace Arcane
1171
1172/*---------------------------------------------------------------------------*/
1173/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fichier contenant les mécanismes de gestion des évènements.
#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.
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.
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...
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)
NodeDirectionMng nodeDirection(Integer idir) override
Liste des noeuds dans la direction dir (0, 1 ou 2)
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.
CartesianMeshPatchListView patches() const override
Vue sur la liste des patchs.
CartesianConnectivity connectivity() override
Informations sur la connectivité
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:1178
Face face(Int32 i) const
i-ème face de la maille
Definition Item.h:1255
Int32 nbFace() const
Nombre de faces de la maille.
Definition Item.h:1252
Int32 level() const
Definition Item.h:1328
Infos sur les face d'une direction spécifique X,Y ou Z d'un maillage structuré.
Face d'une maille.
Definition Item.h:932
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.
static ICartesianMesh * getReference(const MeshHandleOrMesh &mesh, bool create=true)
Récupère ou créé la référence associée à mesh.
virtual IMesh * mesh() const =0
Maillage associé à ce maillage cartésien.
Interface d'une famille d'entités.
virtual ItemGroup findGroup(const String &name) const =0
Recherche un groupe.
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
virtual IMeshInternal * _internalApi()=0
API interne à Arcane.
virtual Int64 timestamp()=0
Compteur indiquant le temps de dernière modification du maillage.
virtual EventObservable< const MeshEventArgs & > & eventObservable(eMeshEventType type)=0
Observable pour un évènement.
virtual const MeshKind meshKind() const =0
Caractéristiques du maillage.
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:229
const String & name() const
Nom du groupe.
Definition ItemGroup.h:76
void removeItems(Int32ConstArrayView items_local_id, bool check_if_present=true)
Supprime des entités.
Definition ItemGroup.cc:467
ItemVectorView view() const
Vue sur les entités du groupe.
Definition ItemGroup.cc:582
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:488
bool null() const
true is le groupe est le groupe nul
Definition ItemGroup.h:70
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:35
Vue sur un tableau typé d'entités.
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:768
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:765
NodeLocalIdView nodeIds() const
Liste des noeuds de l'entité
Definition Item.h:774
bool isOwn() const
true si l'entité est appartient au sous-domaine
Definition Item.h:244
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Definition Item.h:207
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:59
Infos sur les noeuds d'une direction spécifique X,Y ou Z d'un maillage structuré.
Noeud d'un maillage.
Definition Dom.h:204
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
Paramètres nécessaires à la construction d'une variable.
Integer size() const
Nombre d'éléments du vecteur.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Vue constante d'un tableau de type T.
Interface du gestionnaire de traces.
Chaîne de caractères unicode.
TraceMessage warning() const
Flot pour un message d'avertissement.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage info() const
Flot pour un message d'information.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
Vecteur 1D de données avec sémantique par valeur (style STL).
ItemGroupT< Cell > CellGroup
Groupe de mailles.
Definition ItemTypes.h:183
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, Int32 > VariableNodeInt32
Grandeur au noeud de type entier 32 bits.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
MeshVariableScalarRefT< Face, Real3 > VariableFaceReal3
Grandeur aux faces de type coordonnées.
Int32 toInt32(Real r)
Converti un Real en Int32.
Definition Convert.h:71
-*- 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:151
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:640
eMeshDirection
Type de la direction pour un maillage structuré
@ MD_DirZ
Direction Z.
@ MD_DirY
Direction Y.
@ MD_DirX
Direction X.
@ EndPrepareDump
Evènement envoyé à la fin de prepareForDump()
eMeshAMRKind
Type de maillage AMR.
Definition MeshKind.h:40
Int32 Integer
Type représentant un entier.
Real y
deuxième composante du couple
Definition Real2.h:35
Real x
première composante du couple
Definition Real2.h:34
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