Arcane  v3.16.2.0
Documentation développeur
Tout Classes Espaces de nommage Fichiers Fonctions Variables Définitions de type Énumérations Valeurs énumérées Amis Macros Groupes Pages Concepts
DynamicMesh.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* DynamicMesh.cc (C) 2000-2025 */
9/* */
10/* Classe de gestion d'un maillage non structuré évolutif. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/DynamicMesh.h"
15
16#include "arcane/utils/ValueConvert.h"
17#include "arcane/utils/StringBuilder.h"
18#include "arcane/utils/ITraceMng.h"
19#include "arcane/utils/PlatformUtils.h"
20#include "arcane/utils/ArgumentException.h"
21#include "arcane/utils/ScopedPtr.h"
22
23#include "arcane/core/ISubDomain.h"
24#include "arcane/core/ITimeStats.h"
25#include "arcane/core/IVariableMng.h"
26#include "arcane/core/Properties.h"
27#include "arcane/core/SharedVariable.h"
28#include "arcane/core/IParallelMng.h"
29#include "arcane/core/ICaseDocument.h"
31#include "arcane/core/Timer.h"
32#include "arcane/core/ItemPrinter.h"
33#include "arcane/core/IPropertyMng.h"
34#include "arcane/core/CommonVariables.h"
35#include "arcane/core/MeshStats.h"
36#include "arcane/core/IMeshFactory.h"
37#include "arcane/core/IMeshPartitionConstraintMng.h"
38#include "arcane/core/IMeshWriter.h"
39#include "arcane/core/IMeshUtilities.h"
40#include "arcane/core/Connectivity.h"
41#include "arcane/core/FactoryService.h"
42#include "arcane/core/AbstractService.h"
43#include "arcane/core/ServiceBuilder.h"
44#include "arcane/core/MeshToMeshTransposer.h"
45#include "arcane/core/IItemFamilyCompactPolicy.h"
46#include "arcane/core/IItemFamilyExchanger.h"
47#include "arcane/core/IItemFamilySerializer.h"
48#include "arcane/core/IItemFamilyPolicyMng.h"
49#include "arcane/core/IMeshExchanger.h"
50#include "arcane/core/IMeshCompacter.h"
51#include "arcane/core/MeshVisitor.h"
52#include "arcane/core/IVariableSynchronizer.h"
53#include "arcane/core/IParallelReplication.h"
54#include "arcane/core/IMeshMng.h"
55#include "arcane/core/MeshBuildInfo.h"
56#include "arcane/core/ICaseMng.h"
57
58#include "arcane/core/internal/UnstructuredMeshAllocateBuildInfoInternal.h"
59#include "arcane/core/internal/IItemFamilyInternal.h"
60#include "arcane/core/internal/IVariableMngInternal.h"
61#include "arcane/core/internal/IMeshInternal.h"
62#include "arcane/core/internal/IMeshModifierInternal.h"
63
64#include "arcane/mesh/ExtraGhostCellsBuilder.h"
65#include "arcane/mesh/ExtraGhostParticlesBuilder.h"
66
67#include "arcane/mesh/MeshPartitionConstraintMng.h"
68#include "arcane/mesh/ItemGroupsSynchronize.h"
69#include "arcane/mesh/DynamicMeshIncrementalBuilder.h"
70#include "arcane/mesh/OneMeshItemAdder.h"
71#include "arcane/mesh/DynamicMeshChecker.h"
72#include "arcane/mesh/GhostLayerMng.h"
73#include "arcane/mesh/MeshUniqueIdMng.h"
74#include "arcane/mesh/ItemGroupDynamicMeshObserver.h"
75#include "arcane/mesh/ParticleFamily.h"
76#include "arcane/mesh/MeshExchange.h"
77#include "arcane/mesh/UnstructuredMeshUtilities.h"
78#include "arcane/mesh/TiedInterfaceMng.h"
79#include "arcane/mesh/MeshCompactMng.h"
80#include "arcane/mesh/MeshExchangeMng.h"
81#include "arcane/mesh/DynamicMeshMerger.h"
82#include "arcane/mesh/ItemFamilyNetwork.h"
83#include "arcane/mesh/IncrementalItemConnectivity.h"
84#include "arcane/mesh/MeshExchanger.h"
85#include "arcane/mesh/IndexedIncrementalItemConnectivityMng.h"
86#include "arcane/mesh/NodeFamily.h"
87#include "arcane/mesh/EdgeFamily.h"
88#include "arcane/mesh/FaceFamily.h"
89#include "arcane/mesh/CellFamily.h"
90#include "arcane/mesh/DoFFamily.h"
91
93#include "arcane/mesh/MeshRefinement.h"
94#include "arcane/mesh/FaceReorienter.h"
95#include "arcane/mesh/NewItemOwnerBuilder.h"
96
97#include "arcane/mesh/IncrementalItemConnectivity.h"
98#include "arcane/mesh/ItemConnectivityMng.h"
99
100#include <functional>
101#include <memory>
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105
106namespace
107{
108// Propritétés publiques que l'utilisateur peut positionner
109const char* PROPERTY_SORT = "sort";
110const char* PROPERTY_COMPACT = "compact";
111const char* PROPERTY_COMPACT_AFTER_ALLOCATE = "compact-after-allocate";
112const char* PROPERTY_DUMP = "dump";
113const char* PROPERTY_DISPLAY_STATS = "display-stats";
114
115// Propritétés internes à Arcane
116const char* PROPERTY_MESH_VERSION = "mesh-version";
117}
118
119namespace Arcane::mesh
120{
121
122/*---------------------------------------------------------------------------*/
123/*---------------------------------------------------------------------------*/
124
125extern "C++" ARCANE_MESH_EXPORT IItemFamilyPolicyMng*
126createNodeFamilyPolicyMng(ItemFamily* family);
127
128extern "C++" ARCANE_MESH_EXPORT IItemFamilyPolicyMng*
129createEdgeFamilyPolicyMng(ItemFamily* family);
130
131extern "C++" ARCANE_MESH_EXPORT IItemFamilyPolicyMng*
132createFaceFamilyPolicyMng(ItemFamily* family);
133
134extern "C++" ARCANE_MESH_EXPORT IItemFamilyPolicyMng*
135createCellFamilyPolicyMng(ItemFamily* family);
136
137extern "C++" ARCANE_MESH_EXPORT IItemFamilyPolicyMng*
138createParticleFamilyPolicyMng(ItemFamily* family);
139
140extern "C++" ARCANE_MESH_EXPORT IItemFamilyPolicyMng*
141createDoFFamilyPolicyMng(ItemFamily* family);
142
143extern "C++" ARCANE_MESH_EXPORT void
144allocateCartesianMesh(DynamicMesh* mesh,CartesianMeshAllocateBuildInfo& build_info);
145
146/*---------------------------------------------------------------------------*/
147/*---------------------------------------------------------------------------*/
148
149// #define ARCANE_DEBUG_DYNAMIC_MESH
150// #define ARCANE_DEBUG_LOAD_BALANCING
151
152#ifdef ARCANE_DEBUG_LOAD_BALANCING
153static bool arcane_debug_load_balancing = true;
154#else
155static bool arcane_debug_load_balancing = false;
156#endif
157
158#ifdef ACTIVATE_PERF_COUNTER
159const std::string DynamicMesh::PerfCounter::m_names[] = {
160 "UPGHOSTLAYER1",
161 "UPGHOSTLAYER2",
162 "UPGHOSTLAYER3",
163 "UPGHOSTLAYER4",
164 "UPGHOSTLAYER5",
165 "UPGHOSTLAYER6",
166 "UPGHOSTLAYER7"
167} ;
168#endif
169
170/*---------------------------------------------------------------------------*/
171/*---------------------------------------------------------------------------*/
172
174: public IMeshInternal
176{
177 public:
178
179 explicit InternalApi(DynamicMesh* mesh)
180 : m_mesh(mesh)
181 , m_connectivity_mng(std::make_unique<ItemConnectivityMng>(mesh->traceMng()))
182 {}
183
184 public:
185
186 void setMeshKind(const MeshKind& v) override
187 {
188 m_mesh->m_mesh_kind = v;
189 }
190
191 IItemConnectivityMng* dofConnectivityMng() const noexcept override
192 {
193 return m_connectivity_mng.get();
194 }
195
197 {
198 return nullptr;
199 }
200
202 {
203 m_mesh->incrementalBuilder()->removeNeedRemoveMarkedItems();
204 }
205
206 private:
207
208 DynamicMesh* m_mesh = nullptr;
209 std::unique_ptr<IItemConnectivityMng> m_connectivity_mng = nullptr;
210};
211
212/*---------------------------------------------------------------------------*/
213/*---------------------------------------------------------------------------*/
214
215DynamicMesh::
216DynamicMesh(ISubDomain* sub_domain,const MeshBuildInfo& mbi, bool is_submesh)
217: MeshVariables(sub_domain,mbi.name())
218, TraceAccessor(mbi.parallelMngRef()->traceMng())
219, m_sub_domain(sub_domain)
220, m_mesh_mng(sub_domain->meshMng())
221, m_mesh_handle(m_mesh_mng->findMeshHandle(mbi.name()))
222, m_parallel_mng(mbi.parallelMngRef().get())
223, m_variable_mng(sub_domain->variableMng())
224, m_properties(new Properties(sub_domain->propertyMng(),String("ArcaneMeshProperties_")+mbi.name()))
225, m_timestamp(0)
226, m_is_allocated(false)
227, m_dimension(-1)
228, m_name(mbi.name())
229, m_factory_name(mbi.factoryName())
230, m_need_compact(true)
231, m_node_family(nullptr)
232, m_edge_family(nullptr)
233, m_face_family(nullptr)
234, m_cell_family(nullptr)
235, m_parent_mesh(nullptr)
236, m_parent_group(nullptr)
237, m_mesh_utilities(nullptr)
238, m_mesh_builder(nullptr)
239, m_mesh_checker(nullptr)
240, m_submesh_tools(nullptr)
242, m_mesh_refinement(nullptr)
243, m_new_item_owner_builder(nullptr)
244, m_extra_ghost_cells_builder(nullptr)
245, m_extra_ghost_particles_builder(nullptr)
246, m_initial_allocator(this)
247, m_internal_api(std::make_unique<InternalApi>(this))
248, m_is_amr_activated(mbi.meshKind().meshAMRKind()!=eMeshAMRKind::None)
249, m_amr_type(mbi.meshKind().meshAMRKind())
250, m_is_dynamic(false)
251, m_tied_interface_mng(nullptr)
252, m_is_sub_connectivity_set(false)
253, m_tied_interface_need_prepare_dump(true)
254, m_partition_constraint_mng(nullptr)
255, m_ghost_layer_mng(new GhostLayerMng(m_parallel_mng->traceMng()))
256, m_mesh_unique_id_mng(new MeshUniqueIdMng(m_parallel_mng->traceMng()))
257, m_mesh_exchange_mng(new MeshExchangeMng(this))
258, m_mesh_compact_mng(new MeshCompactMng(this))
259, m_connectivity_policy(InternalConnectivityPolicy::NewOnly)
260, m_mesh_part_info(makeMeshPartInfoFromParallelMng(m_parallel_mng))
261, m_item_type_mng(new ItemTypeMng())
262, m_indexed_connectivity_mng(new IndexedIncrementalItemConnectivityMng(m_parallel_mng->traceMng()))
263, m_mesh_kind(mbi.meshKind())
264{
265 m_node_family = new NodeFamily(this,"Node");
266 m_edge_family = new EdgeFamily(this,"Edge");
267 m_face_family = new FaceFamily(this,"Face");
268 m_cell_family = new CellFamily(this,"Cell");
269
270 _addFamily(m_node_family);
271 _addFamily(m_edge_family);
272 _addFamily(m_face_family);
273 _addFamily(m_cell_family);
274
275 m_properties->setBool(PROPERTY_SORT,true);
276 m_properties->setBool(PROPERTY_COMPACT,true);
277 m_properties->setBool(PROPERTY_COMPACT_AFTER_ALLOCATE,true);
278 m_properties->setBool(PROPERTY_DUMP,true);
279 m_properties->setBool(PROPERTY_DISPLAY_STATS,true);
280 m_properties->setInt32(PROPERTY_MESH_VERSION,1);
281
282 m_item_internal_list.mesh = this;
283 m_item_internal_list._internalSetNodeSharedInfo(m_node_family->commonItemSharedInfo());
284 m_item_internal_list._internalSetEdgeSharedInfo(m_edge_family->commonItemSharedInfo());
285 m_item_internal_list._internalSetFaceSharedInfo(m_face_family->commonItemSharedInfo());
286 m_item_internal_list._internalSetCellSharedInfo(m_cell_family->commonItemSharedInfo());
287
288 info() << "Is AMR Activated? = " << m_is_amr_activated
289 << " AMR type = " << m_amr_type
290 << " allow_loose_items=" << m_mesh_kind.isNonManifold();
291
292 _printConnectivityPolicy();
293
294 // Adding the family dependencies if asked
296 m_use_mesh_item_family_dependencies = true ;
297 m_item_family_network = new ItemFamilyNetwork(traceMng());
298 _addDependency(m_cell_family,m_node_family);
299 _addDependency(m_cell_family,m_face_family);
300 _addDependency(m_cell_family,m_edge_family);
301 _addDependency(m_face_family,m_node_family);
302 _addDependency(m_edge_family,m_node_family);
303 _addRelation(m_face_family,m_edge_family);// Not seen as a dependency in DynamicMesh : for example not possible to use replaceConnectedItem for Face to Edge...
304 _addRelation(m_face_family,m_face_family);
305 _addRelation(m_face_family,m_cell_family);
306 _addRelation(m_edge_family,m_cell_family);
307 _addRelation(m_edge_family,m_face_family);
308 _addRelation(m_node_family,m_cell_family);
309 _addRelation(m_node_family,m_face_family);
310 _addRelation(m_node_family,m_edge_family);
311 // The relation concerning edge family are only added when the dimension is known since they change with dimension
312 // cf. 3D Cell <-> Faces <-> Edges <-> Nodes
313 // 2D Cell <-> Faces <-> Nodes
314 // <-> Edges <-> Nodes
315 // 1D No edge...
316 m_family_modifiers.add(m_cell_family);
317 m_family_modifiers.add(m_face_family);
318 m_family_modifiers.add(m_node_family);
319 m_family_modifiers.add(m_edge_family);
320 }
321
322 {
323 String s = platform::getEnvironmentVariable("ARCANE_GRAPH_CONNECTIVITY_POLICY");
324#ifdef USE_GRAPH_CONNECTIVITY_POLICY
325 s = "1";
326#endif
327 if (s == "1") {
328 m_item_family_network = new ItemFamilyNetwork(traceMng());
329 info()<<"Graph connectivity is activated";
330 m_family_modifiers.add(m_cell_family);
331 m_family_modifiers.add(m_face_family);
332 m_family_modifiers.add(m_node_family);
333 m_family_modifiers.add(m_edge_family);
334 }
335 }
336
337 m_extra_ghost_cells_builder = new ExtraGhostCellsBuilder(this);
338 m_extra_ghost_particles_builder = new ExtraGhostParticlesBuilder(this);
339
340 // Pour garder la compatibilité avec l'existant, autorise de ne pas
341 // sauvegarder l'attribut 'need-compact'. Cela a été ajouté pour la version 3.10
342 // de Arcane (juin 2023). A supprimer avant fin 2023.
343 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_NO_SAVE_NEED_COMPACT", true))
344 m_do_not_save_need_compact = v.value();
345
346 // Surcharge la valeur par défaut pour le mécanisme de numérotation
347 // des uniqueId() des arêtes et des faces.
348 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_GENERATE_UNIQUE_ID_FROM_NODES", true)){
349 bool is_generate = (v.value() != 0);
350 // L'utilisation des entités libres implique d'utiliser la génération des uniqueId()
351 // à partir des noeuds.
352 if (!is_generate && meshKind().isNonManifold())
353 is_generate = true;
354 m_mesh_unique_id_mng->setUseNodeUniqueIdToGenerateEdgeAndFaceUniqueId(is_generate);
355 }
356}
357
358/*---------------------------------------------------------------------------*/
359/*---------------------------------------------------------------------------*/
360
363{
364 // Il serait peut-être préférable de lancer une exception mais dans un
365 // destructeur ce n'est pas forcément conseillé
366 if (m_extra_ghost_cells_builder->hasBuilder())
367 info() << "WARNING: pending ExtraGhostCellsBuilder reference";
368 if (m_extra_ghost_particles_builder->hasBuilder())
369 info() << "WARNING: pending ExtraGhostParticlesBuilder reference";
370
371 m_indexed_connectivity_mng = nullptr;
372 delete m_mesh_compact_mng;
373 delete m_mesh_exchange_mng;
374 delete m_extra_ghost_cells_builder;
375 delete m_extra_ghost_particles_builder;
376 delete m_mesh_unique_id_mng;
377 delete m_ghost_layer_mng;
378 delete m_tied_interface_mng;
379 delete m_partition_constraint_mng;
380 delete m_mesh_utilities;
381 delete m_mesh_builder;
382 delete m_mesh_checker;
384 delete m_mesh_refinement;
385 delete m_submesh_tools;
386 delete m_new_item_owner_builder;
387
388 // Détruit les familles allouées dynamiquement.
389 for( IItemFamily* family : m_item_families ){
390 eItemKind kind = family->itemKind();
391 // Seules les familles de particules ou de DoF sont allouées dynamiquement.
392 // TODO: maintenant elles le sont toute donc il faudrait toute
393 // les désallouées par cette boucle
394 if (kind==IK_Particle || kind==IK_DoF)
395 delete family;
396 }
397 m_properties->destroy();
398 delete m_properties;
399
400 delete m_cell_family;
401 delete m_face_family;
402 delete m_edge_family;
403 delete m_node_family;
404
405 delete m_item_type_mng;
406}
407
408/*---------------------------------------------------------------------------*/
409/*---------------------------------------------------------------------------*/
410
412build()
413{
414 Trace::Setter mci(traceMng(),_className());
415
416 info() << "Building DynamicMesh name=" << name()
417 << " ItemInternalMapImpl=" << ItemInternalMap::UseNewImpl;
418
419 m_item_type_mng->build(this);
420
421 m_tied_interface_mng = new TiedInterfaceMng(this);
422
423 // IMPORTANT: les premiers éléments de m_item_families doivent
424 // correspondre aux familles associées aux valeurs de eItemKind
425 // (IK_Node, IK_Edge, IK_Face, IK_Cell)
426 for( IItemFamily* family : m_item_families ){
427 _buildAndInitFamily(family);
428 }
429
430 // Permet d'appeler la fonction '_prepareDump' lorsqu'une
431 // protection va être effectuée
432 IVariableMng* vm = subDomain()->variableMng();
433 m_observer_pool.addObserver(this,
435 vm->writeObservable());
436 // Permet d'appeler la fonction '_reloadFromDump' lorsqu'une
437 // protection est relue
438 m_observer_pool.addObserver(this,
440 vm->readObservable());
441
442 m_mesh_builder = new DynamicMeshIncrementalBuilder(this);
443 m_mesh_checker = new DynamicMeshChecker(this);
444 m_partition_constraint_mng = new MeshPartitionConstraintMng(this);
445
446 if (parentMesh()) {
447 // Cela peut induire des segfaults si le DynamicMesh n'est pas correctement utilisé
448 m_submesh_tools = new SubMeshTools(this, m_mesh_builder);
451
452 this->properties()->setBool(PROPERTY_COMPACT,true);
453 this->properties()->setBool(PROPERTY_SORT,true);
454
455 ItemGroupDynamicMeshObserver * obs = NULL;
456 m_parent_group->attachObserver(this, (obs = new ItemGroupDynamicMeshObserver(this)));
457
458 this->endAllocate();
459 Int32ConstArrayView localIds = m_parent_group->itemsLocalId();
460 obs->executeExtend(&localIds);
461 this->endUpdate();
462
463 } else {
464 m_submesh_tools = 0;
466
467 // GG: ne construit m_mesh_refinement qui si l'AMR est actif
468 // Cela évite de creer des variables inutile lorsque l'AMR n'est pas
469 // demandé. La création de m_mesh_refinement se fait maintenant
470 // dans readAmrActivator(). Ce n'est peut-être pas le bon endroit
471 // pour le faire et on peut éventuellement le déplacer. Il faut
472 // juste que m_mesh_refinement ne soit créé que si l'AMR est actif.
473 // SDC : OK. Remis car maintenant l'info AMR (in)actif est connue a
474 // la construction. Suppression de readAmrActivator.
475
476 if (m_is_amr_activated) {
477 if(m_amr_type == eMeshAMRKind::None || m_amr_type == eMeshAMRKind::Cell){
479 }
480 else if(m_amr_type == eMeshAMRKind::Patch){
481 ARCANE_FATAL("Patch AMR type is not implemented.");
482 }
483 else if(m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly){
484 // L'AMR PatchCartesianMeshOnly n'est pas géré par MeshRefinement().
485 // Voir dans CartesianMesh.cc.
486 }
487 }
488 }
489}
490
491/*---------------------------------------------------------------------------*/
492/*---------------------------------------------------------------------------*/
493
496{
497 return m_parallel_mng;
498}
499
500/*---------------------------------------------------------------------------*/
501/*---------------------------------------------------------------------------*/
502
503void DynamicMesh::
504_checkValidItem(ItemInternal* item)
505{
506 if (!item)
507 ARCANE_FATAL("INTERNAL: DynamicMesh: invalid use of a null entity");
508}
509
510/*---------------------------------------------------------------------------*/
511/*---------------------------------------------------------------------------*/
512
518
519/*---------------------------------------------------------------------------*/
520/*---------------------------------------------------------------------------*/
521
524{
525 Trace::Setter mci(traceMng(),_className());
526 info() << "Reloading the mesh " << name();
527 m_is_allocated = true;
528 Timer timer(subDomain(),"DynamicMesh::reloadMesh",Timer::TimerReal);
529 {
530 Timer::Sentry sentry(&timer);
532 m_mesh_checker->checkMeshFromReferenceFile();
533 }
534 info() << "Time to reallocate the mesh structures (direct method) (unit: second): "
535 << timer.lastActivationTime();
536}
537
538/*---------------------------------------------------------------------------*/
539/*---------------------------------------------------------------------------*/
540
543{
544 m_mesh_checker->setCheckLevel(level);
545}
546
547/*---------------------------------------------------------------------------*/
548/*---------------------------------------------------------------------------*/
549
551checkLevel() const
552{
553 return m_mesh_checker->checkLevel();
554}
555
556/*---------------------------------------------------------------------------*/
557/*---------------------------------------------------------------------------*/
558
561{
562 if (!m_is_allocated)
563 return;
564 m_mesh_checker->checkValidMesh();
565}
566
567/*---------------------------------------------------------------------------*/
568/*---------------------------------------------------------------------------*/
569
572{
573 if (!m_is_allocated)
574 return;
575 m_mesh_checker->checkValidMeshFull();
576}
577
578/*---------------------------------------------------------------------------*/
579/*---------------------------------------------------------------------------*/
580
581void DynamicMesh::
582checkValidConnectivity()
583{
584 m_mesh_checker->checkValidConnectivity();
585}
586
587/*---------------------------------------------------------------------------*/
588/*---------------------------------------------------------------------------*/
589
592{
593 for( IItemFamily* family : m_item_families ){
594 family->destroyGroups();
595 }
596}
597
598/*---------------------------------------------------------------------------*/
599/*---------------------------------------------------------------------------*/
600
602findGroup(const String& name)
603{
604 ItemGroup group;
605 for( IItemFamily* family : m_item_families ){
606 group = family->findGroup(name);
607 if (!group.null())
608 return group;
609 }
610 return group;
611}
612
613/*---------------------------------------------------------------------------*/
614/*---------------------------------------------------------------------------*/
615
617findGroup(const String& name,eItemKind ik,bool create_if_needed)
618{
619 _checkKindRange(ik);
620 IItemFamily* family = m_item_families[ik];
621 return family->findGroup(name,create_if_needed);
622}
623
624/*---------------------------------------------------------------------------*/
625/*---------------------------------------------------------------------------*/
626
627ItemGroup DynamicMesh::
628createGroup(const String& name,eItemKind ik)
629{
630 _checkKindRange(ik);
631 IItemFamily* family = m_item_families[ik];
632 ARCANE_CHECK_PTR(family);
633 return family->findGroup(name);
634}
635
636/*---------------------------------------------------------------------------*/
637/*---------------------------------------------------------------------------*/
638
639ItemGroup DynamicMesh::
640createGroup(const String& name,const ItemGroup& parent)
641{
642 IItemFamily* family = parent.itemFamily();
643 ARCANE_CHECK_PTR(family);
644 return family->createGroup(name,parent);
645}
646
647/*--------------------------------------------------------------------------*/
648/*--------------------------------------------------------------------------*/
649
650void DynamicMesh::
651_computeSynchronizeInfos()
652{
653 _computeFamilySynchronizeInfos();
654 _computeGroupSynchronizeInfos();
655}
656
657/*--------------------------------------------------------------------------*/
658/*--------------------------------------------------------------------------*/
659
660void DynamicMesh::
661_computeFamilySynchronizeInfos()
662{
663 info() << "Computing family synchronization information for " << name();
664 for( IItemFamily* family : m_item_families ){
665 family->computeSynchronizeInfos();
666 }
667
668 // Ecrit la topologie pour la synchronisation des mailles
669 if (!platform::getEnvironmentVariable("ARCANE_DUMP_VARIABLE_SYNCHRONIZER_TOPOLOGY").null()){
670 auto* var_syncer = cellFamily()->allItemsSynchronizer();
671 Int32 iteration = subDomain()->commonVariables().globalIteration();
672 String file_name = String::format("{0}_sync_topology_iter{1}.json",name(),iteration);
673 mesh_utils::dumpSynchronizerTopologyJSON(var_syncer,file_name);
674 }
675}
676
677/*--------------------------------------------------------------------------*/
678/*--------------------------------------------------------------------------*/
679
680void DynamicMesh::
681_computeGroupSynchronizeInfos()
682{
683 auto action = [](ItemGroup& group)
684 {
685 if (group.hasSynchronizer())
686 group.synchronizer()->compute();
687 };
688
689 info() << "Computing group synchronization information for " << name();
690 meshvisitor::visitGroups(this,action);
691}
692
693/*--------------------------------------------------------------------------*/
694/*--------------------------------------------------------------------------*/
695
697groups()
698{
699 m_all_groups.clear();
700 for( IItemFamily* family : m_item_families ){
701 for( ItemGroupCollection::Enumerator i_group(family->groups()); ++i_group; )
702 m_all_groups.add(*i_group);
703 }
704 return m_all_groups;
705}
706
707/*---------------------------------------------------------------------------*/
708/*---------------------------------------------------------------------------*/
713initializeVariables(const XmlNode& init_node)
714{
715 // TEMPORAIRE: recopie pour chaque famille le champ owner() dans
716 // la variable correspondante.
717 for( IItemFamily* family : m_item_families ){
718 VariableItemInt32& items_owner(family->itemsNewOwner());
719 ENUMERATE_ITEM(iitem,family->allItems()){
720 Item item = *iitem;
721 items_owner[iitem] = item.owner();
722 }
723 }
724
725 ICaseDocumentFragment* doc = subDomain()->caseMng()->caseDocumentFragment();
726 XmlNode root = doc->rootElement();
727 if (root.null())
728 return;
729
730 bool has_error = false;
731 IVariableMng* vm = m_sub_domain->variableMng();
732 XmlNodeList child_list = init_node.children(String("variable"));
733 for( const auto& i : child_list ){
734 String var_name = i.attrValue("nom");
735 IVariable* var = vm->findMeshVariable(this,var_name);
736 if (!var){
737 error() << "Failed to initialize the variable `" << var_name
738 << "'\nNo variable with that name exists";
739 has_error = true;
740 continue;
741 }
742 // N'initialise pas les variables non utilisées.
743 if (!var->isUsed())
744 continue;
745
746 String grp_name = i.attrValue("groupe");
747 ItemGroup grp = findGroup(grp_name);
748
749 if (grp.null()){
750 error() << "Failed to initialize the variable `" << var_name
751 << "' on the group `" << grp_name << "'\n"
752 << "No group with that name exists";
753 has_error = true;
754 continue;
755 }
756 debug() << "Read value variable `" << grp_name
757 << "' `" << var_name << "' " << var;
758 String val_str = i.attrValue("valeur");
759 bool ret = var->initialize(grp,val_str);
760 if (ret){
761 error() << "Failed to initialized the variable `" << var_name
762 << "' on the group `" << grp_name << "'";
763 has_error = true;
764 continue;
765 }
766 }
767 if (has_error)
768 fatal() << "Variable initialization failed";
769}
770
771/*---------------------------------------------------------------------------*/
772/*---------------------------------------------------------------------------*/
773
774// NOTE: a priori cette méthode ne fonctionne s'il existe des variables
775// partielles car les groupes sur lesquelles elles reposent vont être détruit
776// (A vérifier)
777
780{
781 if (!m_is_allocated)
782 ARCANE_FATAL("mesh is not allocated");
783
784 clearItems();
786 m_mesh_builder->resetAfterDeallocate();
787
788 m_is_allocated = false;
789 m_mesh_dimension = (-1);
790}
791
792/*---------------------------------------------------------------------------*/
793/*---------------------------------------------------------------------------*/
794
796allocateCells(Integer mesh_nb_cell,Int64ConstArrayView cells_infos,bool one_alloc)
797{
798 if (mesh_nb_cell==0 && !cells_infos.empty())
799 ARCANE_FATAL("Can not dynamically compute the number of cells");
800
801 Trace::Setter mci(traceMng(),_className());
802
803 setEstimatedCells(mesh_nb_cell);
804
805 Timer timer(subDomain(),"AllocateCells",Timer::TimerReal);
806 {
807 Timer::Sentry sentry(&timer);
808 _allocateCells(mesh_nb_cell,cells_infos);
809 if (one_alloc)
810 endAllocate();
811 }
812 info() << "Time to build the mesh structures (indirect method) (unit: second): "
813 << timer.lastActivationTime();
814}
815
816/*---------------------------------------------------------------------------*/
817/*---------------------------------------------------------------------------*/
818
821{
822 Trace::Setter mci(traceMng(),_className());
823 if (m_is_allocated)
824 ARCANE_FATAL("endAllocate() has already been called");
825 _checkDimension(); // HP: add control if endAllocate is called
826 _checkConnectivity(); // without any cell allocation
827
828 bool print_stats = true;
829 ITimeStats* ts = m_sub_domain->timeStats();
831 if (print_stats){
832 info() << "Begin compute face unique ids";
834 }
835 m_mesh_builder->computeFacesUniqueIds();
836 if (print_stats){
837 info() << "Begin compute ghost layer";
839 }
840 m_mesh_builder->addGhostLayers(true);
841 if (print_stats){
842 info() << "Begin compact items";
844 }
845 _allocateCells2(m_mesh_builder);
846
847 if (m_properties->getBool(PROPERTY_COMPACT_AFTER_ALLOCATE))
848 _compactItems(true,false);
849
850 _compactItemInternalReferences();
851 for( IItemFamily* family : m_item_families )
852 family->_internalApi()->endAllocate();
853
854 if (print_stats)
856
857#ifdef ARCANE_DEBUG_DYNAMIC_MESH
858 {
859 String file_name("mesh-end-allocate");
860 if (parallelMng()->isParallel()){
861 file_name += "-";
862 file_name += m_mesh_rank;
863 }
864 mesh_utils::writeMeshConnectivity(this,file_name);
865 }
866#endif
867
869 m_mesh_checker->checkMeshFromReferenceFile();
870
871 // Positionne les proprietaires pour que cela soit comme apres
872 // un echange. Ce n'est a priori pas indispensable
873 // mais cela permet d'assurer la coherence avec
874 // d'autres appels a setOwnersFromCells()
875 if (parallelMng()->isParallel()){
876 String s = platform::getEnvironmentVariable("ARCANE_CHANGE_OWNER_ON_INIT");
877 if (!s.null()){
878 info() << "** Set owners from cells";
879 _setOwnersFromCells();
880 }
881 }
882
883 // Indique aux familles qu'on vient de mettre à jour le maillage
884 // Pour qu'elles puissent recalculer les informations qu'elles souhaitent.
885 _notifyEndUpdateForFamilies();
886
888
889 m_is_allocated = true;
890 if (arcaneIsCheck())
892
893 // Affiche les statistiques du nouveau maillage
894 {
895 MeshStats ms(traceMng(),this,m_parallel_mng);
896 ms.dumpStats();
897 }
898}
899
900/*---------------------------------------------------------------------------*/
901/*---------------------------------------------------------------------------*/
902
903void DynamicMesh::
904_allocateCells(Integer mesh_nb_cell,
905 Int64ConstArrayView cells_infos,
906 Int32ArrayView cells,
907 bool allow_build_face)
908{
909 Trace::Setter mci(traceMng(),_className());
910 _checkDimension();
911 _checkConnectivity();
912 Int32 rank = meshRank();
913 if (m_use_mesh_item_family_dependencies)
914 m_mesh_builder->addCells3(mesh_nb_cell,cells_infos,rank,cells,allow_build_face);
915 else
916 m_mesh_builder->addCells(mesh_nb_cell,cells_infos,rank,cells,allow_build_face);
917}
918
919/*---------------------------------------------------------------------------*/
920/*---------------------------------------------------------------------------*/
921
923addCells(Integer nb_cell,
924 Int64ConstArrayView cells_infos,
925 Int32ArrayView cells)
926{
927 const bool allow_build_face = (m_parallel_mng->commSize() == 1);
928 _allocateCells(nb_cell,cells_infos,cells,allow_build_face);
929}
930
931/*---------------------------------------------------------------------------*/
932/*---------------------------------------------------------------------------*/
933
936{
937 bool allow_build_face = args.isAllowBuildFaces();
938 // En parallèle, on ne peut pas construire à la volée les faces
939 // (car il faut générer un uniqueId() et ce dernier ne serait pas cohérent
940 // entre les sous-domaines)
941 if (m_parallel_mng->commSize() > 1)
942 allow_build_face = false;
943 _allocateCells(args.nbCell(),args.cellInfos(),args.cellLocalIds(),allow_build_face);
944}
945
946/*---------------------------------------------------------------------------*/
947/*---------------------------------------------------------------------------*/
948
950addCells(ISerializer* buffer)
951{
952 _addCells(buffer,0);
953}
954
955/*---------------------------------------------------------------------------*/
956/*---------------------------------------------------------------------------*/
957
959addCells(ISerializer* buffer,Int32Array& cells_local_id)
960{
961 _addCells(buffer,&cells_local_id);
962}
963
964/*---------------------------------------------------------------------------*/
965/*---------------------------------------------------------------------------*/
966
967void DynamicMesh::
968_addCells(ISerializer* buffer,Int32Array* cells_local_id)
969{
970 Trace::Setter mci(traceMng(),_className());
971 _checkDimension();
972 _checkConnectivity();
973 if (!itemFamilyNetwork() ||
974 !(itemFamilyNetwork() && itemFamilyNetwork()->isActivated()) ||
975 !IItemFamilyNetwork::plug_serializer) {
977 ScopedPtrT<IItemFamilySerializer> cell_serializer(m_cell_family->policyMng()->createSerializer());
978 cell_serializer->deserializeItems(buffer,cells_local_id);
979 }
980 else {
981 _deserializeItems(buffer, cells_local_id, m_cell_family);
982 }
983}
984
985/*---------------------------------------------------------------------------*/
986/*---------------------------------------------------------------------------*/
987
988void DynamicMesh::
989allocate(UnstructuredMeshAllocateBuildInfo& build_info)
990{
991 auto* x = build_info._internal();
992 setDimension(x->meshDimension());
993 allocateCells(x->nbCell(),x->cellsInfos(),true);
994}
995
996/*---------------------------------------------------------------------------*/
997/*---------------------------------------------------------------------------*/
998
999void DynamicMesh::
1000allocate(CartesianMeshAllocateBuildInfo& build_info)
1001{
1002 // L'allocation des entités du maillage est effectuée par la
1003 // classe DynamicMeshCartesianBuilder.
1004 allocateCartesianMesh(this,build_info);
1005}
1006
1007/*---------------------------------------------------------------------------*/
1008/*---------------------------------------------------------------------------*/
1009
1011serializeCells(ISerializer* buffer,Int32ConstArrayView cells_local_id)
1012{
1013 Trace::Setter mci(traceMng(),_className());
1014 _checkDimension();
1015 _checkConnectivity();
1016 if ( !itemFamilyNetwork() ||
1017 !(itemFamilyNetwork() && itemFamilyNetwork()->isActivated()) ||
1018 !IItemFamilyNetwork::plug_serializer) {
1019 ScopedPtrT<IItemFamilySerializer> cell_serializer(m_cell_family->policyMng()->createSerializer());
1020 buffer->setMode(ISerializer::ModeReserve);
1021 cell_serializer->serializeItems(buffer,cells_local_id);
1022 buffer->allocateBuffer();
1024 cell_serializer->serializeItems(buffer,cells_local_id);
1025 }
1026 else {
1027 _serializeItems(buffer, cells_local_id, m_cell_family);
1028 }
1029}
1030
1031/*---------------------------------------------------------------------------*/
1032/*---------------------------------------------------------------------------*/
1033
1034void DynamicMesh::
1035_serializeItems(ISerializer* buffer,Int32ConstArrayView item_local_ids, IItemFamily* item_family)
1036{
1037 // 1-Get item lids for family and downard dependencies.
1038 // Rk downard relations are not taken here => automatically added in addItems(ItemData) :
1039 // this will change. Todo add relations when addItems has been updated
1040 using FamilyLidMap = std::map<String, Int32UniqueArray>;
1041 FamilyLidMap serialized_items;
1042 serialized_items[item_family->name()] = item_local_ids;
1043 for (const auto& connectivity : mesh()->itemFamilyNetwork()->getChildDependencies(item_family)){
1044 ENUMERATE_ITEM(item, item_family->view(item_local_ids)) {
1045 auto connectivity_accessor = ConnectivityItemVector{connectivity};
1046 auto& connected_family_serialized_items = serialized_items[connectivity->targetFamily()->name()];
1047 connected_family_serialized_items.addRange(connectivity_accessor.connectedItems(ItemLocalId(item)).localIds());
1048 }
1049 }
1050 // 2-Serialize each family in the buffer. The order is important: use the family graph from leaves to root
1051 buffer->setMode(ISerializer::ModeReserve);
1052 _fillSerializer(buffer, serialized_items);
1053 buffer->allocateBuffer();
1055 _fillSerializer(buffer, serialized_items);
1056
1057}
1058
1059/*---------------------------------------------------------------------------*/
1060/*---------------------------------------------------------------------------*/
1061
1062void DynamicMesh::
1063_deserializeItems(ISerializer* buffer,Int32Array* item_local_ids, IItemFamily* item_family)
1064{
1065 ARCANE_UNUSED(item_family);
1066 buffer->setMode(ISerializer::ModeGet);
1067 mesh()->itemFamilyNetwork()->schedule([item_local_ids,buffer](IItemFamily* family) {
1068 auto family_serializer = std::unique_ptr<IItemFamilySerializer>{family->policyMng()->createSerializer()}; // todo make_unique (not in 4.7.2...)
1069 family_serializer->deserializeItems(buffer,item_local_ids);
1070 } ,
1071 IItemFamilyNetwork::InverseTopologicalOrder);
1072 mesh()->itemFamilyNetwork()->schedule([item_local_ids,buffer](IItemFamily* family) {
1073 auto family_serializer = std::unique_ptr<IItemFamilySerializer>{family->policyMng()->createSerializer()}; // todo make_unique (not in 4.7.2...)
1074 family_serializer->deserializeItemRelations(buffer,item_local_ids);
1075 } ,
1076 IItemFamilyNetwork::InverseTopologicalOrder);
1077}
1078
1079/*---------------------------------------------------------------------------*/
1080/*---------------------------------------------------------------------------*/
1081
1082void DynamicMesh::
1083_fillSerializer(ISerializer* buffer, std::map<String, Int32UniqueArray>& serialized_items)
1084{
1085 mesh()->itemFamilyNetwork()->schedule([& serialized_items,buffer](IItemFamily* family) {
1086 auto family_serializer = std::unique_ptr<IItemFamilySerializer>{family->policyMng()->createSerializer()}; // todo make_unique (not in 4.7.2...)
1087 auto& serialized_items_local_ids = serialized_items[family->name()];
1088 family_serializer->serializeItems(buffer,serialized_items_local_ids);
1089 } ,
1090 IItemFamilyNetwork::InverseTopologicalOrder);
1091 mesh()->itemFamilyNetwork()->schedule([& serialized_items,buffer](IItemFamily* family) {
1092 auto family_serializer = std::unique_ptr<IItemFamilySerializer>{family->policyMng()->createSerializer()}; // todo make_unique (not in 4.7.2...)
1093 auto& serialized_items_local_ids = serialized_items[family->name()];
1094 family_serializer->serializeItemRelations(buffer,serialized_items_local_ids);
1095 } ,
1096 IItemFamilyNetwork::InverseTopologicalOrder);
1097}
1098
1099/*---------------------------------------------------------------------------*/
1100/*---------------------------------------------------------------------------*/
1101
1102void DynamicMesh::
1103addParentCells(ItemVectorView & items)
1104{
1105 Trace::Setter mci(traceMng(),_className());
1106 _checkDimension();
1107 _checkConnectivity();
1108 m_mesh_builder->addParentCells(items);
1109}
1110/*---------------------------------------------------------------------------*/
1111/*---------------------------------------------------------------------------*/
1112
1115addHChildrenCells(Cell parent_cell,Integer nb_cell,Int64ConstArrayView cells_infos,Int32ArrayView cells)
1116{
1117 Trace::Setter mci(traceMng(),_className());
1118 _checkDimension();
1119 _checkConnectivity();
1120 bool allow_build_face = false /*(m_parallel_mng->commSize() == 1)*/;
1121 m_mesh_builder->addHChildrenCells(parent_cell,nb_cell,cells_infos,meshRank(),cells,allow_build_face);
1122}
1123
1124/*---------------------------------------------------------------------------*/
1125/*---------------------------------------------------------------------------*/
1126
1127void DynamicMesh::
1128addParentCellToCell(Cell child, Cell parent)
1129{
1130 Trace::Setter mci(traceMng(),_className());
1131 _checkDimension();
1132 _checkConnectivity();
1133
1134 m_cell_family->_addParentCellToCell(child,parent);
1135}
1136
1137/*---------------------------------------------------------------------------*/
1138/*---------------------------------------------------------------------------*/
1139
1140void DynamicMesh::
1141addChildCellToCell(Cell parent, Cell child)
1142{
1143 Trace::Setter mci(traceMng(),_className());
1144 _checkDimension();
1145 _checkConnectivity();
1146
1147 m_cell_family->_addChildCellToCell2(parent, child);
1148}
1149
1150/*---------------------------------------------------------------------------*/
1151/*---------------------------------------------------------------------------*/
1152
1153void DynamicMesh::
1154addParentFaceToFace(Face child, Face parent)
1155{
1156 Trace::Setter mci(traceMng(), _className());
1157 _checkDimension();
1158 _checkConnectivity();
1159
1160 m_face_family->_addParentFaceToFace(parent, child);
1161}
1162
1163/*---------------------------------------------------------------------------*/
1164/*---------------------------------------------------------------------------*/
1165
1166void DynamicMesh::
1167addChildFaceToFace(Face parent, Face child)
1168{
1169 Trace::Setter mci(traceMng(), _className());
1170 _checkDimension();
1171 _checkConnectivity();
1172
1173 m_face_family->_addChildFaceToFace(parent, child);
1174}
1175
1176/*---------------------------------------------------------------------------*/
1177/*---------------------------------------------------------------------------*/
1178
1179void DynamicMesh::
1180addParentNodeToNode(Node child, Node parent)
1181{
1182 Trace::Setter mci(traceMng(), _className());
1183 _checkDimension();
1184 _checkConnectivity();
1185
1186 m_node_family->_addParentNodeToNode(parent, child);
1187}
1188
1189/*---------------------------------------------------------------------------*/
1190/*---------------------------------------------------------------------------*/
1191
1192void DynamicMesh::
1193addChildNodeToNode(Node parent, Node child)
1194{
1195 Trace::Setter mci(traceMng(), _className());
1196 _checkDimension();
1197 _checkConnectivity();
1198
1199 m_node_family->_addChildNodeToNode(parent, child);
1200}
1201
1202/*---------------------------------------------------------------------------*/
1203/*---------------------------------------------------------------------------*/
1204
1206addFaces(Integer nb_face,Int64ConstArrayView face_infos,Int32ArrayView faces)
1207{
1208 _checkDimension();
1209 _checkConnectivity();
1210 Int32 rank = meshRank();
1211 if (m_use_mesh_item_family_dependencies)
1212 m_mesh_builder->addFaces3(nb_face,face_infos,rank,faces);
1213 else
1214 m_mesh_builder->addFaces(nb_face,face_infos,rank,faces);
1215}
1216
1217/*---------------------------------------------------------------------------*/
1218/*---------------------------------------------------------------------------*/
1219
1222{
1223 addFaces(args.nbFace(),args.faceInfos(),args.faceLocalIds());
1224}
1225
1226/*---------------------------------------------------------------------------*/
1227/*---------------------------------------------------------------------------*/
1228
1230addEdges(Integer nb_edge,Int64ConstArrayView edge_infos,Int32ArrayView edges)
1231{
1232 _checkDimension();
1233 _checkConnectivity();
1234 Int32 rank = meshRank();
1235 if (m_use_mesh_item_family_dependencies)
1236 m_mesh_builder->addEdges3(nb_edge,edge_infos,rank,edges);
1237 else
1238 m_mesh_builder->addEdges(nb_edge,edge_infos,rank,edges);
1239}
1240
1241/*---------------------------------------------------------------------------*/
1242/*---------------------------------------------------------------------------*/
1243
1246{
1247 _checkDimension();
1248 _checkConnectivity();
1249 Int32 rank = meshRank();
1250 if (m_use_mesh_item_family_dependencies)
1251 m_mesh_builder->addNodes2(nodes_uid,rank,nodes);
1252 else
1253 m_mesh_builder->addNodes(nodes_uid,rank,nodes);
1254}
1255
1256/*---------------------------------------------------------------------------*/
1257/*---------------------------------------------------------------------------*/
1258
1259void DynamicMesh::
1260removeCells(Int32ConstArrayView cells_local_id,bool update_graph)
1261{
1262 ARCANE_UNUSED(update_graph);
1263 Trace::Setter mci(traceMng(),_className());
1264 if (m_use_mesh_item_family_dependencies)
1265 removeItems(m_cell_family,cells_local_id);
1266 else
1267 m_cell_family->internalRemoveItems(cells_local_id);
1268
1269 if(m_item_family_network)
1270 {
1271 m_item_family_network->removeConnectedDoFsFromCells(cells_local_id) ;
1272 }
1273}
1274
1275/*---------------------------------------------------------------------------*/
1276/*---------------------------------------------------------------------------*/
1277
1278void DynamicMesh::
1279removeItems(IItemFamily* item_family, Int32ConstArrayView cells_local_id)
1280{
1281 ARCANE_UNUSED(item_family);
1282 ARCANE_ASSERT((itemFamilyNetwork()),("Cannot call DynamicMesh::removeItems if no ItemFamilyNetwork available"))
1283
1284 if (cells_local_id.empty())
1285 return;
1286
1287 // Create item info (to remove items)
1288 ItemDataList item_data_list;
1289 ItemData& cell_data = item_data_list.itemData(Integer(m_cell_family->itemKind()),
1290 cells_local_id.size(),cells_local_id.size(),Int32ArrayView(),
1291 m_cell_family,(IItemFamilyModifier*)(m_cell_family),m_parallel_mng->commRank());
1292 Integer i(0);
1293 for (auto local_id : cells_local_id) {
1294 // TODO Find a better place in ItemData to put removed item lids (with Int32...) .
1295 cell_data.itemInfos()[i++] = (Int64)local_id;
1296 }
1297 itemFamilyNetwork()->schedule([&item_data_list](IItemFamily* family){
1298 // send the whole ItemDataList since removed items are to be added for child families
1299 family->removeItems2(item_data_list);
1300 },
1301 IItemFamilyNetwork::TopologicalOrder); // item destruction done from root to leaves
1302}
1303
1304/*---------------------------------------------------------------------------*/
1305/*---------------------------------------------------------------------------*/
1306
1308detachCells(Int32ConstArrayView cells_local_id)
1309{
1310 Trace::Setter mci(traceMng(),_className());
1311 if (m_use_mesh_item_family_dependencies)
1312 m_cell_family->detachCells2(cells_local_id);
1313 else {
1314 ItemInternalList cells = m_cell_family->itemsInternal();
1315 for( Integer i=0, is=cells_local_id.size(); i<is; ++i )
1316 m_cell_family->detachCell(cells[cells_local_id[i]]);
1317 }
1318}
1319
1320/*---------------------------------------------------------------------------*/
1321/*---------------------------------------------------------------------------*/
1322
1325{
1326 Trace::Setter mci(traceMng(),_className());
1327 if (m_use_mesh_item_family_dependencies)
1328 removeItems(m_cell_family,cells_local_id);
1329 else {
1330 ItemInternalList cells = m_cell_family->itemsInternal();
1331 for( Integer i=0, is=cells_local_id.size(); i<is; ++i )
1332 m_cell_family->removeDetachedCell(cells[cells_local_id[i]]);
1333 }
1334}
1335
1336/*---------------------------------------------------------------------------*/
1337/*---------------------------------------------------------------------------*/
1338
1342{
1343 Trace::Setter mci(traceMng(),_className());
1344 _checkAMR();
1345 m_mesh_refinement->flagCellToRefine(lids);
1346}
1347
1348/*---------------------------------------------------------------------------*/
1349/*---------------------------------------------------------------------------*/
1350
1351void DynamicMesh::
1352flagCellToCoarsen(Int32ConstArrayView lids)
1353{
1354 Trace::Setter mci(traceMng(),_className());
1355 _checkAMR();
1356 m_mesh_refinement->flagCellToCoarsen(lids);
1357}
1358
1359/*---------------------------------------------------------------------------*/
1360/*---------------------------------------------------------------------------*/
1361
1362void DynamicMesh::
1363refineItems()
1364{
1365 Trace::Setter mci(traceMng(),_className());
1366 _checkDimension();
1367 _checkConnectivity();
1368 _checkAMR();
1370}
1371/*---------------------------------------------------------------------------*/
1372/*---------------------------------------------------------------------------*/
1373
1374void DynamicMesh::
1375coarsenItems()
1376{
1377 Trace::Setter mci(traceMng(),_className());
1378 _checkDimension();
1379 _checkConnectivity();
1380 _checkAMR();
1382}
1383
1384/*---------------------------------------------------------------------------*/
1385/*---------------------------------------------------------------------------*/
1386
1387void DynamicMesh::
1388coarsenItemsV2(bool update_parent_flag)
1389{
1390 Trace::Setter mci(traceMng(), _className());
1391 _checkDimension();
1392 _checkConnectivity();
1393 _checkAMR();
1394 if (m_amr_type != eMeshAMRKind::Cell) {
1395 ARCANE_FATAL("This method is not compatible with Cartesian Mesh Patch AMR");
1396 }
1397 m_mesh_refinement->coarsenItemsV2(update_parent_flag);
1398}
1399
1400/*---------------------------------------------------------------------------*/
1401/*---------------------------------------------------------------------------*/
1402
1403bool DynamicMesh::
1404adapt()
1405{
1406 Trace::Setter mci(traceMng(),_className());
1407 _checkDimension();
1408 _checkConnectivity();
1409 _checkAMR();
1410 if(m_mesh_refinement->needUpdate())
1411 m_mesh_refinement->update() ;
1412 return m_mesh_refinement->refineAndCoarsenItems(true);
1413}
1414
1415/*---------------------------------------------------------------------------*/
1416/*---------------------------------------------------------------------------*/
1417
1418void DynamicMesh::
1419compact()
1420{
1421 _compactItems(false,true);
1422}
1423
1424/*---------------------------------------------------------------------------*/
1425/*---------------------------------------------------------------------------*/
1426
1427void DynamicMesh::
1428registerCallBack(IAMRTransportFunctor* f)
1429{
1430 Trace::Setter mci(traceMng(),_className());
1431 _checkAMR();
1432 m_mesh_refinement->registerCallBack(f);
1433}
1434/*---------------------------------------------------------------------------*/
1435/*---------------------------------------------------------------------------*/
1436
1437void DynamicMesh::
1438unRegisterCallBack(IAMRTransportFunctor* f)
1439{
1440 Trace::Setter mci(traceMng(),_className());
1441 _checkAMR();
1442 m_mesh_refinement->unRegisterCallBack(f);
1443}
1444
1445/*---------------------------------------------------------------------------*/
1446/*---------------------------------------------------------------------------*/
1447
1448void DynamicMesh::
1449_allocateCells2(DynamicMeshIncrementalBuilder* mib)
1450{
1451 Trace::Setter mci(traceMng(),_className());
1452
1453 _finalizeMeshChanged();
1454
1455 mib->printInfos();
1456
1457#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1458 OCStringStream ostr;
1459 _printMesh(ostr());
1460 info() << ostr.str();
1461#endif
1462}
1463
1464/*---------------------------------------------------------------------------*/
1465/*---------------------------------------------------------------------------*/
1466
1467void DynamicMesh::
1468_writeMesh(const String& base_name)
1469{
1470 StringBuilder file_name(base_name);
1471 file_name += "-";
1472 IParallelMng* pm = m_parallel_mng;
1473 bool is_parallel = pm->isParallel();
1474 Int32 rank = meshRank();
1475 if (is_parallel){
1476 file_name += subDomain()->commonVariables().globalIteration();
1477 file_name += "-";
1478 file_name += rank;
1479 }
1480 mesh_utils::writeMeshConnectivity(this,file_name.toString());
1481 //TODO pouvoir changer le nom du service
1482 auto writer(ServiceBuilder<IMeshWriter>::createReference(subDomain(),"Lima"));
1483 if (writer.get()){
1484 String mesh_file_name = file_name.toString() + ".mli";
1485 writer->writeMeshToFile(this,mesh_file_name);
1486 }
1487}
1488
1489/*---------------------------------------------------------------------------*/
1490/*---------------------------------------------------------------------------*/
1491
1492void DynamicMesh::
1493_printMesh(std::ostream& ostr)
1494{
1495 ostr << "----------- Mesh\n";
1496 ostr << " Nodes: " << nbNode() << '\n';
1497 ostr << " Edges: " << nbEdge() << '\n';
1498 ostr << " Faces: " << nbFace() << '\n';
1499 ostr << " Cells: " << nbCell() << '\n';
1500 mesh_utils::printItems(ostr,"Nodes",allNodes());
1501 mesh_utils::printItems(ostr,"Edges",allEdges());
1502 mesh_utils::printItems(ostr,"Faces",allFaces());
1503 mesh_utils::printItems(ostr,"Cells",allCells());
1504}
1505
1506/*---------------------------------------------------------------------------*/
1507/*---------------------------------------------------------------------------*/
1513{
1514 info(4) << "DynamicMesh::_saveProperties() name=" << name()
1515 << " nb-ghost=" << ghostLayerMng()->nbGhostLayer();
1516
1517 auto p = m_properties;
1518 p->setInt32("nb-ghostlayer",ghostLayerMng()->nbGhostLayer());
1519 p->setInt32("ghostlayer-builder-version",ghostLayerMng()->builderVersion());
1520 p->setInt32("part-info-part-rank",m_mesh_part_info.partRank());
1521 p->setInt32("part-info-nb-part",m_mesh_part_info.nbPart());
1522 p->setInt32("part-info-replication-rank",m_mesh_part_info.replicationRank());
1523 p->setInt32("part-info-nb-replication",m_mesh_part_info.nbReplication());
1524 p->setBool("has-itemsharedinfo-variables",true);
1525 p->setInt64("mesh-timestamp",m_timestamp);
1526 if (!m_do_not_save_need_compact)
1527 p->setBool("need-compact",m_need_compact);
1528}
1529
1530/*---------------------------------------------------------------------------*/
1531/*---------------------------------------------------------------------------*/
1537{
1538 auto p = m_properties;
1539
1540 info(4) << "DynamicMesh::_readProperties() name=" << name()
1541 << " mesh-version=" << p->getInt32WithDefault(PROPERTY_MESH_VERSION,-1);
1542
1543 {
1544 // Relit les infos sur le gestionnaire de mailles fantômes.
1545 Int32 x = 0;
1546 if (p->get("nb-ghostlayer",x))
1548 if (p->get("ghostlayer-builder-version",x))
1550 if (p->get("part-info-part-rank",x))
1551 m_mesh_part_info.setPartRank(x);
1552 if (p->get("part-info-nb-part",x))
1553 m_mesh_part_info.setNbPart(x);
1554 if (p->get("part-info-replication-rank",x))
1555 m_mesh_part_info.setReplicationRank(x);
1556 if (p->get("part-info-nb-replication",x))
1557 m_mesh_part_info.setNbReplication(x);
1558 if (!m_do_not_save_need_compact){
1559 bool xb = false;
1560 if (p->get("need-compact",xb))
1561 m_need_compact = xb;
1562 }
1563 Int64 x2 = 0;
1564 if (p->get("mesh-timestamp",x2))
1565 m_timestamp = x2;
1566 }
1567}
1568
1569/*---------------------------------------------------------------------------*/
1570/*---------------------------------------------------------------------------*/
1576{
1577 bool want_dump = m_properties->getBool(PROPERTY_DUMP);
1578 info(4) << "DynamicMesh::prepareForDump() name=" << name()
1579 << " need_compact?=" << m_need_compact
1580 << " want_dump?=" << want_dump
1581 << " timestamp=" << m_timestamp;
1582
1583 {
1585 m_mesh_events.eventObservable(t).notify(MeshEventArgs(this,t));
1586 }
1587
1588 // Si le maillage n'est pas sauvé, ne fait rien. Cela évite de compacter
1589 // et trier le maillage ce qui n'est pas souhaitable si les propriétés
1590 // 'sort' et 'compact' sont à 'false'.
1591 if (want_dump)
1593
1594 // Sauve les propriétés. Il faut le faire à la fin car l'appel à
1595 // prepareForDumpReal() peut modifier ces propriétés
1597
1598 {
1600 m_mesh_events.eventObservable(t).notify(MeshEventArgs(this,t));
1601 }
1602}
1603
1604/*---------------------------------------------------------------------------*/
1605/*---------------------------------------------------------------------------*/
1611{
1612 if (m_need_compact){
1613 // Pour l'instant, il faut trier et compacter les entites
1614 // avant une sauvegarde
1615 _compactItems(true,true);
1616 }
1617
1618 // Préparation des connexions maillage/sous-maillage
1619 {
1620 if (m_parent_mesh) {
1621 ARCANE_ASSERT((m_parent_group != NULL),("Unexpected NULL parent group"));
1622 m_parent_mesh_name = m_parent_mesh->name();
1623 m_parent_group_name = m_parent_group->name();
1624 } else {
1625 ARCANE_ASSERT((m_parent_group == NULL),("Unexpected non-NULL parent group"));
1628 }
1629 const Integer n_sub_mesh = m_child_meshes.size();
1630 m_child_meshes_name.resize(n_sub_mesh);
1631 for(Integer i=0;i<n_sub_mesh; ++i)
1632 m_child_meshes_name[i] = m_child_meshes[i]->name();
1633 }
1634
1635 // Sauve les infos sur les familles d'entités
1636 {
1637 Integer nb_item_family = m_item_families.count();
1638 m_item_families_name.resize(nb_item_family);
1639 m_item_families_kind.resize(nb_item_family);
1640 Integer index = 0;
1641 for( IItemFamily* family : m_item_families ){
1642 m_item_families_kind[index] = family->itemKind();
1643 m_item_families_name[index] = family->name();
1644 ++index;
1645 }
1646 }
1647
1648 for( IItemFamily* family : m_item_families ){
1649 family->prepareForDump();
1650 }
1651
1652 if (m_tied_interface_need_prepare_dump){
1653 m_tied_interface_mng->prepareTiedInterfacesForDump();
1654 m_tied_interface_need_prepare_dump = false;
1655 }
1656}
1657
1658/*---------------------------------------------------------------------------*/
1659/*---------------------------------------------------------------------------*/
1660
1663{
1664 IItemFamily* xfamily = findItemFamily(ik,name,false,false);
1665 if (xfamily)
1666 ARCANE_FATAL("Attempting to create a family that already exists '{0}'",name);
1667
1668 debug() << "Creating the entities family "
1669 << " name=" << name
1670 << " kind=" << itemKindName(ik);
1671 ItemFamily* family = _createNewFamily(ik,name);
1672
1673 _addFamily(family);
1674 _buildAndInitFamily(family);
1675
1676 return family;
1677}
1678
1679/*---------------------------------------------------------------------------*/
1680/*---------------------------------------------------------------------------*/
1681
1682ItemFamily* DynamicMesh::
1683_createNewFamily(eItemKind kind, const String& name)
1684{
1685 switch (kind) {
1686 case IK_Node:
1687 return new NodeFamily(this,name);
1688 case IK_Edge:
1689 return new EdgeFamily(this,name);
1690 case IK_Face:
1691 return new FaceFamily(this,name);
1692 case IK_Cell:
1693 return new CellFamily(this,name);
1694 case IK_Particle:
1695 return new ParticleFamily(this,name);
1696 case IK_DoF:
1697 return new DoFFamily(this,name);
1698 case IK_Unknown:
1699 ARCANE_FATAL("Attempting to create an ItemFamily with an unknown item kind.");
1700 }
1701 ARCANE_FATAL("Invalid ItemKind");
1702}
1703
1704/*---------------------------------------------------------------------------*/
1705/*---------------------------------------------------------------------------*/
1706
1707IItemFamilyPolicyMng* DynamicMesh::
1708_createFamilyPolicyMng(ItemFamily* family)
1709{
1710 eItemKind kind = family->itemKind();
1711 switch (kind) {
1712 case IK_Node:
1713 return createNodeFamilyPolicyMng(family);
1714 case IK_Edge:
1715 return createEdgeFamilyPolicyMng(family);
1716 case IK_Face:
1717 return createFaceFamilyPolicyMng(family);
1718 case IK_Cell:
1719 return createCellFamilyPolicyMng(family);
1720 case IK_Particle:
1721 return createParticleFamilyPolicyMng(family);
1722 case IK_DoF:
1723 return createDoFFamilyPolicyMng(family);
1724 case IK_Unknown:
1725 ARCANE_FATAL("Attempting to create an ItemFamily with an unknown item kind.");
1726 }
1727 ARCANE_FATAL("Invalid ItemKind");
1728}
1729
1730/*---------------------------------------------------------------------------*/
1731/*---------------------------------------------------------------------------*/
1732
1733void DynamicMesh::
1734_buildAndInitFamily(IItemFamily* family)
1735{
1736 family->build();
1737 ItemFamily* true_family = ARCANE_CHECK_POINTER(dynamic_cast<ItemFamily*>(family));
1738 IItemFamilyPolicyMng* policy_mng = _createFamilyPolicyMng(true_family);
1739 true_family->setPolicyMng(policy_mng);
1740}
1741
1742/*---------------------------------------------------------------------------*/
1743/*---------------------------------------------------------------------------*/
1744
1745void DynamicMesh::
1746_addFamily(ItemFamily* family)
1747{
1748 m_item_families.add(family);
1749 m_true_item_families.add(family);
1750}
1751
1752/*---------------------------------------------------------------------------*/
1753/*---------------------------------------------------------------------------*/
1754
1756findItemFamily(eItemKind ik,const String& name,bool create_if_needed,
1757 bool register_modifier_if_created)
1758{
1759 for( IItemFamily* family : m_item_families)
1760 if (family->name()==name && family->itemKind()==ik)
1761 return family;
1762 if (create_if_needed){
1763 IItemFamily* family = createItemFamily(ik,name);
1764 if(register_modifier_if_created){
1765 IItemFamilyModifier* modifier = dynamic_cast<IItemFamilyModifier*>(family) ;
1766 if(modifier)
1767 m_family_modifiers.add(modifier);
1768 }
1769 return family;
1770 }
1771 return nullptr;
1772}
1773
1774/*---------------------------------------------------------------------------*/
1775/*---------------------------------------------------------------------------*/
1776
1778findItemFamily(const String& name,bool throw_exception)
1779{
1780 for( IItemFamily* family : m_item_families )
1781 if (family->name()==name)
1782 return family;
1783 if (throw_exception)
1784 ARCANE_FATAL("No family with name '{0}' exist",name);
1785 return nullptr;
1786}
1787
1788/*---------------------------------------------------------------------------*/
1789/*---------------------------------------------------------------------------*/
1790
1793{
1794 IItemFamily* family = findItemFamily(ik, name, false,false);
1795 if (!family)
1796 return nullptr;
1797 for ( IItemFamilyModifier* modifier : m_family_modifiers )
1798 if (modifier->family() == family)
1799 return modifier;
1800 return nullptr;
1801}
1802
1803/*---------------------------------------------------------------------------*/
1804/*---------------------------------------------------------------------------*/
1805
1806void DynamicMesh::
1807_exchangeItems(bool do_compact)
1808{
1809 String nb_exchange_str = platform::getEnvironmentVariable("ARCANE_NB_EXCHANGE");
1810 // Il faudrait calculer la valeur par defaut en tenant compte du nombre
1811 // de maille échangées et du nombre de variables et de leur utilisation
1812 // mémoire. Faire bien attention à ce que tous les procs utilisent la meme valeur.
1813 // Dans la pratique mieux vaut ne pas dépasser 3 ou 4 échanges car cela
1814 // augmente le temps consommé à et ne réduit pas trop la mémoire.
1815 Integer nb_exchange = 1;
1816 if (!nb_exchange_str.null()){
1817 bool is_bad = builtInGetValue(nb_exchange,nb_exchange_str);
1818 if (is_bad)
1819 nb_exchange = 1;
1820 }
1821 String exchange_version_str = platform::getEnvironmentVariable("ARCANE_MESH_EXCHANGE_VERSION");
1822 Integer exchange_version = 1;
1823 if (!exchange_version_str.null()){
1824 builtInGetValue(exchange_version,exchange_version_str);
1825 }
1826
1827 info() << "DynamicMesh::_echangeItems() do_compact?=" << do_compact
1828 << " nb_exchange=" << nb_exchange << " version=" << exchange_version;
1829
1830 if (nb_exchange>1){
1831 _multipleExchangeItems(nb_exchange,exchange_version,do_compact);
1832 }
1833 else
1834 _exchangeItemsNew();
1835 // Actuellement, la méthode exchangeItemsNew() ne prend en compte
1836 // qu'une couche de maille fantômes. Si on en demande plus, il faut
1837 // les ajouter maintenant. Cet appel n'est pas optimum mais permet
1838 // de traiter correctement tous les cas (enfin j'espère).
1839 if (ghostLayerMng()->nbGhostLayer()>1 && !m_use_mesh_item_family_dependencies) // many ghost already handled in MeshExchange with ItemFamilyNetwork
1840 updateGhostLayers(true);
1841 String check_exchange = platform::getEnvironmentVariable("ARCANE_CHECK_EXCHANGE");
1842 if (!check_exchange.null()){
1843 m_mesh_checker->checkGhostCells();
1844 pwarning() << "CHECKING SYNCHRONISATION !";
1845 m_mesh_checker->checkVariablesSynchronization();
1846 m_mesh_checker->checkItemGroupsSynchronization();
1847 }
1848 if (checkLevel()>=2)
1849 m_mesh_checker->checkValidMesh();
1850 else if (checkLevel()>=1)
1851 m_mesh_checker->checkValidConnectivity();
1852}
1853
1854/*---------------------------------------------------------------------------*/
1855/*---------------------------------------------------------------------------*/
1887_multipleExchangeItems(Integer nb_exchange,Integer version,bool do_compact)
1888{
1889 if (version<1 || version>2)
1890 ARCANE_FATAL("Invalid value '{0}' for version. Valid values are 1 or 2",version);
1891
1892 info() << "** ** MULTIPLE EXCHANGE ITEM version=" << version << " nb_exchange=" << nb_exchange;
1893 UniqueArray<UniqueArray<Int32>> cells_to_exchange_new_owner(nb_exchange);
1894 // Il faut stocker le uid car suite a un equilibrage les localId vont changer
1895 UniqueArray<UniqueArray<Int64>> cells_to_exchange_uid(nb_exchange);
1896
1897 IItemFamily* cell_family = cellFamily();
1898 VariableItemInt32& cells_new_owner = cell_family->itemsNewOwner();
1899
1900 Integer nb_cell= ownCells().size();
1901 ENUMERATE_CELL(icell,ownCells()){
1902 Cell cell = *icell;
1903 Int32 current_owner = cell.owner();
1904 Int32 new_owner = cells_new_owner[icell];
1905 if (current_owner==new_owner)
1906 continue;
1907 Integer phase = 0;
1908 if (version==2)
1909 phase = (new_owner % nb_exchange);
1910 else if (version==1)
1911 phase = icell.index() / nb_cell;
1912 cells_to_exchange_new_owner[phase].add(new_owner);
1913 cells_to_exchange_uid[phase].add(cell.uniqueId().asInt64());
1914 }
1915
1916 // Remet comme si la maille ne changeait pas de propriétaire pour
1917 // éviter de l'envoyer.
1918 ENUMERATE_CELL(icell,ownCells()){
1919 Cell cell = *icell;
1920 cells_new_owner[icell] = cell.owner();
1921 }
1922
1923 // A partir d'ici, le cells_new_owner est identique au cell.owner()
1924 // pour chaque maille.
1925 Int32UniqueArray uids_to_lids;
1926 for( Integer i=0; i<nb_exchange; ++i ){
1927 Int32ConstArrayView new_owners = cells_to_exchange_new_owner[i];
1928 Int64ConstArrayView new_uids = cells_to_exchange_uid[i];
1929 Integer nb_cell = new_uids.size();
1930 info() << "MultipleExchange current_exchange=" << i << " nb_cell=" << nb_cell;
1931 uids_to_lids.resize(nb_cell);
1932 cell_family->itemsUniqueIdToLocalId(uids_to_lids,new_uids);
1933 ItemInternalList cells = cell_family->itemsInternal();
1934 // Pour chaque maille de la partie en cours d'echange, positionne le new_owner
1935 // a la bonne valeurs
1936 for( Integer z=0; z<nb_cell; ++z )
1937 cells_new_owner[cells[uids_to_lids[z]]] = new_owners[z];
1938 cells_new_owner.synchronize();
1940 _exchangeItemsNew();
1941 }
1942
1943 if (do_compact){
1944 Timer::Action ts_action1(m_sub_domain,"CompactItems",true);
1945 bool do_sort = m_properties->getBool(PROPERTY_SORT);
1946 _compactItems(do_sort,true);
1947 }
1948}
1949
1950/*---------------------------------------------------------------------------*/
1951/*---------------------------------------------------------------------------*/
1952
1955{
1956 _exchangeItems(m_properties->getBool(PROPERTY_COMPACT));
1957}
1958
1959/*---------------------------------------------------------------------------*/
1960/*---------------------------------------------------------------------------*/
1961
1963clearItems()
1964{
1965 for( IItemFamily* family : m_item_families )
1966 family->clearItems();
1967 endUpdate();
1968}
1969
1970/*---------------------------------------------------------------------------*/
1971/*---------------------------------------------------------------------------*/
1972#if 0
1973class ItemsExchangeInfo2List
1974 : public UniqueArray<ItemsExchangeInfo2*>
1975{
1976public:
1977 ~ItemsExchangeInfo2List()
1978 {
1979 for( Integer i=0, is=size(); i<is; ++i ){
1980 ItemsExchangeInfo2* info = this->operator[](i);
1981 delete info;
1982 }
1983 clear();
1984 }
1985};
1986#endif
1987
1988/*---------------------------------------------------------------------------*/
1989/*---------------------------------------------------------------------------*/
1990
1991void DynamicMesh::
1992_exchangeItemsNew()
1993{
1994 // L'algo ici employé n'est pas récursif avec les sous-maillages.
1995 // Toutes les comms sont regroupées et les différents niveaux de modifs
1996 // seront dépilés ici même. Cette implémentation ne permet pas d'avoir
1997 // plus d'un niveau de sous-maillage par maillage.
1998
1999 Trace::Setter mci(traceMng(),_className());
2000
2001 if (!m_is_dynamic)
2002 ARCANE_FATAL("property isDynamic() has to be 'true'");
2003
2004 m_need_compact = true;
2005
2006 if (arcane_debug_load_balancing){
2007 // TODO: faire cela dans le MeshExchanger et par famille.
2008 // Vérifie que les variables sont bien synchronisées
2009 m_node_family->itemsNewOwner().checkIfSync(10);
2010 m_edge_family->itemsNewOwner().checkIfSync(10);
2011 m_face_family->itemsNewOwner().checkIfSync(10);
2012 m_cell_family->itemsNewOwner().checkIfSync(10);
2013 }
2014 // TODO: Vérifier que tout le monde a les mêmes familles et dans le même ordre.
2015
2016 // Cascade tous les maillages associés à ce maillage
2017 typedef Collection<DynamicMesh*> DynamicMeshCollection;
2018 DynamicMeshCollection all_cascade_meshes = List<DynamicMesh*>();
2019 all_cascade_meshes.add(this);
2020 for(Integer i=0;i<m_child_meshes.size();++i)
2021 all_cascade_meshes.add(m_child_meshes[i]);
2022
2023 IMeshExchanger* iexchanger = m_mesh_exchange_mng->beginExchange();
2024 MeshExchanger* mesh_exchanger = ARCANE_CHECK_POINTER(dynamic_cast<MeshExchanger*>(iexchanger));
2025
2026 // S'il n'y a aucune entité à échanger, on arrête immédiatement l'échange.
2027 if (mesh_exchanger->computeExchangeInfos()){
2028 info() << "No load balance is performed";
2029 m_mesh_exchange_mng->endExchange();
2030 return;
2031 }
2032
2033 // Éffectue l'échange des infos
2034 mesh_exchanger->processExchange();
2035
2036 // Supprime les entités qui ne doivent plus être dans notre sous-domaine.
2037 mesh_exchanger->removeNeededItems();
2038
2039 // Réajuste les groupes en supprimant les entités qui ne sont plus dans le maillage ou en
2040 // invalidant les groupes calculés.
2041 // TODO: faire une méthode de la famille qui fait cela.
2042 {
2043 auto action = [](ItemGroup& group)
2044 {
2045 // (HP) TODO: 'if (group.internal()->hasComputeFunctor())' ne fonctionne pas simplement, why ?
2046 // Anciennement: if (group.isLocalToSubDomain() || group.isOwn())
2047 // Redondant avec des calculs de ItemFamily::notifyItemsOwnerChanged
2048 if (group.internal()->hasComputeFunctor() || group.isLocalToSubDomain())
2049 group.invalidate();
2050 else
2051 group.internal()->removeSuppressedItems();
2052 };
2053 for( DynamicMesh* mesh : all_cascade_meshes ){
2054 meshvisitor::visitGroups(mesh,action);
2055 }
2056 }
2057
2058 // Supprime les potentiels items fantômes restant après la mise à jour du groupe support
2059 // qui ont été marqués par NeedRemove (ce qui nettoie un éventuel état inconsistent du
2060 // sous-maillage vis-à-vis de son parent)
2061 // Cette partie est importante car il est possible que la mise à jour des groupes
2062 // support ne suffise pas à mettre à jour les parties fantômes des sous-maillages
2063 // (à moins de mettre une contrainte plus forte sur le groupe d'intégrer aussi tous
2064 // les fantômes du sous-maillage)
2065#if HEAD
2066 for( DynamicMesh* child_mesh : m_child_meshes )
2067 child_mesh->m_submesh_tools->removeDeadGhostCells();
2068#else
2069 for(Integer i_child_mesh=0;i_child_mesh<m_child_meshes.size();++i_child_mesh)
2070 m_child_meshes[i_child_mesh]->m_submesh_tools->removeDeadGhostCells();
2071#endif
2072
2073 // Créé les entités qu'on a recu des autres sous-domaines.
2074 mesh_exchanger->allocateReceivedItems();
2075
2076 // On reprend maintenant un cycle standard de endUpdate
2077 // mais en entrelaçant les niveaux de sous-maillages
2078 for( DynamicMesh* mesh : all_cascade_meshes )
2079 mesh->_internalEndUpdateInit(true);
2080
2081 mesh_exchanger->updateItemGroups();
2082
2083 // Recalcule des synchroniseurs sur groupes.
2084 for( DynamicMesh* mesh : all_cascade_meshes )
2085 mesh->_computeGroupSynchronizeInfos();
2086
2087 // Met à jour les valeurs des variables des entités receptionnées
2088 mesh_exchanger->updateVariables();
2089
2090 // Finalise les modifications dont le triage et compactage
2091 for( DynamicMesh* mesh : all_cascade_meshes ){
2092 // Demande l'affichage des infos pour le maillage actuel
2093 bool print_info = (mesh==this);
2094 mesh->_internalEndUpdateFinal(print_info);
2095 }
2096
2097 // Finalize les échanges
2098 // Pour l'instante cela n'est utile que pour les TiedInterface mais il
2099 // faudrait supprimer cela.
2100 mesh_exchanger->finalizeExchange();
2101
2102 // TODO: garantir cet appel en cas d'exception.
2103 m_mesh_exchange_mng->endExchange();
2104
2105 // Maintenant, le maillage est à jour mais les mailles fantômes extraordinaires
2106 // ont été potentiellement retirées. On les replace dans le maillage.
2107 // Version non optimisée. L'idéal est de gérer les mailles extraordinaires
2108 // dans MeshExchange.
2109 // endUpdate() doit être appelé dans tous les cas pour s'assurer
2110 // que les variables et les groupes sont bien dimensionnées.
2111 if (m_extra_ghost_cells_builder->hasBuilder() || m_extra_ghost_particles_builder->hasBuilder())
2112 this->endUpdate(true,false);
2113 else
2114 this->endUpdate();
2115}
2116
2117/*---------------------------------------------------------------------------*/
2118/*---------------------------------------------------------------------------*/
2119
2122{
2123 m_extra_ghost_cells_builder->addExtraGhostCellsBuilder(builder);
2124}
2125
2126/*---------------------------------------------------------------------------*/
2127/*---------------------------------------------------------------------------*/
2128
2131{
2132 m_extra_ghost_cells_builder->removeExtraGhostCellsBuilder(builder);
2133}
2134
2135/*---------------------------------------------------------------------------*/
2136/*---------------------------------------------------------------------------*/
2137
2140{
2141 m_extra_ghost_particles_builder->addExtraGhostParticlesBuilder(builder);
2142}
2143
2144/*---------------------------------------------------------------------------*/
2145/*---------------------------------------------------------------------------*/
2146
2149{
2150 m_extra_ghost_particles_builder->removeExtraGhostParticlesBuilder(builder);
2151}
2152
2153/*---------------------------------------------------------------------------*/
2154/*---------------------------------------------------------------------------*/
2155
2156void DynamicMesh::
2157_computeExtraGhostCells()
2158{
2159 m_extra_ghost_cells_builder->computeExtraGhostCells();
2160}
2161
2162/*---------------------------------------------------------------------------*/
2163/*---------------------------------------------------------------------------*/
2164
2165void DynamicMesh::
2166_computeExtraGhostParticles()
2167{
2168 m_extra_ghost_particles_builder->computeExtraGhostParticles();
2169}
2170
2171/*---------------------------------------------------------------------------*/
2172/*---------------------------------------------------------------------------*/
2173
2174void DynamicMesh::
2175_removeGhostItems()
2176{
2177 const Int32 sid = meshRank();
2178
2179 // Suppression des mailles fantômes.
2180 // Il faut passer par un tableau intermédiaire, car supprimer
2181 // des mailles invalide les itérateurs sur 'cells_map'.
2182 UniqueArray<Int32> cells_to_remove;
2183 cells_to_remove.reserve(1000);
2184
2185 ItemInternalMap& cells_map = m_cell_family->itemsMap();
2186 cells_map.eachItem([&](Item cell) {
2187 if (cell.owner() != sid)
2188 cells_to_remove.add(cell.localId());
2189 });
2190
2191 info() << "Number of cells to remove: " << cells_to_remove.size();
2192 m_cell_family->removeCells(cells_to_remove);
2193
2194 // Réajuste les groupes en supprimant les entités qui ne sont plus dans le maillage
2196}
2197
2198/*---------------------------------------------------------------------------*/
2199/*---------------------------------------------------------------------------*/
2205{
2206 auto action = [&](const ItemGroup& group){ group.itemFamily()->partialEndUpdateGroup(group); };
2207 meshvisitor::visitGroups(this,action);
2208}
2209
2210/*---------------------------------------------------------------------------*/
2211/*---------------------------------------------------------------------------*/
2212
2215{
2216 updateGhostLayers(true);
2217}
2218
2219/*---------------------------------------------------------------------------*/
2220/*---------------------------------------------------------------------------*/
2221
2222void DynamicMesh::
2223updateGhostLayers(bool remove_old_ghost)
2224{
2225 Trace::Setter mci(traceMng(),_className());
2226
2227 if (!m_is_dynamic)
2228 ARCANE_FATAL("property isDynamic() has to be 'true'");
2229 if (m_parent_mesh)
2230 ARCANE_FATAL("Cannot be called on submesh");
2231
2232 _internalUpdateGhost(true, remove_old_ghost);
2233 _internalEndUpdateInit(true);
2234 _synchronizeGroups();
2235 _computeGroupSynchronizeInfos();
2236 _internalEndUpdateResizeVariables();
2237 _synchronizeVariables();
2239
2240 // Finalisation des sous-maillages récursives
2241 for(Integer i=0;i<m_child_meshes.size();++i) {
2242 m_child_meshes[i]->endUpdate(true, remove_old_ghost);
2243 }
2244}
2245/*---------------------------------------------------------------------------*/
2246/*---------------------------------------------------------------------------*/
2247
2248void DynamicMesh::
2249_removeGhostChildItems()
2250{
2251 const Int32 sid = meshRank();
2252
2253 // Suppression des mailles
2254 UniqueArray<Int32> cells_to_remove;
2255 cells_to_remove.reserve(1000);
2256
2257 ItemInternalMap& cells_map = m_cell_family->itemsMap();
2258 Integer max_level=0;
2259 cells_map.eachItem([&](impl::ItemBase cell) {
2260 if ((cell.owner() != sid) && (cell.level() != 0))
2261 max_level = math::max(cell.level(),max_level);
2262 });
2263
2264 if (max_level==0)
2265 return;
2266
2267 cells_map.eachItem([&](impl::ItemBase cell) {
2268 if ((cell.owner() != sid) && (cell.level() == max_level)) {
2269 cells_to_remove.add(cell.localId());
2270 }
2271 });
2272
2273 info() << "Number of cells to remove: " << cells_to_remove.size();
2274 m_cell_family->removeCells(cells_to_remove);
2275
2276 // Réajuste les groupes en supprimant les entités qui ne sont plus dans le maillage
2278}
2279
2280/*---------------------------------------------------------------------------*/
2281/*---------------------------------------------------------------------------*/
2282
2283void DynamicMesh::
2284_removeGhostChildItems2(Array<Int64>& cells_to_coarsen)
2285{
2286 const Int32 sid = meshRank();
2287
2288 cells_to_coarsen.reserve(1000);
2289
2290 // Suppression des mailles
2291 UniqueArray<Cell> cells_to_remove;
2292 cells_to_remove.reserve(1000);
2293
2294 ItemInternalMap& cells_map = m_cell_family->itemsMap();
2295 Integer counter=0;
2296 cells_map.eachItem([&](Cell cell) {
2297 if (cell.owner() != sid)
2298 return;
2299 if (cell.hasFlags(ItemFlags::II_JustCoarsened)) {
2300 cells_to_coarsen.add(cell.uniqueId());
2301 for (Integer c = 0, cs = cell.nbHChildren(); c < cs; c++) {
2302 cells_to_remove.add(cell.hChild(c));
2303 counter++;
2304 }
2305 }
2306 });
2307
2308 if (counter==0)
2309 return;
2310
2311 //info() << "Number of cells to remove: " << cells_to_remove.size();
2312 for( Integer i=0, is=cells_to_remove.size(); i<is; ++i )
2313 m_cell_family->removeCell(cells_to_remove[i]);
2314
2315 // Réajuste les groupes en supprimant les entités qui ne sont plus dans le maillage
2317}
2318
2319/*---------------------------------------------------------------------------*/
2320/*---------------------------------------------------------------------------*/
2323updateGhostLayerFromParent(Array<Int64>& ghost_cell_to_refine_uid,
2324 Array<Int64>& ghost_cell_to_coarsen_uid, bool remove_old_ghost)
2325{
2326 Trace::Setter mci(traceMng(),_className());
2327 CHECKPERF( m_perf_counter.start(PerfCounter::UPGHOSTLAYER1) ) ;
2328
2329 m_need_compact = true;
2330 //Integer current_iteration = subDomain()->commonVariables().globalIteration();
2331 if (!m_is_dynamic)
2332 ARCANE_FATAL("Property isDynamic() has to be 'true'");
2333
2334 if(remove_old_ghost){
2335 _removeGhostChildItems2(ghost_cell_to_coarsen_uid) ;
2336 }
2337
2338 // En cas de raffinement/déraffinement, il est possible que l'orientation soit invalide à un moment.
2339 m_face_family->setCheckOrientation(false);
2340
2341 m_mesh_builder->addGhostChildFromParent(ghost_cell_to_refine_uid);
2342 m_face_family->setCheckOrientation(true);
2343
2344 // A partir d'ici, les entités du maillages sont toutes connues. Il
2345 // est donc possible de les compacter si nécessaire
2346 m_mesh_builder->printStats();
2347 CHECKPERF( m_perf_counter.stop(PerfCounter::UPGHOSTLAYER1) )
2348
2349
2350 CHECKPERF( m_perf_counter.start(PerfCounter::UPGHOSTLAYER2) )
2351 //_finalizeMeshChanged();
2352 {
2353 ++m_timestamp;
2354 for( IItemFamily* family : m_item_families )
2355 family->endUpdate();
2356 }
2357 CHECKPERF( m_perf_counter.stop(PerfCounter::UPGHOSTLAYER2) )
2358
2359
2360 // Réalloue les variables du maillage car leur groupe a évolué
2361 // TODO: ce devrait être à chaque famille de le faire
2362 CHECKPERF( m_perf_counter.start(PerfCounter::UPGHOSTLAYER3) )
2363 {
2364 IVariableMng* vm = m_sub_domain->variableMng();
2365 VariableCollection used_vars(vm->usedVariables());
2366 used_vars.each(std::mem_fn(&IVariable::resizeFromGroup));
2367 }
2368 CHECKPERF( m_perf_counter.stop(PerfCounter::UPGHOSTLAYER3) )
2369
2370
2371 // Recalcule les informations nécessaires pour la synchronisation
2372 // des entités
2373 //pm->computeSynchronizeInfos();
2374 CHECKPERF( m_perf_counter.start(PerfCounter::UPGHOSTLAYER4) )
2376 _synchronizeGroupsAndVariables();
2377 CHECKPERF( m_perf_counter.stop(PerfCounter::UPGHOSTLAYER4) )
2378
2379
2380 //Loop of new refine ghost
2381 CHECKPERF( m_perf_counter.start(PerfCounter::UPGHOSTLAYER5) )
2382 UniqueArray<Integer> ghost_cell_to_refine_lid(ghost_cell_to_refine_uid.size());
2383 m_cell_family->itemsUniqueIdToLocalId(ghost_cell_to_refine_lid,ghost_cell_to_refine_uid,true) ;
2384 ItemInternalList cells = m_cell_family->itemsInternal() ;
2385 for (Integer e = 0, i_size=ghost_cell_to_refine_lid.size(); e != i_size; ++e){
2386 Cell i_hParent_cell(cells[ghost_cell_to_refine_lid[e]]);
2387 m_mesh_refinement->populateBackFrontCellsFromParentFaces(i_hParent_cell);
2388
2389 //need to populate also the new own cell connected to the new ghost
2390 Integer nb_face = i_hParent_cell.nbFace();
2391 Integer lid = i_hParent_cell.localId() ;
2392 for(Integer iface=0;iface<nb_face;++iface){
2393 Face face = i_hParent_cell.face(iface);
2394 Integer nb_cell = face.nbCell() ;
2395 for(Integer icell=0;icell<nb_cell;++icell){
2396 Cell cell = face.cell(icell);
2397 if( (cell.localId()!=lid) && (cell.isOwn()) ){
2399 m_face_family->familyTree(childs,cell,false) ;
2400 for(Integer i=0,nchilds=childs.size();i<nchilds;++i){
2401 ItemInternal* child = childs[i];
2402 if(child->isAncestor())
2403 m_mesh_refinement->populateBackFrontCellsFromParentFaces(child);
2404 }
2405 }
2406 }
2407 }
2408 }
2409 CHECKPERF( m_perf_counter.stop(PerfCounter::UPGHOSTLAYER5) )
2410
2411
2412 // Vérifie que le maillage est conforme avec la référence
2413 CHECKPERF( m_perf_counter.start(PerfCounter::UPGHOSTLAYER6) )
2414 m_mesh_checker->checkMeshFromReferenceFile();
2415
2416 // Compacte les références pour ne pas laisser de trou et profiter
2417 // au mieux des effets de cache.
2418 // NOTE: ce n'est en théorie pas indispensable mais actuellement si
2419 // car on ne sauve pas le #m_data_index des ItemInternal.
2420 //_compactItemInternalReferences();
2421 bool do_compact = m_properties->getBool(PROPERTY_COMPACT);
2422 if (do_compact){
2423 bool do_sort = m_properties->getBool(PROPERTY_SORT);
2424 _compactItems(do_sort,do_compact);
2425 }
2426 CHECKPERF( m_perf_counter.stop(PerfCounter::UPGHOSTLAYER6) )
2427
2428 if (arcane_debug_load_balancing){
2429 _writeMesh("update-ghost-layer-after");
2430 }
2431
2432 // Affiche les statistiques du nouveau maillage
2433 {
2434 MeshStats ms(traceMng(),this,m_parallel_mng);
2435 ms.dumpStats();
2436 pinfo() << "Proc: " << meshRank()
2437 << " cellown=" << m_cell_family->allItems().own().size()
2438 << " cellloc=" << m_cell_family->allItems().size();
2439 }
2440
2442 CHECKPERF( m_perf_counter.start(PerfCounter::UPGHOSTLAYER7) )
2444 m_mesh_checker->updateAMRFaceOrientation(ghost_cell_to_refine_uid);
2445
2446 if (m_mesh_checker->checkLevel()>=1)
2447 m_mesh_checker->checkValidConnectivity();
2448 CHECKPERF( m_perf_counter.stop(PerfCounter::UPGHOSTLAYER7) )
2449
2450#ifdef ACTIVATE_PERF_COUNTER
2451 m_perf_counter.printInfo(info().file()) ;
2452#endif
2453}
2454
2455/*---------------------------------------------------------------------------*/
2456/*---------------------------------------------------------------------------*/
2457
2458void DynamicMesh::
2459_internalUpdateGhost(bool update_ghost_layer,bool remove_old_ghost)
2460{
2461 m_need_compact = true;
2462
2463 // Surcharge le comportement pour les sous-maillages
2464 if (parentMesh()){
2465 if (update_ghost_layer)
2466 m_submesh_tools->updateGhostMesh();
2467 }
2468 else{
2469 if (update_ghost_layer){
2470 if(remove_old_ghost){
2471 _removeGhostItems();
2472 }
2473 // En cas de raffinement/déraffinement, il est possible que l'orientation soit invalide à un moment.
2474 m_face_family->setCheckOrientation(false);
2475 m_mesh_builder->addGhostLayers(false);
2476 m_face_family->setCheckOrientation(true);
2477 _computeExtraGhostCells();
2478 _computeExtraGhostParticles();
2479 }
2480 }
2481}
2482
2483/*---------------------------------------------------------------------------*/
2484/*---------------------------------------------------------------------------*/
2485
2486void DynamicMesh::
2487_internalEndUpdateInit(bool update_ghost_layer)
2488{
2489 // A partir d'ici, les entités du maillages sont toutes connues. Il
2490 // est donc possible de les compacter si nécessaire
2491 //m_mesh_builder->printStats();
2492
2493 //info() << "Finalize date=" << platform::getCurrentDateTime();
2494 _finalizeMeshChanged();
2495
2496 // Recalcule les informations nécessaires pour la synchronisation
2497 // des entités
2498 if (update_ghost_layer){
2499 info() << "ComputeSyncInfos date=" << platform::getCurrentDateTime();
2500 _computeFamilySynchronizeInfos();
2501 }
2502}
2503
2504/*---------------------------------------------------------------------------*/
2505/*---------------------------------------------------------------------------*/
2506
2507void DynamicMesh::
2508_internalEndUpdateResizeVariables()
2509{
2510 // Réalloue les variables du maillage car leur groupe a évolué
2511 for( IItemFamily* family : m_item_families )
2512 family->_internalApi()->resizeVariables(true);
2513}
2514
2515/*---------------------------------------------------------------------------*/
2516/*---------------------------------------------------------------------------*/
2517
2518void
2520_internalEndUpdateFinal(bool print_stat)
2521{
2522 // Vérifie que le maillage est conforme avec la référence
2523 m_mesh_checker->checkMeshFromReferenceFile();
2524
2525 // Compacte les références pour ne pas laisser de trou et profiter
2526 // au mieux des effets de cache.
2527 // NOTE: ce n'est en théorie pas indispensable mais actuellement si
2528 // car on ne sauve pas le #m_data_index des ItemInternal.
2529 {
2530 //Timer::Action ts_action1(m_sub_domain,"CompactReferences",true);
2531 _compactItemInternalReferences(); // Utilité à confirmer
2532
2533 {
2534 bool do_compact = m_properties->getBool(PROPERTY_COMPACT);
2535 info(4) << "DynamicMesh::_internalEndUpdateFinal() compact?=" << do_compact << " sort?=" << m_properties->getBool(PROPERTY_SORT);
2536 if (do_compact){
2537 bool do_sort = m_properties->getBool(PROPERTY_SORT);
2538 _compactItems(do_sort,do_compact);
2539 }
2540 }
2541 }
2542
2543 _notifyEndUpdateForFamilies();
2544
2545 // Affiche les statistiques du nouveau maillage
2546 if (print_stat){
2547 if (m_properties->getBool(PROPERTY_DISPLAY_STATS)){
2548 MeshStats ms(traceMng(),this,m_parallel_mng);
2549 ms.dumpStats();
2550 }
2551 }
2552
2555 m_mesh_checker->updateAMRFaceOrientation();
2556
2557 if (m_mesh_checker->checkLevel()>=1)
2558 m_mesh_checker->checkValidConnectivity();
2559}
2560
2561/*---------------------------------------------------------------------------*/
2562/*---------------------------------------------------------------------------*/
2563
2564void DynamicMesh::
2565_notifyEndUpdateForFamilies()
2566{
2567 for( IItemFamily* family : m_item_families )
2568 family->_internalApi()->notifyEndUpdateFromMesh();
2569}
2570
2571/*---------------------------------------------------------------------------*/
2572/*---------------------------------------------------------------------------*/
2573
2575endUpdate()
2576{
2577 endUpdate(false,false);
2578}
2579
2580/*---------------------------------------------------------------------------*/
2581/*---------------------------------------------------------------------------*/
2582
2583void DynamicMesh::
2584endUpdate(bool update_ghost_layer,bool remove_old_ghost)
2585{
2586 // L'ordre d'action est le suivant:
2587 // 1- Mise à jour des fantomes
2588 // 2- Finalization du maillage (fige les items)
2589 // Calcul si demandé (update_ghost_layer) les synchroniseurs sur les familles
2590 // 3- Synchronize les groupes (requiert des synchroniseurs de familles à jour)
2591 // 4- Calcul si demandé (update_ghost_layer) les synchroniseurs sur les groupes
2592 // 5- Retaille les variables (familles et groupes)
2593 // 6- Synchronize si demandé (update_ghost_layer) les variables (familles et groupes)
2594 // 7- Finalisation comprenant: compactage, triage (si activés), statistiques et contrôle de validé
2595 // 8- Appels récursifs aux sous-maillages
2596
2597 Trace::Setter mci(traceMng(),_className());
2598 _internalUpdateGhost(update_ghost_layer, remove_old_ghost);
2599
2600 _internalEndUpdateInit(update_ghost_layer);
2601 if (update_ghost_layer){
2602 _synchronizeGroups();
2603 _computeGroupSynchronizeInfos();
2604 }
2605 _internalEndUpdateResizeVariables();
2606 if (update_ghost_layer){
2607 _synchronizeVariables();
2608 }
2610
2611 // Finalisation des sous-maillages recursives
2612 for( DynamicMesh* child_mesh : m_child_meshes )
2613 child_mesh->endUpdate(update_ghost_layer, remove_old_ghost);
2614}
2615
2616/*---------------------------------------------------------------------------*/
2617/*---------------------------------------------------------------------------*/
2618
2621{
2622 _synchronizeGroupsAndVariables();
2623 // Peu tester dans le cas où le groupe parent d'un sous-maillage
2624 // avant l'appel aux maillages enfants.
2625 // Cela pourrait peut-être nécessité une mise à jour des synchronisers enfants
2626 for( DynamicMesh* child_mesh : m_child_meshes )
2627 child_mesh->synchronizeGroupsAndVariables();
2628}
2629
2630/*---------------------------------------------------------------------------*/
2631/*---------------------------------------------------------------------------*/
2632
2633void DynamicMesh::
2634_synchronizeGroupsAndVariables()
2635{
2636 _synchronizeGroups();
2637 _synchronizeVariables();
2638}
2639
2640/*---------------------------------------------------------------------------*/
2641/*---------------------------------------------------------------------------*/
2642
2643void DynamicMesh::
2644_synchronizeGroups()
2645{
2646 {
2647 ItemGroupsSynchronize igs(m_node_family);
2648 igs.synchronize();
2649 }
2650 {
2651 ItemGroupsSynchronize igs(m_edge_family);
2652 igs.synchronize();
2653 }
2654 {
2655 ItemGroupsSynchronize igs(m_face_family);
2656 igs.synchronize();
2657 }
2658 {
2659 ItemGroupsSynchronize igs(m_cell_family);
2660 igs.synchronize();
2661 }
2662 {
2663 for( IItemFamily* family : m_item_families ){
2664 if (family->itemKind()==IK_Particle){
2665 IParticleFamily* pfamily = family->toParticleFamily();
2666 if (pfamily && pfamily->getEnableGhostItems()){
2667 ItemGroupsSynchronize igs(family);
2668 igs.synchronize();
2669 }
2670 }
2671 }
2672 }
2673}
2674
2675/*---------------------------------------------------------------------------*/
2676/*---------------------------------------------------------------------------*/
2677
2678void DynamicMesh::
2679_synchronizeVariables()
2680{
2681 // On ne synchronise que les variables sur les items du maillage courant
2682 // - Les items de graphe ne sont pas traités ici (était déjà retiré de
2683 // la version précédente du code)
2684 // - Les particules et ceux sans genre (Unknown) ne pas sujet à synchronisation
2685 // La synchronisation est ici factorisée par collection de variables de même
2686 // synchroniser (même pour les synchronisers sur groupes != famille)
2687 // Pour préserver un ordre consistent de synchronisation une structure
2688 // auxiliaire OrderedSyncList est utilisée.
2689
2690 // Peut on le faire avec une structure plus compacte ?
2691 typedef UniqueArray<IVariableSynchronizer*> OrderedSyncList;
2692 typedef std::map<IVariableSynchronizer*, VariableCollection> SyncList;
2693 OrderedSyncList ordered_sync_list;
2694 SyncList sync_list;
2695
2696 VariableCollection used_vars(subDomain()->variableMng()->usedVariables());
2697 for( VariableCollection::Enumerator i_var(used_vars); ++i_var; ) {
2698 IVariable* var = *i_var;
2699 switch(var->itemKind()) {
2700 case IK_Node:
2701 case IK_Edge:
2702 case IK_Face:
2703 case IK_Cell:
2704 case IK_DoF:{
2705 IVariableSynchronizer * synchronizer = 0;
2706 if (var->isPartial())
2707 synchronizer = var->itemGroup().synchronizer();
2708 else
2709 synchronizer = var->itemFamily()->allItemsSynchronizer();
2710 IMesh * sync_mesh = synchronizer->itemGroup().mesh();
2711 if (sync_mesh != this) continue; // on ne synchronise que sur le maillage courant
2712 std::pair<SyncList::iterator,bool> inserter = sync_list.insert(std::make_pair(synchronizer,VariableCollection()));
2713 if (inserter.second) { // nouveau synchronizer
2714 ordered_sync_list.add(synchronizer);
2715 }
2716 VariableCollection & collection = inserter.first->second;
2717 collection.add(var);
2718 } break;
2719 case IK_Particle:
2720 case IK_Unknown:
2721 break;
2722 }
2723 }
2724
2725 for(Integer i_sync = 0; i_sync < ordered_sync_list.size(); ++i_sync) {
2726 IVariableSynchronizer * synchronizer = ordered_sync_list[i_sync];
2727 VariableCollection & collection = sync_list[synchronizer];
2728 synchronizer->synchronize(collection);
2729 }
2730}
2731
2732/*---------------------------------------------------------------------------*/
2733/*---------------------------------------------------------------------------*/
2734
2735 void DynamicMesh::
2736_sortInternalReferences()
2737{
2738 // TODO: cet appel spécifique doit être gérée par NodeFamily.
2739 m_node_family->sortInternalReferences();
2740}
2741
2742/*---------------------------------------------------------------------------*/
2743/*---------------------------------------------------------------------------*/
2744
2745void DynamicMesh::
2746_finalizeMeshChanged()
2747{
2748 ++m_timestamp;
2749 for( IItemFamily* family : m_item_families ){
2750 debug() << "_finalizeMeshChanged on " << family->name() << " Family on Mesh " << name();
2751 family->endUpdate();
2752 }
2753
2754 bool do_sort = m_properties->getBool(PROPERTY_SORT);
2755 if (do_sort)
2756 _sortInternalReferences();
2757 m_tied_interface_need_prepare_dump = true;
2758}
2759
2760/*---------------------------------------------------------------------------*/
2761/*---------------------------------------------------------------------------*/
2762
2763void DynamicMesh::
2764_applyCompactPolicy(const String& timer_name,
2765 std::function<void(IItemFamilyCompactPolicy*)> functor)
2766{
2767 Timer::Action ts_action(m_sub_domain,timer_name);
2768 for( IItemFamily* family : m_item_families ){
2769 IItemFamilyCompactPolicy* c = family->policyMng()->compactPolicy();
2770 if (c)
2771 functor(c);
2772 }
2773}
2774
2775/*---------------------------------------------------------------------------*/
2776/*---------------------------------------------------------------------------*/
2777
2778void DynamicMesh::
2779_compactItemInternalReferences()
2780{
2781 _applyCompactPolicy("CompactConnectivityData",[&](IItemFamilyCompactPolicy* c)
2782 { c->compactConnectivityData(); });
2783}
2784
2785/*---------------------------------------------------------------------------*/
2786/*---------------------------------------------------------------------------*/
2787
2788void DynamicMesh::
2789_compactItems(bool do_sort,bool compact_variables_and_groups)
2790{
2791 if (do_sort)
2792 info(4) << "Compress and sort the mesh entities " << name() << ".";
2793 else
2794 info(4) << "Compress the mesh entities " << name() << ".";
2795
2796 IMeshCompacter* compacter = m_mesh_compact_mng->beginCompact();
2797
2798 try{
2799 compacter->setSorted(do_sort);
2800 compacter->_setCompactVariablesAndGroups(compact_variables_and_groups);
2801
2802 compacter->doAllActions();
2803 }
2804 catch(...){
2805 m_mesh_compact_mng->endCompact();
2806 throw;
2807 }
2808 m_mesh_compact_mng->endCompact();
2809
2810 if (do_sort){
2811 Timer::Action ts_action(m_sub_domain,"CompactItemSortReferences");
2812 // TODO: mettre cela dans la politique de la famille (a priori ne sert
2813 // que pour les familles de noeud)
2814 _sortInternalReferences();
2815 }
2816
2817 m_need_compact = false;
2818
2819 // Considère le compactage comme une évolution du maillage car cela
2820 // change les structures associées aux entités et leurs connectivités
2821 ++m_timestamp;
2822}
2823
2824/*---------------------------------------------------------------------------*/
2825/*---------------------------------------------------------------------------*/
2826
2827void DynamicMesh::
2828setEstimatedCells(Integer nb_cell0)
2829{
2830 Real factor = 1.0;
2831 if (m_parallel_mng->isParallel())
2832 factor = 1.2; // Considère 20% d'entités fantômes.
2833 // Les estimations suivantes correspondantes à une évaluation pour un cube de côté N=16
2834 Integer nb_node = Convert::toInteger(nb_cell0 * 1.2 * factor); // (N+1)^3/N^3 => 1.2
2835 Integer nb_edge = Convert::toInteger(nb_cell0 * 6.8 * factor); // 6*(N+1)^2*N/N^3 => 6.8
2836 Integer nb_face = Convert::toInteger(nb_cell0 * 3.4 * factor); // 3*N^2*(N+1)/N^3 => 3.19
2837 Integer nb_cell = Convert::toInteger(nb_cell0 * 1.0 * factor); // trivial => 1.0
2838 info() << "Estimating the number of entities:"
2839 << " Node=" << nb_node
2840 << " Edge=" << nb_edge
2841 << " Face=" << nb_face
2842 << " Cell=" << nb_cell;
2843 m_node_family->preAllocate(nb_node);
2844 m_edge_family->preAllocate(nb_edge);
2845 m_face_family->preAllocate(nb_face);
2846 m_cell_family->preAllocate(nb_cell);
2847}
2848
2849/*---------------------------------------------------------------------------*/
2850/*---------------------------------------------------------------------------*/
2856{
2858
2859 // Ne fais rien sur un maillage pas encore alloué.
2860 if (m_mesh_dimension()<0)
2861 return;
2862
2863 // Connexion maillage/sous-maillage
2864 {
2865 IMeshMng* mm = meshMng();
2866 if (!m_parent_mesh_name.value().null()) {
2867 m_parent_mesh = mm->findMeshHandle(m_parent_mesh_name.value()).mesh();
2868 }
2869 if (!m_parent_group_name.value().null()) {
2870 ARCANE_ASSERT((m_parent_mesh != NULL),("Unexpected NULL Mesh"));
2871 m_parent_group = m_parent_mesh->findGroup(m_parent_group_name.value()).internal();
2872 }
2873 const Integer n_sub_mesh = m_child_meshes_name.size();
2874 m_child_meshes.resize(n_sub_mesh);
2875 for(Integer i=0;i<n_sub_mesh;++i)
2876 {
2877 IMesh* child_mesh = mm->findMeshHandle(m_child_meshes_name[i]).mesh();
2878 DynamicMesh* dynamic_child_mesh = dynamic_cast<DynamicMesh*>(child_mesh);
2879 if (dynamic_child_mesh == 0)
2880 ARCANE_FATAL("Cannot associate sub mesh from a different concrete type");
2881 m_child_meshes[i] = dynamic_child_mesh;
2882 }
2883 }
2884
2885 {
2886 Integer nb_item_family = m_item_families_name.size();
2887 for( Integer i=0; i<nb_item_family; ++i ){
2888 info(5) << "Found family: I=" << i
2889 << " name=" << m_item_families_name[i]
2890 << " kind=" << (eItemKind)m_item_families_kind[i];
2891 }
2892 }
2893
2894 // Relit les infos sur les familles d'entités
2895 {
2896 Integer nb_item_family = m_item_families_name.size();
2897 for( Integer i=0; i<nb_item_family; ++i ){
2899 }
2900 }
2901
2902 // GG: Remise à jour des choix de connectivité
2903 // Il faut le faire ici car les familles peuvent être créées au début de cette
2904 // méthode et du coup ne pas tenir compte de la connectivité.
2905 if (!m_is_sub_connectivity_set)
2906 _setSubConnectivity();
2907
2908
2909 for( IItemFamily* family : m_item_families )
2910 family->readFromDump();
2911
2912 // Après relecture, il faut notifier les familles du changement potentiel
2913 // des entités.
2914 _notifyEndUpdateForFamilies();
2915
2916 //TODO: ne devrait pas etre fait ici.
2917 m_item_internal_list.nodes = m_node_family->itemsInternal();
2918 m_item_internal_list.edges = m_edge_family->itemsInternal();
2919 m_item_internal_list.faces = m_face_family->itemsInternal();
2920 m_item_internal_list.cells = m_cell_family->itemsInternal();
2921 m_item_internal_list.mesh = this;
2922
2923 m_tied_interface_mng->readTiedInterfacesFromDump();
2924
2925 m_mesh_builder->readFromDump();
2926 //_writeMesh("after-read-dump-"+name());
2927}
2928
2929/*---------------------------------------------------------------------------*/
2930/*---------------------------------------------------------------------------*/
2931
2934{
2935 return m_tied_interface_mng->hasTiedInterface();
2936}
2937
2938/*---------------------------------------------------------------------------*/
2939/*---------------------------------------------------------------------------*/
2940
2943{
2944 return m_tied_interface_mng->tiedInterfaces();
2945}
2946
2947/*---------------------------------------------------------------------------*/
2948/*---------------------------------------------------------------------------*/
2949
2951trueTiedInterfaces()
2952{
2953 return m_tied_interface_mng->trueTiedInterfaces();
2954}
2955
2956/*---------------------------------------------------------------------------*/
2957/*---------------------------------------------------------------------------*/
2958
2960computeTiedInterfaces(const XmlNode& mesh_node)
2961{
2962 m_tied_interface_mng->computeTiedInterfaces(mesh_node);
2963}
2964
2965/*---------------------------------------------------------------------------*/
2966/*---------------------------------------------------------------------------*/
2967
2970{
2971 _setDimension(dim);
2972 _checkConnectivity();
2973}
2974
2975/*---------------------------------------------------------------------------*/
2976/*---------------------------------------------------------------------------*/
2977
2978void DynamicMesh::
2979_setDimension(Integer dim)
2980{
2981 if (m_is_allocated)
2982 ARCANE_FATAL("DynamicMesh::setDimension(): mesh is already allocated");
2983 info() << "Mesh name=" << name() << " set dimension = " << dim;
2984 m_mesh_dimension = dim;
2985 const bool is_non_manifold = meshKind().isNonManifold();
2986 // Force le fait de ne pas re-numéroter les faces et les arêtes
2987 // dans le cas d'un maillage non-manifold
2988 if (is_non_manifold){
2989 info() << "Force no-renumbering of edge and face uid because we are using non manifold mesh";
2990 m_mesh_unique_id_mng->setFaceBuilderVersion(0);
2991 m_mesh_unique_id_mng->setEdgeBuilderVersion(0);
2992 }
2993 bool v = m_mesh_unique_id_mng->isUseNodeUniqueIdToGenerateEdgeAndFaceUniqueId();
2994 // Si le maillage est non-manifold, alors il faut obligatoirement utiliser
2995 // la génération à partir des uniqueId() à partir des noeuds pour garantir
2996 // la cohérence des entités créées.
2997 // Cette contrainte pourra être éventuellement être supprimée lorsque ce type
2998 // de maillage ne sera plus expérimental.
2999 if (!v && is_non_manifold) {
3000 v = true;
3001 info() << "Force using edge and face uid generation from nodes because we are using non manifold mesh";
3002 }
3003 if (m_mesh_builder){
3004 auto* adder = m_mesh_builder->oneMeshItemAdder();
3005 if (adder)
3007 }
3008 // En 3D, avec les maillages non manifold, il faut obligatoirement créer les arêtes.
3009 // Elles seront utilisées à la place des faces pour les mailles 2D.
3010 if (dim == 3 && is_non_manifold) {
3011 Connectivity c(m_mesh_connectivity);
3012 if (!c.hasConnectivity(Connectivity::CT_HasEdge)) {
3013 c.enableConnectivity(Connectivity::CT_HasEdge);
3014 info() << "Force creating edges for 3D non-manifold mesh";
3015 }
3016 }
3017}
3018
3019/*---------------------------------------------------------------------------*/
3020/*---------------------------------------------------------------------------*/
3021
3022void DynamicMesh::
3023_checkDimension() const
3024{
3025 if (m_mesh_dimension()<0)
3026 ARCANE_FATAL("dimension not set. setDimension() must be called before allocating cells");
3027}
3028
3029/*---------------------------------------------------------------------------*/
3030/*---------------------------------------------------------------------------*/
3031
3032void DynamicMesh::
3033_checkConnectivity()
3034{
3035 Connectivity c(m_mesh_connectivity);
3036 if (!c.isFrozen()) {
3037 c.freeze(this);
3038 debug() << "Mesh " << name() << " connectivity : " << Connectivity::Printer(m_mesh_connectivity());
3039 _setSubConnectivity();
3040 _updateItemFamilyDependencies(m_mesh_connectivity);
3041 }
3042}
3043
3044/*---------------------------------------------------------------------------*/
3045/*---------------------------------------------------------------------------*/
3046// AMR
3047void DynamicMesh::
3048_checkAMR() const
3049{
3050 if (!m_is_amr_activated)
3051 ARCANE_FATAL("DynamicMesh::_checkAMR(): amr activator not set.\t"
3052 "amr='true' must be set in the .arc file");
3053}
3054
3055/*---------------------------------------------------------------------------*/
3056/*---------------------------------------------------------------------------*/
3057
3058void DynamicMesh::
3059_setSubConnectivity()
3060{
3061 m_mesh_builder->setConnectivity(m_mesh_connectivity());
3062 m_node_family->setConnectivity(m_mesh_connectivity());
3063 m_edge_family->setConnectivity(m_mesh_connectivity());
3064 m_face_family->setConnectivity(m_mesh_connectivity());
3065 m_cell_family->setConnectivity(m_mesh_connectivity());
3066 m_is_sub_connectivity_set = true;
3067}
3068
3069/*---------------------------------------------------------------------------*/
3070/*---------------------------------------------------------------------------*/
3071
3072void DynamicMesh::
3073_writeCells(const String& filename)
3074{
3075 CellGroup cells(m_cell_family->allItems());
3076 std::ofstream ofile(filename.localstr());
3077 ENUMERATE_CELL(icell,cells){
3078 Cell cell = *icell;
3079 ofile << "CELL: uid=" << cell.uniqueId() << " isown="
3080 << cell.isOwn() << " owner=" << cell.owner() << '\n';
3081 }
3082}
3083
3084/*---------------------------------------------------------------------------*/
3085/*---------------------------------------------------------------------------*/
3086
3089{
3090 return m_node_family->nodesCoordinates();
3091}
3092
3093/*---------------------------------------------------------------------------*/
3094/*---------------------------------------------------------------------------*/
3095
3104
3105/*---------------------------------------------------------------------------*/
3106/*---------------------------------------------------------------------------*/
3107
3108void DynamicMesh::
3109_setOwnersFromCells()
3110{
3111 // On suppose qu'on connait les nouveaux propriétaires des mailles, qui
3112 // se trouvent dans cells_owner. Il faut
3113 // maintenant déterminer les nouveaux propriétaires des noeuds et
3114 // des faces. En attendant d'avoir un algorithme qui équilibre mieux
3115 // les messages, on applique le suivant:
3116 // - chaque sous-domaine est responsable pour déterminer le nouveau
3117 // propriétaire des noeuds et des faces qui lui appartiennent.
3118 // - pour les noeuds et les arêtes, le nouveau propriétaire est le nouveau
3119 // propriétaire de la maille connectée à ce noeud dont le uniqueId() est le plus petit.
3120 // - pour les faces, le nouveau propriétaire est le nouveau propriétaire
3121 // de la maille qui est derrière cette face s'il s'agit d'une face
3122 // interne et de la maille connectée s'il s'agit d'une face frontière.
3123 // - pour les noeuds duaux, le nouveau propriétaire est le nouveau propriétaire
3124 // de la maille connectée à l'élément dual
3125 // - pour les liaisons, le nouveau propriétaire est le nouveau propriétaire
3126 // de la maille connectée au premier noeud dual, c'est-à-dire le propriétaire
3127 // du premier noeud dual de la liaison
3128
3129 VariableItemInt32& nodes_owner(nodeFamily()->itemsNewOwner());
3130 VariableItemInt32& edges_owner(edgeFamily()->itemsNewOwner());
3131 VariableItemInt32& faces_owner(faceFamily()->itemsNewOwner());
3132
3133 const Integer sid = subDomain()->subDomainId();
3134
3135 // Outil d'affectation des owners pour les items
3136 if(m_new_item_owner_builder == NULL)
3137 m_new_item_owner_builder = new NewItemOwnerBuilder();
3138
3139 // Détermine les nouveaux propriétaires des noeuds
3140 {
3141 ENUMERATE_NODE(i_node,ownNodes()){
3142 Node node = *i_node;
3143 nodes_owner[node] = m_new_item_owner_builder->ownerOfItem(node);
3144 }
3145 nodes_owner.synchronize();
3146 }
3147
3148 ENUMERATE_NODE(i_node,allNodes()){
3149 Node node = *i_node;
3150 node.mutableItemBase().setOwner(nodes_owner[node],sid);
3151 }
3152
3153 // Détermine les nouveaux propriétaires des arêtes
3154 {
3155 ENUMERATE_EDGE(i_edge,ownEdges()){
3156 Edge edge = *i_edge;
3157 edges_owner[edge] = m_new_item_owner_builder->ownerOfItem(edge);
3158 }
3159 edges_owner.synchronize();
3160 }
3161
3162 ENUMERATE_EDGE(i_edge,allEdges()){
3163 Edge edge = *i_edge;
3164 edge.mutableItemBase().setOwner(edges_owner[edge],sid);
3165 }
3166
3167 // Détermine les nouveaux propriétaires des faces
3168 {
3169 ENUMERATE_FACE(i_face,ownFaces()){
3170 Face face = *i_face;
3171 faces_owner[face] = m_new_item_owner_builder->ownerOfItem(face);
3172 }
3173 faces_owner.synchronize();
3174 }
3175
3176 ENUMERATE_FACE(i_face,allFaces()){
3177 Face face = *i_face;
3178 face.mutableItemBase().setOwner(faces_owner[face],sid);
3179 }
3180
3184 _computeFamilySynchronizeInfos();
3185}
3186
3187/*---------------------------------------------------------------------------*/
3188/*---------------------------------------------------------------------------*/
3189
3191utilities()
3192{
3193 if (!m_mesh_utilities)
3194 m_mesh_utilities = new UnstructuredMeshUtilities(this);
3195 return m_mesh_utilities;
3196}
3197
3198/*---------------------------------------------------------------------------*/
3199/*---------------------------------------------------------------------------*/
3200
3202outerFaces()
3203{
3204 return m_cell_family->allItems().outerFaceGroup();
3205}
3206
3208/*---------------------------------------------------------------------------*/
3209/*---------------------------------------------------------------------------*/
3213{
3214 return m_cell_family->allItems().activeCellGroup();
3215}
3216/*---------------------------------------------------------------------------*/
3217/*---------------------------------------------------------------------------*/
3221{
3222 return m_cell_family->allItems().ownActiveCellGroup();
3223}
3224/*---------------------------------------------------------------------------*/
3225/*---------------------------------------------------------------------------*/
3228allLevelCells(const Integer& level)
3229{
3230 return m_cell_family->allItems().levelCellGroup(level);
3231}
3232/*---------------------------------------------------------------------------*/
3233/*---------------------------------------------------------------------------*/
3236ownLevelCells(const Integer& level)
3237{
3238 return m_cell_family->allItems().ownLevelCellGroup(level);
3239}
3240/*---------------------------------------------------------------------------*/
3241/*---------------------------------------------------------------------------*/
3245{
3246 return m_cell_family->allItems().activeFaceGroup();
3247}
3248/*---------------------------------------------------------------------------*/
3249/*---------------------------------------------------------------------------*/
3253{
3254 return m_cell_family->allItems().ownActiveFaceGroup();
3255}
3256/*---------------------------------------------------------------------------*/
3257/*---------------------------------------------------------------------------*/
3258
3259/*---------------------------------------------------------------------------*/
3260/*---------------------------------------------------------------------------*/
3264{
3265 return m_cell_family->allItems().innerActiveFaceGroup();
3266}
3267/*---------------------------------------------------------------------------*/
3268/*---------------------------------------------------------------------------*/
3272{
3273 return m_cell_family->allItems().outerActiveFaceGroup();
3274}
3275/*---------------------------------------------------------------------------*/
3276/*---------------------------------------------------------------------------*/
3277
3278
3279/*---------------------------------------------------------------------------*/
3280/*---------------------------------------------------------------------------*/
3281
3284{
3285 Trace::Setter mci(traceMng(),_className());
3286 if (!mesh)
3287 ARCANE_FATAL("Cannot set NULL parent mesh to mesh '{0}'",name());
3288
3289 if (mesh != group.mesh())
3290 ARCANE_FATAL("Cannot set inconsistant mesh/group parents to mesh '{0}'",name());
3291
3292 if (m_parent_mesh) {
3293 if (m_parent_mesh != mesh)
3294 ARCANE_FATAL("Mesh '{0}' already has parent mesh '{1}'",name(),m_parent_mesh->name());
3295 if (m_parent_group != group.internal())
3296 ARCANE_FATAL("Mesh '{0}' already has parent group '{1}'",name(),m_parent_group->name());
3297 }
3298
3299 m_parent_mesh = mesh;
3300 m_parent_group = group.internal();
3301
3302 Integer dimension_shift = 0;
3303 if (group.itemKind() == IK_Face) {
3304 dimension_shift = 1;
3305 }
3306 else if (group.itemKind() == IK_Cell) {
3307 dimension_shift = 0;
3308 }
3309 else {
3310 ARCANE_FATAL("Only SubMesh on FaceGroup or CellGoup is allowed");
3311 }
3312
3313 _setDimension(mesh->dimension()-dimension_shift);
3314
3315 for( IItemFamily* family : m_item_families ){
3316 const eItemKind kind = family->itemKind();
3317 // Uniquement sur les items constructifs d'un maillage
3318 if (kind == IK_Node || kind == IK_Edge || kind == IK_Face || kind == IK_Cell) {
3319 const eItemKind parent_kind = MeshToMeshTransposer::kindTranspose(kind, this, mesh);
3320 if (parent_kind != IK_Unknown) {
3321 family->setParentFamily(mesh->itemFamily(parent_kind));
3322 } // else : pas de transposition
3323 } else {
3324 // do nothing. Another idea ?
3325 }
3326 }
3327}
3328
3329/*---------------------------------------------------------------------------*/
3330/*---------------------------------------------------------------------------*/
3331
3334{
3335 return m_partition_constraint_mng;
3336}
3337
3338/*---------------------------------------------------------------------------*/
3339/*---------------------------------------------------------------------------*/
3340
3342parentMesh() const
3343{
3344 return m_parent_mesh;
3345}
3346
3347/*---------------------------------------------------------------------------*/
3348/*---------------------------------------------------------------------------*/
3349
3351parentGroup() const
3352{
3353 return ItemGroup(m_parent_group);
3354}
3355
3356/*---------------------------------------------------------------------------*/
3357/*---------------------------------------------------------------------------*/
3358
3360addChildMesh(IMesh * sub_mesh)
3361{
3362 DynamicMesh * dynamic_child_mesh = dynamic_cast<DynamicMesh*>(sub_mesh);
3363 if (!dynamic_child_mesh)
3364 ARCANE_FATAL("Cannot associate sub mesh from a different concrete type");
3365 for(Integer i=0;i<m_child_meshes.size();++i)
3366 if (m_child_meshes[i] == dynamic_child_mesh)
3367 return;
3368 m_child_meshes.add(dynamic_child_mesh);
3369}
3370
3371/*---------------------------------------------------------------------------*/
3372/*---------------------------------------------------------------------------*/
3373
3375childMeshes() const
3376{
3377 IMeshCollection collection = List<IMesh*>();
3378 for(Integer i=0;i<m_child_meshes.size(); ++i) {
3379 collection.add(m_child_meshes[i]);
3380 }
3381 return collection;
3382}
3383
3384/*---------------------------------------------------------------------------*/
3385/*---------------------------------------------------------------------------*/
3386
3388checker() const
3389{
3390 return m_mesh_checker;
3391}
3392
3393/*---------------------------------------------------------------------------*/
3394/*---------------------------------------------------------------------------*/
3395
3397isPrimaryMesh() const
3398{
3399 return (this->parentMesh()==nullptr);
3400}
3401
3402/*---------------------------------------------------------------------------*/
3403/*---------------------------------------------------------------------------*/
3404
3407{
3408 if (!isPrimaryMesh())
3409 throw BadCastException(A_FUNCINFO,"Mesh is not a primary mesh");
3410 return this;
3411}
3412
3413/*---------------------------------------------------------------------------*/
3414/*---------------------------------------------------------------------------*/
3415
3417nbNode()
3418{
3419 return m_node_family->nbItem();
3420}
3422nbEdge()
3423{
3424 return m_edge_family->nbItem();
3425}
3427nbFace()
3428{
3429 return m_face_family->nbItem();
3430}
3432nbCell()
3433{
3434 return m_cell_family->nbItem();
3435}
3436
3438nodeFamily()
3439{
3440 return m_node_family;
3441}
3442
3444edgeFamily()
3445{
3446 return m_edge_family;
3447}
3448
3450faceFamily()
3451{
3452 return m_face_family;
3453}
3454
3456cellFamily()
3457{
3458 return m_cell_family;
3459}
3460
3461DynamicMeshKindInfos::ItemInternalMap& DynamicMesh::
3462nodesMap()
3463{
3464 return m_node_family->itemsMap();
3465}
3466
3467DynamicMeshKindInfos::ItemInternalMap& DynamicMesh::
3468edgesMap()
3469{
3470 return m_edge_family->itemsMap();
3471}
3472
3473DynamicMeshKindInfos::ItemInternalMap& DynamicMesh::
3474facesMap()
3475{
3476 return m_face_family->itemsMap();
3477}
3478
3479DynamicMeshKindInfos::ItemInternalMap& DynamicMesh::
3480cellsMap()
3481{
3482 return m_cell_family->itemsMap();
3483}
3484
3485/*---------------------------------------------------------------------------*/
3486/*---------------------------------------------------------------------------*/
3487
3490{
3491 UniqueArray<DynamicMesh*> true_meshes;
3492 for( IMesh* mesh : meshes ){
3493 DynamicMesh* true_mesh = ARCANE_CHECK_POINTER(dynamic_cast<DynamicMesh*>(mesh));
3494 true_meshes.add(true_mesh);
3495 }
3496 DynamicMeshMerger merger(this);
3497 merger.mergeMeshes(true_meshes);
3498}
3499
3500/*---------------------------------------------------------------------------*/
3501/*---------------------------------------------------------------------------*/
3502
3503void DynamicMesh::
3504_printConnectivityPolicy()
3505{
3506 info() << "Connectivity policy=" << (int)m_connectivity_policy;
3507
3508 if (m_connectivity_policy != InternalConnectivityPolicy::NewOnly)
3509 ARCANE_FATAL("Invalid value '{0}' for InternalConnectivityPolicy. Only '{1}' is allowed",
3510 (int)m_connectivity_policy,(int)InternalConnectivityPolicy::NewOnly);
3511}
3512
3513/*---------------------------------------------------------------------------*/
3514/*---------------------------------------------------------------------------*/
3515
3517setMeshPartInfo(const MeshPartInfo& mpi)
3518{
3519 m_mesh_part_info = mpi;
3520 // TODO: notifier les familles
3521}
3522
3523/*---------------------------------------------------------------------------*/
3524/*---------------------------------------------------------------------------*/
3525
3526void DynamicMesh::
3527_updateItemFamilyDependencies(VariableScalarInteger connectivity)
3528{
3529 if (!m_item_family_network)
3530 return;
3532 for (const auto& con : m_item_family_network->getConnectivities()) {
3533 if (c.hasConnectivity(c.kindsToConnectivity(con->sourceFamily()->itemKind(),con->targetFamily()->itemKind()))){
3534 m_item_family_network->setIsStored(con);
3535 }
3536 }
3537}
3538
3539/*---------------------------------------------------------------------------*/
3540/*---------------------------------------------------------------------------*/
3541
3544{
3545 return m_internal_api.get();
3546}
3547
3548/*---------------------------------------------------------------------------*/
3549/*---------------------------------------------------------------------------*/
3550
3553{
3554 return m_internal_api.get();
3555}
3556
3557/*---------------------------------------------------------------------------*/
3558/*---------------------------------------------------------------------------*/
3559
3562{
3563 _computeSynchronizeInfos();
3564}
3565
3566/*---------------------------------------------------------------------------*/
3567/*---------------------------------------------------------------------------*/
3568
3569class ARCANE_MESH_EXPORT DynamicMeshFactoryBase
3570: public AbstractService
3571, public IMeshFactory
3572{
3573 public:
3574
3575 DynamicMeshFactoryBase(const ServiceBuildInfo& sbi,bool is_amr)
3576 : AbstractService(sbi), m_is_amr(is_amr) {}
3577
3578 public:
3579
3580 void build() override {}
3581 IPrimaryMesh* createMesh(IMeshMng* mm,const MeshBuildInfo& build_info) override
3582 {
3583 MeshBuildInfo mbi(build_info);
3584 MeshKind mk(mbi.meshKind());
3585 // Si on demande l'AMR mais que cela n'est pas indiqué dans MeshPart,
3586 // on l'ajoute.
3587 if (m_is_amr && mk.meshAMRKind()==eMeshAMRKind::None)
3588 mk.setMeshAMRKind(eMeshAMRKind::Cell);
3589 mbi.addMeshKind(mk);
3591 bool is_submesh = !mbi.parentGroup().null();
3592 if (is_submesh && m_is_amr)
3593 ARCANE_FATAL("Submesh cannot be refined with AMR.");
3594 return new DynamicMesh(sd,mbi,is_submesh);
3595 }
3596
3597 private:
3598
3599 bool m_is_amr;
3600};
3601
3602/*---------------------------------------------------------------------------*/
3603/*---------------------------------------------------------------------------*/
3604
3605class ARCANE_MESH_EXPORT DynamicMeshFactory
3606: public DynamicMeshFactoryBase
3607{
3608 public:
3609 explicit DynamicMeshFactory(const ServiceBuildInfo& sbi)
3610 : DynamicMeshFactoryBase(sbi,false) {}
3611};
3612
3613/*---------------------------------------------------------------------------*/
3614/*---------------------------------------------------------------------------*/
3615
3616class ARCANE_MESH_EXPORT DynamicAMRMeshFactory
3617: public DynamicMeshFactoryBase
3618{
3619 public:
3620 explicit DynamicAMRMeshFactory(const ServiceBuildInfo& sbi)
3621 : DynamicMeshFactoryBase(sbi,true) {}
3622};
3623
3624/*---------------------------------------------------------------------------*/
3625/*---------------------------------------------------------------------------*/
3626
3628 ServiceProperty("ArcaneDynamicMeshFactory",ST_Application),
3630
3632 ServiceProperty("ArcaneDynamicAMRMeshFactory",ST_Application),
3634
3635/*---------------------------------------------------------------------------*/
3636/*---------------------------------------------------------------------------*/
3637
3638} // End namespace Arcane::mesh
3639
3640/*---------------------------------------------------------------------------*/
3641/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#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_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
#define ENUMERATE_EDGE(name, group)
Enumérateur générique d'un groupe d'arêtes.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
Fonctions utilitaires sur le maillage.
void writeMeshConnectivity(IMesh *mesh, const String &file_name)
Ecrit sur le fichier file_name la connectivité du maillage mesh.
Definition MeshUtils.cc:828
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
Integer size() const
Nombre d'éléments du vecteur.
AbstractService(const ServiceBuildInfo &)
Constructeur à partir d'un ServiceBuildInfo.
Tableau d'items de types quelconques.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Exception lorsqu'une conversion d'un type vers un autre est invalide.
Maille d'un maillage.
Definition Item.h:1205
Face face(Int32 i) const
i-ème face de la maille
Definition Item.h:1283
Int32 nbFace() const
Nombre de faces de la maille.
Definition Item.h:1280
EnumeratorT< ItemGroup > Enumerator
Definition Collection.h:129
Gère la récupération des informations de connectivité.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
constexpr bool empty() const noexcept
true si le tableau est vide (size()==0)
static std::optional< Int32 > tryParseFromEnvironment(StringView s, bool throw_if_invalid)
Definition Convert.cc:122
Face d'une maille.
Definition Item.h:958
Cell cell(Int32 i) const
i-ème maille de la face
Definition Item.h:1647
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
Definition Item.h:1033
Interface d'une partie d'un jeu de données.
virtual XmlNode rootElement()=0
Retourne l'élément racine.
Interface d'un constructeur de mailles fantômes "extraordinaires".
Interface d'un constructeur de mailles fantômes "extraordinaires".
virtual void setBuilderVersion(Integer n)=0
Positionne la version du constructeur de mailles fantômes. Pour l'instant (version 3....
virtual Integer nbGhostLayer() const =0
Nombre de couches fantômes.
virtual void setNbGhostLayer(Integer n)=0
Positionne le nombre de couches fantômes.
Interface de modification d'une famille.
virtual List< IIncrementalItemConnectivity * > getConnectivities()=0
Obtenir la liste de toutes les connectivités, qu'elles soient relation ou dépendance.
virtual void removeConnectedDoFsFromCells(Int32ConstArrayView local_ids)=0
supprime les DoFs et les liens entre DoFs connectés aux mailles supprimées
virtual void setIsStored(IIncrementalItemConnectivity *connectivity)=0
Positionne une connectivité comme étant stockée.
virtual void schedule(IItemFamilyNetworkTask task, eSchedulingOrder order=TopologicalOrder)=0
Ordonnance l'exécution d'une tâche, dans l'ordre topologique ou topologique inverse du graphe de dépe...
virtual IItemFamilySerializer * createSerializer(bool with_flags=false)=0
Créé une instance pour la sérialisation des entités. L'instance retournée doit être détruite par l'op...
Interface d'une famille d'entités.
Definition IItemFamily.h:84
virtual ItemGroup findGroup(const String &name) const =0
Recherche un groupe.
virtual IVariableSynchronizer * allItemsSynchronizer()=0
Synchroniseur sur toutes les entités de la famille.
virtual ItemInternalArrayView itemsInternal()=0
Tableau interne des entités.
virtual String name() const =0
Nom de la famille.
virtual void notifyItemsOwnerChanged()=0
Notifie que les entités propres au sous-domaine de la famille ont été modifiées.
virtual ItemVectorView view(Int32ConstArrayView local_ids)=0
Vue sur les entités.
virtual void itemsUniqueIdToLocalId(Int32ArrayView local_ids, Int64ConstArrayView unique_ids, bool do_fatal=true) const =0
Converti un tableau de numéros uniques en numéros locaux.
virtual VariableItemInt32 & itemsNewOwner()=0
Variable contenant le numéro du nouveau sous-domaine propriétaire de l'entité.
Interface de méthodes de vérification d'un maillage.
Interface du service gérant la lecture d'un maillage.
Partie interne de IMesh.
Interface du gestionnaire des maillages.
Definition IMeshMng.h:40
virtual IVariableMng * variableMng() const =0
Gestionnaire de variables associé à ce gestionnaire.
virtual MeshHandle * findMeshHandle(const String &name, bool throw_exception)=0
Recherche le maillage de nom name.
Partie interne de IMeshModifier.
Interface d'un gestionnaire de contraintes de partitionnement de maillage.
virtual void setFaceBuilderVersion(Integer n)=0
Positionne la version de la numérotation des faces.
virtual void setEdgeBuilderVersion(Integer n)=0
Positionne la version de la numérotation des arêtes.
virtual bool isUseNodeUniqueIdToGenerateEdgeAndFaceUniqueId() const =0
Indique le mécanisme utilisé pour numéroter les arêtes ou les faces.
Interface d'une classe proposant des fonctions utilitaires sur maillage.
virtual void changeOwnersFromCells()=0
Positionne les nouveaux propriétaires des noeuds, arêtes et faces à partir des mailles.
virtual IMeshUtilities * utilities()=0
Interface des fonctions utilitaires associée.
virtual IItemFamilyNetwork * itemFamilyNetwork()=0
Interface du réseau de familles (familles connectées)
Interface du gestionnaire de parallélisme pour un sous-domaine.
@ ModePut
Le sérialiseur attend des reserve()
virtual void allocateBuffer()=0
Alloue la mémoire du sérialiseur.
virtual void setMode(eMode new_mode)=0
Positionne le fonctionnement actuel.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
virtual Int32 subDomainId() const =0
Numéro du sous-domaine associé à ce gestionnaire.
Interface gérant les statistiques sur les temps d'exécution.
Definition ITimeStats.h:43
virtual void dumpTimeAndMemoryUsage(IParallelMng *pm)=0
Affiche la date actuelle et la mémoire consommée.
virtual ISubDomain * internalSubDomain() const =0
Fonction interne temporaire pour récupérer le sous-domaine.
Interface du gestionnaire de variables.
virtual VariableCollection usedVariables()=0
Liste des variables utilisées.
virtual IVariable * findMeshVariable(IMesh *mesh, const String &name)=0
Retourne la variable du maillage de nom name ou 0 si aucune de se nom existe.
virtual IObservable * writeObservable()=0
Observable pour les variables en écriture.
virtual IVariableMngInternal * _internalApi()=0
API interne à Arcane.
virtual IObservable * readObservable()=0
Observable pour les variables en lecture.
Interface d'une variable.
Definition IVariable.h:56
virtual bool initialize(const ItemGroup &group, const String &value)=0
Initialise la variable sur un groupe.
virtual void resizeFromGroup()=0
Positionne le nombre d'éléments pour une variable du maillage.
virtual bool isUsed() const =0
Etat d'utilisation de la variable.
bool isAncestor() const
@ II_JustCoarsened
L'entité vient d'être dé-raffiné
Definition ItemFlags.h:79
void executeExtend(const Int32ConstArrayView *new_items_info)
Execute l'action associée à l'extension.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
ItemGroupImpl * internal() const
Retourne l'implémentation du groupe.
Definition ItemGroup.h:120
FaceGroup activeFaceGroup() const
Groupe des faces actives.
Definition ItemGroup.cc:352
FaceGroup innerActiveFaceGroup() const
Groupe des faces internes des éléments de ce groupe.
Definition ItemGroup.cc:379
Integer size() const
Nombre d'éléments du groupe.
Definition ItemGroup.h:88
FaceGroup ownActiveFaceGroup() const
Groupe des faces actives propres au domaine des éléments de ce groupe.
Definition ItemGroup.cc:364
CellGroup levelCellGroup(const Integer &level) const
Groupe des mailles de niveau l des éléments de ce groupe.
Definition ItemGroup.cc:329
eItemKind itemKind() const
Genre du groupe. Il s'agit du genre de ses éléments.
Definition ItemGroup.h:109
CellGroup ownActiveCellGroup() const
Groupe des mailles propres actives des éléments de ce groupe.
Definition ItemGroup.cc:317
bool null() const
true is le groupe est le groupe nul
Definition ItemGroup.h:70
CellGroup ownLevelCellGroup(const Integer &level) const
Groupe des mailles propres de niveau l des éléments de ce groupe.
Definition ItemGroup.cc:341
FaceGroup outerActiveFaceGroup() const
Groupe des faces externes actives des éléments de ce groupe.
Definition ItemGroup.cc:391
IMesh * mesh() const
Maillage auquel appartient ce groupe (0 pour le group nul)
Definition ItemGroup.h:126
CellGroup activeCellGroup() const
AMR.
Definition ItemGroup.cc:305
FaceGroup outerFaceGroup() const
Groupe des faces externes des éléments de ce groupe.
Definition ItemGroup.cc:290
Informations pour synchroniser les groupes entre sous-domaines.
Structure interne d'une entité de maillage.
Index d'un Item dans une variable.
Definition ItemLocalId.h:41
Gestionnaire des types d'entités d'un maillage.
Definition ItemTypeMng.h:65
Classe de base d'un élément de maillage.
Definition Item.h:83
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
Definition Item.h:380
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
bool isOwn() const
true si l'entité est appartient au sous-domaine
Definition Item.h:253
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
Definition Item.h:238
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
Implémentation d'une collection d'éléments sous forme de vecteur.
Definition List.h:222
Paramètres nécessaires à la construction d'un maillage.
const ItemGroup & parentGroup() const
Groupe parent dans le cas d'un sous-maillage, null sinon.
const MeshKind meshKind() const
Caractéristiques du maillage.
MeshBuildInfo & addMeshKind(const MeshKind &v)
Positionne les caractéristiques du maillage.
Gestionnaire des compactages de familles d'un maillage.
Arguments des évènements sur le maillage.
Definition MeshEvents.h:43
Interface du gestionnaire des échanges de maillages entre sous-domaines.
IMesh * mesh() const
Maillage associé.
Caractéristiques d'un maillage.
Definition MeshKind.h:104
Arguments pour IMeshModifier::addCells().
Arguments pour IMeshModifier::addFaces().
Informations un maillage partitionné.
void dumpStats() override
Imprime des infos sur le maillage.
Definition MeshStats.cc:62
static eItemKind kindTranspose(eItemKind kindA, IMesh *meshA, IMesh *meshB)
Transpose le genre kindA du maillage meshA en le genre associé dans meshB.
Variables contenant les informations de connectivités communes aux maillages 1D, 2D et 3D.
VariableScalarString m_parent_group_name
Nom du groupe parent.
VariableScalarInteger m_mesh_connectivity
Connectivité du maillage.
VariableScalarInteger m_mesh_dimension
Dimension du maillage.
VariableArrayString m_item_families_name
Noms des familles d'entités.
VariableScalarString m_parent_mesh_name
Nom du maillage parent.
VariableArrayString m_child_meshes_name
Noms des maillages parentés.
VariableArrayInteger m_item_families_kind
Genre des entités des familles.
void setOwner(Integer suid, Int32 current_sub_domain)
Positionne le numéro du sous-domaine propriétaire de l'entité.
Noeud d'un maillage.
Definition Item.h:582
Liste de propriétés.
Definition Properties.h:64
void setBool(const String &name, bool value)
Positionne une propriété de type bool de nom name et de valeur value.
Encapsulation d'un pointeur qui se détruit automatiquement.
Definition ScopedPtr.h:44
Structure contenant les informations pour créer un service.
Ref< InterfaceType > createReference(const String &name, eServiceBuilderProperties properties=SB_None)
Créé une instance implémentant l'interface InterfaceType.
Propriétés de création d'un service.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:304
Implémentation du gestionnaire d'interfaces liées.
Postionne le nom de l'action en cours d'exécution.
Definition Timer.h:110
Sentinelle pour le timer. La sentinelle associée à un timer permet de déclancher celui-ci au moment d...
Definition Timer.h:89
Gestion d'un timer.
Definition Timer.h:62
@ TimerReal
Timer utilisant le temps réel.
Definition Timer.h:76
Real lastActivationTime() const
Retourne le temps (en secondes) passé lors de la dernière activation du timer.
Definition Timer.h:219
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage pinfo() const
Flot pour un message d'information en parallèle.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage error() const
Flot pour un message d'erreur.
TraceMessage pwarning() const
Positionne une classe de message.
Vecteur 1D de données avec sémantique par valeur (style STL).
Fonctions utilitaires sur un maillage.
Collection de variables.
Function each(Function f)
Applique le fonctor f à tous les éléments de la collection.
String name() const
Nom de la variable.
Liste de noeuds d'un arbre DOM.
Definition XmlNodeList.h:33
Noeud d'un arbre DOM.
Definition XmlNode.h:51
XmlNodeList children(const String &name) const
Ensemble des noeuds fils de ce noeud ayant pour nom name.
Definition XmlNode.cc:93
bool null() const
Vrai si le noeud est nul.
Definition XmlNode.h:294
Famille de mailles.
Definition CellFamily.h:46
virtual void internalRemoveItems(Int32ConstArrayView local_ids, bool keep_ghost=false) override
void _addParentCellToCell(Cell cell, Cell parent_cell)
AMR.
IPrimaryMesh * createMesh(IMeshMng *mm, const MeshBuildInfo &build_info) override
Créé un maillage avec les informations de build_info.
void build() override
Construction de niveau build du service.
Construction d'un maillage de manière incrémentale.
void addCells(Integer nb_cell, Int64ConstArrayView cell_infos, Integer sub_domain_id, Int32ArrayView cells, bool allow_build_face=true)
Ajoute des mailles au maillage actuel.
void addCells3(Integer nb_cell, Int64ConstArrayView cell_infos, Integer sub_domain_id, Int32ArrayView cells, bool allow_build_face=true)
Ajoute des mailles au maillage actuel. Utilise l'ajout d'item générique basé sur dépendances entre fa...
Informations pour un échange de maillage entre sous-domaines.
IItemConnectivityMng * dofConnectivityMng() const noexcept override
Renvoie le gestionnaire de connectivités des dofs.
void removeNeedRemoveMarkedItems() override
Suppression des items qui quittent le sous-domaine. Cette méthode est appelée dans MeshExchanger.
void setMeshKind(const MeshKind &v) override
Positionne le type de maillage.
IPolyhedralMeshModifier * polyhedralMeshModifier() const noexcept override
Implémentation d'un maillage.
Definition DynamicMesh.h:97
IPrimaryMesh * toPrimaryMesh() override
Retourne l'instance sous la forme d'un IPrimaryMesh.
FaceGroup ownActiveFaces() override
Groupe de toutes les faces actives sur la frontière.
void computeSynchronizeInfos() override
Recalcule les informations de synchronisation.
void flagCellToRefine(Int32ConstArrayView cells_lids) override
AMR.
IMeshPartitionConstraintMng * partitionConstraintMng() override
Gestionnaire des contraintes de partitionnement associées à ce maillage.
void checkValidMeshFull() override
Vérification de la validité du maillage.
Integer checkLevel() const override
Niveau actuel de vérification.
VariableItemInt32 & itemsNewOwner(eItemKind ik) override
Variable contenant l'identifiant du sous-domaine propriétaire.
IItemFamily * nodeFamily() override
Retourne la famille des noeuds.
FaceGroup outerActiveFaces() override
Groupe de toutes les faces actives sur la frontière.
void addExtraGhostCellsBuilder(IExtraGhostCellsBuilder *builder) override
ajout du algorithme d'ajout de mailles fantômes "extraordinaires".
IItemFamily * cellFamily() override
Retourne la famille des mailles.
IMeshCollection childMeshes() const override
Liste des sous-maillages du maillage courant.
void endAllocate() override
Indique une fin d'allocation de mailles.
FaceGroup allFaces() override
Groupe de toutes les faces.
void _internalEndUpdateFinal(bool print_stat)
void addEdges(Integer nb_edge, Int64ConstArrayView edge_infos, Int32ArrayView edges) override
Ajoute des arêtes.
IMeshModifierInternal * _modifierInternalApi() override
API interne à Arcane.
UniqueArray< ItemFamily * > m_true_item_families
Liste des implémentations des familles d'entités.
CellGroup allActiveCells() override
AMR.
ITraceMng * traceMng() override
Gestionnaire de message associé
void setDimension(Integer dim) override
Positionne la dimension du maillage (1D, 2D ou 3D).
IParallelMng * parallelMng() override
Gestionnaire de parallèlisme.
Integer nbCell() override
Nombre de mailles du maillage.
ItemGroup findGroup(const String &name) override
Retourne le groupe de nom name ou le groupe nul s'il n'y en a pas.
bool isPrimaryMesh() const override
Indique si l'instance est un maillage primaire.
IMeshChecker * checker() const override
Interface du vérificateur.
IMesh * mesh() override
Maillage associé
void removeExtraGhostCellsBuilder(IExtraGhostCellsBuilder *builder) override
Supprime l'association à l'instance builder.
void mergeMeshes(ConstArrayView< IMesh * > meshes) override
Fusionne les maillages de meshes avec le maillage actuel.
VariableNodeReal3 & nodesCoordinates() override
Coordonnées des noeuds.
IItemFamily * createItemFamily(eItemKind ik, const String &name) override
Créé une famille de particule de nom name.
String name() const override
Nom du maillage.
IMeshMng * meshMng() const override
Gestionnaire de maillage associé
void setCheckLevel(Integer level) override
Positionne le niveau de vérification du maillage.
NodeGroup ownNodes() override
Groupe de tous les noeuds propres au domaine.
void _readFromDump()
Recharge le maillage à partir des variables protégés.
EdgeGroup ownEdges() override
Groupe de toutes les arêtes propres au domaine.
void serializeCells(ISerializer *buffer, Int32ConstArrayView cells_local_id) override
void reloadMesh() override
Recharge le maillage à partir des variables protégées.
IMeshModifier * modifier() override
Interface de modification associée.
void addCells(Integer nb_cell, Int64ConstArrayView cell_infos, Int32ArrayView cells) override
Ajoute des mailles.
IItemFamilyModifier * findItemFamilyModifier(eItemKind ik, const String &name) override
Retourne l'interface IItemFamilyModifier pour famille de nom name et de type ik.
bool hasTiedInterface() override
Vrai s'il existe des interfaces semi-conformes dans le maillage.
VariableScalarInteger connectivity() override
Descripteur de connectivité
void addExtraGhostParticlesBuilder(IExtraGhostParticlesBuilder *builder) override
Ajout du algorithme d'ajout de particules fantômes "extraordinaires".
void exchangeItems() override
Change les sous-domaines propriétaires des entités.
void prepareForDump() override
Prépare l'instance en vue d'une protection.
SharedVariableNodeReal3 sharedNodesCoordinates() override
Coordonnées des noeuds.
void deallocate() override
Désalloue le maillage.
ItemGroupCollection groups() override
Liste des groupes.
void clearItems() override
Supprime toutes les entitées de toutes les familles de ce maillage.
void updateGhostLayers() override
ItemFamilyList m_item_families
Liste des interfaces familles d'entités.
EdgeGroup allEdges() override
Groupe de toutes les arêtes.
void detachCells(Int32ConstArrayView cells_local_id) override
Détache des mailles du maillage.
Integer nbNode() override
Nombre de noeuds du maillage.
CellGroup allCells() override
Groupe de toutes les mailles.
FaceGroup outerFaces() override
Groupe de toutes les faces sur la frontière.
IVariableMng * variableMng() const override
Gestionnaire de variable associé
IGhostLayerMng * ghostLayerMng() const override
Gestionnare de couche fantômes associé
void addChildMesh(IMesh *sub_mesh) override
Ajoute un sous-maillage au maillage parent.
void endUpdate() override
Notifie l'instance de la fin de la modification du maillage.
TiedInterfaceCollection tiedInterfaces() override
Liste des interfaces semi-conformes.
void synchronizeGroupsAndVariables() override
Synchronise tous les groupes et les variables du maillage.
void defineParentForBuild(IMesh *mesh, ItemGroup group) override
Définit les maillage et groupe parents.
InternalConnectivityPolicy _connectivityPolicy() const override
Politique d'utilisation des connectivitées.
void removeDetachedCells(Int32ConstArrayView cells_local_id) override
Supprime les mailles détachées.
Integer nbEdge() override
Nombre d'arêtes du maillage.
FaceGroup ownFaces() override
Groupe de toutes les faces propres au domaine.
IItemFamily * faceFamily() override
Retourne la famille des faces.
void addHChildrenCells(Cell parent_cell, Integer nb_cell, Int64ConstArrayView cells_infos, Int32ArrayView cells) override
AMR.
ItemGroup parentGroup() const override
Groupe parent.
void removeExtraGhostParticlesBuilder(IExtraGhostParticlesBuilder *builder) override
Supprime l'association à l'instance builder.
void destroyGroups() override
Détruit tous les groupes de toutes les familles.
void _saveProperties()
Sauve les propriétés avant une protection.
Integer nbFace() override
Nombre de faces du maillage.
IItemFamily * findItemFamily(eItemKind ik, const String &name, bool create_if_needed, bool register_modifier_if_created) override
Retourne la famille de nom name.
const MeshKind meshKind() const override
Caractéristiques du maillage.
Properties * properties() override
Propriétés associées à ce maillage.
FaceGroup allActiveFaces() override
Groupe de toutes les faces actives.
CellGroup ownCells() override
Groupe de toutes les mailles propres au domaine.
IMeshInternal * _internalApi() override
API interne à Arcane.
IItemFamilyNetwork * itemFamilyNetwork() override
Interface du réseau de familles (familles connectées)
void computeTiedInterfaces(const XmlNode &xml_node) override
Détermine les interfaces de semi-conformités.
IMesh * parentMesh() const override
Accès au maillage parent.
void setMeshPartInfo(const MeshPartInfo &mpi) override
Positionne les informations de partitionnement.
CellGroup ownActiveCells() override
Groupe de toutes les mailles actives et propres au domaine.
void _loadProperties()
Relit les propriétés depuis une protection.
void checkValidMesh() override
Vérification de la validité des structues internes de maillage (interne)
void initializeVariables(const XmlNode &init_node) override
void addNodes(Int64ConstArrayView nodes_uid, Int32ArrayView nodes) override
Ajoute des noeuds.
void updateGhostLayerFromParent(Array< Int64 > &ghost_cell_to_refine, Array< Int64 > &cells_to_coarsen, bool remove_old_ghost) override
AMR.
FaceGroup innerActiveFaces() override
Groupe de toutes les faces actives.
NodeGroup allNodes() override
Groupe de tous les noeuds.
void _prepareForDump()
Prépare les variables pour une protection.
void allocateCells(Integer mesh_nb_cell, Int64ConstArrayView cells_info, bool one_alloc) override
Allocation d'un maillage.
IItemFamily * edgeFamily() override
Retourne la famille des arêtes.
IMeshUtilities * utilities() override
Interface des fonctions utilitaires associée.
void _updateGroupsAfterRemove()
Met à jour les groupes suite à des suppressions d'entités.
void _multipleExchangeItems(Integer nb_exchange, Integer version, bool do_compact)
Echange les entités en plusieurs fois.
void _prepareForDumpReal()
Prépare les variables pour une protection.
ItemGroupList m_all_groups
Liste des groupes d'entités.
MeshRefinement * m_mesh_refinement
AMR.
CellGroup ownLevelCells(const Integer &level) override
Groupe de toutes les mailles propres de niveau level.
CellGroup allLevelCells(const Integer &level) override
Groupe de toutes les mailles de niveau level.
void addFaces(Integer nb_face, Int64ConstArrayView face_infos, Int32ArrayView faces) override
Ajoute des faces.
Famille d'arêtes.
Definition EdgeFamily.h:35
Famille de faces.
Definition FaceFamily.h:53
void setCheckOrientation(bool is_check)
Indique s'il faut vérifier l'orientation des mailles et des faces.
Definition FaceFamily.h:134
Interface du gestionnaire des connectivités incrémentales indexées sur les entités.
Famille d'entités.
Definition ItemFamily.h:76
IItemFamilyPolicyMng * policyMng() override
Interface des comportements/politiques associées à cette famille.
Definition ItemFamily.h:274
Informations pour échanger des entités d'une famille donnée et leur caractéristiques.
Implémentation des algorithmes d'adaptation par raffinement de maillages non-structuré.
bool refineItems(const bool maintain_level_one=true)
bool coarsenItems(const bool maintain_level_one=true)
Gestionnaire de numérotation des uniqueId() d'un maillage.
Famille de noeuds.
Definition NodeFamily.h:37
void setUseNodeUniqueIdToGenerateEdgeAndFaceUniqueId(bool v)
Positionne le mécanisme de numérotation des uniqueId().
Famille de particules.
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
Definition MathUtils.h:392
ItemGroupT< Cell > CellGroup
Groupe de mailles.
Definition ItemTypes.h:183
ItemGroupT< Face > FaceGroup
Groupe de faces.
Definition ItemTypes.h:178
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro pour enregistrer un service.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
ItemVariableScalarRefT< Int32 > VariableItemInt32
Grandeur de type entier 32 bits.
VariableRefScalarT< Integer > VariableScalarInteger
Variable scalaire de type entier.
@ None
Aucune politique d'exécution.
Integer toInteger(Real r)
Converti un Real en Integer.
Definition Convert.h:45
ARCCORE_BASE_EXPORT String getCurrentDateTime()
Date et l'heure courante sous la forme ISO 8601.
ARCCORE_BASE_EXPORT String getEnvironmentVariable(const String &name)
Variable d'environnement du nom name.
bool arcaneIsCheck()
Vrai si on est en mode vérification.
Definition Misc.cc:68
Collection< ItemGroup > ItemGroupCollection
Collection de groupes d'éléments du maillage.
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:569
ConstArrayView< ItemInternal * > ItemInternalList
Type de la liste interne des entités.
Definition ItemTypes.h:466
SharedMeshVariableScalarRefT< Node, Real3 > SharedVariableNodeReal3
Grandeur au noeud de type coordonnées.
@ ST_Application
Le service s'utilise au niveau de l'application.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:567
eMeshEventType
Evènements générés par IMesh.
Definition MeshEvents.h:30
@ EndPrepareDump
Evènement envoyé à la fin de prepareForDump()
Definition MeshEvents.h:34
@ BeginPrepareDump
Evènement envoyé au début de prepareForDump()
Definition MeshEvents.h:32
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:428
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:540
eItemKind
Genre d'entité de maillage.
@ IK_Particle
Entité de maillage de genre particule.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Unknown
Entité de maillage de genre inconnu ou non initialisé
@ IK_Face
Entité de maillage de genre face.
@ IK_DoF
Entité de maillage de genre degre de liberte.
@ IK_Edge
Entité de maillage de genre arête.
const char * itemKindName(eItemKind kind)
Nom du genre d'entité.
double Real
Type représentant un réel.
Array< Int32 > Int32Array
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:214
Collection< IMesh * > IMeshCollection
Collection de maillages.
InternalConnectivityPolicy
Politique d'utilisation des connectivités.
Definition ItemTypes.h:516
@ NewOnly
Alloue uniquement les nouvelles connectivités.
Definition ItemTypes.h:554
@ NewWithDependenciesAndLegacy
Alloue les anciennes et les nouvelles connectivités utilise les nouvelles via les nouveaux accesseurs...
Definition ItemTypes.h:550
eMeshAMRKind
Type de maillage AMR.
Definition MeshKind.h:48
@ Patch
Le maillage est AMR par patch.
Definition MeshKind.h:54
@ Cell
Le maillage est AMR par maille.
Definition MeshKind.h:52
@ None
Le maillage n'est pas AMR.
Definition MeshKind.h:50
@ PatchCartesianMeshOnly
Le maillage est AMR par patch cartésien (rectangulaire)
Definition MeshKind.h:56
Collection< ITiedInterface * > TiedInterfaceCollection
Collection d'interfaces liées.
std::int32_t Int32
Type entier signé sur 32 bits.