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