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