Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
PolyhedralMesh.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* PolyhedralMesh.cc (C) 2000-2024 */
9/* */
10/* Polyhedral mesh impl using Neo data structure. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/PolyhedralMesh.h"
15
16#include "arcane/core/ISubDomain.h"
17#include "arcane/core/ItemSharedInfo.h"
18#include "arcane/core/ItemTypeInfo.h"
19#include "arcane/core/ItemTypeMng.h"
20#include "arcane/core/VariableBuildInfo.h"
21#include "arcane/core/MeshBuildInfo.h"
23#include "arcane/core/AbstractService.h"
24#include "arcane/core/IMeshFactory.h"
25#include "arcane/core/ItemInternal.h"
26#include "arcane/core/IDoFFamily.h"
27#include "arcane/core/IMeshCompactMng.h"
28#include "arcane/core/IMeshCompacter.h"
29#include "arcane/core/internal/IVariableMngInternal.h"
30#include "arcane/core/internal/IPolyhedralMeshModifier.h"
31
32#include "arcane/mesh/ItemFamily.h"
33#include "arcane/mesh/DynamicMeshKindInfos.h"
34#include "arcane/utils/ITraceMng.h"
35#include "arcane/utils/FatalErrorException.h"
36
37#ifdef ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
38
39#include "arcane/core/IMeshMng.h"
40#include "arcane/core/MeshHandle.h"
41#include "arcane/core/IItemFamily.h"
42#include "arcane/core/internal/IMeshInternal.h"
43#include "arcane/utils/Collection.h"
44#include "arcane/utils/List.h"
45
46#include "neo/Mesh.h"
47#include "ItemConnectivityMng.h"
48
49#endif
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
54void Arcane::mesh::PolyhedralMesh::
55_errorEmptyMesh() const
56{
57 ARCANE_FATAL("Cannot use PolyhedralMesh if Arcane is not linked with lib Neo");
58}
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63namespace Arcane
64{
65
66/*---------------------------------------------------------------------------*/
67/*---------------------------------------------------------------------------*/
68
69namespace mesh
70{
71
72 /*---------------------------------------------------------------------------*/
73 /*---------------------------------------------------------------------------*/
74
76 : public ItemFamily
77 , public IDoFFamily
78 {
79 ItemSharedInfoWithType* m_shared_info = nullptr;
80 Int32UniqueArray m_empty_connectivity{ 0 };
81 Int32UniqueArray m_empty_connectivity_indexes;
82 Int32UniqueArray m_empty_connectivity_nb_item;
83
84 public:
85
86 inline static const String m_arcane_item_lids_property_name{ "Arcane_Item_Lids" }; // inline used to initialize within the declaration
87 inline static const String m_arcane_remove_item_property_name{ "Arcane_Remove_Items" }; // inline used to initialize within the declaration
88
89 public:
90
92 : ItemFamily(mesh, ik, name)
93 {}
94
95 public:
96
97 void preAllocate(Integer nb_item)
98 {
99 Integer nb_hash = itemsMap().nbBucket();
100 Integer wanted_size = 2 * (nb_item + nbItem());
101 if (nb_hash < wanted_size)
102 itemsMap().resize(wanted_size, true);
103 m_empty_connectivity_indexes.resize(nb_item + nbItem(), 0);
104 m_empty_connectivity_nb_item.resize(nb_item + nbItem(), 0);
105 _updateEmptyConnectivity();
106 }
107
108 ItemInternal* _allocItem(const Int64 uid)
109 {
110 bool need_alloc; // given by alloc
111 ItemInternal* item_internal = ItemFamily::_allocOne(uid, need_alloc);
112 if (!need_alloc)
113 item_internal->setUniqueId(uid);
114 else {
115 _allocateInfos(item_internal, uid, m_shared_info);
116 }
117 item_internal->setOwner(m_sub_domain_id, m_sub_domain_id);
118 return item_internal;
119 }
120
121 void addItems(Int64ConstSmallSpan uids, Int32ArrayView items)
122 {
123 if (uids.empty())
124 return;
125 ARCANE_ASSERT((uids.size() == items.size()), ("one must have items.size==uids.size()"));
126 m_mesh->traceMng()->debug(Arccore::Trace::Highest) << " PolyhedralFamily::addItems ";
127 preAllocate(uids.size());
128 auto index{ 0 };
129 for (auto uid : uids) {
130 ItemInternal* ii = _allocItem(uid);
131 items[index++] = ii->localId();
132 }
133 m_need_prepare_dump = true;
134 _updateItemInternalList();
135 }
136
137 void removeItems(Int32ConstArrayView local_ids)
138 {
139 _removeMany(local_ids);
140 }
141
142 void _updateItemInternalList()
143 {
144 switch (itemKind()) {
145 case IK_Cell:
146 m_item_internal_list->cells = _itemsInternal();
147 break;
148 case IK_Face:
149 m_item_internal_list->faces = _itemsInternal();
150 break;
151 case IK_Edge:
152 m_item_internal_list->edges = _itemsInternal();
153 break;
154 case IK_Node:
155 m_item_internal_list->nodes = _itemsInternal();
156 break;
157 case IK_DoF:
158 case IK_Particle:
159 case IK_Unknown:
160 break;
161 }
162 }
163
164 void _updateEmptyConnectivity()
165 {
166 auto item_internal_connectivity_list = itemInternalConnectivityList();
167 for (auto item_kind = 0; item_kind < ItemInternalConnectivityList::MAX_ITEM_KIND; ++item_kind) {
168 item_internal_connectivity_list->_setConnectivityList(item_kind, m_empty_connectivity);
169 item_internal_connectivity_list->_setConnectivityIndex(item_kind, m_empty_connectivity_indexes);
170 item_internal_connectivity_list->_setConnectivityNbItem(item_kind, m_empty_connectivity_nb_item);
171 }
172 }
173
174 // IItemFamily
176 return this;
177 }
178 // todo bloquer toutes les methodes d'allocation de IItemFamily
179
180 void build() override {
181 ItemFamily::build();
182 m_sub_domain_id = subDomain()->subDomainId();
183 ItemTypeMng* itm = m_mesh->itemTypeMng();
184 ItemTypeInfo* dof_type_info = itm->typeFromId(IT_NullType);
185 m_shared_info = _findSharedInfo(dof_type_info);
186 _updateEmptyConnectivity();
187 }
188
189 // IDoFFamily
190 String name() const override { return ItemFamily::name(); }
191 String fullName() const override { return ItemFamily::fullName(); }
192 Integer nbItem() const override { return ItemFamily::nbItem(); }
193 ItemGroup allItems() const override { return ItemFamily::allItems(); }
194 void endUpdate() override { info() << "END UPDATE "<< m_name ; return ItemFamily::endUpdate(); }
195 IItemFamily* itemFamily() override { return this; }
196
197
199 auto* polyhedral_mesh_modifier = m_mesh->_internalApi()->polyhedralMeshModifier();
201 polyhedral_mesh_modifier->addItems(dof_uids, dof_lids, ItemFamily::itemKind(), name());
202 return ItemFamily::view(dof_lids);
203 }
204
207 {
208 ARCANE_NOT_YET_IMPLEMENTED("");
209 ARCANE_UNUSED(dof_uids);
210 ARCANE_UNUSED(owners);
211 return ItemFamily::view(dof_lids);
212 }
213
214 void removeDoFs(Int32ConstArrayView items_local_id){
215 auto* mesh_modifier = m_mesh->_internalApi()->polyhedralMeshModifier();
216 mesh_modifier->removeItems(items_local_id, ItemFamily::itemKind(), m_name);
217 }
218 };
219
220} // namespace mesh
221/*---------------------------------------------------------------------------*/
222/*---------------------------------------------------------------------------*/
223
224} // namespace Arcane
225
226/*---------------------------------------------------------------------------*/
227/*---------------------------------------------------------------------------*/
228
229#ifdef ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
230
231/*---------------------------------------------------------------------------*/
232/*---------------------------------------------------------------------------*/
233
234namespace Arcane
235{
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
239
240namespace mesh
241{
242
243 /*---------------------------------------------------------------------------*/
244 /*---------------------------------------------------------------------------*/
245
246 class PolyhedralMeshImpl
247 {
248 ISubDomain* m_subdomain;
249 Neo::Mesh m_mesh{ "Test" };
250
251 template <eItemKind IK>
252 class ItemKindTraits
253 {
254 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_None;
255 };
256
257 static Neo::ItemKind itemKindArcaneToNeo(eItemKind ik)
258 {
259 switch (ik) {
260 case IK_Cell:
261 return Neo::ItemKind::IK_Cell;
262 case IK_Face:
263 return Neo::ItemKind::IK_Face;
264 case IK_Edge:
265 return Neo::ItemKind::IK_Edge;
266 case IK_Node:
267 return Neo::ItemKind::IK_Node;
268 case IK_DoF:
269 return Neo::ItemKind::IK_Dof;
270 case IK_Unknown:
271 case IK_Particle:
272 return Neo::ItemKind::IK_None;
273 }
274 return Neo::ItemKind::IK_Node;
275 }
276
277 public:
278
279 class ItemLocalIds
280 {
281 Neo::FutureItemRange m_future_items;
282
283 public:
284 void fillArrayView(Int32ArrayView local_ids, Neo::EndOfMeshUpdate mesh_state)
285 {
286 auto lids = m_future_items.get(mesh_state);
287 std::copy(lids.begin(),lids.end(),local_ids.begin());
288 }
289 friend class PolyhedralMeshImpl;
290 };
291
292 public:
293
294 explicit PolyhedralMeshImpl(ISubDomain* subDomain)
295 : m_subdomain(subDomain)
296 {}
297
298 public:
299
300 String name() const { return m_mesh.name(); }
301
302 Integer dimension() const { return m_mesh.dimension(); }
303
304 Integer nbNode() const { return m_mesh.nbNodes(); }
305 Integer nbEdge() const { return m_mesh.nbEdges(); }
306 Integer nbFace() const { return m_mesh.nbFaces(); }
307 Integer nbCell() const { return m_mesh.nbCells(); }
308 Integer nbItem(eItemKind ik) const { return m_mesh.nbItems(itemKindArcaneToNeo(ik)); }
309
310 static void _setFaceInfos(Int32 mod_flags, Face& face)
311 {
312 Int32 face_flags = face.itemBase().flags();
313 face_flags &= ~ItemFlags::II_InterfaceFlags;
314 face_flags |= mod_flags;
315 face.mutableItemBase().setFlags(face_flags);
316 }
317
318 /*---------------------------------------------------------------------------*/
319
320 void addFamily(eItemKind ik, const String& name)
321 {
322 m_mesh.addFamily(itemKindArcaneToNeo(ik), name.localstr());
323 }
324
325 /*---------------------------------------------------------------------------*/
326
327 void scheduleAddItems(PolyhedralFamily* arcane_item_family,
328 Int64ConstSmallSpan uids,
329 ItemLocalIds& item_local_ids)
330 {
331 auto& added_items = item_local_ids.m_future_items;
332 auto& item_family = m_mesh.findFamily(itemKindArcaneToNeo(arcane_item_family->itemKind()),
333 arcane_item_family->name().localstr());
334 m_mesh.scheduleAddItems(item_family, std::vector<Int64>{ uids.begin(), uids.end() }, added_items);
335 // add arcane items
336 auto& mesh_graph = m_mesh.internalMeshGraph();
337 item_family.addMeshScalarProperty<Neo::utils::Int32>(PolyhedralFamily::m_arcane_item_lids_property_name.localstr());
338 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ item_family, item_family.lidPropName() },
339 Neo::MeshKernel::OutProperty{ item_family, PolyhedralFamily::m_arcane_item_lids_property_name.localstr() },
340 [arcane_item_family, uids,added_items](Neo::ItemLidsProperty const& lids_property,
341 Neo::MeshScalarPropertyT<Neo::utils::Int32>&) {
342 Int32UniqueArray arcane_items(uids.size());
343 arcane_item_family->addItems(uids, arcane_items);
344 arcane_item_family->traceMng()->debug(Trace::Highest) << arcane_items;
345 // debug check lid matching. maybe to remove if too coostly
346 auto neo_lids = lids_property.values();
347 if (!std::equal(neo_lids.begin(), neo_lids.end(), arcane_items.begin()))
348 if (!std::equal(added_items.new_items.begin(), added_items.new_items.end(), arcane_items.begin()))
349 arcane_item_family->traceMng()->fatal() << "Inconsistent item lids generation between Arcane and Neo.";
350 });
351 }
352
353 /*---------------------------------------------------------------------------*/
354
355 void scheduleRemoveItems(PolyhedralFamily* arcane_item_family,
356 Int32ConstArrayView local_ids)
357 {
358 auto& item_family = m_mesh.findFamily(itemKindArcaneToNeo(arcane_item_family->itemKind()),
359 arcane_item_family->name().localstr());
360 Neo::ItemRange removed_items{Neo::ItemLocalIds{{local_ids.begin(),local_ids.end()},0,0}};
361 m_mesh.scheduleRemoveItems(item_family, removed_items);
362 // Remove Arcane items
363 auto& mesh_graph = m_mesh.internalMeshGraph();
364 item_family.addMeshScalarProperty<Neo::utils::Int32>(PolyhedralFamily::m_arcane_remove_item_property_name.localstr());
365 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ item_family, m_mesh._removeItemPropertyName(item_family) },
366 Neo::MeshKernel::OutProperty{ item_family, PolyhedralFamily::m_arcane_remove_item_property_name.localstr() },
367 [arcane_item_family,local_ids](Neo::MeshScalarPropertyT<Neo::utils::Int32> const&,
368 Neo::MeshScalarPropertyT<Neo::utils::Int32>&) {
369 // plutôt utiliser remove property ?
370 arcane_item_family->removeItems(local_ids);
371 });
372 }
373
374 /*---------------------------------------------------------------------------*/
375
376 void scheduleAddConnectivity(PolyhedralFamily* arcane_source_item_family,
377 ItemLocalIds& source_items,
378 Integer nb_connected_items_per_item,
379 PolyhedralFamily* arcane_target_item_family,
380 Int64ConstArrayView target_items_uids,
381 String const& name)
382 {
383 // add connectivity in Neo
384 _scheduleAddConnectivity(arcane_source_item_family,
385 source_items,
386 nb_connected_items_per_item,
387 arcane_target_item_family,
388 target_items_uids,
389 name);
390 }
391
392 /*---------------------------------------------------------------------------*/
393
394 void scheduleAddConnectivity(PolyhedralFamily* arcane_source_item_family,
395 ItemLocalIds& source_items,
396 Int32ConstSmallSpan nb_connected_items_per_item,
397 PolyhedralFamily* arcane_target_item_family,
398 Int64ConstSmallSpan target_items_uids,
399 String const& connectivity_name)
400 {
401 _scheduleAddConnectivity(arcane_source_item_family,
402 source_items,
403 std::vector<Int32>{ nb_connected_items_per_item.begin(), nb_connected_items_per_item.end() },
404 arcane_target_item_family,
405 target_items_uids,
406 connectivity_name);
407 }
408
409 /*---------------------------------------------------------------------------*/
410
411 // template to handle nb_items_per_item type (an int or an array)
412 template <typename ConnectivitySizeType>
413 void _scheduleAddConnectivity(PolyhedralFamily* arcane_source_item_family,
414 ItemLocalIds& source_items,
415 ConnectivitySizeType&& nb_connected_items_per_item,
416 PolyhedralFamily* arcane_target_item_family,
417 Int64ConstSmallSpan target_item_uids,
418 String const& connectivity_name)
419 {
420 // add connectivity in Neo
421 auto& source_family = m_mesh.findFamily(itemKindArcaneToNeo(arcane_source_item_family->itemKind()),
422 arcane_source_item_family->name().localstr());
423 auto& target_family = m_mesh.findFamily(itemKindArcaneToNeo(arcane_target_item_family->itemKind()),
424 arcane_target_item_family->name().localstr());
425 // Remove connectivities with a null item
426 std::vector<Int64> target_item_uids_filtered;
427 target_item_uids_filtered.reserve(target_item_uids.size());
428 std::copy_if(target_item_uids.begin(),
429 target_item_uids.end(),
430 std::back_inserter(target_item_uids_filtered),
431 [](auto uid) { return uid != NULL_ITEM_UNIQUE_ID; });
432 // Add connectivity in Neo (async)
433 m_mesh.scheduleAddConnectivity(source_family, source_items.m_future_items, target_family,
434 std::forward<ConnectivitySizeType>(nb_connected_items_per_item),
435 std::move(target_item_uids_filtered),
436 connectivity_name.localstr());
437 // Register Neo connectivities in Arcane
438 auto& mesh_graph = m_mesh.internalMeshGraph();
439 std::string connectivity_add_output_property_name = std::string{ "EndOf" } + connectivity_name.localstr() + "Add";
440 source_family.addScalarProperty<Neo::utils::Int32>(connectivity_add_output_property_name);
441 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ source_family, connectivity_name.localstr() },
442 Neo::MeshKernel::OutProperty{ source_family, connectivity_add_output_property_name },
443 [arcane_source_item_family, arcane_target_item_family, &source_family, &target_family, this, connectivity_name](Neo::Mesh::ConnectivityPropertyType const&,
444 Neo::ScalarPropertyT<Neo::utils::Int32>&) {
445 auto item_internal_connectivity_list = arcane_source_item_family->itemInternalConnectivityList();
446 // todo check if families are default families
447 auto connectivity = m_mesh.getConnectivity(source_family, target_family, connectivity_name.localstr());
448 // to access connectivity data (for initializing Arcane connectivities) create a proxy on Neo connectivity
449 auto& connectivity_values = source_family.getConcreteProperty<Neo::Mesh::ConnectivityPropertyType>(connectivity_name.localstr());
450 Neo::MeshArrayPropertyProxyT<Neo::Mesh::ConnectivityPropertyType::PropertyDataType> connectivity_proxy{connectivity_values};
451 auto nb_item_data = connectivity_proxy.arrayPropertyOffsets();
452 auto nb_item_size = connectivity_proxy.arrayPropertyOffsetsSize(); // todo check MeshArrayProperty::size
453 item_internal_connectivity_list->_setConnectivityNbItem(arcane_target_item_family->itemKind(),
454 Int32ArrayView{ Integer(nb_item_size), nb_item_data });
455 auto max_nb_connected_items = connectivity.maxNbConnectedItems();
456 item_internal_connectivity_list->_setMaxNbConnectedItem(arcane_target_item_family->itemKind(), max_nb_connected_items);
457 auto connectivity_values_data = connectivity_proxy.arrayPropertyData();
458 auto connectivity_values_size = connectivity_proxy.arrayPropertyDataSize();
459 item_internal_connectivity_list->_setConnectivityList(arcane_target_item_family->itemKind(),
460 Int32ArrayView{ Integer(connectivity_values_size), connectivity_values_data });
461 auto connectivity_index_data = connectivity_proxy.arrayPropertyIndex();
462 auto connectivity_index_size = connectivity_proxy.arrayPropertyIndexSize();
463 item_internal_connectivity_list->_setConnectivityIndex(arcane_target_item_family->itemKind(),
464 Int32ArrayView{ Integer(connectivity_index_size), connectivity_index_data });
465 });
466 // If FaceToCellConnectivity Add face flags II_Boundary, II_SubdomainBoundary, II_HasFrontCell, II_HasBackCell
467 if (arcane_source_item_family->itemKind() == IK_Face && arcane_target_item_family->itemKind() == IK_Cell) {
468 std::string flag_definition_output_property_name{ "EndOfFlagDefinition" };
469 source_family.addScalarProperty<Neo::utils::Int32>(flag_definition_output_property_name);
470 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ source_family, connectivity_add_output_property_name }, Neo::MeshKernel::OutProperty{ source_family, flag_definition_output_property_name },
471 [arcane_source_item_family, this, target_item_uids, &source_items](Neo::ScalarPropertyT<Neo::utils::Int32> const&, Neo::ScalarPropertyT<Neo::utils::Int32> const&) {
472 auto current_face_index = 0;
473 auto arcane_faces = arcane_source_item_family->itemInfoListView();
474 for (auto face_lid : source_items.m_future_items.new_items) {
475 Face current_face = arcane_faces[face_lid].toFace();
476 if (target_item_uids[2 * current_face_index + 1] == NULL_ITEM_LOCAL_ID) {
477 // if (current_face.frontCell().null()) {
478 // Reste uniquement la back_cell ou aucune maille.
479 Int32 mod_flags = (target_item_uids[2 * current_face_index] != NULL_ITEM_LOCAL_ID) ? (ItemFlags::II_Boundary | ItemFlags::II_HasBackCell | ItemFlags::II_BackCellIsFirst) : 0;
480 _setFaceInfos(mod_flags, current_face);
481 }
482 else if (target_item_uids[2 * current_face_index] == NULL_ITEM_LOCAL_ID) {
483 // Reste uniquement la front cell
484 _setFaceInfos(ItemFlags::II_Boundary | ItemFlags::II_HasFrontCell | ItemFlags::II_FrontCellIsFirst, current_face);
485 }
486 else {
487 // Il y a deux mailles connectées.
488 _setFaceInfos(ItemFlags::II_HasFrontCell | ItemFlags::II_HasBackCell | ItemFlags::II_BackCellIsFirst, current_face);
489 }
490 ++current_face_index;
491 }
492 });
493 }
494 }
495
496 /*---------------------------------------------------------------------------*/
497
498 void scheduleSetItemCoordinates(PolyhedralFamily* item_family, ItemLocalIds& local_ids, Real3ConstSmallSpan item_coords, VariableItemReal3& arcane_coords)
499 {
500 auto& _item_family = m_mesh.findFamily(itemKindArcaneToNeo(item_family->itemKind()), item_family->name().localstr());
501 std::vector<Neo::utils::Real3> _node_coords(item_coords.size());
502 auto node_index = 0;
503 for (auto&& node_coord : item_coords) {
504 _node_coords[node_index++] = Neo::utils::Real3{ node_coord.x, node_coord.y, node_coord.z };
505 }
506 m_mesh.scheduleSetItemCoords(_item_family, local_ids.m_future_items, _node_coords);
507 // Fill Arcane Variable
508 auto& mesh_graph = m_mesh.internalMeshGraph();
509 _item_family.addScalarProperty<Int32>("NoOutProperty42"); // todo remove : create noOutput algo in Neo
510 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ _item_family, m_mesh._itemCoordPropertyName(_item_family) },
511 Neo::MeshKernel::OutProperty{ _item_family, "NoOutProperty42" },
512 [this, item_family, &_item_family, &arcane_coords](Neo::Mesh::CoordPropertyType const& item_coords_property,
513 Neo::ScalarPropertyT<Neo::utils::Int32>&) {
514 // enumerate nodes : ensure again Arcane/Neo local_ids are identicals
515 auto& all_items = _item_family.all();
516 VariableNodeReal3 node_coords{ VariableBuildInfo{ item_family->mesh(), "NodeCoord" } };
517 for (auto item : all_items) {
518 arcane_coords[ItemLocalId{ item }] = { item_coords_property[item].x,
519 item_coords_property[item].y,
520 item_coords_property[item].z };
521 // std::cout << "x y z : " << item_coords_property[item].x << " "
522 // << item_coords_property[item].y << " "
523 // << item_coords_property[item].z;
524 }
525 });
526 }
527
528 /*---------------------------------------------------------------------------*/
529
530 Neo::EndOfMeshUpdate applyScheduledOperations() noexcept
531 {
532 return m_mesh.applyScheduledOperations();
533 }
534
535 };
536
537 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_Cell>
538 {
539 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Cell;
540 };
541 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_Face>
542 {
543 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Face;
544 };
545 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_Edge>
546 {
547 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Edge;
548 };
549 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_Node>
550 {
551 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Node;
552 };
553 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_DoF>
554 {
555 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Dof;
556 };
557
558} // End namespace mesh
559
560/*---------------------------------------------------------------------------*/
561/*---------------------------------------------------------------------------*/
562
563class mesh::PolyhedralMesh::PolyhedralMeshModifier
564: public IPolyhedralMeshModifier
565{
566 public:
567
568 explicit PolyhedralMeshModifier(PolyhedralMesh* mesh)
569 : m_mesh(mesh)
570 {}
571
572 void addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, eItemKind ik, const String& family_name) override
573 {
574 m_mesh->addItems(unique_ids,local_ids,ik,family_name);
575 }
576
577 void removeItems(Int32ConstArrayView local_ids, eItemKind ik, const String& family_name) override
578 {
579 m_mesh->removeItems(local_ids, ik, family_name);
580 }
581
582 private:
583 PolyhedralMesh* m_mesh;
584};
585
586/*---------------------------------------------------------------------------*/
587/*---------------------------------------------------------------------------*/
588
589class mesh::PolyhedralMesh::InternalApi
590: public IMeshInternal
591{
592 public:
593
594 explicit InternalApi(PolyhedralMesh* mesh)
595 : m_mesh(mesh)
596 , m_connectivity_mng(std::make_unique<ItemConnectivityMng>(mesh->traceMng()))
597 , m_polyhedral_mesh_modifier(std::make_unique<PolyhedralMeshModifier>(mesh))
598 {}
599
600 public:
601
602 void setMeshKind(const MeshKind& v) override
603 {
604 if (v.meshStructure() != eMeshStructure::Polyhedral && v.meshAMRKind() != eMeshAMRKind::None) {
605 ARCANE_FATAL("Incompatible mesh structure ({0}) and amr kind ({1}) for Polyhedral mesh {2}. Must be (Polyhedral,None). ",
606 v.meshStructure(),v.meshAMRKind(), m_mesh->name());
607 }
608 m_mesh->m_mesh_kind = v;
609 }
610
611 IItemConnectivityMng* dofConnectivityMng() const noexcept override
612 {
613 return m_connectivity_mng.get();
614 }
615
616 IPolyhedralMeshModifier* polyhedralMeshModifier() const noexcept override
617 {
618 return m_polyhedral_mesh_modifier.get();
619 }
620
621 private:
622
623 PolyhedralMesh* m_mesh = nullptr;
624 std::unique_ptr<IItemConnectivityMng> m_connectivity_mng = nullptr;
625 std::unique_ptr<IPolyhedralMeshModifier> m_polyhedral_mesh_modifier = nullptr;
626};
627
628/*---------------------------------------------------------------------------*/
629/*---------------------------------------------------------------------------*/
630
631class mesh::PolyhedralMesh::NoCompactionMeshCompacter
632: public IMeshCompacter
633{
634 public:
635 explicit NoCompactionMeshCompacter(PolyhedralMesh* mesh)
636 : m_mesh(mesh)
637 , m_trace_mng(mesh->traceMng()){}
638
639 void doAllActions() override {_info();};
640
641 void beginCompact() override {_info();};
642 void compactVariablesAndGroups() override {_info();};
643 void updateInternalReferences() override {_info();};
644 void endCompact() override {_info();};
645 void finalizeCompact() override {_info();};
646
647 IMesh* mesh() const override {return m_mesh;};
648
649 const ItemFamilyCompactInfos* findCompactInfos(IItemFamily* family) const override {_info(); return nullptr;}
650
651 ePhase phase() const override {_info(); return ePhase::Ended;}
652
653 void setSorted(bool v) override {_info();};
654
655 bool isSorted() const override {_info();return false;};
656
657 ItemFamilyCollection families() const override {_info();return ItemFamilyCollection {};};
658
659 void _setCompactVariablesAndGroups(bool v) override {_info();};
660
661 private:
662 PolyhedralMesh* m_mesh = nullptr;
663 ITraceMng* m_trace_mng = nullptr;
664
665 void _info() const {m_trace_mng->info() << A_FUNCINFO << "No compacting in PolyhedralMesh";}
666};
667
668/*---------------------------------------------------------------------------*/
669/*---------------------------------------------------------------------------*/
670
671class mesh::PolyhedralMesh::NoCompactionMeshCompactMng
672: public IMeshCompactMng
673{
674 public:
675 explicit NoCompactionMeshCompactMng(PolyhedralMesh* mesh)
676 : m_mesh(mesh)
677 , m_trace_mng(mesh->traceMng())
678 , m_mesh_compacter{std::make_unique<NoCompactionMeshCompacter>(m_mesh)}
679 {}
680
681 IMesh* mesh() const override {return m_mesh;}
682 IMeshCompacter* beginCompact() override
683 {
684 _info();
685 return m_mesh_compacter.get();
686 }
687
688 IMeshCompacter* beginCompact(IItemFamily* family) override
689 {
690 ARCANE_UNUSED(family);
691 _info();
692 return m_mesh_compacter.get();
693 };
694
695 void endCompact() override {_info();};
696
697 IMeshCompacter* compacter() override
698 {
699 _info();
700 return m_mesh_compacter.get();
701 };
702
703
704 private:
705 PolyhedralMesh* m_mesh = nullptr;
706 ITraceMng* m_trace_mng = nullptr;
707 std::unique_ptr<IMeshCompacter> m_mesh_compacter = nullptr;
708
709 void _info() const {m_trace_mng->info() << A_FUNCINFO << "No compacting in PolyhedralMesh";}
710};
711
712/*---------------------------------------------------------------------------*/
713/*---------------------------------------------------------------------------*/
714
715mesh::PolyhedralMesh::
716~PolyhedralMesh()
717{
718 m_mesh_handle._setMesh(nullptr);
719}
720
721/*---------------------------------------------------------------------------*/
722/*---------------------------------------------------------------------------*/
723
724ITraceMng* mesh::PolyhedralMesh::
725traceMng()
726{
727 return m_subdomain->traceMng();
728}
729
730/*---------------------------------------------------------------------------*/
731/*---------------------------------------------------------------------------*/
732
733MeshHandle mesh::PolyhedralMesh::
734handle() const
735{
736 return m_mesh_handle;
737}
738
739/*---------------------------------------------------------------------------*/
740/*---------------------------------------------------------------------------*/
741
742mesh::PolyhedralMesh::
743PolyhedralMesh(ISubDomain* subdomain, const MeshBuildInfo& mbi)
744: EmptyMesh{ subdomain->traceMng() }
745, m_name{ mbi.name() }
746, m_subdomain{ subdomain }
747, m_mesh_handle{ m_subdomain->defaultMeshHandle() }
748, m_properties(std::make_unique<Properties>(subdomain->propertyMng(), String("ArcaneMeshProperties_") + m_name))
749, m_mesh{ std::make_unique<mesh::PolyhedralMeshImpl>(m_subdomain) }
750, m_parallel_mng{ mbi.parallelMngRef().get() }
751, m_mesh_part_info{ makeMeshPartInfoFromParallelMng(m_parallel_mng) }
752, m_item_type_mng(ItemTypeMng::_singleton())
753, m_mesh_kind(mbi.meshKind())
754, m_initial_allocator(*this)
755, m_variable_mng{ subdomain->variableMng() }
756, m_mesh_checker{ this }
757, m_internal_api{std::make_unique<InternalApi>(this)}
758, m_compact_mng{std::make_unique<NoCompactionMeshCompactMng>(this)}
759{
760 m_mesh_handle._setMesh(this);
761 m_mesh_item_internal_list.mesh = this;
762 m_default_arcane_families.fill(nullptr);
763}
764
765/*---------------------------------------------------------------------------*/
766/*---------------------------------------------------------------------------*/
767
768void Arcane::mesh::PolyhedralMesh::
769allocateItems(const Arcane::ItemAllocationInfo& item_allocation_info)
770{
771 // Second step read a vtk polyhedral mesh
772 m_subdomain->traceMng()->info() << "--PolyhedralMesh : allocate items --";
773 UniqueArray<PolyhedralMeshImpl::ItemLocalIds> item_local_ids(item_allocation_info.family_infos.size());
774 auto family_index = 0;
775 // Prepare item creation
776 for (auto& family_info : item_allocation_info.family_infos) {
777 bool create_if_needed = true;
778 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name,create_if_needed);
779 m_trace_mng->debug() << " Create items " << family_info.name;
780 m_mesh->scheduleAddItems(item_family, family_info.item_uids, item_local_ids[family_index++]);
781 }
782 // Prepare connectivity creation
783 family_index = 0;
784 for (auto& family_info : item_allocation_info.family_infos) {
785 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name);
786 m_trace_mng->debug(Trace::High) << "Current family " << family_info.name;
787 for (auto& current_connected_family_info : family_info.connected_family_info) {
788 auto connected_family = _findItemFamily(current_connected_family_info.item_kind, current_connected_family_info.name);
789 m_trace_mng->debug(Trace::High) << " Create connectivity " << current_connected_family_info.connectivity_name;
790 // check if connected family exists
791 if (!connected_family) {
792 ARCANE_WARNING((String::format("Cannot find family {0} with kind {1} "
793 "The connectivity between {1} and this family is skipped",
794 current_connected_family_info.name,
795 current_connected_family_info.item_kind,
796 item_family->name())
797 .localstr()));
798 continue;
799 }
800 m_mesh->scheduleAddConnectivity(item_family,
801 item_local_ids[family_index],
802 current_connected_family_info.nb_connected_items_per_item,
803 connected_family,
804 current_connected_family_info.connected_items_uids,
805 current_connected_family_info.connectivity_name);
806 }
807 ++family_index;
808 }
809 // Create items and connectivities
810 m_mesh->applyScheduledOperations();
811 // Create variable for coordinates. This has to be done before call to family::endUpdate. Todo add to the graph
812 for (auto& family_info : item_allocation_info.family_infos) {
813 if (family_info.item_coordinates.empty()) {
814 ++family_index;
815 continue;
816 }
817 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name);
818 if (item_family == itemFamily(IK_Node)) { // mesh node coords
819 m_arcane_node_coords = std::make_unique<VariableNodeReal3>(VariableBuildInfo(this, family_info.item_coordinates_variable_name));
820 m_arcane_node_coords->setUsed(true);
821 }
822 else {
823 auto arcane_item_coords_var_ptr = std::make_unique<VariableItemReal3>(VariableBuildInfo(this, family_info.item_coordinates_variable_name),
824 item_family->itemKind());
825 arcane_item_coords_var_ptr->setUsed(true);
826 m_arcane_item_coords.push_back(std::move(arcane_item_coords_var_ptr));
827 }
828 }
829 // Call Arcane ItemFamily endUpdate
830 for (auto& family : m_arcane_families) {
831 family->endUpdate();
832 }
833 endUpdate();
834 // Add coordinates when needed (nodes, or dof, or particles...)
835 family_index = 0;
836 auto index = 0;
837 for (auto& family_info : item_allocation_info.family_infos) {
838 if (family_info.item_coordinates.empty()) {
839 ++family_index;
840 continue;
841 }
842 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name);
843 if (item_family == itemFamily(IK_Node)) { // mesh node coords
844 m_mesh->scheduleSetItemCoordinates(item_family, item_local_ids[family_index], family_info.item_coordinates, *m_arcane_node_coords);
845 }
846 else
847 m_mesh->scheduleSetItemCoordinates(item_family, item_local_ids[family_index], family_info.item_coordinates, *m_arcane_item_coords[index++].get());
848 }
849 m_mesh->applyScheduledOperations();
850 m_is_allocated = true;
851 // indicates mesh contains general Cells
852 itemTypeMng()->setMeshWithGeneralCells(this);
853}
854
855/*---------------------------------------------------------------------------*/
856/*---------------------------------------------------------------------------*/
857
859name() const
860{
861 return m_name;
862}
863
864/*---------------------------------------------------------------------------*/
865/*---------------------------------------------------------------------------*/
866
868dimension()
869{
870 return m_mesh->dimension();
871}
872
873/*---------------------------------------------------------------------------*/
874/*---------------------------------------------------------------------------*/
875
877nbNode()
878{
879 return m_mesh->nbNode();
880}
881
882/*---------------------------------------------------------------------------*/
883/*---------------------------------------------------------------------------*/
884
886nbEdge()
887{
888 return m_mesh->nbEdge();
889}
890
891/*---------------------------------------------------------------------------*/
892/*---------------------------------------------------------------------------*/
893
895nbFace()
896{
897 return m_mesh->nbFace();
898}
899
900/*---------------------------------------------------------------------------*/
901/*---------------------------------------------------------------------------*/
902
904nbCell()
905{
906 return m_mesh->nbCell();
907}
908
909/*---------------------------------------------------------------------------*/
910/*---------------------------------------------------------------------------*/
911
914{
915 return m_mesh->nbItem(ik);
916}
917
918/*---------------------------------------------------------------------------*/
919/*---------------------------------------------------------------------------*/
920
922allNodes()
923{
924 if (m_default_arcane_families[IK_Node])
925 return m_default_arcane_families[IK_Node]->allItems();
926 else
927 return NodeGroup{};
928}
929
930/*---------------------------------------------------------------------------*/
931/*---------------------------------------------------------------------------*/
932
934allEdges()
935{
936 if (m_default_arcane_families[IK_Edge])
937 return m_default_arcane_families[IK_Edge]->allItems();
938 else
939 return EdgeGroup{};
940}
941
942/*---------------------------------------------------------------------------*/
943/*---------------------------------------------------------------------------*/
944
946allFaces()
947{
948 if (m_default_arcane_families[IK_Face])
949 return m_default_arcane_families[IK_Face]->allItems();
950 else
951 return FaceGroup{};
952}
953
954/*---------------------------------------------------------------------------*/
955/*---------------------------------------------------------------------------*/
956
958allCells()
959{
960 if (m_default_arcane_families[IK_Cell])
961 return m_default_arcane_families[IK_Cell]->allItems();
962 else
963 return CellGroup{};
964}
965
966/*---------------------------------------------------------------------------*/
967/*---------------------------------------------------------------------------*/
968
970ownNodes()
971{
972 if (m_default_arcane_families[IK_Node])
973 return m_default_arcane_families[IK_Node]->allItems().own();
974 else
975 return NodeGroup{};
976}
977
978/*---------------------------------------------------------------------------*/
979/*---------------------------------------------------------------------------*/
980
982ownEdges()
983{
984 if (m_default_arcane_families[IK_Edge])
985 return m_default_arcane_families[IK_Edge]->allItems().own();
986 else
987 return EdgeGroup{};
988}
989
990/*---------------------------------------------------------------------------*/
991/*---------------------------------------------------------------------------*/
992
994ownFaces()
995{
996 if (m_default_arcane_families[IK_Face])
997 return m_default_arcane_families[IK_Face]->allItems().own();
998 else
999 return FaceGroup{};
1000}
1001
1002/*---------------------------------------------------------------------------*/
1003/*---------------------------------------------------------------------------*/
1004
1006ownCells()
1007{
1008 if (m_default_arcane_families[IK_Cell])
1009 return m_default_arcane_families[IK_Cell]->allItems().own();
1010 else
1011 return CellGroup{};
1012}
1013
1014/*---------------------------------------------------------------------------*/
1015/*---------------------------------------------------------------------------*/
1016
1018outerFaces()
1019{
1020 if (m_default_arcane_families[IK_Cell])
1021 return m_default_arcane_families[IK_Cell]->allItems().outerFaceGroup();
1022 else
1023 return FaceGroup{};
1024}
1025
1026/*---------------------------------------------------------------------------*/
1027/*---------------------------------------------------------------------------*/
1028
1029mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1030_createItemFamily(eItemKind ik, const String& name)
1031{
1032 m_mesh->addFamily(ik, name);
1033 m_arcane_families.push_back(std::make_unique<PolyhedralFamily>(this, ik, name));
1034 auto current_family = m_arcane_families.back().get();
1035 if (m_default_arcane_families[ik] == nullptr) {
1036 m_default_arcane_families[ik] = current_family;
1037 _updateMeshInternalList(ik);
1038 }
1039 m_item_family_collection.add(current_family);
1040 current_family->build();
1041 return current_family;
1042}
1043
1044/*---------------------------------------------------------------------------*/
1045/*---------------------------------------------------------------------------*/
1046
1047IItemFamily* mesh::PolyhedralMesh::
1048createItemFamily(eItemKind ik, const String& name)
1049{
1050 return _createItemFamily(ik, name);
1051}
1052
1053/*---------------------------------------------------------------------------*/
1054/*---------------------------------------------------------------------------*/
1055
1056void mesh::PolyhedralMesh::
1057_createUnitMesh()
1058{
1059 createItemFamily(IK_Cell, "CellFamily");
1060 createItemFamily(IK_Node, "NodeFamily");
1061 auto cell_family = m_default_arcane_families[IK_Cell];
1062 auto node_family = m_default_arcane_families[IK_Node];
1063 Int64UniqueArray cell_uids{ 0 }, node_uids{ 0, 1, 2, 3, 4, 5 };
1064 // todo add a cell_lids struct (containing future)
1065 PolyhedralMeshImpl::ItemLocalIds cell_lids, node_lids;
1066 m_mesh->scheduleAddItems(cell_family, cell_uids.constView(), cell_lids);
1067 m_mesh->scheduleAddItems(node_family, node_uids.constView(), node_lids);
1068 int nb_node = 6;
1069 m_mesh->scheduleAddConnectivity(cell_family, cell_lids, nb_node, node_family, node_uids, String{ "CellToNodes" });
1070 m_mesh->scheduleAddConnectivity(node_family, node_lids, 1, cell_family,
1071 Int64UniqueArray{ 0, 0, 0, 0, 0, 0 }, String{ "NodeToCells" });
1072 m_mesh->applyScheduledOperations();
1073 cell_family->endUpdate();
1074 node_family->endUpdate();
1075 endUpdate();
1076 // Mimic what IMeshModifier::endUpdate would do => default families are completed.
1077 // Families created after a first endUpdate call are not default families
1078}
1079
1080/*---------------------------------------------------------------------------*/
1081/*---------------------------------------------------------------------------*/
1082
1083void mesh::PolyhedralMesh::
1084endUpdate()
1085{
1086 // create empty default families not already created
1087 for (auto ik = 0; ik < NB_ITEM_KIND; ++ik) {
1088 if (m_default_arcane_families[ik] == nullptr && ik != eItemKind::IK_DoF) {
1089 String name = String::concat(itemKindName((eItemKind)ik), "EmptyFamily");
1090 m_empty_arcane_families[ik] = std::make_unique<mesh::PolyhedralFamily>(this, (eItemKind)ik, name);
1091 m_default_arcane_families[ik] = m_empty_arcane_families[ik].get();
1092 }
1093 }
1094}
1095
1096/*---------------------------------------------------------------------------*/
1097/*---------------------------------------------------------------------------*/
1098
1099IItemFamily* mesh::PolyhedralMesh::
1100nodeFamily()
1101{
1102 return m_default_arcane_families[IK_Node];
1103}
1104
1105/*---------------------------------------------------------------------------*/
1106/*---------------------------------------------------------------------------*/
1107
1108IItemFamily* mesh::PolyhedralMesh::
1109edgeFamily()
1110{
1111 return m_default_arcane_families[IK_Edge];
1112}
1113
1114/*---------------------------------------------------------------------------*/
1115/*---------------------------------------------------------------------------*/
1116
1117IItemFamily* mesh::PolyhedralMesh::
1118faceFamily()
1119{
1120 return m_default_arcane_families[IK_Face];
1121}
1122
1123/*---------------------------------------------------------------------------*/
1124/*---------------------------------------------------------------------------*/
1125
1126IItemFamily* mesh::PolyhedralMesh::
1127cellFamily()
1128{
1129 return m_default_arcane_families[IK_Cell];
1130}
1131
1132void mesh::PolyhedralMesh::
1133_updateMeshInternalList(eItemKind kind)
1134{
1135 switch (kind) {
1136 case IK_Cell:
1137 m_mesh_item_internal_list.cells = m_default_arcane_families[kind]->itemsInternal();
1138 m_mesh_item_internal_list._internalSetCellSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1139 break;
1140 case IK_Face:
1141 m_mesh_item_internal_list.faces = m_default_arcane_families[kind]->itemsInternal();
1142 m_mesh_item_internal_list._internalSetFaceSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1143 break;
1144 case IK_Edge:
1145 m_mesh_item_internal_list.edges = m_default_arcane_families[kind]->itemsInternal();
1146 m_mesh_item_internal_list._internalSetEdgeSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1147 break;
1148 case IK_Node:
1149 m_mesh_item_internal_list.nodes = m_default_arcane_families[kind]->itemsInternal();
1150 m_mesh_item_internal_list._internalSetNodeSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1151 break;
1152 case IK_DoF:
1153 case IK_Particle:
1154 case IK_Unknown:
1155 break;
1156 }
1157}
1158
1159/*---------------------------------------------------------------------------*/
1160/*---------------------------------------------------------------------------*/
1161
1162mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1163_itemFamily(eItemKind ik)
1164{
1165 return m_default_arcane_families[ik];
1166}
1167
1168/*---------------------------------------------------------------------------*/
1169/*---------------------------------------------------------------------------*/
1170
1171IItemFamily* mesh::PolyhedralMesh::
1173{
1174 return _itemFamily(ik);
1175}
1176
1177/*---------------------------------------------------------------------------*/
1178/*---------------------------------------------------------------------------*/
1179
1180ItemTypeMng* mesh::PolyhedralMesh::
1181itemTypeMng() const
1182{
1183 return m_item_type_mng;
1184}
1185
1186/*---------------------------------------------------------------------------*/
1187/*---------------------------------------------------------------------------*/
1188
1189mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1190_findItemFamily(eItemKind ik, const String& name, bool create_if_needed)
1191{
1192 // Check if is a default family
1193 auto found_family = _itemFamily(ik);
1194 if (found_family) {
1195 if (found_family->name() == name)
1196 return found_family;
1197 }
1198 for (auto& family : m_arcane_families) {
1199 if (family->itemKind() == ik && family->name() == name)
1200 return family.get();
1201 }
1202 if (!create_if_needed)
1203 return nullptr;
1204 return _createItemFamily(ik, name);
1205}
1206
1207/*---------------------------------------------------------------------------*/
1208/*---------------------------------------------------------------------------*/
1209
1210IItemFamily* mesh::PolyhedralMesh::
1211findItemFamily(eItemKind ik, const String& name, bool create_if_needed, bool register_modifier_if_created)
1212{
1213 ARCANE_UNUSED(register_modifier_if_created); // IItemFamilyModifier not yet used in polyhedral mesh
1214 return _findItemFamily(ik, name, create_if_needed);
1215}
1216
1217/*---------------------------------------------------------------------------*/
1218/*---------------------------------------------------------------------------*/
1219
1220mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1221arcaneDefaultFamily(eItemKind ik)
1222{
1223 return m_default_arcane_families[ik];
1224}
1225
1226/*---------------------------------------------------------------------------*/
1227/*---------------------------------------------------------------------------*/
1228
1231{
1232 ARCANE_ASSERT(m_arcane_node_coords, ("Node coordinates not yet loaded."));
1233 return *m_arcane_node_coords;
1234}
1235
1236/*---------------------------------------------------------------------------*/
1237/*---------------------------------------------------------------------------*/
1238
1239ItemGroup mesh::PolyhedralMesh::
1240findGroup(const String& name)
1241{
1242 ItemGroup group;
1243 for (auto& family : m_arcane_families) {
1244 group = family->findGroup(name);
1245 if (!group.null())
1246 return group;
1247 }
1248 return group;
1249}
1250
1251/*---------------------------------------------------------------------------*/
1252/*---------------------------------------------------------------------------*/
1253
1255groups()
1256{
1257 m_all_groups.clear();
1258 for (auto& family : m_arcane_families) {
1259 for (ItemGroupCollection::Enumerator i_group(family->groups()); ++i_group;)
1260 m_all_groups.add(*i_group);
1261 }
1262 return m_all_groups;
1263}
1264
1265/*---------------------------------------------------------------------------*/
1266/*---------------------------------------------------------------------------*/
1267
1270{
1271 for (auto& family : m_arcane_families) {
1272 family->destroyGroups();
1273 }
1274}
1275
1276/*---------------------------------------------------------------------------*/
1277/*---------------------------------------------------------------------------*/
1278
1279IItemFamilyCollection mesh::PolyhedralMesh::
1280itemFamilies()
1281{
1282 return m_item_family_collection;
1283}
1284
1285/*---------------------------------------------------------------------------*/
1286/*---------------------------------------------------------------------------*/
1287
1288IMeshInternal* mesh::PolyhedralMesh::
1290{
1291 return m_internal_api.get();
1292}
1293
1294/*---------------------------------------------------------------------------*/
1295/*---------------------------------------------------------------------------*/
1296
1297IMeshCompactMng* mesh::PolyhedralMesh::
1299{
1300 return m_compact_mng.get();
1301}
1302
1303/*---------------------------------------------------------------------------*/
1304/*---------------------------------------------------------------------------*/
1305
1306void mesh::PolyhedralMesh::
1307addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, eItemKind ik, const String& family_name)
1308{
1309 auto* item_family = _findItemFamily(ik, family_name, false);
1310 PolyhedralMeshImpl::ItemLocalIds item_local_ids;
1311 m_mesh->scheduleAddItems(item_family,unique_ids,item_local_ids);
1312 auto mesh_state = m_mesh->applyScheduledOperations();
1313 item_local_ids.fillArrayView(local_ids,mesh_state);
1314}
1315
1316/*---------------------------------------------------------------------------*/
1317/*---------------------------------------------------------------------------*/
1318
1319void mesh::PolyhedralMesh::
1320removeItems(Int32ConstArrayView local_ids, eItemKind ik, const String& family_name)
1321{
1322 auto* item_family = _findItemFamily(ik, family_name, false);
1323 m_mesh->scheduleRemoveItems(item_family,local_ids);
1324 m_mesh->applyScheduledOperations();
1325}
1326
1327/*---------------------------------------------------------------------------*/
1328/*---------------------------------------------------------------------------*/
1329
1332{
1333 return allCells().activeCellGroup();
1334}
1335
1336/*---------------------------------------------------------------------------*/
1337/*---------------------------------------------------------------------------*/
1338
1340{
1341 return allCells().ownActiveCellGroup();
1342}
1343
1344/*---------------------------------------------------------------------------*/
1345/*---------------------------------------------------------------------------*/
1346
1348allLevelCells(const Integer& level)
1349{
1350 return allCells().levelCellGroup(level);
1351}
1352
1353/*---------------------------------------------------------------------------*/
1354/*---------------------------------------------------------------------------*/
1355
1357ownLevelCells(const Integer& level)
1358{
1359 return allCells().ownLevelCellGroup(level);
1360}
1361
1362/*---------------------------------------------------------------------------*/
1363/*---------------------------------------------------------------------------*/
1364
1367{
1368 return allCells().activeFaceGroup();
1369}
1370
1371/*---------------------------------------------------------------------------*/
1372/*---------------------------------------------------------------------------*/
1373
1376{
1377 return allCells().ownActiveFaceGroup();
1378}
1379
1380/*---------------------------------------------------------------------------*/
1381/*---------------------------------------------------------------------------*/
1382
1385{
1386 return allCells().innerActiveFaceGroup();
1387}
1388
1389/*---------------------------------------------------------------------------*/
1390/*---------------------------------------------------------------------------*/
1391
1393{
1394 return allCells().outerActiveFaceGroup();
1395}
1396
1397/*---------------------------------------------------------------------------*/
1398/*---------------------------------------------------------------------------*/
1399
1400
1401} // End namespace Arcane
1402
1403/*---------------------------------------------------------------------------*/
1404/*---------------------------------------------------------------------------*/
1405
1406#else // ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
1407
1408/*---------------------------------------------------------------------------*/
1409/*---------------------------------------------------------------------------*/
1410
1411namespace Arcane::mesh
1412{
1415} // namespace Arcane::mesh
1416
1417/*---------------------------------------------------------------------------*/
1418/*---------------------------------------------------------------------------*/
1419
1420Arcane::mesh::PolyhedralMesh::
1421~PolyhedralMesh() = default;
1422
1423/*---------------------------------------------------------------------------*/
1424/*---------------------------------------------------------------------------*/
1425
1426Arcane::mesh::PolyhedralMesh::
1427PolyhedralMesh(ISubDomain* subdomain, const MeshBuildInfo& mbi)
1428: EmptyMesh{ subdomain->traceMng() }
1429, m_subdomain{ subdomain }
1430, m_mesh{ nullptr }
1431, m_mesh_kind(mbi.meshKind())
1432{
1433}
1434
1435/*---------------------------------------------------------------------------*/
1436/*---------------------------------------------------------------------------*/
1437
1438void Arcane::mesh::PolyhedralMesh::
1439read([[maybe_unused]] const String& filename)
1440{
1441 _errorEmptyMesh();
1442}
1443
1444/*---------------------------------------------------------------------------*/
1445/*---------------------------------------------------------------------------*/
1446
1447void Arcane::mesh::PolyhedralMesh::
1448allocateItems(const Arcane::ItemAllocationInfo& item_allocation_info)
1449{
1450 ARCANE_UNUSED(item_allocation_info);
1451 _errorEmptyMesh();
1452}
1453
1454/*---------------------------------------------------------------------------*/
1455/*---------------------------------------------------------------------------*/
1456
1457#endif // ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
1458
1459/*---------------------------------------------------------------------------*/
1460/*---------------------------------------------------------------------------*/
1461
1462namespace Arcane
1463{
1464
1465class ARCANE_MESH_EXPORT PolyhedralMeshFactory
1466: public AbstractService
1467, public IMeshFactory
1468{
1469 public:
1470
1473 {}
1474
1475 public:
1476
1477 void build() override {}
1479 {
1480 ISubDomain* sd = mm->variableMng()->_internalApi()->internalSubDomain();
1481 return new mesh::PolyhedralMesh(sd, build_info);
1482 }
1483
1484 static String name() { return "ArcanePolyhedralMeshFactory"; }
1485};
1486
1487ARCANE_REGISTER_SERVICE(PolyhedralMeshFactory,
1488 ServiceProperty(PolyhedralMeshFactory::name().localstr(), ST_Application),
1489 ARCANE_SERVICE_INTERFACE(IMeshFactory));
1490
1491/*---------------------------------------------------------------------------*/
1492/*---------------------------------------------------------------------------*/
1493
1494#if ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
1495
1496/*---------------------------------------------------------------------------*/
1497/*---------------------------------------------------------------------------*/
1498
1499String mesh::PolyhedralMesh::
1500factoryName() const
1501{
1502 return PolyhedralMeshFactory::name();
1503}
1504
1505/*---------------------------------------------------------------------------*/
1506/*---------------------------------------------------------------------------*/
1507
1508#endif // ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
1509
1510/*---------------------------------------------------------------------------*/
1511/*---------------------------------------------------------------------------*/
1512
1513} // End namespace Arcane
1514
1515/*---------------------------------------------------------------------------*/
1516/*---------------------------------------------------------------------------*/
#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.
Ce fichier contient les différentes fabriques de services et macro pour enregistrer les services.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
Classe de base d'un service.
EnumeratorT< ItemGroup > Enumerator
Type d'un itérateur sur toute la collection.
Definition Collection.h:129
Interface d'une famille de DoF.
Definition IDoFFamily.h:33
Interface d'une famille d'entités.
virtual NodeGroup ownNodes()=0
Groupe de tous les noeuds propres au domaine.
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual String name() const =0
Nom du maillage.
virtual Integer nbCell()=0
Nombre de mailles du maillage.
virtual CellGroup ownCells()=0
Groupe de toutes les mailles propres au domaine.
virtual FaceGroup ownFaces()=0
Groupe de toutes les faces propres au domaine.
virtual FaceGroup allFaces()=0
Groupe de toutes les faces.
virtual Integer nbEdge()=0
Nombre d'arêtes du maillage.
virtual IItemFamily * itemFamily(eItemKind ik)=0
Retourne la famille d'entité de type ik.
virtual IItemFamily * edgeFamily()=0
Retourne la famille des arêtes.
virtual Integer nbNode()=0
Nombre de noeuds du maillage.
virtual FaceGroup outerFaces()=0
Groupe de toutes les faces sur la frontière.
virtual IItemFamily * findItemFamily(eItemKind ik, const String &name, bool create_if_needed=false, bool register_modifier_if_created=false)=0
Retourne la famille de nom name.
virtual Integer nbItem(eItemKind ik)=0
Nombre d'éléments du genre ik.
virtual Integer dimension()=0
Dimension du maillage (1D, 2D ou 3D).
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
virtual EdgeGroup ownEdges()=0
Groupe de toutes les arêtes propres au domaine.
virtual NodeGroup allNodes()=0
Groupe de tous les noeuds.
virtual CellGroup allCells()=0
Groupe de toutes les mailles.
virtual Integer nbFace()=0
Nombre de faces du maillage.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
virtual IItemFamily * createItemFamily(eItemKind ik, const String &name)=0
Créé une famille de particule de nom name.
virtual EdgeGroup allEdges()=0
Groupe de toutes les arêtes.
Interface du service gérant la lecture d'un maillage.
Interface du gestionnaire des maillages.
Definition IMeshMng.h:40
virtual VariableNodeReal3 & nodesCoordinates()=0
Coordonnées des noeuds.
virtual FaceGroup outerActiveFaces()=0
Groupe de toutes les faces actives sur la frontière.
virtual void destroyGroups()=0
Détruit tous les groupes de toutes les familles.
virtual CellGroup allLevelCells(const Integer &level)=0
Groupe de toutes les mailles de niveau level.
virtual FaceGroup innerActiveFaces()=0
Groupe de toutes les faces actives.
virtual ItemGroupCollection groups()=0
Liste des groupes.
virtual ItemGroup findGroup(const String &name)=0
Retourne le groupe de nom name ou le groupe nul s'il n'y en a pas.
virtual IMeshInternal * _internalApi()=0
API interne à Arcane.
virtual CellGroup allActiveCells()=0
virtual FaceGroup allActiveFaces()=0
Groupe de toutes les faces actives.
virtual ItemTypeMng * itemTypeMng() const =0
Gestionnaire de types d'entités associé
virtual CellGroup ownActiveCells()=0
Groupe de toutes les mailles actives et propres au domaine.
virtual CellGroup ownLevelCells(const Integer &level)=0
Groupe de toutes les mailles propres de niveau level.
virtual FaceGroup ownActiveFaces()=0
Groupe de toutes les faces actives propres au domaine.
virtual IMeshCompactMng * _compactMng()=0
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
Groupe d'entités de maillage.
Definition ItemGroup.h:49
Structure interne d'une entité de maillage.
Infos sur un type d'entité du maillage.
Gestionnaire des types d'entités de maillage.
Definition ItemTypeMng.h:66
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Paramètres nécessaires à la construction d'un maillage.
void build() override
Construction de niveau build du service.
IPrimaryMesh * createMesh(IMeshMng *mm, const MeshBuildInfo &build_info) override
Créé un maillage avec les informations de build_info.
Structure contenant les informations pour créer un service.
Integer nbCell() override
Nombre de mailles du maillage.
Integer dimension() override
Dimension du maillage (1D, 2D ou 3D).
Integer nbNode() override
Nombre de noeuds du maillage.
void endUpdate() override
Notifie l'instance de la fin de la modification du maillage.
Integer nbEdge() override
Nombre d'arêtes du maillage.
Integer nbItem(eItemKind ik) override
Nombre d'éléments du genre ik.
Integer nbFace() override
Nombre de faces du maillage.
Famille d'entités.
Definition ItemFamily.h:76
Classe temporaire pour conserver un ItemSharedInfo et un type d'entité.
IDoFFamily * toDoFFamily() override
Retourne l'interface de la famille de particule de cette famille.
DoFVectorView addGhostDoFs(Int64ConstArrayView dof_uids, Int32ArrayView dof_lids, Int32ConstArrayView owners)
L'ajout de fantomes doit etre suivi d'un appel de computeSynchronizeInfos.
void endUpdate() override
Notifie la fin de modification de la liste des entités.
Integer nbItem() const override
Nombre d'entités.
String name() const override
Nom de la famille.
DoFVectorView addDoFs(Int64ConstArrayView dof_uids, Int32ArrayView dof_lids)
En entree les uids des dofs et on recupere leurs lids.
String fullName() const override
Nom complet de la famille (avec celui du maillage)
ItemGroup allItems() const override
Groupe de toutes les entités.
Vue modifiable d'un tableau d'un type T.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
Vue constante d'un tableau de type T.
Vue d'un tableau d'éléments de type T.
Definition Span.h:670
constexpr ARCCORE_HOST_DEVICE bool empty() const noexcept
Retourne true si le tableau est vide (dimension nulle)
Definition Span.h:372
constexpr ARCCORE_HOST_DEVICE SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:209
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
ItemGroupT< Cell > CellGroup
Groupe de mailles.
Definition ItemTypes.h:183
ItemGroupT< Face > FaceGroup
Groupe de faces.
Definition ItemTypes.h:178
ItemGroupT< Edge > EdgeGroup
Groupe d'arêtes.
Definition ItemTypes.h:173
ItemGroupT< Node > NodeGroup
Groupe de noeuds.
Definition ItemTypes.h:167
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro pour enregistrer un service.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:513
Collection< ItemGroup > ItemGroupCollection
Collection de groupes d'éléments du maillage.
Collection< IItemFamily * > ItemFamilyCollection
Collection de familles d'entités.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:640
Collection< IItemFamily * > IItemFamilyCollection
Collection de familles d'entités.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:515
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é.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:638
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:611
Int32 Integer
Type représentant un entier.