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