Arcane  4.1.11.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
DynamicMesh.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* DynamicMesh.cc (C) 2000-2026 */
9/* */
10/* Class for managing an evolving unstructured mesh. */
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// Public properties that the user can set
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// Internal Arcane properties
118const char* PROPERTY_MESH_VERSION = "mesh-version";
119} // namespace
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 // To keep compatibility with the existing code, allows not to
301 // save the 'need-compact' attribute. This was added for version 3.10
302 // of Arcane (June 2023). To be removed before end of 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 // Overrides the default value for the numbering mechanism
307 // of uniqueId() for edges and faces.
308 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_GENERATE_UNIQUE_ID_FROM_NODES", true)) {
309 bool is_generate = (v.value() != 0);
310 // Using free entities implies using uniqueId() generation
311 // from nodes.
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 // It might be better to throw an exception but in a
325 // destructor this is not necessarily advisable
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 // Destroys dynamically allocated families.
349 for (IItemFamily* family : m_item_families) {
350 eItemKind kind = family->itemKind();
351 // Only particle or DoF families are dynamically allocated.
352 // TODO: now they are all so they should all be
353 // deallocated by this loop
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: the first elements of m_item_families must
384 // correspond to the families associated with eItemKind values
385 // (IK_Node, IK_Edge, IK_Face, IK_Cell)
386 for (IItemFamily* family : m_item_families) {
387 _buildAndInitFamily(family);
388 }
389
390 // Allows calling the '_prepareDump' function when a
391 // dump is performed
392 IVariableMng* vm = subDomain()->variableMng();
393 m_observer_pool.addObserver(this,
395 vm->writeObservable());
396 // Allows calling the '_readFromDump' function when a
397 // dump is read
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 // This can induce segfaults if the DynamicMesh is not used correctly
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
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 else {
424 m_submesh_tools = 0;
426
427 // GG: does not build m_mesh_refinement if AMR is active
428 // This avoids creating unnecessary variables when AMR is not
429 // requested. The creation of m_mesh_refinement is now
430 // done in readAmrActivator(). This might not be the right place
431 // to do it and it can potentially be moved. It just needs
432 // m_mesh_refinement to be created only if AMR is active.
433 // SDC: OK. Restored because now the AMR (in)active info is known at
434 // construction. Removal of readAmrActivator.
435
436 if (m_is_amr_activated) {
437 if (m_amr_type == eMeshAMRKind::None || m_amr_type == eMeshAMRKind::Cell) {
439 }
440 else if (m_amr_type == eMeshAMRKind::Patch) {
441 ARCANE_FATAL("Patch AMR type is not implemented.");
442 }
443 else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
444 // The AMR PatchCartesianMeshOnly is not handled by MeshRefinement().
445 // See in CartesianMesh.cc.
446 // TODO: CartesianMeshAMRPatchMng needs it for ghost meshes.
447 // See to remove or replace the call to the method
448 // updateGhostLayerFromParent().
450 }
451 }
452 }
453
454 m_internal_api->build();
455}
456
457/*---------------------------------------------------------------------------*/
458/*---------------------------------------------------------------------------*/
459
460IParallelMng* DynamicMesh::
461parallelMng()
462{
463 return m_parallel_mng;
464}
465
466/*---------------------------------------------------------------------------*/
467/*---------------------------------------------------------------------------*/
468
469void DynamicMesh::
470_checkValidItem(ItemInternal* item)
471{
472 if (!item)
473 ARCANE_FATAL("INTERNAL: DynamicMesh: invalid use of a null entity");
474}
475
476/*---------------------------------------------------------------------------*/
477/*---------------------------------------------------------------------------*/
478
479void DynamicMesh::
480prepareForDump()
481{
483}
484
485/*---------------------------------------------------------------------------*/
486/*---------------------------------------------------------------------------*/
487
488void DynamicMesh::
489reloadMesh()
490{
491 Trace::Setter mci(traceMng(), _className());
492 info() << "Reloading the mesh " << name();
493 m_is_allocated = true;
494 Timer timer(subDomain(), "DynamicMesh::reloadMesh", Timer::TimerReal);
495 {
496 Timer::Sentry sentry(&timer);
498 m_mesh_checker->checkMeshFromReferenceFile();
499 }
500 info() << "Time to reallocate the mesh structures (direct method) (unit: second): "
501 << timer.lastActivationTime();
502}
503
504/*---------------------------------------------------------------------------*/
505/*---------------------------------------------------------------------------*/
506
507void DynamicMesh::
508setCheckLevel(Integer level)
509{
510 m_mesh_checker->setCheckLevel(level);
511}
512
513/*---------------------------------------------------------------------------*/
514/*---------------------------------------------------------------------------*/
515
516Integer DynamicMesh::
517checkLevel() const
518{
519 return m_mesh_checker->checkLevel();
520}
521
522/*---------------------------------------------------------------------------*/
523/*---------------------------------------------------------------------------*/
524
525void DynamicMesh::
526checkValidMesh()
527{
528 if (!m_is_allocated)
529 return;
530 m_mesh_checker->checkValidMesh();
531}
532
533/*---------------------------------------------------------------------------*/
534/*---------------------------------------------------------------------------*/
535
536void DynamicMesh::
537checkValidMeshFull()
538{
539 if (!m_is_allocated)
540 return;
541 m_mesh_checker->checkValidMeshFull();
542}
543
544/*---------------------------------------------------------------------------*/
545/*---------------------------------------------------------------------------*/
546
547void DynamicMesh::
548checkValidConnectivity()
549{
550 m_mesh_checker->checkValidConnectivity();
551}
552
553/*---------------------------------------------------------------------------*/
554/*---------------------------------------------------------------------------*/
555
556void DynamicMesh::
557destroyGroups()
558{
559 for (IItemFamily* family : m_item_families) {
560 family->destroyGroups();
561 }
562}
563
564/*---------------------------------------------------------------------------*/
565/*---------------------------------------------------------------------------*/
566
567ItemGroup DynamicMesh::
568findGroup(const String& name)
569{
570 ItemGroup group;
571 for (IItemFamily* family : m_item_families) {
572 group = family->findGroup(name);
573 if (!group.null())
574 return group;
575 }
576 return group;
577}
578
579/*---------------------------------------------------------------------------*/
580/*---------------------------------------------------------------------------*/
581
582ItemGroup DynamicMesh::
583findGroup(const String& name, eItemKind ik, bool create_if_needed)
584{
585 _checkKindRange(ik);
586 IItemFamily* family = m_item_families[ik];
587 return family->findGroup(name, create_if_needed);
588}
589
590/*---------------------------------------------------------------------------*/
591/*---------------------------------------------------------------------------*/
592
593ItemGroup DynamicMesh::
594createGroup(const String& name, eItemKind ik)
595{
596 _checkKindRange(ik);
597 IItemFamily* family = m_item_families[ik];
598 ARCANE_CHECK_PTR(family);
599 return family->findGroup(name);
600}
601
602/*---------------------------------------------------------------------------*/
603/*---------------------------------------------------------------------------*/
604
605ItemGroup DynamicMesh::
606createGroup(const String& name, const ItemGroup& parent)
607{
608 IItemFamily* family = parent.itemFamily();
609 ARCANE_CHECK_PTR(family);
610 return family->createGroup(name, parent);
611}
612
613/*--------------------------------------------------------------------------*/
614/*--------------------------------------------------------------------------*/
615
616void DynamicMesh::
617_computeSynchronizeInfos()
618{
619 _computeFamilySynchronizeInfos();
620 _computeGroupSynchronizeInfos();
621}
622
623/*--------------------------------------------------------------------------*/
624/*--------------------------------------------------------------------------*/
625
626void DynamicMesh::
627_computeFamilySynchronizeInfos()
628{
629 info() << "Computing family synchronization information for " << name();
630 for (IItemFamily* family : m_item_families) {
631 family->computeSynchronizeInfos();
632 }
633
634 // Writes the topology for mesh synchronization
635 if (!platform::getEnvironmentVariable("ARCANE_DUMP_VARIABLE_SYNCHRONIZER_TOPOLOGY").null()) {
636 auto* var_syncer = cellFamily()->allItemsSynchronizer();
637 Int32 iteration = subDomain()->commonVariables().globalIteration();
638 String file_name = String::format("{0}_sync_topology_iter{1}.json", name(), iteration);
639 mesh_utils::dumpSynchronizerTopologyJSON(var_syncer, file_name);
640 }
641}
642
643/*--------------------------------------------------------------------------*/
644/*--------------------------------------------------------------------------*/
645
646void DynamicMesh::
647_computeGroupSynchronizeInfos()
648{
649 auto action = [](ItemGroup& group) {
650 if (group.hasSynchronizer())
651 group.synchronizer()->compute();
652 };
653
654 info() << "Computing group synchronization information for " << name();
655 meshvisitor::visitGroups(this, action);
656}
657
658/*--------------------------------------------------------------------------*/
659/*--------------------------------------------------------------------------*/
660
662groups()
663{
664 m_all_groups.clear();
665 for (IItemFamily* family : m_item_families) {
666 for (ItemGroupCollection::Enumerator i_group(family->groups()); ++i_group;)
667 m_all_groups.add(*i_group);
668 }
669 return m_all_groups;
670}
671
672/*---------------------------------------------------------------------------*/
673/*---------------------------------------------------------------------------*/
677void DynamicMesh::
678initializeVariables(const XmlNode& init_node)
679{
680 // TEMPORARY: copies the owner() field for each family into
681 // the corresponding variable.
682 for (IItemFamily* family : m_item_families) {
683 VariableItemInt32& items_owner(family->itemsNewOwner());
684 ENUMERATE_ITEM (iitem, family->allItems()) {
685 Item item = *iitem;
686 items_owner[iitem] = item.owner();
687 }
688 }
689
690 ICaseDocumentFragment* doc = subDomain()->caseMng()->caseDocumentFragment();
691 XmlNode root = doc->rootElement();
692 if (root.null())
693 return;
694
695 bool has_error = false;
696 IVariableMng* vm = m_sub_domain->variableMng();
697 XmlNodeList child_list = init_node.children(String("variable"));
698 for (const auto& i : child_list) {
699 String var_name = i.attrValue("nom");
700 IVariable* var = vm->findMeshVariable(this, var_name);
701 if (!var) {
702 error() << "Failed to initialize the variable '" << var_name
703 << "' : no variable with that name exists";
704 has_error = true;
705 continue;
706 }
707 // Does not initialize unused variables.
708 if (!var->isUsed())
709 continue;
710
711 // Tests if the variable has a family. Normally this is always
712 // the case because we used findMeshVariable() to find the variable.
713 IItemFamily* family = var->itemFamily();
714 if (!family) {
715 error() << "Variable '" << var->name() << "' has no family";
716 continue;
717 }
718 String grp_name = i.attrValue("groupe");
719 ItemGroup grp = family->findGroup(grp_name);
720
721 if (grp.null()) {
722 error() << "Failed to initialize the variable '" << var_name
723 << "' on the group `" << grp_name << "' : "
724 << "No group with that name exists for family '" << family->name() << "'\n";
725 has_error = true;
726 continue;
727 }
728 debug() << "Read value variable `" << grp_name
729 << "' `" << var_name << "' " << var;
730 String val_str = i.attrValue("valeur");
731 bool ret = var->initialize(grp, val_str);
732 if (ret) {
733 error() << "Failed to initialized the variable '" << var_name
734 << "' on the group `" << grp_name << "'";
735 has_error = true;
736 continue;
737 }
738 }
739 if (has_error)
740 ARCANE_FATAL("Variables initialization failed");
741}
742
743/*---------------------------------------------------------------------------*/
744/*---------------------------------------------------------------------------*/
745
746// NOTE: This method probably does not work if there are variables
747// partial because the groups they rely on will be destroyed
748// (To be checked)
749
750void DynamicMesh::
751deallocate()
752{
753 if (!m_is_allocated)
754 ARCANE_FATAL("mesh is not allocated");
755
756 clearItems();
758 m_mesh_builder->resetAfterDeallocate();
759
760 m_is_allocated = false;
761 m_mesh_dimension = (-1);
762}
763
764/*---------------------------------------------------------------------------*/
765/*---------------------------------------------------------------------------*/
766
767void DynamicMesh::
768allocateCells(Integer mesh_nb_cell, Int64ConstArrayView cells_infos, bool one_alloc)
769{
770 ARCANE_FATAL_IF(m_is_allocated, "mesh has already been allocated (via endAllocate() or allocateCells())");
771 if (mesh_nb_cell == 0 && !cells_infos.empty())
772 ARCANE_FATAL("Can not dynamically compute the number of cells");
773
774 Trace::Setter mci(traceMng(), _className());
775
776 setEstimatedCells(mesh_nb_cell);
777
778 Timer timer(subDomain(), "AllocateCells", Timer::TimerReal);
779 {
780 Timer::Sentry sentry(&timer);
781 _allocateCells(mesh_nb_cell, cells_infos);
782 if (one_alloc)
783 endAllocate();
784 }
785 info() << "Time to build the mesh structures (indirect method) (unit: second): "
786 << timer.lastActivationTime();
787}
788
789/*---------------------------------------------------------------------------*/
790/*---------------------------------------------------------------------------*/
791
792void DynamicMesh::
793endAllocate()
794{
795 ARCANE_FATAL_IF(m_is_allocated, "mesh has already been allocated (via endAllocate() or allocateCells())");
796
797 Trace::Setter mci(traceMng(), _className());
798
799 _checkDimension(); // HP: add control if endAllocate is called
800 _checkConnectivity(); // without any cell allocation
801
802 bool print_stats = true;
803 ITimeStats* ts = m_sub_domain->timeStats();
805 if (print_stats) {
806 info() << "Begin compute face unique ids";
808 }
809 m_mesh_builder->computeFacesUniqueIds();
810 if (print_stats) {
811 info() << "Begin compute ghost layer";
813 }
814 m_mesh_builder->addGhostLayers(true);
815 if (print_stats) {
816 info() << "Begin compact items";
818 }
819 _allocateCells2(m_mesh_builder);
820
821 if (m_properties->getBool(PROPERTY_COMPACT_AFTER_ALLOCATE))
822 _compactItems(true, false);
823
824 _compactItemInternalReferences();
825 for (IItemFamily* family : m_item_families)
826 family->_internalApi()->endAllocate();
827
828 if (print_stats)
830
831#ifdef ARCANE_DEBUG_DYNAMIC_MESH
832 {
833 String file_name("mesh-end-allocate");
834 if (parallelMng()->isParallel()) {
835 file_name += "-";
836 file_name += m_mesh_rank;
837 }
838 mesh_utils::writeMeshConnectivity(this, file_name);
839 }
840#endif
841
843 m_mesh_checker->checkMeshFromReferenceFile();
844
845 // Positions the owners so that it is like after
846 // an exchange. This is not strictly necessary
847 // but it ensures consistency with
848 // other calls to setOwnersFromCells()
849 if (parallelMng()->isParallel()) {
850 String s = platform::getEnvironmentVariable("ARCANE_CHANGE_OWNER_ON_INIT");
851 if (!s.null()) {
852 info() << "** Set owners from cells";
853 _setOwnersFromCells();
854 }
855 }
856
857 // Notifies the families that the mesh has just been updated
858 // So that they can recalculate the information they want.
859 _notifyEndUpdateForFamilies();
860
862
863 m_is_allocated = true;
864 if (arcaneIsCheck())
866
867 // Displays the statistics of the new mesh
868 {
869 MeshStats ms(traceMng(), this, m_parallel_mng);
870 ms.dumpStats();
871 }
872}
873
874/*---------------------------------------------------------------------------*/
875/*---------------------------------------------------------------------------*/
876
877void DynamicMesh::
878_allocateCells(Integer mesh_nb_cell,
879 Int64ConstArrayView cells_infos,
880 Int32ArrayView cells,
881 bool allow_build_face)
882{
883 Trace::Setter mci(traceMng(), _className());
884 _checkDimension();
885 _checkConnectivity();
886 Int32 rank = meshRank();
887 if (m_use_mesh_item_family_dependencies)
888 m_mesh_builder->addCells3(mesh_nb_cell, cells_infos, rank, cells, allow_build_face);
889 else
890 m_mesh_builder->addCells(mesh_nb_cell, cells_infos, rank, cells, allow_build_face);
891}
892
893/*---------------------------------------------------------------------------*/
894/*---------------------------------------------------------------------------*/
895
896void DynamicMesh::
897addCells(Integer nb_cell,
898 Int64ConstArrayView cells_infos,
899 Int32ArrayView cells)
900{
901 const bool allow_build_face = (m_parallel_mng->commSize() == 1);
902 _allocateCells(nb_cell, cells_infos, cells, allow_build_face);
903}
904
905/*---------------------------------------------------------------------------*/
906/*---------------------------------------------------------------------------*/
907
908void DynamicMesh::
909addCells(const MeshModifierAddCellsArgs& args)
910{
911 bool allow_build_face = args.isAllowBuildFaces();
912 // In parallel, we cannot build faces on the fly
913 // (because it is necessary to generate a uniqueId(), and this ID would not be consistent
914 // between the sub-domains)
915 if (m_parallel_mng->commSize() > 1)
916 allow_build_face = false;
917 _allocateCells(args.nbCell(), args.cellInfos(), args.cellLocalIds(), allow_build_face);
918}
919
920/*---------------------------------------------------------------------------*/
921/*---------------------------------------------------------------------------*/
922
923void DynamicMesh::
924addCells(ISerializer* buffer)
925{
926 _addCells(buffer, 0);
927}
928
929/*---------------------------------------------------------------------------*/
930/*---------------------------------------------------------------------------*/
931
932void DynamicMesh::
933addCells(ISerializer* buffer, Int32Array& cells_local_id)
934{
935 _addCells(buffer, &cells_local_id);
936}
937
938/*---------------------------------------------------------------------------*/
939/*---------------------------------------------------------------------------*/
940
941void DynamicMesh::
942_addCells(ISerializer* buffer, Int32Array* cells_local_id)
943{
944 Trace::Setter mci(traceMng(), _className());
945 _checkDimension();
946 _checkConnectivity();
947 if (!itemFamilyNetwork() ||
948 !(itemFamilyNetwork() && itemFamilyNetwork()->isActivated()) ||
949 !IItemFamilyNetwork::plug_serializer) {
951 ScopedPtrT<IItemFamilySerializer> cell_serializer(m_cell_family->policyMng()->createSerializer());
952 cell_serializer->deserializeItems(buffer, cells_local_id);
953 }
954 else {
955 _deserializeItems(buffer, cells_local_id, m_cell_family);
956 }
957}
958
959/*---------------------------------------------------------------------------*/
960/*---------------------------------------------------------------------------*/
961
962void DynamicMesh::
963allocate(UnstructuredMeshAllocateBuildInfo& build_info)
964{
965 auto* x = build_info._internal();
966 setDimension(x->meshDimension());
967 allocateCells(x->nbCell(), x->cellsInfos(), true);
968}
969
970/*---------------------------------------------------------------------------*/
971/*---------------------------------------------------------------------------*/
972
973void DynamicMesh::
974allocate(CartesianMeshAllocateBuildInfo& build_info)
975{
976 // The allocation of mesh entities is performed by the
977 // DynamicMeshCartesianBuilder class.
978 allocateCartesianMesh(this, build_info);
979}
980
981/*---------------------------------------------------------------------------*/
982/*---------------------------------------------------------------------------*/
983
984void DynamicMesh::
985serializeCells(ISerializer* buffer, Int32ConstArrayView cells_local_id)
986{
987 Trace::Setter mci(traceMng(), _className());
988 _checkDimension();
989 _checkConnectivity();
990 if (!itemFamilyNetwork() ||
991 !(itemFamilyNetwork() && itemFamilyNetwork()->isActivated()) ||
992 !IItemFamilyNetwork::plug_serializer) {
993 ScopedPtrT<IItemFamilySerializer> cell_serializer(m_cell_family->policyMng()->createSerializer());
994 buffer->setMode(ISerializer::ModeReserve);
995 cell_serializer->serializeItems(buffer, cells_local_id);
996 buffer->allocateBuffer();
998 cell_serializer->serializeItems(buffer, cells_local_id);
999 }
1000 else {
1001 _serializeItems(buffer, cells_local_id, m_cell_family);
1002 }
1003}
1004
1005/*---------------------------------------------------------------------------*/
1006/*---------------------------------------------------------------------------*/
1007
1008void DynamicMesh::
1009_serializeItems(ISerializer* buffer, Int32ConstArrayView item_local_ids, IItemFamily* item_family)
1010{
1011 // 1-Get item lids for family and downard dependencies.
1012 // Rk downard relations are not taken here => automatically added in addItems(ItemData) :
1013 // this will change. Todo add relations when addItems has been updated
1014 using FamilyLidMap = std::map<String, Int32UniqueArray>;
1015 FamilyLidMap serialized_items;
1016 serialized_items[item_family->name()] = item_local_ids;
1017 for (const auto& connectivity : mesh()->itemFamilyNetwork()->getChildDependencies(item_family)) {
1018 ENUMERATE_ITEM (item, item_family->view(item_local_ids)) {
1019 auto connectivity_accessor = ConnectivityItemVector{ connectivity };
1020 auto& connected_family_serialized_items = serialized_items[connectivity->targetFamily()->name()];
1021 connected_family_serialized_items.addRange(connectivity_accessor.connectedItems(ItemLocalId(item)).localIds());
1022 }
1023 }
1024 // 2-Serialize each family in the buffer. The order is important: use the family graph from leaves to root
1025 buffer->setMode(ISerializer::ModeReserve);
1026 _fillSerializer(buffer, serialized_items);
1027 buffer->allocateBuffer();
1028 buffer->setMode(ISerializer::ModePut);
1029 _fillSerializer(buffer, serialized_items);
1030}
1031
1032/*---------------------------------------------------------------------------*/
1033/*---------------------------------------------------------------------------*/
1034
1035void DynamicMesh::
1036_deserializeItems(ISerializer* buffer, Int32Array* item_local_ids, IItemFamily* item_family)
1037{
1038 ARCANE_UNUSED(item_family);
1039 buffer->setMode(ISerializer::ModeGet);
1040 mesh()->itemFamilyNetwork()->schedule([item_local_ids, buffer](IItemFamily* family) {
1041 auto family_serializer = std::unique_ptr<IItemFamilySerializer>{ family->policyMng()->createSerializer() }; // todo make_unique (not in 4.7.2...)
1042 family_serializer->deserializeItems(buffer, item_local_ids);
1043 },
1044 IItemFamilyNetwork::InverseTopologicalOrder);
1045 mesh()->itemFamilyNetwork()->schedule([item_local_ids, buffer](IItemFamily* family) {
1046 auto family_serializer = std::unique_ptr<IItemFamilySerializer>{ family->policyMng()->createSerializer() }; // todo make_unique (not in 4.7.2...)
1047 family_serializer->deserializeItemRelations(buffer, item_local_ids);
1048 },
1049 IItemFamilyNetwork::InverseTopologicalOrder);
1050}
1051
1052/*---------------------------------------------------------------------------*/
1053/*---------------------------------------------------------------------------*/
1054
1055void DynamicMesh::
1056_fillSerializer(ISerializer* buffer, std::map<String, Int32UniqueArray>& serialized_items)
1057{
1058 mesh()->itemFamilyNetwork()->schedule([&serialized_items, buffer](IItemFamily* family) {
1059 auto family_serializer = std::unique_ptr<IItemFamilySerializer>{ family->policyMng()->createSerializer() }; // todo make_unique (not in 4.7.2...)
1060 auto& serialized_items_local_ids = serialized_items[family->name()];
1061 family_serializer->serializeItems(buffer, serialized_items_local_ids);
1062 },
1063 IItemFamilyNetwork::InverseTopologicalOrder);
1064 mesh()->itemFamilyNetwork()->schedule([&serialized_items, buffer](IItemFamily* family) {
1065 auto family_serializer = std::unique_ptr<IItemFamilySerializer>{ family->policyMng()->createSerializer() }; // todo make_unique (not in 4.7.2...)
1066 auto& serialized_items_local_ids = serialized_items[family->name()];
1067 family_serializer->serializeItemRelations(buffer, serialized_items_local_ids);
1068 },
1069 IItemFamilyNetwork::InverseTopologicalOrder);
1070}
1071
1072/*---------------------------------------------------------------------------*/
1073/*---------------------------------------------------------------------------*/
1074
1075void DynamicMesh::
1076addParentCells(ItemVectorView& items)
1077{
1078 Trace::Setter mci(traceMng(), _className());
1079 _checkDimension();
1080 _checkConnectivity();
1081 m_mesh_builder->addParentCells(items);
1082}
1083/*---------------------------------------------------------------------------*/
1084/*---------------------------------------------------------------------------*/
1085
1087void DynamicMesh::
1088addHChildrenCells(Cell parent_cell, Integer nb_cell, Int64ConstArrayView cells_infos, Int32ArrayView cells)
1089{
1090 Trace::Setter mci(traceMng(), _className());
1091 _checkDimension();
1092 _checkConnectivity();
1093 bool allow_build_face = false /*(m_parallel_mng->commSize() == 1)*/;
1094 m_mesh_builder->addHChildrenCells(parent_cell, nb_cell, cells_infos, meshRank(), cells, allow_build_face);
1095}
1096
1097/*---------------------------------------------------------------------------*/
1098/*---------------------------------------------------------------------------*/
1099
1100void DynamicMesh::
1101addParentCellToCell(Cell child, Cell parent)
1102{
1103 Trace::Setter mci(traceMng(), _className());
1104 _checkDimension();
1105 _checkConnectivity();
1106
1107 m_cell_family->_addParentCellToCell(child, parent);
1108}
1109
1110/*---------------------------------------------------------------------------*/
1111/*---------------------------------------------------------------------------*/
1112
1113void DynamicMesh::
1114addChildCellToCell(Cell parent, Cell child)
1115{
1116 Trace::Setter mci(traceMng(), _className());
1117 _checkDimension();
1118 _checkConnectivity();
1119
1120 m_cell_family->_addChildCellToCell2(parent, child);
1121}
1122
1123/*---------------------------------------------------------------------------*/
1124/*---------------------------------------------------------------------------*/
1125
1126void DynamicMesh::
1127addParentFaceToFace(Face child, Face parent)
1128{
1129 Trace::Setter mci(traceMng(), _className());
1130 _checkDimension();
1131 _checkConnectivity();
1132
1133 m_face_family->_addParentFaceToFace(parent, child);
1134}
1135
1136/*---------------------------------------------------------------------------*/
1137/*---------------------------------------------------------------------------*/
1138
1139void DynamicMesh::
1140addChildFaceToFace(Face parent, Face child)
1141{
1142 Trace::Setter mci(traceMng(), _className());
1143 _checkDimension();
1144 _checkConnectivity();
1145
1146 m_face_family->_addChildFaceToFace(parent, child);
1147}
1148
1149/*---------------------------------------------------------------------------*/
1150/*---------------------------------------------------------------------------*/
1151
1152void DynamicMesh::
1153addParentNodeToNode(Node child, Node parent)
1154{
1155 Trace::Setter mci(traceMng(), _className());
1156 _checkDimension();
1157 _checkConnectivity();
1158
1159 m_node_family->_addParentNodeToNode(parent, child);
1160}
1161
1162/*---------------------------------------------------------------------------*/
1163/*---------------------------------------------------------------------------*/
1164
1165void DynamicMesh::
1166addChildNodeToNode(Node parent, Node child)
1167{
1168 Trace::Setter mci(traceMng(), _className());
1169 _checkDimension();
1170 _checkConnectivity();
1171
1172 m_node_family->_addChildNodeToNode(parent, child);
1173}
1174
1175/*---------------------------------------------------------------------------*/
1176/*---------------------------------------------------------------------------*/
1177
1178void DynamicMesh::
1179addFaces(Integer nb_face, Int64ConstArrayView face_infos, Int32ArrayView faces)
1180{
1181 _checkDimension();
1182 _checkConnectivity();
1183 Int32 rank = meshRank();
1184 if (m_use_mesh_item_family_dependencies)
1185 m_mesh_builder->addFaces3(nb_face, face_infos, rank, faces);
1186 else
1187 m_mesh_builder->addFaces(nb_face, face_infos, rank, faces);
1188}
1189
1190/*---------------------------------------------------------------------------*/
1191/*---------------------------------------------------------------------------*/
1192
1193void DynamicMesh::
1194addFaces(const MeshModifierAddFacesArgs& args)
1195{
1196 addFaces(args.nbFace(), args.faceInfos(), args.faceLocalIds());
1197}
1198
1199/*---------------------------------------------------------------------------*/
1200/*---------------------------------------------------------------------------*/
1201
1202void DynamicMesh::
1203addEdges(Integer nb_edge, Int64ConstArrayView edge_infos, Int32ArrayView edges)
1204{
1205 _checkDimension();
1206 _checkConnectivity();
1207 Int32 rank = meshRank();
1208 if (m_use_mesh_item_family_dependencies)
1209 m_mesh_builder->addEdges3(nb_edge, edge_infos, rank, edges);
1210 else
1211 m_mesh_builder->addEdges(nb_edge, edge_infos, rank, edges);
1212}
1213
1214/*---------------------------------------------------------------------------*/
1215/*---------------------------------------------------------------------------*/
1216
1217void DynamicMesh::
1218addNodes(Int64ConstArrayView nodes_uid, Int32ArrayView nodes)
1219{
1220 _checkDimension();
1221 _checkConnectivity();
1222 Int32 rank = meshRank();
1223 if (m_use_mesh_item_family_dependencies)
1224 m_mesh_builder->addNodes2(nodes_uid, rank, nodes);
1225 else
1226 m_mesh_builder->addNodes(nodes_uid, rank, nodes);
1227}
1228
1229/*---------------------------------------------------------------------------*/
1230/*---------------------------------------------------------------------------*/
1231
1232void DynamicMesh::
1233removeCells(Int32ConstArrayView cells_local_id, bool update_graph)
1234{
1235 ARCANE_UNUSED(update_graph);
1236 Trace::Setter mci(traceMng(), _className());
1237 if (m_use_mesh_item_family_dependencies)
1238 removeItems(m_cell_family, cells_local_id);
1239 else
1240 m_cell_family->internalRemoveItems(cells_local_id);
1241
1242 if (m_item_family_network) {
1243 m_item_family_network->removeConnectedDoFsFromCells(cells_local_id);
1244 }
1245}
1246
1247/*---------------------------------------------------------------------------*/
1248/*---------------------------------------------------------------------------*/
1249
1250void DynamicMesh::
1251removeItems(IItemFamily* item_family, Int32ConstArrayView cells_local_id)
1252{
1253 ARCANE_UNUSED(item_family);
1254 ARCANE_ASSERT((itemFamilyNetwork()), ("Cannot call DynamicMesh::removeItems if no ItemFamilyNetwork available"))
1255
1256 if (cells_local_id.empty())
1257 return;
1258
1259 // Create item info (to remove items)
1260 ItemDataList item_data_list;
1261 ItemData& cell_data = item_data_list.itemData(Integer(m_cell_family->itemKind()),
1262 cells_local_id.size(), cells_local_id.size(), Int32ArrayView(),
1263 m_cell_family, (IItemFamilyModifier*)(m_cell_family), m_parallel_mng->commRank());
1264 Integer i(0);
1265 for (auto local_id : cells_local_id) {
1266 // TODO Find a better place in ItemData to put removed item lids (with Int32...) .
1267 cell_data.itemInfos()[i++] = (Int64)local_id;
1268 }
1269 itemFamilyNetwork()->schedule([&item_data_list](IItemFamily* family) {
1270 // send the whole ItemDataList since removed items are to be added for child families
1271 family->removeItems2(item_data_list);
1272 },
1273 IItemFamilyNetwork::TopologicalOrder); // item destruction done from root to leaves
1274}
1275
1276/*---------------------------------------------------------------------------*/
1277/*---------------------------------------------------------------------------*/
1278
1279void DynamicMesh::
1280detachCells(Int32ConstArrayView cells_local_id)
1281{
1282 Trace::Setter mci(traceMng(), _className());
1283 if (m_use_mesh_item_family_dependencies)
1284 m_cell_family->detachCells2(cells_local_id);
1285 else {
1286 ItemInternalList cells = m_cell_family->itemsInternal();
1287 for (Integer i = 0, is = cells_local_id.size(); i < is; ++i)
1288 m_cell_family->detachCell(cells[cells_local_id[i]]);
1289 }
1290}
1291
1292/*---------------------------------------------------------------------------*/
1293/*---------------------------------------------------------------------------*/
1294
1295void DynamicMesh::
1296removeDetachedCells(Int32ConstArrayView cells_local_id)
1297{
1298 Trace::Setter mci(traceMng(), _className());
1299 if (m_use_mesh_item_family_dependencies)
1300 removeItems(m_cell_family, cells_local_id);
1301 else {
1302 ItemInternalList cells = m_cell_family->itemsInternal();
1303 for (Integer i = 0, is = cells_local_id.size(); i < is; ++i)
1304 m_cell_family->removeDetachedCell(cells[cells_local_id[i]]);
1305 }
1306}
1307
1308/*---------------------------------------------------------------------------*/
1309/*---------------------------------------------------------------------------*/
1310
1312void DynamicMesh::
1313flagCellToRefine(Int32ConstArrayView lids)
1314{
1315 Trace::Setter mci(traceMng(), _className());
1316 _checkAMR();
1317 m_mesh_refinement->flagCellToRefine(lids);
1318}
1319
1320/*---------------------------------------------------------------------------*/
1321/*---------------------------------------------------------------------------*/
1322
1323void DynamicMesh::
1324flagCellToCoarsen(Int32ConstArrayView lids)
1325{
1326 Trace::Setter mci(traceMng(), _className());
1327 _checkAMR();
1328 m_mesh_refinement->flagCellToCoarsen(lids);
1329}
1330
1331/*---------------------------------------------------------------------------*/
1332/*---------------------------------------------------------------------------*/
1333
1334void DynamicMesh::
1335refineItems()
1336{
1337 Trace::Setter mci(traceMng(), _className());
1338 _checkDimension();
1339 _checkConnectivity();
1340 _checkAMR();
1341 m_mesh_refinement->refineItems(true);
1342}
1343/*---------------------------------------------------------------------------*/
1344/*---------------------------------------------------------------------------*/
1345
1346void DynamicMesh::
1347coarsenItems()
1348{
1349 Trace::Setter mci(traceMng(), _className());
1350 _checkDimension();
1351 _checkConnectivity();
1352 _checkAMR();
1353 m_mesh_refinement->coarsenItems(true);
1354}
1355
1356/*---------------------------------------------------------------------------*/
1357/*---------------------------------------------------------------------------*/
1358
1359void DynamicMesh::
1360coarsenItemsV2(bool update_parent_flag)
1361{
1362 Trace::Setter mci(traceMng(), _className());
1363 _checkDimension();
1364 _checkConnectivity();
1365 _checkAMR();
1366 if (m_amr_type != eMeshAMRKind::Cell) {
1367 ARCANE_FATAL("This method is not compatible with Cartesian Mesh Patch AMR");
1368 }
1369 m_mesh_refinement->coarsenItemsV2(update_parent_flag);
1370}
1371
1372/*---------------------------------------------------------------------------*/
1373/*---------------------------------------------------------------------------*/
1374
1375bool DynamicMesh::
1376adapt()
1377{
1378 Trace::Setter mci(traceMng(), _className());
1379 _checkDimension();
1380 _checkConnectivity();
1381 _checkAMR();
1382 if (m_mesh_refinement->needUpdate())
1383 m_mesh_refinement->update();
1384 return m_mesh_refinement->refineAndCoarsenItems(true);
1385}
1386
1387/*---------------------------------------------------------------------------*/
1388/*---------------------------------------------------------------------------*/
1389
1390void DynamicMesh::
1391compact()
1392{
1393 _compactItems(false, true);
1394}
1395
1396/*---------------------------------------------------------------------------*/
1397/*---------------------------------------------------------------------------*/
1398
1399void DynamicMesh::
1400registerCallBack(IAMRTransportFunctor* f)
1401{
1402 Trace::Setter mci(traceMng(), _className());
1403 _checkAMR();
1404 m_mesh_refinement->registerCallBack(f);
1405}
1406/*---------------------------------------------------------------------------*/
1407/*---------------------------------------------------------------------------*/
1408
1409void DynamicMesh::
1410unRegisterCallBack(IAMRTransportFunctor* f)
1411{
1412 Trace::Setter mci(traceMng(), _className());
1413 _checkAMR();
1414 m_mesh_refinement->unRegisterCallBack(f);
1415}
1416
1417/*---------------------------------------------------------------------------*/
1418/*---------------------------------------------------------------------------*/
1419
1420void DynamicMesh::
1421_allocateCells2(DynamicMeshIncrementalBuilder* mib)
1422{
1423 Trace::Setter mci(traceMng(), _className());
1424
1425 _finalizeMeshChanged();
1426
1427 mib->printInfos();
1428
1429#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1430 OCStringStream ostr;
1431 _printMesh(ostr());
1432 info() << ostr.str();
1433#endif
1434}
1435
1436/*---------------------------------------------------------------------------*/
1437/*---------------------------------------------------------------------------*/
1438
1439void DynamicMesh::
1440_writeMesh(const String& base_name)
1441{
1442 StringBuilder file_name(base_name);
1443 file_name += "-";
1444 IParallelMng* pm = m_parallel_mng;
1445 bool is_parallel = pm->isParallel();
1446 Int32 rank = meshRank();
1447 if (is_parallel) {
1448 file_name += subDomain()->commonVariables().globalIteration();
1449 file_name += "-";
1450 file_name += rank;
1451 }
1452 mesh_utils::writeMeshConnectivity(this, file_name.toString());
1453 //TODO ability to change the service name
1454 auto writer(ServiceBuilder<IMeshWriter>::createReference(subDomain(), "Lima"));
1455 if (writer.get()) {
1456 String mesh_file_name = file_name.toString() + ".mli";
1457 writer->writeMeshToFile(this, mesh_file_name);
1458 }
1459}
1460
1461/*---------------------------------------------------------------------------*/
1462/*---------------------------------------------------------------------------*/
1463
1464void DynamicMesh::
1465_printMesh(std::ostream& ostr)
1466{
1467 ostr << "----------- Mesh\n";
1468 ostr << " Nodes: " << nbNode() << '\n';
1469 ostr << " Edges: " << nbEdge() << '\n';
1470 ostr << " Faces: " << nbFace() << '\n';
1471 ostr << " Cells: " << nbCell() << '\n';
1472 mesh_utils::printItems(ostr, "Nodes", allNodes());
1473 mesh_utils::printItems(ostr, "Edges", allEdges());
1474 mesh_utils::printItems(ostr, "Faces", allFaces());
1475 mesh_utils::printItems(ostr, "Cells", allCells());
1476}
1477
1478/*---------------------------------------------------------------------------*/
1479/*---------------------------------------------------------------------------*/
1483void DynamicMesh::
1484_saveProperties()
1485{
1486 info(4) << "DynamicMesh::_saveProperties() name=" << name()
1487 << " nb-ghost=" << ghostLayerMng()->nbGhostLayer();
1488
1489 auto p = m_properties;
1490 p->setInt32("nb-ghostlayer", ghostLayerMng()->nbGhostLayer());
1491 p->setInt32("ghostlayer-builder-version", ghostLayerMng()->builderVersion());
1492 p->setInt32("part-info-part-rank", m_mesh_part_info.partRank());
1493 p->setInt32("part-info-nb-part", m_mesh_part_info.nbPart());
1494 p->setInt32("part-info-replication-rank", m_mesh_part_info.replicationRank());
1495 p->setInt32("part-info-nb-replication", m_mesh_part_info.nbReplication());
1496 p->setBool("has-itemsharedinfo-variables", true);
1497 p->setInt64("mesh-timestamp", m_timestamp);
1498 if (!m_do_not_save_need_compact)
1499 p->setBool("need-compact", m_need_compact);
1500}
1501
1502/*---------------------------------------------------------------------------*/
1503/*---------------------------------------------------------------------------*/
1507void DynamicMesh::
1508_loadProperties()
1509{
1510 auto p = m_properties;
1511
1512 info(4) << "DynamicMesh::_readProperties() name=" << name()
1513 << " mesh-version=" << p->getInt32WithDefault(PROPERTY_MESH_VERSION, -1);
1514
1515 {
1516 // Reloads info on the ghost layer manager.
1517 Int32 x = 0;
1518 if (p->get("nb-ghostlayer", x))
1519 ghostLayerMng()->setNbGhostLayer(x);
1520 if (p->get("ghostlayer-builder-version", x))
1521 ghostLayerMng()->setBuilderVersion(x);
1522 if (p->get("part-info-part-rank", x))
1523 m_mesh_part_info.setPartRank(x);
1524 if (p->get("part-info-nb-part", x))
1525 m_mesh_part_info.setNbPart(x);
1526 if (p->get("part-info-replication-rank", x))
1527 m_mesh_part_info.setReplicationRank(x);
1528 if (p->get("part-info-nb-replication", x))
1529 m_mesh_part_info.setNbReplication(x);
1530 if (!m_do_not_save_need_compact) {
1531 bool xb = false;
1532 if (p->get("need-compact", xb))
1533 m_need_compact = xb;
1534 }
1535 Int64 x2 = 0;
1536 if (p->get("mesh-timestamp", x2))
1537 m_timestamp = x2;
1538 }
1539}
1540
1541/*---------------------------------------------------------------------------*/
1542/*---------------------------------------------------------------------------*/
1546void DynamicMesh::
1547_prepareForDump()
1548{
1549 bool want_dump = m_properties->getBool(PROPERTY_DUMP);
1550 info(4) << "DynamicMesh::prepareForDump() name=" << name()
1551 << " need_compact?=" << m_need_compact
1552 << " want_dump?=" << want_dump
1553 << " timestamp=" << m_timestamp;
1554
1555 {
1557 m_mesh_events.eventObservable(t).notify(MeshEventArgs(this, t));
1558 }
1559
1560 // If the mesh is not saved, do nothing. This prevents compacting
1561 // and sorting the mesh, which is undesirable if the properties
1562 // 'sort' and 'compact' are set to 'false'.
1563 if (want_dump)
1565
1566 // Save properties. This must be done at the end because the call to
1567 // prepareForDumpReal() might modify these properties
1569
1570 {
1572 m_mesh_events.eventObservable(t).notify(MeshEventArgs(this, t));
1573 }
1574}
1575
1576/*---------------------------------------------------------------------------*/
1577/*---------------------------------------------------------------------------*/
1581void DynamicMesh::
1582_prepareForDumpReal()
1583{
1584 if (m_need_compact) {
1585 // For now, the entities must be sorted and compacted
1586 // before a save
1587 _compactItems(true, true);
1588 }
1589
1590 // Preparation of mesh/sub-mesh connections
1591 {
1592 if (m_parent_mesh) {
1593 ARCANE_ASSERT((m_parent_group != NULL), ("Unexpected NULL parent group"));
1594 m_parent_mesh_name = m_parent_mesh->name();
1595 m_parent_group_name = m_parent_group->name();
1596 }
1597 else {
1598 ARCANE_ASSERT((m_parent_group == NULL), ("Unexpected non-NULL parent group"));
1601 }
1602 const Integer n_sub_mesh = m_child_meshes.size();
1603 m_child_meshes_name.resize(n_sub_mesh);
1604 for (Integer i = 0; i < n_sub_mesh; ++i)
1605 m_child_meshes_name[i] = m_child_meshes[i]->name();
1606 }
1607
1608 // Save info on entity families
1609 {
1610 Integer nb_item_family = m_item_families.count();
1611 m_item_families_name.resize(nb_item_family);
1612 m_item_families_kind.resize(nb_item_family);
1613 Integer index = 0;
1614 for (IItemFamily* family : m_item_families) {
1615 m_item_families_kind[index] = family->itemKind();
1616 m_item_families_name[index] = family->name();
1617 ++index;
1618 }
1619 }
1620
1621 for (IItemFamily* family : m_item_families) {
1622 family->prepareForDump();
1623 }
1624
1625 if (m_tied_interface_need_prepare_dump) {
1626 m_tied_interface_mng->prepareTiedInterfacesForDump();
1627 m_tied_interface_need_prepare_dump = false;
1628 }
1629}
1630
1631/*---------------------------------------------------------------------------*/
1632/*---------------------------------------------------------------------------*/
1633
1634IItemFamily* DynamicMesh::
1635createItemFamily(eItemKind ik, const String& name)
1636{
1637 IItemFamily* xfamily = findItemFamily(ik, name, false, false);
1638 if (xfamily)
1639 ARCANE_FATAL("Attempting to create a family that already exists '{0}'", name);
1640
1641 debug() << "Creating the entities family "
1642 << " name=" << name
1643 << " kind=" << itemKindName(ik);
1644 ItemFamily* family = _createNewFamily(ik, name);
1645
1646 _addFamily(family);
1647 _buildAndInitFamily(family);
1648
1649 return family;
1650}
1651
1652/*---------------------------------------------------------------------------*/
1653/*---------------------------------------------------------------------------*/
1654
1655ItemFamily* DynamicMesh::
1656_createNewFamily(eItemKind kind, const String& name)
1657{
1658 switch (kind) {
1659 case IK_Node:
1660 return new NodeFamily(this, name);
1661 case IK_Edge:
1662 return new EdgeFamily(this, name);
1663 case IK_Face:
1664 return new FaceFamily(this, name);
1665 case IK_Cell:
1666 return new CellFamily(this, name);
1667 case IK_Particle:
1668 return new ParticleFamily(this, name);
1669 case IK_DoF:
1670 return new DoFFamily(this, name);
1671 case IK_Unknown:
1672 ARCANE_FATAL("Attempting to create an ItemFamily with an unknown item kind.");
1673 }
1674 ARCANE_FATAL("Invalid ItemKind");
1675}
1676
1677/*---------------------------------------------------------------------------*/
1678/*---------------------------------------------------------------------------*/
1679
1680IItemFamilyPolicyMng* DynamicMesh::
1681_createFamilyPolicyMng(ItemFamily* family)
1682{
1683 eItemKind kind = family->itemKind();
1684 switch (kind) {
1685 case IK_Node:
1686 return createNodeFamilyPolicyMng(family);
1687 case IK_Edge:
1688 return createEdgeFamilyPolicyMng(family);
1689 case IK_Face:
1690 return createFaceFamilyPolicyMng(family);
1691 case IK_Cell:
1692 return createCellFamilyPolicyMng(family);
1693 case IK_Particle:
1694 return createParticleFamilyPolicyMng(family);
1695 case IK_DoF:
1696 return createDoFFamilyPolicyMng(family);
1697 case IK_Unknown:
1698 ARCANE_FATAL("Attempting to create an ItemFamily with an unknown item kind.");
1699 }
1700 ARCANE_FATAL("Invalid ItemKind");
1701}
1702
1703/*---------------------------------------------------------------------------*/
1704/*---------------------------------------------------------------------------*/
1705
1706void DynamicMesh::
1707_buildAndInitFamily(IItemFamily* family)
1708{
1709 family->build();
1710 ItemFamily* true_family = ARCANE_CHECK_POINTER(dynamic_cast<ItemFamily*>(family));
1711 IItemFamilyPolicyMng* policy_mng = _createFamilyPolicyMng(true_family);
1712 true_family->setPolicyMng(policy_mng);
1713}
1714
1715/*---------------------------------------------------------------------------*/
1716/*---------------------------------------------------------------------------*/
1717
1718void DynamicMesh::
1719_addFamily(ItemFamily* family)
1720{
1721 m_item_families.add(family);
1722 m_true_item_families.add(family);
1723}
1724
1725/*---------------------------------------------------------------------------*/
1726/*---------------------------------------------------------------------------*/
1727
1728IItemFamily* DynamicMesh::
1729findItemFamily(eItemKind ik, const String& name, bool create_if_needed,
1730 bool register_modifier_if_created)
1731{
1732 for (IItemFamily* family : m_item_families)
1733 if (family->name() == name && family->itemKind() == ik)
1734 return family;
1735 if (create_if_needed) {
1736 IItemFamily* family = createItemFamily(ik, name);
1737 if (register_modifier_if_created) {
1738 IItemFamilyModifier* modifier = dynamic_cast<IItemFamilyModifier*>(family);
1739 if (modifier)
1740 m_family_modifiers.add(modifier);
1741 }
1742 return family;
1743 }
1744 return nullptr;
1745}
1746
1747/*---------------------------------------------------------------------------*/
1748/*---------------------------------------------------------------------------*/
1749
1750IItemFamily* DynamicMesh::
1751findItemFamily(const String& name, bool throw_exception)
1752{
1753 for (IItemFamily* family : m_item_families)
1754 if (family->name() == name)
1755 return family;
1756 if (throw_exception)
1757 ARCANE_FATAL("No family with name '{0}' exist", name);
1758 return nullptr;
1759}
1760
1761/*---------------------------------------------------------------------------*/
1762/*---------------------------------------------------------------------------*/
1763
1765findItemFamilyModifier(eItemKind ik, const String& name)
1766{
1767 IItemFamily* family = findItemFamily(ik, name, false, false);
1768 if (!family)
1769 return nullptr;
1770 for (IItemFamilyModifier* modifier : m_family_modifiers)
1771 if (modifier->family() == family)
1772 return modifier;
1773 return nullptr;
1774}
1775
1776/*---------------------------------------------------------------------------*/
1777/*---------------------------------------------------------------------------*/
1778
1779void DynamicMesh::
1780_exchangeItems(bool do_compact)
1781{
1782 String nb_exchange_str = platform::getEnvironmentVariable("ARCANE_NB_EXCHANGE");
1783 // It would be necessary to calculate the default value taking into account the number
1784 // of exchanged meshes and the number of variables and their memory usage. Be careful that all procs use the same value.
1785 // In practice, it is better not to exceed 3 or 4 exchanges because this
1786 // increases the time consumed and does not reduce memory enough.
1787 Integer nb_exchange = 1;
1788 if (!nb_exchange_str.null()) {
1789 bool is_bad = builtInGetValue(nb_exchange, nb_exchange_str);
1790 if (is_bad)
1791 nb_exchange = 1;
1792 }
1793 String exchange_version_str = platform::getEnvironmentVariable("ARCANE_MESH_EXCHANGE_VERSION");
1794 Integer exchange_version = 1;
1795 if (!exchange_version_str.null()) {
1796 builtInGetValue(exchange_version, exchange_version_str);
1797 }
1798
1799 info() << "DynamicMesh::_echangeItems() do_compact?=" << do_compact
1800 << " nb_exchange=" << nb_exchange << " version=" << exchange_version;
1801
1802 if (nb_exchange > 1) {
1803 _multipleExchangeItems(nb_exchange, exchange_version, do_compact);
1804 }
1805 else
1806 _exchangeItemsNew();
1807 // Currently, the exchangeItemsNew() method only takes into account
1808 // one layer of ghost meshes. If we request more, we must
1809 // add them now. This call is not optimal but allows
1810 // for correctly processing all cases (I hope).
1811 if (ghostLayerMng()->nbGhostLayer() > 1 && !m_use_mesh_item_family_dependencies) // many ghost already handled in MeshExchange with ItemFamilyNetwork
1812 updateGhostLayers(true);
1813 String check_exchange = platform::getEnvironmentVariable("ARCANE_CHECK_EXCHANGE");
1814 if (!check_exchange.null()) {
1815 m_mesh_checker->checkGhostCells();
1816 pwarning() << "CHECKING SYNCHRONISATION !";
1817 m_mesh_checker->checkVariablesSynchronization();
1818 m_mesh_checker->checkItemGroupsSynchronization();
1819 }
1820 if (checkLevel() >= 2)
1821 m_mesh_checker->checkValidMesh();
1822 else if (checkLevel() >= 1)
1823 m_mesh_checker->checkValidConnectivity();
1824}
1825
1826/*---------------------------------------------------------------------------*/
1827/*---------------------------------------------------------------------------*/
1857void DynamicMesh::
1858_multipleExchangeItems(Integer nb_exchange, Integer version, bool do_compact)
1859{
1860 if (version < 1 || version > 2)
1861 ARCANE_FATAL("Invalid value '{0}' for version. Valid values are 1 or 2", version);
1862
1863 info() << "** ** MULTIPLE EXCHANGE ITEM version=" << version << " nb_exchange=" << nb_exchange;
1864 UniqueArray<UniqueArray<Int32>> cells_to_exchange_new_owner(nb_exchange);
1865 // We must store the uid because after load balancing the localIds will change
1866 UniqueArray<UniqueArray<Int64>> cells_to_exchange_uid(nb_exchange);
1867
1868 IItemFamily* cell_family = cellFamily();
1869 VariableItemInt32& cells_new_owner = cell_family->itemsNewOwner();
1870
1871 Integer nb_cell = ownCells().size();
1872 ENUMERATE_CELL (icell, ownCells()) {
1873 Cell cell = *icell;
1874 Int32 current_owner = cell.owner();
1875 Int32 new_owner = cells_new_owner[icell];
1876 if (current_owner == new_owner)
1877 continue;
1878 Integer phase = 0;
1879 if (version == 2)
1880 phase = (new_owner % nb_exchange);
1881 else if (version == 1)
1882 phase = icell.index() / nb_cell;
1883 cells_to_exchange_new_owner[phase].add(new_owner);
1884 cells_to_exchange_uid[phase].add(cell.uniqueId().asInt64());
1885 }
1886
1887 // Sets it as if the mesh did not change owner to
1888 ENUMERATE_CELL (icell, ownCells()) {
1889 Cell cell = *icell;
1890 cells_new_owner[icell] = cell.owner();
1891 }
1892
1893 // From here, cells_new_owner is identical to cell.owner()
1894 // for each mesh.
1895 Int32UniqueArray uids_to_lids;
1896 for (Integer i = 0; i < nb_exchange; ++i) {
1897 Int32ConstArrayView new_owners = cells_to_exchange_new_owner[i];
1898 Int64ConstArrayView new_uids = cells_to_exchange_uid[i];
1899 Integer nb_cell = new_uids.size();
1900 info() << "MultipleExchange current_exchange=" << i << " nb_cell=" << nb_cell;
1901 uids_to_lids.resize(nb_cell);
1902 cell_family->itemsUniqueIdToLocalId(uids_to_lids, new_uids);
1903 ItemInternalList cells = cell_family->itemsInternal();
1904 // For each mesh in the current exchange part, sets the new_owner
1905 // to the correct value
1906 for (Integer z = 0; z < nb_cell; ++z)
1907 cells_new_owner[cells[uids_to_lids[z]]] = new_owners[z];
1908 cells_new_owner.synchronize();
1909 mesh()->utilities()->changeOwnersFromCells();
1910 _exchangeItemsNew();
1911 }
1912
1913 if (do_compact) {
1914 Timer::Action ts_action1(m_sub_domain, "CompactItems", true);
1915 bool do_sort = m_properties->getBool(PROPERTY_SORT);
1916 _compactItems(do_sort, true);
1917 }
1918}
1919
1920/*---------------------------------------------------------------------------*/
1921/*---------------------------------------------------------------------------*/
1922
1923void DynamicMesh::
1924exchangeItems()
1925{
1926 _exchangeItems(m_properties->getBool(PROPERTY_COMPACT));
1927}
1928
1929/*---------------------------------------------------------------------------*/
1930/*---------------------------------------------------------------------------*/
1931
1932void DynamicMesh::
1933clearItems()
1934{
1935 for (IItemFamily* family : m_item_families)
1936 family->clearItems();
1937 endUpdate();
1938}
1939
1940/*---------------------------------------------------------------------------*/
1941/*---------------------------------------------------------------------------*/
1942#if 0
1943class ItemsExchangeInfo2List
1944 : public UniqueArray<ItemsExchangeInfo2*>
1945{
1946public:
1947 ~ItemsExchangeInfo2List()
1948 {
1949 for( Integer i=0, is=size(); i<is; ++i ){
1950 ItemsExchangeInfo2* info = this->operator[](i);
1951 delete info;
1952 }
1953 clear();
1954 }
1955};
1956#endif
1957
1958/*---------------------------------------------------------------------------*/
1959/*---------------------------------------------------------------------------*/
1960
1961void DynamicMesh::
1962_exchangeItemsNew()
1963{
1964 // The algorithm used here is not recursive with submeshes.
1965 // All communications are grouped and the different levels of modifications
1966 // will be popped here. This implementation does not allow having
1967 // more than one submesh level per mesh.
1968
1969 Trace::Setter mci(traceMng(), _className());
1970
1971 if (!m_is_dynamic)
1972 ARCANE_FATAL("property isDynamic() has to be 'true'");
1973
1974 m_need_compact = true;
1975
1976 if (arcane_debug_load_balancing) {
1977 // TODO: do this in the MeshExchanger and by family.
1978 // Checks that the variables are properly synchronized
1979 m_node_family->itemsNewOwner().checkIfSync(10);
1980 m_edge_family->itemsNewOwner().checkIfSync(10);
1981 m_face_family->itemsNewOwner().checkIfSync(10);
1982 m_cell_family->itemsNewOwner().checkIfSync(10);
1983 }
1984 // TODO: Check that everyone has the same families and in the same order.
1985
1986 // Cascades all meshes associated with this mesh
1987 typedef Collection<DynamicMesh*> DynamicMeshCollection;
1988 DynamicMeshCollection all_cascade_meshes = List<DynamicMesh*>();
1989 all_cascade_meshes.add(this);
1990 for (Integer i = 0; i < m_child_meshes.size(); ++i)
1991 all_cascade_meshes.add(m_child_meshes[i]);
1992
1993 IMeshExchanger* iexchanger = m_mesh_exchange_mng->beginExchange();
1994 MeshExchanger* mesh_exchanger = ARCANE_CHECK_POINTER(dynamic_cast<MeshExchanger*>(iexchanger));
1995
1996 // If there are no entities to exchange, the exchange stops immediately.
1997 if (mesh_exchanger->computeExchangeInfos()) {
1998 info() << "No load balance is performed";
1999 m_mesh_exchange_mng->endExchange();
2000 return;
2001 }
2002
2003 // Performs the info exchange
2004 mesh_exchanger->processExchange();
2005
2006 // Removes entities that should no longer be in our sub-domain.
2007 mesh_exchanger->removeNeededItems();
2008
2009 // Readjusts the groups by removing entities that are no longer in the mesh or by
2010 // invalidating the calculated groups.
2011 // TODO: make a method in the family that does this.
2012 {
2013 auto action = [](ItemGroup& group) {
2014 // (HP) TODO: 'if (group.internal()->hasComputeFunctor())' does not work simply, why ?
2015 // Formerly: if (group.isLocalToSubDomain() || group.isOwn())
2016 // Redundant with ItemFamily::notifyItemsOwnerChanged calculations
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 // Removes potential ghost items remaining after updating the support group
2028 // which were marked by NeedRemove (which cleans up a potential inconsistent state of the
2029 // submesh relative to its parent)
2030 // This part is important because it is possible that updating the groups
2031 // is not enough to update the ghost parts of the submeshes
2032 // (unless a stronger constraint is placed on the group to also include all
2033 // ghost meshes of the submesh)
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 // Allocates the entities we received from other sub-domains.
2043 mesh_exchanger->allocateReceivedItems();
2044
2045 // We now resume a standard endUpdate cycle
2046 // but interleaving the submesh levels
2047 for (DynamicMesh* mesh : all_cascade_meshes)
2048 mesh->_internalEndUpdateInit(true);
2049
2050 mesh_exchanger->updateItemGroups();
2051
2052 // Recalculates synchronizers on groups.
2053 for (DynamicMesh* mesh : all_cascade_meshes)
2054 mesh->_computeGroupSynchronizeInfos();
2055
2056 // Updates the variable values of the received entities
2057 mesh_exchanger->updateVariables();
2058
2059 // Finalizes the modifications whose sorting and compaction
2060 for (DynamicMesh* mesh : all_cascade_meshes) {
2061 // Requests the display of info for the current mesh
2062 bool print_info = (mesh == this);
2063 mesh->_internalEndUpdateFinal(print_info);
2064 }
2065
2066 // Finalizes the exchanges
2067 // For now, this is only useful for TiedInterface but it
2068 // should be removed.
2069 mesh_exchanger->finalizeExchange();
2070
2071 // TODO: ensure this call in case of an exception.
2072 m_mesh_exchange_mng->endExchange();
2073
2074 // Now, the mesh is updated but the extraordinary ghost meshes
2075 // have been potentially removed. We replace them in the mesh.
2076 // Non-optimized version. Ideally, extraordinary meshes
2077 // should be managed in MeshExchange.
2078 // endUpdate() must be called in all cases to ensure
2079 // that the variables and groups are properly sized.
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 // Removal of ghost meshes.
2149 // We must use an intermediate array, because deleting
2150 // meshes invalidates the iterators on '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 // Readjusts the groups by removing entities that are no longer in the mesh
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 // Finalization of recursive submeshes
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 // Removal of meshes
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 // Readjusts the groups by removing entities that are no longer in the mesh
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 // Removal of cells
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 // Readjust groups by removing entities that are no longer in the mesh
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 // In case of refinement/coarsening, the orientation might be invalid at a point.
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 // From here, all mesh entities are known. It
2314 // is therefore possible to compact them if necessary
2315 m_mesh_builder->printStats();
2316 CHECKPERF(m_perf_counter.stop(PerfCounter::UPGHOSTLAYER1))
2317
2318 CHECKPERF(m_perf_counter.start(PerfCounter::UPGHOSTLAYER2))
2319 //_finalizeMeshChanged();
2320 {
2321 ++m_timestamp;
2322 for (IItemFamily* family : m_item_families)
2323 family->endUpdate();
2324 }
2325 CHECKPERF(m_perf_counter.stop(PerfCounter::UPGHOSTLAYER2))
2326
2327 // Reallocate mesh variables because their group has changed
2328 // TODO: this should be done for every family
2329 CHECKPERF(m_perf_counter.start(PerfCounter::UPGHOSTLAYER3))
2330 {
2331 IVariableMng* vm = m_sub_domain->variableMng();
2332 VariableCollection used_vars(vm->usedVariables());
2333 used_vars.each(std::mem_fn(&IVariable::resizeFromGroup));
2334 }
2335 CHECKPERF(m_perf_counter.stop(PerfCounter::UPGHOSTLAYER3))
2336
2337 // Recalculate the necessary information for the synchronization
2338 // of
2339 // entities
2340 //pm->computeSynchronizeInfos();
2341 CHECKPERF(m_perf_counter.start(PerfCounter::UPGHOSTLAYER4))
2343 _synchronizeGroupsAndVariables();
2344 CHECKPERF(m_perf_counter.stop(PerfCounter::UPGHOSTLAYER4))
2345
2346 //Loop of new refine ghost
2347 CHECKPERF(m_perf_counter.start(PerfCounter::UPGHOSTLAYER5))
2348 UniqueArray<Integer> ghost_cell_to_refine_lid(ghost_cell_to_refine_uid.size());
2349 m_cell_family->itemsUniqueIdToLocalId(ghost_cell_to_refine_lid, ghost_cell_to_refine_uid, true);
2350 ItemInternalList cells = m_cell_family->itemsInternal();
2351 for (Integer e = 0, i_size = ghost_cell_to_refine_lid.size(); e != i_size; ++e) {
2352 Cell i_hParent_cell(cells[ghost_cell_to_refine_lid[e]]);
2353 m_mesh_refinement->populateBackFrontCellsFromParentFaces(i_hParent_cell);
2354
2355 //need to populate also the new own cell connected to the new ghost
2356 Integer nb_face = i_hParent_cell.nbFace();
2357 Integer lid = i_hParent_cell.localId();
2358 for (Integer iface = 0; iface < nb_face; ++iface) {
2359 Face face = i_hParent_cell.face(iface);
2360 Integer nb_cell = face.nbCell();
2361 for (Integer icell = 0; icell < nb_cell; ++icell) {
2362 Cell cell = face.cell(icell);
2363 if ((cell.localId() != lid) && (cell.isOwn())) {
2365 m_face_family->familyTree(childs, cell, false);
2366 for (Integer i = 0, nchilds = childs.size(); i < nchilds; ++i) {
2367 ItemInternal* child = childs[i];
2368 if (child->isAncestor())
2369 m_mesh_refinement->populateBackFrontCellsFromParentFaces(child);
2370 }
2371 }
2372 }
2373 }
2374 }
2375 CHECKPERF(m_perf_counter.stop(PerfCounter::UPGHOSTLAYER5))
2376
2377 // Verify that the mesh conforms to the reference
2378 CHECKPERF(m_perf_counter.start(PerfCounter::UPGHOSTLAYER6))
2379 m_mesh_checker->checkMeshFromReferenceFile();
2380
2381 // Compact references to avoid gaps and take
2382 // advantage of cache effects.
2383 // NOTE: this is not theoretically necessary but currently is
2384 // because we do not save the #m_data_index of the ItemInternal.
2385 //_compactItemInternalReferences();
2386 bool do_compact = m_properties->getBool(PROPERTY_COMPACT);
2387 if (do_compact) {
2388 bool do_sort = m_properties->getBool(PROPERTY_SORT);
2389 _compactItems(do_sort, do_compact);
2390 }
2391 CHECKPERF(m_perf_counter.stop(PerfCounter::UPGHOSTLAYER6))
2392
2393 if (arcane_debug_load_balancing) {
2394 _writeMesh("update-ghost-layer-after");
2395 }
2396
2397 // Display the statistics of the new mesh
2398 {
2399 MeshStats ms(traceMng(), this, m_parallel_mng);
2400 ms.dumpStats();
2401 pinfo() << "Proc: " << meshRank()
2402 << " cellown=" << m_cell_family->allItems().own().size()
2403 << " cellloc=" << m_cell_family->allItems().size();
2404 }
2405
2407 CHECKPERF(m_perf_counter.start(PerfCounter::UPGHOSTLAYER7))
2409 m_mesh_checker->updateAMRFaceOrientation(ghost_cell_to_refine_uid);
2410
2411 if (m_mesh_checker->checkLevel() >= 1)
2412 m_mesh_checker->checkValidConnectivity();
2413 CHECKPERF(m_perf_counter.stop(PerfCounter::UPGHOSTLAYER7))
2414
2415#ifdef ACTIVATE_PERF_COUNTER
2416 m_perf_counter.printInfo(info().file());
2417#endif
2418}
2419
2420/*---------------------------------------------------------------------------*/
2421/*---------------------------------------------------------------------------*/
2422
2423void DynamicMesh::
2424_internalUpdateGhost(bool update_ghost_layer, bool remove_old_ghost)
2425{
2426 m_need_compact = true;
2427
2428 // Overrides behavior for submeshes
2429 if (parentMesh()) {
2430 if (update_ghost_layer)
2431 m_submesh_tools->updateGhostMesh();
2432 }
2433 else {
2434 if (update_ghost_layer) {
2435 if (remove_old_ghost) {
2436 _removeGhostItems();
2437 }
2438 // In case of refinement/coarsening, the orientation might be invalid at a point.
2439 m_face_family->setCheckOrientation(false);
2440 m_mesh_builder->addGhostLayers(false);
2441 m_face_family->setCheckOrientation(true);
2442 _computeExtraGhostCells();
2443 _computeExtraGhostParticles();
2444 }
2445 }
2446}
2447
2448/*---------------------------------------------------------------------------*/
2449/*---------------------------------------------------------------------------*/
2450
2451void DynamicMesh::
2452_internalEndUpdateInit(bool update_ghost_layer)
2453{
2454 // From here, all mesh entities are known. It
2455 // is therefore possible to compact them if necessary
2456 //m_mesh_builder->printStats();
2457
2458 //info() << "Finalize date=" << platform::getCurrentDateTime();
2459 _finalizeMeshChanged();
2460
2461 // Recalculate the necessary information for the synchronization
2462 // of
2463 // entities
2464 if (update_ghost_layer) {
2465 info() << "ComputeSyncInfos date=" << platform::getCurrentDateTime();
2466 _computeFamilySynchronizeInfos();
2467 }
2468}
2469
2470/*---------------------------------------------------------------------------*/
2471/*---------------------------------------------------------------------------*/
2472
2473void DynamicMesh::
2474_internalEndUpdateResizeVariables()
2475{
2476 // Reallocate mesh variables because their group has changed
2477 for (IItemFamily* family : m_item_families)
2478 family->_internalApi()->resizeVariables(true);
2479}
2480
2481/*---------------------------------------------------------------------------*/
2482/*---------------------------------------------------------------------------*/
2483
2484void DynamicMesh::
2485_internalEndUpdateFinal(bool print_stat)
2486{
2487 // Verify that the mesh conforms to the reference
2488 m_mesh_checker->checkMeshFromReferenceFile();
2489
2490 // Compact references to avoid gaps and take
2491 // advantage of cache effects.
2492 // NOTE: this is not theoretically necessary but currently is
2493 // because we do not save the #m_data_index of the ItemInternal.
2494 {
2495 //Timer::Action ts_action1(m_sub_domain,"CompactReferences",true);
2496 _compactItemInternalReferences(); // Utility to confirm
2497
2498 {
2499 bool do_compact = m_properties->getBool(PROPERTY_COMPACT);
2500 info(4) << "DynamicMesh::_internalEndUpdateFinal() compact?=" << do_compact << " sort?=" << m_properties->getBool(PROPERTY_SORT);
2501 if (do_compact) {
2502 bool do_sort = m_properties->getBool(PROPERTY_SORT);
2503 _compactItems(do_sort, do_compact);
2504 }
2505 }
2506 }
2507
2508 _notifyEndUpdateForFamilies();
2509
2510 // Display the statistics of the new mesh
2511 if (print_stat) {
2512 if (m_properties->getBool(PROPERTY_DISPLAY_STATS)) {
2513 MeshStats ms(traceMng(), this, m_parallel_mng);
2514 ms.dumpStats();
2515 }
2516 }
2517
2520 m_mesh_checker->updateAMRFaceOrientation();
2521
2522 if (m_mesh_checker->checkLevel() >= 1)
2523 m_mesh_checker->checkValidConnectivity();
2524}
2525
2526/*---------------------------------------------------------------------------*/
2527/*---------------------------------------------------------------------------*/
2528
2529void DynamicMesh::
2530_notifyEndUpdateForFamilies()
2531{
2532 for (IItemFamily* family : m_item_families)
2533 family->_internalApi()->notifyEndUpdateFromMesh();
2534}
2535
2536/*---------------------------------------------------------------------------*/
2537/*---------------------------------------------------------------------------*/
2538
2539void DynamicMesh::
2540endUpdate()
2541{
2542 endUpdate(false, false);
2543}
2544
2545/*---------------------------------------------------------------------------*/
2546/*---------------------------------------------------------------------------*/
2547
2548void DynamicMesh::
2549endUpdate(bool update_ghost_layer, bool remove_old_ghost)
2550{
2551 // The order of operations is as follows:
2552 // 1- Ghost layer update
2553 // 2- Mesh finalization (freezes items)
2554 // Calculate if requested (update_ghost_layer) the synchronizers on the families
2555 // 3- Synchronize groups (requires updated family synchronizers)
2556 // 4- Calculate if requested (update_ghost_layer) the synchronizers on the groups
2557 // 5- Resize variables (families and groups)
2558 // 6- Synchronize if requested (update_ghost_layer) the variables (families and groups)
2559 // 7- Finalization including: compaction, sorting (if enabled), statistics, and validity check
2560 // 8- Recursive calls to submeshes
2561
2562 Trace::Setter mci(traceMng(), _className());
2563 _internalUpdateGhost(update_ghost_layer, remove_old_ghost);
2564
2565 _internalEndUpdateInit(update_ghost_layer);
2566 if (update_ghost_layer) {
2567 _synchronizeGroups();
2568 _computeGroupSynchronizeInfos();
2569 }
2570 _internalEndUpdateResizeVariables();
2571 if (update_ghost_layer) {
2572 _synchronizeVariables();
2573 }
2574 _internalEndUpdateFinal(false);
2575
2576 // Recursive finalization of submeshes
2577 for (DynamicMesh* child_mesh : m_child_meshes)
2578 child_mesh->endUpdate(update_ghost_layer, remove_old_ghost);
2579}
2580
2581/*---------------------------------------------------------------------------*/
2582/*---------------------------------------------------------------------------*/
2583
2584void DynamicMesh::
2585synchronizeGroupsAndVariables()
2586{
2587 _synchronizeGroupsAndVariables();
2588 // Can be tested in the case where the parent group of a submesh
2589 // before calling the child meshes.
2590 // This might require an update of the child synchronizers
2591 for (DynamicMesh* child_mesh : m_child_meshes)
2592 child_mesh->synchronizeGroupsAndVariables();
2593}
2594
2595/*---------------------------------------------------------------------------*/
2596/*---------------------------------------------------------------------------*/
2597
2598void DynamicMesh::
2599_synchronizeGroupsAndVariables()
2600{
2601 _synchronizeGroups();
2602 _synchronizeVariables();
2603}
2604
2605/*---------------------------------------------------------------------------*/
2606/*---------------------------------------------------------------------------*/
2607
2608void DynamicMesh::
2609_synchronizeGroups()
2610{
2611 {
2612 ItemGroupsSynchronize igs(m_node_family);
2613 igs.synchronize();
2614 }
2615 {
2616 ItemGroupsSynchronize igs(m_edge_family);
2617 igs.synchronize();
2618 }
2619 {
2620 ItemGroupsSynchronize igs(m_face_family);
2621 igs.synchronize();
2622 }
2623 {
2624 ItemGroupsSynchronize igs(m_cell_family);
2625 igs.synchronize();
2626 }
2627 {
2628 for (IItemFamily* family : m_item_families) {
2629 if (family->itemKind() == IK_Particle) {
2630 IParticleFamily* pfamily = family->toParticleFamily();
2631 if (pfamily && pfamily->getEnableGhostItems()) {
2632 ItemGroupsSynchronize igs(family);
2633 igs.synchronize();
2634 }
2635 }
2636 }
2637 }
2638}
2639
2640/*---------------------------------------------------------------------------*/
2641/*---------------------------------------------------------------------------*/
2642
2643void DynamicMesh::
2644_synchronizeVariables()
2645{
2646 // We only synchronize variables on the items of the current mesh
2647 // - Graph items are not handled here (it was already removed from
2648 // the previous version of the code)
2649 // - Particles and those without kind (Unknown) are not subject to synchronization
2650 // Synchronization is factored here by a collection of variables with the same
2651 // synchronizer (even for synchronizers on groups != family)
2652 // To preserve a consistent synchronization order, an
2653 // auxiliary OrderedSyncList structure is used.
2654
2655 // Can we do this with a more compact structure?
2656 typedef UniqueArray<IVariableSynchronizer*> OrderedSyncList;
2657 typedef std::map<IVariableSynchronizer*, VariableCollection> SyncList;
2658 OrderedSyncList ordered_sync_list;
2659 SyncList sync_list;
2660
2661 VariableCollection used_vars(subDomain()->variableMng()->usedVariables());
2662 for (VariableCollection::Enumerator i_var(used_vars); ++i_var;) {
2663 IVariable* var = *i_var;
2664 switch (var->itemKind()) {
2665 case IK_Node:
2666 case IK_Edge:
2667 case IK_Face:
2668 case IK_Cell:
2669 case IK_DoF: {
2670 IVariableSynchronizer* synchronizer = 0;
2671 if (var->isPartial())
2672 synchronizer = var->itemGroup().synchronizer();
2673 else
2674 synchronizer = var->itemFamily()->allItemsSynchronizer();
2675 IMesh* sync_mesh = synchronizer->itemGroup().mesh();
2676 if (sync_mesh != this)
2677 continue; // we only synchronize on the current mesh
2678 std::pair<SyncList::iterator, bool> inserter = sync_list.insert(std::make_pair(synchronizer, VariableCollection()));
2679 if (inserter.second) { // new synchronizer
2680 ordered_sync_list.add(synchronizer);
2681 }
2682 VariableCollection& collection = inserter.first->second;
2683 collection.add(var);
2684 } break;
2685 case IK_Particle:
2686 case IK_Unknown:
2687 break;
2688 }
2689 }
2690
2691 for (Integer i_sync = 0; i_sync < ordered_sync_list.size(); ++i_sync) {
2692 IVariableSynchronizer* synchronizer = ordered_sync_list[i_sync];
2693 VariableCollection& collection = sync_list[synchronizer];
2694 synchronizer->synchronize(collection);
2695 }
2696}
2697
2698/*---------------------------------------------------------------------------*/
2699/*---------------------------------------------------------------------------*/
2700
2701void DynamicMesh::
2702_sortInternalReferences()
2703{
2704 // TODO: this specific call must be handled by NodeFamily.
2705 m_node_family->sortInternalReferences();
2706}
2707
2708/*---------------------------------------------------------------------------*/
2709/*---------------------------------------------------------------------------*/
2710
2711void DynamicMesh::
2712_finalizeMeshChanged()
2713{
2714 ++m_timestamp;
2715 for (IItemFamily* family : m_item_families) {
2716 debug() << "_finalizeMeshChanged on " << family->name() << " Family on Mesh " << name();
2717 family->endUpdate();
2718 }
2719
2720 bool do_sort = m_properties->getBool(PROPERTY_SORT);
2721 if (do_sort)
2722 _sortInternalReferences();
2723 m_tied_interface_need_prepare_dump = true;
2724}
2725
2726/*---------------------------------------------------------------------------*/
2727/*---------------------------------------------------------------------------*/
2728
2729void DynamicMesh::
2730_applyCompactPolicy(const String& timer_name,
2731 std::function<void(IItemFamilyCompactPolicy*)> functor)
2732{
2733 Timer::Action ts_action(m_sub_domain, timer_name);
2734 for (IItemFamily* family : m_item_families) {
2735 IItemFamilyCompactPolicy* c = family->policyMng()->compactPolicy();
2736 if (c)
2737 functor(c);
2738 }
2739}
2740
2741/*---------------------------------------------------------------------------*/
2742/*---------------------------------------------------------------------------*/
2743
2744void DynamicMesh::
2745_compactItemInternalReferences()
2746{
2747 _applyCompactPolicy("CompactConnectivityData", [&](IItemFamilyCompactPolicy* c) { c->compactConnectivityData(); });
2748}
2749
2750/*---------------------------------------------------------------------------*/
2751/*---------------------------------------------------------------------------*/
2752
2753void DynamicMesh::
2754_compactItems(bool do_sort, bool compact_variables_and_groups)
2755{
2756 if (do_sort)
2757 info(4) << "Compress and sort the mesh entities " << name() << ".";
2758 else
2759 info(4) << "Compress the mesh entities " << name() << ".";
2760
2761 IMeshCompacter* compacter = m_mesh_compact_mng->beginCompact();
2762
2763 try {
2764 compacter->setSorted(do_sort);
2765 compacter->_setCompactVariablesAndGroups(compact_variables_and_groups);
2766
2767 compacter->doAllActions();
2768 }
2769 catch (...) {
2770 m_mesh_compact_mng->endCompact();
2771 throw;
2772 }
2773 m_mesh_compact_mng->endCompact();
2774
2775 if (do_sort) {
2776 Timer::Action ts_action(m_sub_domain, "CompactItemSortReferences");
2777 // TODO: put this in the family policy (apparently only useful
2778 // for node families)
2779 _sortInternalReferences();
2780 }
2781
2782 m_need_compact = false;
2783
2784 // Consider compaction as a mesh evolution because this
2785 // changes the structures associated with the entities and their connectivities
2786 ++m_timestamp;
2787}
2788
2789/*---------------------------------------------------------------------------*/
2790/*---------------------------------------------------------------------------*/
2791
2792void DynamicMesh::
2793setEstimatedCells(Integer nb_cell0)
2794{
2795 Real factor = 1.0;
2796 if (m_parallel_mng->isParallel())
2797 factor = 1.2; // Considers 20% ghost entities.
2798 // The following estimations corresponding to an evaluation for a cube of side N=16
2799 Integer nb_node = Convert::toInteger(nb_cell0 * 1.2 * factor); // (N+1)^3/N^3 => 1.2
2800 Integer nb_edge = Convert::toInteger(nb_cell0 * 6.8 * factor); // 6*(N+1)^2*N/N^3 => 6.8
2801 Integer nb_face = Convert::toInteger(nb_cell0 * 3.4 * factor); // 3*N^2*(N+1)/N^3 => 3.19
2802 Integer nb_cell = Convert::toInteger(nb_cell0 * 1.0 * factor); // trivial => 1.0
2803 info() << "Estimating the number of entities:"
2804 << " Node=" << nb_node
2805 << " Edge=" << nb_edge
2806 << " Face=" << nb_face
2807 << " Cell=" << nb_cell;
2808 m_node_family->preAllocate(nb_node);
2809 m_edge_family->preAllocate(nb_edge);
2810 m_face_family->preAllocate(nb_face);
2811 m_cell_family->preAllocate(nb_cell);
2812}
2813
2814/*---------------------------------------------------------------------------*/
2815/*---------------------------------------------------------------------------*/
2819void DynamicMesh::
2820_readFromDump()
2821{
2823
2824 // Do nothing on a mesh that has not yet been allocated.
2825 if (m_mesh_dimension() < 0)
2826 return;
2827
2828 // Mesh/sub-mesh connection
2829 {
2830 IMeshMng* mm = meshMng();
2831 if (!m_parent_mesh_name.value().null()) {
2832 m_parent_mesh = mm->findMeshHandle(m_parent_mesh_name.value()).mesh();
2833 }
2834 if (!m_parent_group_name.value().null()) {
2835 ARCANE_ASSERT((m_parent_mesh != NULL), ("Unexpected NULL Mesh"));
2836 m_parent_group = m_parent_mesh->findGroup(m_parent_group_name.value()).internal();
2837 }
2838 const Integer n_sub_mesh = m_child_meshes_name.size();
2839 m_child_meshes.resize(n_sub_mesh);
2840 for (Integer i = 0; i < n_sub_mesh; ++i) {
2841 IMesh* child_mesh = mm->findMeshHandle(m_child_meshes_name[i]).mesh();
2842 DynamicMesh* dynamic_child_mesh = dynamic_cast<DynamicMesh*>(child_mesh);
2843 if (dynamic_child_mesh == 0)
2844 ARCANE_FATAL("Cannot associate sub mesh from a different concrete type");
2845 m_child_meshes[i] = dynamic_child_mesh;
2846 }
2847 }
2848
2849 {
2850 Integer nb_item_family = m_item_families_name.size();
2851 for (Integer i = 0; i < nb_item_family; ++i) {
2852 info(5) << "Found family: I=" << i
2853 << " name=" << m_item_families_name[i]
2854 << " kind=" << (eItemKind)m_item_families_kind[i];
2855 }
2856 }
2857
2858 // Relit les infos sur les familles d'entités
2859 {
2860 Integer nb_item_family = m_item_families_name.size();
2861 for (Integer i = 0; i < nb_item_family; ++i) {
2863 }
2864 }
2865
2866 // GG: Update of connectivity choices
2867 // This must be done here because the families might be created at the beginning of this
2868 // method and thus not account for connectivity.
2869 if (!m_is_sub_connectivity_set)
2870 _setSubConnectivity();
2871
2872 for (IItemFamily* family : m_item_families)
2873 family->readFromDump();
2874
2875 // After reading, the families must be notified of the potential
2876 // change in entities.
2877 _notifyEndUpdateForFamilies();
2878
2879 //TODO: should not be done here.
2880 m_item_internal_list.nodes = m_node_family->itemsInternal();
2881 m_item_internal_list.edges = m_edge_family->itemsInternal();
2882 m_item_internal_list.faces = m_face_family->itemsInternal();
2883 m_item_internal_list.cells = m_cell_family->itemsInternal();
2884 m_item_internal_list.mesh = this;
2885
2886 m_tied_interface_mng->readTiedInterfacesFromDump();
2887
2888 m_mesh_builder->readFromDump();
2889 //_writeMesh("after-read-dump-"+name());
2890}
2891
2892/*---------------------------------------------------------------------------*/
2893/*---------------------------------------------------------------------------*/
2894
2895bool DynamicMesh::
2896hasTiedInterface()
2897{
2898 return m_tied_interface_mng->hasTiedInterface();
2899}
2900
2901/*---------------------------------------------------------------------------*/
2902/*---------------------------------------------------------------------------*/
2903
2905tiedInterfaces()
2906{
2907 return m_tied_interface_mng->tiedInterfaces();
2908}
2909
2910/*---------------------------------------------------------------------------*/
2911/*---------------------------------------------------------------------------*/
2912
2914trueTiedInterfaces()
2915{
2916 return m_tied_interface_mng->trueTiedInterfaces();
2917}
2918
2919/*---------------------------------------------------------------------------*/
2920/*---------------------------------------------------------------------------*/
2921
2922void DynamicMesh::
2923computeTiedInterfaces(const XmlNode& mesh_node)
2924{
2925 m_tied_interface_mng->computeTiedInterfaces(mesh_node);
2926}
2927
2928/*---------------------------------------------------------------------------*/
2929/*---------------------------------------------------------------------------*/
2930
2931void DynamicMesh::
2932setDimension(Integer dim)
2933{
2934 _setDimension(dim);
2935 _checkConnectivity();
2936}
2937
2938/*---------------------------------------------------------------------------*/
2939/*---------------------------------------------------------------------------*/
2940
2941void DynamicMesh::
2942_setDimension(Integer dim)
2943{
2944 if (m_is_allocated)
2945 ARCANE_FATAL("DynamicMesh::setDimension(): mesh is already allocated");
2946 info() << "Mesh name=" << name() << " set dimension = " << dim;
2947 m_mesh_dimension = dim;
2948 const bool is_non_manifold = meshKind().isNonManifold();
2949 // Force the fact of not re-numbering faces and edges
2950 // in the case of a non-manifold mesh
2951 if (is_non_manifold) {
2952 info() << "Force no-renumbering of edge and face uid because we are using non manifold mesh";
2953 m_mesh_unique_id_mng->setFaceBuilderVersion(0);
2954 m_mesh_unique_id_mng->setEdgeBuilderVersion(0);
2955 }
2956 bool v = m_mesh_unique_id_mng->isUseNodeUniqueIdToGenerateEdgeAndFaceUniqueId();
2957 // If the mesh is non-manifold, then it is mandatory to use
2958 // generation from uniqueId() from nodes to guarantee
2959 // the consistency of the created entities.
2960 // This constraint may eventually be removed when this type
2961 // of mesh is no longer experimental.
2962 if (!v && is_non_manifold) {
2963 v = true;
2964 info() << "Force using edge and face uid generation from nodes because we are using non manifold mesh";
2965 }
2966 if (m_mesh_builder) {
2967 auto* adder = m_mesh_builder->oneMeshItemAdder();
2968 if (adder)
2969 adder->setUseNodeUniqueIdToGenerateEdgeAndFaceUniqueId(v);
2970 }
2971 // In 3D, with non-manifold meshes, it is mandatory to create edges.
2972 // They will be used instead of faces for 2D meshes.
2973 if (dim == 3 && is_non_manifold) {
2974 Connectivity c(m_mesh_connectivity);
2975 if (!c.hasConnectivity(Connectivity::CT_HasEdge)) {
2976 c.enableConnectivity(Connectivity::CT_HasEdge);
2977 info() << "Force creating edges for 3D non-manifold mesh";
2978 }
2979 }
2980}
2981
2982/*---------------------------------------------------------------------------*/
2983/*---------------------------------------------------------------------------*/
2984
2985void DynamicMesh::
2986_checkDimension() const
2987{
2988 if (m_mesh_dimension() < 0)
2989 ARCANE_FATAL("dimension not set. setDimension() must be called before allocating cells");
2990}
2991
2992/*---------------------------------------------------------------------------*/
2993/*---------------------------------------------------------------------------*/
2994
2995void DynamicMesh::
2996_checkConnectivity()
2997{
2998 Connectivity c(m_mesh_connectivity);
2999 if (!c.isFrozen()) {
3000 c.freeze(this);
3001 debug() << "Mesh " << name() << " connectivity : " << Connectivity::Printer(m_mesh_connectivity());
3002 _setSubConnectivity();
3003 _updateItemFamilyDependencies(m_mesh_connectivity);
3004 }
3005}
3006
3007/*---------------------------------------------------------------------------*/
3008/*---------------------------------------------------------------------------*/
3009// AMR
3010void DynamicMesh::
3011_checkAMR() const
3012{
3013 if (!m_is_amr_activated)
3014 ARCANE_FATAL("DynamicMesh::_checkAMR(): amr activator not set.\t"
3015 "amr='true' must be set in the .arc file");
3016}
3017
3018/*---------------------------------------------------------------------------*/
3019/*---------------------------------------------------------------------------*/
3020
3021void DynamicMesh::
3022_setSubConnectivity()
3023{
3024 m_mesh_builder->setConnectivity(m_mesh_connectivity());
3025 m_node_family->setConnectivity(m_mesh_connectivity());
3026 m_edge_family->setConnectivity(m_mesh_connectivity());
3027 m_face_family->setConnectivity(m_mesh_connectivity());
3028 m_cell_family->setConnectivity(m_mesh_connectivity());
3029 m_is_sub_connectivity_set = true;
3030}
3031
3032/*---------------------------------------------------------------------------*/
3033/*---------------------------------------------------------------------------*/
3034
3035void DynamicMesh::
3036_writeCells(const String& filename)
3037{
3038 CellGroup cells(m_cell_family->allItems());
3039 std::ofstream ofile(filename.localstr());
3040 ENUMERATE_CELL (icell, cells) {
3041 Cell cell = *icell;
3042 ofile << "CELL: uid=" << cell.uniqueId() << " isown="
3043 << cell.isOwn() << " owner=" << cell.owner() << '\n';
3044 }
3045}
3046
3047/*---------------------------------------------------------------------------*/
3048/*---------------------------------------------------------------------------*/
3049
3050VariableNodeReal3& DynamicMesh::
3051nodesCoordinates()
3052{
3053 return m_node_family->nodesCoordinates();
3054}
3055
3056/*---------------------------------------------------------------------------*/
3057/*---------------------------------------------------------------------------*/
3058
3060sharedNodesCoordinates()
3061{
3062 if (parentMesh())
3064 else
3066}
3067
3068/*---------------------------------------------------------------------------*/
3069/*---------------------------------------------------------------------------*/
3070
3071void DynamicMesh::
3072_setOwnersFromCells()
3073{
3074 // We assume we know the new owners of the meshes, which
3075 // are found in cells_owner. We must now determine the new owners of the nodes and
3076 // faces. Until we have an algorithm that better balances
3077 // the messages, we apply the following:
3078 // - each sub-domain is responsible for determining the new
3079 // owner of the nodes and faces belonging to it.
3080 // - for nodes and edges, the new owner is the new owner of the mesh connected to this node whose uniqueId() is the smallest.
3081 // - for faces, the new owner is the new owner
3082 // of the mesh behind this face if it is an internal face, and of the connected mesh if it is a boundary face.
3083 // - for dual nodes, the new owner is the new owner
3084 // of the mesh connected to the dual element
3085 // - for links, the new owner is the new owner
3086 // of the mesh connected to the first dual node, i.e., the owner
3087 // of the first dual node of the link
3088
3089 VariableItemInt32& nodes_owner(nodeFamily()->itemsNewOwner());
3090 VariableItemInt32& edges_owner(edgeFamily()->itemsNewOwner());
3091 VariableItemInt32& faces_owner(faceFamily()->itemsNewOwner());
3092
3093 const Integer sid = subDomain()->subDomainId();
3094
3095 // Owner assignment tool for items
3096 if (m_new_item_owner_builder == NULL)
3097 m_new_item_owner_builder = new NewItemOwnerBuilder();
3098
3099 // Determines the new owners of the nodes
3100 {
3101 ENUMERATE_NODE (i_node, ownNodes()) {
3102 Node node = *i_node;
3103 nodes_owner[node] = m_new_item_owner_builder->ownerOfItem(node);
3104 }
3105 nodes_owner.synchronize();
3106 }
3107
3108 ENUMERATE_NODE (i_node, allNodes()) {
3109 Node node = *i_node;
3110 node.mutableItemBase().setOwner(nodes_owner[node], sid);
3111 }
3112
3113 // Determines the new owners of the edges
3114 {
3115 ENUMERATE_EDGE (i_edge, ownEdges()) {
3116 Edge edge = *i_edge;
3117 edges_owner[edge] = m_new_item_owner_builder->ownerOfItem(edge);
3118 }
3119 edges_owner.synchronize();
3120 }
3121
3122 ENUMERATE_EDGE (i_edge, allEdges()) {
3123 Edge edge = *i_edge;
3124 edge.mutableItemBase().setOwner(edges_owner[edge], sid);
3125 }
3126
3127 // Determines the new owners of the faces
3128 {
3129 ENUMERATE_FACE (i_face, ownFaces()) {
3130 Face face = *i_face;
3131 faces_owner[face] = m_new_item_owner_builder->ownerOfItem(face);
3132 }
3133 faces_owner.synchronize();
3134 }
3135
3136 ENUMERATE_FACE (i_face, allFaces()) {
3137 Face face = *i_face;
3138 face.mutableItemBase().setOwner(faces_owner[face], sid);
3139 }
3140
3141 nodeFamily()->notifyItemsOwnerChanged();
3142 edgeFamily()->notifyItemsOwnerChanged();
3143 faceFamily()->notifyItemsOwnerChanged();
3144 _computeFamilySynchronizeInfos();
3145}
3146
3147/*---------------------------------------------------------------------------*/
3148/*---------------------------------------------------------------------------*/
3149
3150IMeshUtilities* DynamicMesh::
3151utilities()
3152{
3153 if (!m_mesh_utilities)
3154 m_mesh_utilities = new UnstructuredMeshUtilities(this);
3155 return m_mesh_utilities;
3156}
3157
3158/*---------------------------------------------------------------------------*/
3159/*---------------------------------------------------------------------------*/
3160
3161FaceGroup DynamicMesh::
3162outerFaces()
3163{
3164 return m_cell_family->allItems().outerFaceGroup();
3165}
3166
3168/*---------------------------------------------------------------------------*/
3169/*---------------------------------------------------------------------------*/
3170
3172CellGroup DynamicMesh::
3173allActiveCells()
3174{
3175 return m_cell_family->allItems().activeCellGroup();
3176}
3177/*---------------------------------------------------------------------------*/
3178/*---------------------------------------------------------------------------*/
3180CellGroup DynamicMesh::
3181ownActiveCells()
3182{
3183 return m_cell_family->allItems().ownActiveCellGroup();
3184}
3185/*---------------------------------------------------------------------------*/
3186/*---------------------------------------------------------------------------*/
3188CellGroup DynamicMesh::
3189allLevelCells(const Integer& level)
3190{
3191 return m_cell_family->allItems().levelCellGroup(level);
3192}
3193/*---------------------------------------------------------------------------*/
3194/*---------------------------------------------------------------------------*/
3196CellGroup DynamicMesh::
3197ownLevelCells(const Integer& level)
3198{
3199 return m_cell_family->allItems().ownLevelCellGroup(level);
3200}
3201/*---------------------------------------------------------------------------*/
3202/*---------------------------------------------------------------------------*/
3204FaceGroup DynamicMesh::
3205allActiveFaces()
3206{
3207 return m_cell_family->allItems().activeFaceGroup();
3208}
3209/*---------------------------------------------------------------------------*/
3210/*---------------------------------------------------------------------------*/
3212FaceGroup DynamicMesh::
3213ownActiveFaces()
3214{
3215 return m_cell_family->allItems().ownActiveFaceGroup();
3216}
3217/*---------------------------------------------------------------------------*/
3218/*---------------------------------------------------------------------------*/
3219
3220/*---------------------------------------------------------------------------*/
3221/*---------------------------------------------------------------------------*/
3223FaceGroup DynamicMesh::
3224innerActiveFaces()
3225{
3226 return m_cell_family->allItems().innerActiveFaceGroup();
3227}
3228/*---------------------------------------------------------------------------*/
3229/*---------------------------------------------------------------------------*/
3231FaceGroup DynamicMesh::
3232outerActiveFaces()
3233{
3234 return m_cell_family->allItems().outerActiveFaceGroup();
3235}
3236/*---------------------------------------------------------------------------*/
3237/*---------------------------------------------------------------------------*/
3238
3239/*---------------------------------------------------------------------------*/
3240/*---------------------------------------------------------------------------*/
3241
3242void DynamicMesh::
3243defineParentForBuild(IMesh* mesh, ItemGroup group)
3244{
3245 Trace::Setter mci(traceMng(), _className());
3246 if (!mesh)
3247 ARCANE_FATAL("Cannot set NULL parent mesh to mesh '{0}'", name());
3248
3249 if (mesh != group.mesh())
3250 ARCANE_FATAL("Cannot set inconsistant mesh/group parents to mesh '{0}'", name());
3251
3252 if (m_parent_mesh) {
3253 if (m_parent_mesh != mesh)
3254 ARCANE_FATAL("Mesh '{0}' already has parent mesh '{1}'", name(), m_parent_mesh->name());
3255 if (m_parent_group != group.internal())
3256 ARCANE_FATAL("Mesh '{0}' already has parent group '{1}'", name(), m_parent_group->name());
3257 }
3258
3259 m_parent_mesh = mesh;
3260 m_parent_group = group.internal();
3261
3262 Integer dimension_shift = 0;
3263 if (group.itemKind() == IK_Face) {
3264 dimension_shift = 1;
3265 }
3266 else if (group.itemKind() == IK_Cell) {
3267 dimension_shift = 0;
3268 }
3269 else {
3270 ARCANE_FATAL("Only SubMesh on FaceGroup or CellGoup is allowed");
3271 }
3272
3273 _setDimension(mesh->dimension() - dimension_shift);
3274
3275 for (IItemFamily* family : m_item_families) {
3276 const eItemKind kind = family->itemKind();
3277 // Uniquement sur les items constructifs d'un maillage
3278 if (kind == IK_Node || kind == IK_Edge || kind == IK_Face || kind == IK_Cell) {
3279 const eItemKind parent_kind = MeshToMeshTransposer::kindTranspose(kind, this, mesh);
3280 if (parent_kind != IK_Unknown) {
3281 family->setParentFamily(mesh->itemFamily(parent_kind));
3282 } // else : pas de transposition
3283 }
3284 else {
3285 // do nothing. Another idea ?
3286 }
3287 }
3288}
3289
3290/*---------------------------------------------------------------------------*/
3291/*---------------------------------------------------------------------------*/
3292
3294partitionConstraintMng()
3295{
3296 return m_partition_constraint_mng;
3297}
3298
3299/*---------------------------------------------------------------------------*/
3300/*---------------------------------------------------------------------------*/
3301
3302IMesh* DynamicMesh::
3303parentMesh() const
3304{
3305 return m_parent_mesh;
3306}
3307
3308/*---------------------------------------------------------------------------*/
3309/*---------------------------------------------------------------------------*/
3310
3311ItemGroup DynamicMesh::
3312parentGroup() const
3313{
3314 return ItemGroup(m_parent_group);
3315}
3316
3317/*---------------------------------------------------------------------------*/
3318/*---------------------------------------------------------------------------*/
3319
3320void DynamicMesh::
3321addChildMesh(IMesh* sub_mesh)
3322{
3323 DynamicMesh* dynamic_child_mesh = dynamic_cast<DynamicMesh*>(sub_mesh);
3324 if (!dynamic_child_mesh)
3325 ARCANE_FATAL("Cannot associate sub mesh from a different concrete type");
3326 for (Integer i = 0; i < m_child_meshes.size(); ++i)
3327 if (m_child_meshes[i] == dynamic_child_mesh)
3328 return;
3329 m_child_meshes.add(dynamic_child_mesh);
3330}
3331
3332/*---------------------------------------------------------------------------*/
3333/*---------------------------------------------------------------------------*/
3334
3335IMeshCollection DynamicMesh::
3336childMeshes() const
3337{
3338 IMeshCollection collection = List<IMesh*>();
3339 for (Integer i = 0; i < m_child_meshes.size(); ++i) {
3340 collection.add(m_child_meshes[i]);
3341 }
3342 return collection;
3343}
3344
3345/*---------------------------------------------------------------------------*/
3346/*---------------------------------------------------------------------------*/
3347
3348IMeshChecker* DynamicMesh::
3349checker() const
3350{
3351 return m_mesh_checker;
3352}
3353
3354/*---------------------------------------------------------------------------*/
3355/*---------------------------------------------------------------------------*/
3356
3357bool DynamicMesh::
3358isPrimaryMesh() const
3359{
3360 return (this->parentMesh() == nullptr);
3361}
3362
3363/*---------------------------------------------------------------------------*/
3364/*---------------------------------------------------------------------------*/
3365
3366IPrimaryMesh* DynamicMesh::
3367toPrimaryMesh()
3368{
3369 if (!isPrimaryMesh())
3370 throw BadCastException(A_FUNCINFO, "Mesh is not a primary mesh");
3371 return this;
3372}
3373
3374/*---------------------------------------------------------------------------*/
3375/*---------------------------------------------------------------------------*/
3376
3377Integer DynamicMesh::
3378nbNode()
3379{
3380 return m_node_family->nbItem();
3381}
3382Integer DynamicMesh::
3383nbEdge()
3384{
3385 return m_edge_family->nbItem();
3386}
3387Integer DynamicMesh::
3388nbFace()
3389{
3390 return m_face_family->nbItem();
3391}
3392Integer DynamicMesh::
3393nbCell()
3394{
3395 return m_cell_family->nbItem();
3396}
3397
3398IItemFamily* DynamicMesh::
3399nodeFamily()
3400{
3401 return m_node_family;
3402}
3403
3404IItemFamily* DynamicMesh::
3405edgeFamily()
3406{
3407 return m_edge_family;
3408}
3409
3410IItemFamily* DynamicMesh::
3411faceFamily()
3412{
3413 return m_face_family;
3414}
3415
3416IItemFamily* DynamicMesh::
3417cellFamily()
3418{
3419 return m_cell_family;
3420}
3421
3422DynamicMeshKindInfos::ItemInternalMap& DynamicMesh::
3423nodesMap()
3424{
3425 return m_node_family->itemsMap();
3426}
3427
3428DynamicMeshKindInfos::ItemInternalMap& DynamicMesh::
3429edgesMap()
3430{
3431 return m_edge_family->itemsMap();
3432}
3433
3434DynamicMeshKindInfos::ItemInternalMap& DynamicMesh::
3435facesMap()
3436{
3437 return m_face_family->itemsMap();
3438}
3439
3440DynamicMeshKindInfos::ItemInternalMap& DynamicMesh::
3441cellsMap()
3442{
3443 return m_cell_family->itemsMap();
3444}
3445
3446/*---------------------------------------------------------------------------*/
3447/*---------------------------------------------------------------------------*/
3448
3449void DynamicMesh::
3450mergeMeshes(ConstArrayView<IMesh*> meshes)
3451{
3452 UniqueArray<DynamicMesh*> true_meshes;
3453 for (IMesh* mesh : meshes) {
3454 DynamicMesh* true_mesh = ARCANE_CHECK_POINTER(dynamic_cast<DynamicMesh*>(mesh));
3455 true_meshes.add(true_mesh);
3456 }
3457 DynamicMeshMerger merger(this);
3458 merger.mergeMeshes(true_meshes);
3459}
3460
3461/*---------------------------------------------------------------------------*/
3462/*---------------------------------------------------------------------------*/
3463
3464void DynamicMesh::
3465_printConnectivityPolicy()
3466{
3467 info() << "Connectivity policy=" << (int)m_connectivity_policy;
3468
3469 if (m_connectivity_policy != InternalConnectivityPolicy::NewOnly)
3470 ARCANE_FATAL("Invalid value '{0}' for InternalConnectivityPolicy. Only '{1}' is allowed",
3471 (int)m_connectivity_policy, (int)InternalConnectivityPolicy::NewOnly);
3472}
3473
3474/*---------------------------------------------------------------------------*/
3475/*---------------------------------------------------------------------------*/
3476
3477void DynamicMesh::
3478setMeshPartInfo(const MeshPartInfo& mpi)
3479{
3480 m_mesh_part_info = mpi;
3481 // TODO: notify the families
3482}
3483
3484/*---------------------------------------------------------------------------*/
3485/*---------------------------------------------------------------------------*/
3486
3487void DynamicMesh::
3488_updateItemFamilyDependencies(VariableScalarInteger connectivity)
3489{
3490 if (!m_item_family_network)
3491 return;
3492 Connectivity c(connectivity);
3493 for (const auto& con : m_item_family_network->getConnectivities()) {
3494 if (c.hasConnectivity(c.kindsToConnectivity(con->sourceFamily()->itemKind(), con->targetFamily()->itemKind()))) {
3495 m_item_family_network->setIsStored(con);
3496 }
3497 }
3498}
3499
3500/*---------------------------------------------------------------------------*/
3501/*---------------------------------------------------------------------------*/
3502
3503IMeshInternal* DynamicMesh::
3504_internalApi()
3505{
3506 return m_internal_api.get();
3507}
3508
3509/*---------------------------------------------------------------------------*/
3510/*---------------------------------------------------------------------------*/
3511
3513_modifierInternalApi()
3514{
3515 return m_internal_api.get();
3516}
3517
3518/*---------------------------------------------------------------------------*/
3519/*---------------------------------------------------------------------------*/
3520
3521void DynamicMesh::
3522computeSynchronizeInfos()
3523{
3524 _computeSynchronizeInfos();
3525}
3526
3527/*---------------------------------------------------------------------------*/
3528/*---------------------------------------------------------------------------*/
3529
3530class ARCANE_MESH_EXPORT DynamicMeshFactoryBase
3531: public AbstractService
3532, public IMeshFactory
3533{
3534 public:
3535
3536 DynamicMeshFactoryBase(const ServiceBuildInfo& sbi, bool is_amr)
3537 : AbstractService(sbi)
3538 , m_is_amr(is_amr)
3539 {}
3540
3541 public:
3542
3543 void build() override {}
3544 IPrimaryMesh* createMesh(IMeshMng* mm, const MeshBuildInfo& build_info) override
3545 {
3546 MeshBuildInfo mbi(build_info);
3547 MeshKind mk(mbi.meshKind());
3548 // If AMR is requested but not indicated in MeshPart,
3549 // we add it.
3550 if (m_is_amr && mk.meshAMRKind() == eMeshAMRKind::None)
3551 mk.setMeshAMRKind(eMeshAMRKind::Cell);
3552 mbi.addMeshKind(mk);
3554 bool is_submesh = !mbi.parentGroup().null();
3555 if (is_submesh && m_is_amr)
3556 ARCANE_FATAL("Submesh cannot be refined with AMR.");
3557 return new DynamicMesh(sd, mbi, is_submesh);
3558 }
3559
3560 private:
3561
3562 bool m_is_amr;
3563};
3564
3565/*---------------------------------------------------------------------------*/
3566/*---------------------------------------------------------------------------*/
3567
3568class ARCANE_MESH_EXPORT DynamicMeshFactory
3569: public DynamicMeshFactoryBase
3570{
3571 public:
3572
3573 explicit DynamicMeshFactory(const ServiceBuildInfo& sbi)
3574 : DynamicMeshFactoryBase(sbi, false)
3575 {}
3576};
3577
3578/*---------------------------------------------------------------------------*/
3579/*---------------------------------------------------------------------------*/
3580
3581class ARCANE_MESH_EXPORT DynamicAMRMeshFactory
3582: public DynamicMeshFactoryBase
3583{
3584 public:
3585
3586 explicit DynamicAMRMeshFactory(const ServiceBuildInfo& sbi)
3587 : DynamicMeshFactoryBase(sbi, true)
3588 {}
3589};
3590
3591/*---------------------------------------------------------------------------*/
3592/*---------------------------------------------------------------------------*/
3593
3595 ServiceProperty("ArcaneDynamicMeshFactory", ST_Application),
3597
3599 ServiceProperty("ArcaneDynamicAMRMeshFactory", ST_Application),
3601
3602/*---------------------------------------------------------------------------*/
3603/*---------------------------------------------------------------------------*/
3604
3605} // End namespace Arcane::mesh
3606
3607/*---------------------------------------------------------------------------*/
3608/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL_IF(const,...)
Macro envoyant une exception FatalErrorException si cond est vrai.
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_FACE(name, group)
Enumérateur générique d'un groupe de faces.
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
#define ENUMERATE_EDGE(name, group)
Enumérateur générique d'un groupe d'arêtes.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
Fonctions utilitaires sur le maillage.
void writeMeshConnectivity(IMesh *mesh, const String &file_name)
Ecrit sur le fichier file_name la connectivité du maillage mesh.
Definition MeshUtils.cc:829
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
Integer size() const
Nombre d'éléments du vecteur.
AbstractService(const ServiceBuildInfo &)
Constructeur à partir d'un ServiceBuildInfo.
Tableau d'items de types quelconques.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
T & operator[](const T &item)
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Exception lorsqu'une conversion d'un type vers un autre est invalide.
Maille d'un maillage.
Definition Item.h:1214
Face face(Int32 i) const
i-ème face de la maille
Definition Item.h:1295
Int32 nbFace() const
Nombre de faces de la maille.
Definition Item.h:1292
Gère la récupération des informations de connectivité.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
constexpr bool empty() const noexcept
true si le tableau est vide (size()==0)
Face d'une maille.
Definition Item.h:964
Cell cell(Int32 i) const
i-ème maille de la face
Definition Item.h:1665
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2).
Definition Item.h:1042
Interface d'une partie d'un jeu de données.
virtual XmlNode rootElement()=0
Retourne l'élément racine.
Interface d'un constructeur de mailles fantômes "extraordinaires".
Interface d'un constructeur de mailles fantômes "extraordinaires".
Interface de modification d'une famille.
Interface d'une famille d'entités.
Definition IItemFamily.h:84
virtual ItemGroup findGroup(const String &name) const =0
Recherche un groupe.
virtual ItemInternalArrayView itemsInternal()=0
Tableau interne des entités.
virtual String name() const =0
Nom de la famille.
virtual ItemVectorView view(Int32ConstArrayView local_ids)=0
Vue sur les entités.
virtual void itemsUniqueIdToLocalId(Int32ArrayView local_ids, Int64ConstArrayView unique_ids, bool do_fatal=true) const =0
Converti un tableau de numéros uniques en numéros locaux.
virtual VariableItemInt32 & itemsNewOwner()=0
Variable contenant le numéro du nouveau sous-domaine propriétaire de l'entité.
Interface de méthodes de vérification d'un maillage.
Interface du service gérant la lecture d'un maillage.
Partie interne de IMesh.
Interface du gestionnaire des maillages.
Definition IMeshMng.h:40
virtual IVariableMng * variableMng() const =0
Gestionnaire de variables associé à ce gestionnaire.
virtual MeshHandle * findMeshHandle(const String &name, bool throw_exception)=0
Recherche le maillage de nom name.
Partie interne de IMeshModifier.
Interface d'un gestionnaire de contraintes de partitionnement de maillage.
Interface d'une classe proposant des fonctions utilitaires sur maillage.
Interface du gestionnaire de parallélisme pour un sous-domaine.
@ ModePut
Le sérialiseur attend des reserve().
virtual void allocateBuffer()=0
Alloue la mémoire du sérialiseur.
virtual void setMode(eMode new_mode)=0
Positionne le fonctionnement actuel.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
Interface gérant les statistiques sur les temps d'exécution.
Definition ITimeStats.h:43
virtual void dumpTimeAndMemoryUsage(IParallelMng *pm)=0
Affiche la date actuelle et la mémoire consommée.
virtual ISubDomain * internalSubDomain() const =0
Fonction interne temporaire pour récupérer le sous-domaine.
Interface du gestionnaire de variables.
virtual VariableCollection usedVariables()=0
Liste des variables utilisées.
virtual IVariable * findMeshVariable(IMesh *mesh, const String &name)=0
Retourne la variable du maillage de nom name ou 0 si aucune de se nom existe.
virtual IObservable * writeObservable()=0
Observable pour les variables en écriture.
virtual IVariableMngInternal * _internalApi()=0
API interne à Arcane.
virtual IObservable * readObservable()=0
Observable pour les variables en lecture.
Interface d'une variable.
Definition IVariable.h:39
virtual bool initialize(const ItemGroup &group, const String &value)=0
Initialise la variable sur un groupe.
virtual void resizeFromGroup()=0
Positionne le nombre d'éléments pour une variable du maillage.
virtual bool isUsed() const =0
Etat d'utilisation de la variable.
virtual IItemFamily * itemFamily() const =0
Famille d'entité associée.
virtual String name() const =0
Nom de la variable.
bool isAncestor() const
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
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:63
static eItemKind kindTranspose(eItemKind kindA, IMesh *meshA, IMesh *meshB)
Transpose le genre kindA du maillage meshA en le genre associé dans meshB.
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
Postionne le nom de l'action en cours d'exécution.
Definition Timer.h:110
Sentinelle pour le timer. La sentinelle associée à un timer permet de déclancher celui-ci au moment d...
Definition Timer.h:89
Gestion d'un timer.
Definition Timer.h:62
@ TimerReal
Timer utilisant le temps réel.
Definition Timer.h:76
Real lastActivationTime() const
Retourne le temps (en secondes) passé lors de la dernière activation du timer.
Definition Timer.h:219
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage pinfo() const
Flot pour un message d'information en parallèle.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage error() const
Flot pour un message d'erreur.
Positionne une classe de message.
Vecteur 1D de données avec sémantique par valeur (style STL).
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
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.
Information for mesh exchange between subdomains.
Implementation of a mesh.
Definition DynamicMesh.h:98
IPrimaryMesh * toPrimaryMesh() override
Retourne l'instance sous la forme d'un IPrimaryMesh.
void computeSynchronizeInfos() override
Recalcule les informations de synchronisation.
IItemFamily * nodeFamily() override
Retourne la famille des noeuds.
IItemFamily * cellFamily() override
Retourne la famille des mailles.
void endAllocate() override
Indique une fin d'allocation de mailles.
ITraceMng * traceMng() override
Gestionnaire de message associé
IParallelMng * parallelMng() override
Gestionnaire de parallèlisme.
bool isPrimaryMesh() const override
Indique si l'instance est un maillage primaire.
IMesh * mesh() override
Maillage associé
VariableNodeReal3 & nodesCoordinates() override
Coordonnées des noeuds.
IItemFamily * createItemFamily(eItemKind ik, const String &name) override
Créé une famille de particule de nom name.
String name() const override
Nom du maillage.
IMeshMng * meshMng() const override
Gestionnaire de maillage associé
void _readFromDump()
Reloads the mesh from protected variables.
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
List of entity family interfaces.
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()
Saves properties before a dump.
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()
Reloads properties from a dump.
void checkValidMesh() override
Vérification de la validité des structues internes de maillage (interne).
void _prepareForDump()
Prepares variables for a dump.
void _prepareForDumpReal()
Prepares variables for a dump.
ItemGroupList m_all_groups
List of entity groups.
MeshRefinement * m_mesh_refinement
AMR.
void addFaces(Integer nb_face, Int64ConstArrayView face_infos, Int32ArrayView faces) override
Ajoute des faces.
Interface for the manager of incremental connectivities indexed on entities.
void executeExtend(const Int32ConstArrayView *new_items_info)
Execute l'action associée à l'extension.
Information for exchanging entities of a given family and their characteristics.
Manager for compacting families of a mesh.
Interface for the mesh exchange manager between subdomains.
Mesh partitioning constraint manager.
Implementation of unstructured mesh refinement adaptation algorithms.
Mesh uniqueId() numbering manager.
Variables containing the information of connectivities common to 1D, 2D, and 3D meshes.
VariableArrayString m_item_families_name
Names of entity families.
VariableArrayString m_child_meshes_name
Names of parent meshes.
VariableArrayInteger m_item_families_kind
Kind of entities in the families.
VariableScalarString m_parent_mesh_name
Name of the parent mesh.
VariableScalarString m_parent_group_name
Name of the parent group.
VariableScalarInteger m_mesh_dimension
Mesh dimension.
Implementation of the tied interface manager.
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.
String getEnvironmentVariable(const String &name)
Variable d'environnement du nom name.
bool arcaneIsCheck()
Vrai si on est en mode vérification.
Definition Misc.cc:68
Collection< ItemGroup > ItemGroupCollection
Collection de groupes d'éléments du maillage.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:482
ConstArrayView< ItemInternal * > ItemInternalList
Type de la liste interne des entités.
Definition ItemTypes.h:466
@ ST_Application
Le service s'utilise au niveau de l'application.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:480
eMeshEventType
Evènements générés par IMesh.
Definition MeshEvents.h:30
@ EndPrepareDump
Evènement envoyé à la fin de prepareForDump().
Definition MeshEvents.h:34
@ BeginPrepareDump
Evènement envoyé au début de prepareForDump().
Definition MeshEvents.h:32
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:341
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:453
SharedMeshVariableScalarRefT< Node, Real3 > SharedVariableNodeReal3
Grandeur au noeud de type coordonnées.
eItemKind
Genre d'entité de maillage.
@ IK_Particle
Entité de maillage de genre particule.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Unknown
Entité de maillage de genre inconnu ou non initialisé
@ IK_Face
Entité de maillage de genre face.
@ IK_DoF
Entité de maillage de genre degre de liberte.
@ IK_Edge
Entité de maillage de genre arête.
const char * itemKindName(eItemKind kind)
Nom du genre d'entité.
Array< Int32 > Int32Array
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:127
Collection< IMesh * > IMeshCollection
Collection de maillages.
InternalConnectivityPolicy
Politique d'utilisation des connectivités.
Definition ItemTypes.h:516
@ NewOnly
Alloue uniquement les nouvelles connectivités.
Definition ItemTypes.h:554
eMeshAMRKind
Type de maillage AMR.
Definition MeshKind.h:48
@ Patch
Le maillage est AMR par patch.
Definition MeshKind.h:54
@ Cell
Le maillage est AMR par maille.
Definition MeshKind.h:52
@ None
Le maillage n'est pas AMR.
Definition MeshKind.h:50
@ PatchCartesianMeshOnly
Le maillage est AMR par patch cartésien (rectangulaire).
Definition MeshKind.h:56
Collection< ITiedInterface * > TiedInterfaceCollection
Collection d'interfaces liées.
std::int32_t Int32
Type entier signé sur 32 bits.