Arcane  v3.16.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
OneMeshItemAdder.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* OneMeshItemAdder.cc (C) 2000-2025 */
9/* */
10/* Ajout des entités une par une. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/OneMeshItemAdder.h"
15
16#include "arcane/utils/NotSupportedException.h"
17#include "arcane/utils/ValueConvert.h"
18#include "arcane/utils/FixedArray.h"
19
21#include "arcane/core/MeshToMeshTransposer.h"
22#include "arcane/core/IParallelMng.h"
23#include "arcane/core/ItemPrinter.h"
24
25#include "arcane/mesh/DynamicMesh.h"
26#include "arcane/mesh/DynamicMeshIncrementalBuilder.h"
27#include "arcane/mesh/ItemTools.h"
28#include "arcane/mesh/ConnectivityNewWithDependenciesTypes.h"
29#include "arcane/mesh/GraphDoFs.h"
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34namespace Arcane::mesh
35{
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
41{
42 public:
43
44 CellInfoProxy(ItemTypeInfo* type_info,
45 Int64 cell_uid,
46 Int32 sub_domain_id,
48 bool allow_build_face = false)
49 : m_type_info(type_info)
50 , m_cell_uid(cell_uid)
51 , m_info(info)
52 , m_owner(sub_domain_id)
53 , m_allow_build_face(allow_build_face) {}
54
55 Int64 uniqueId() const { return m_cell_uid; }
56 ItemTypeInfo* typeInfo() const { return m_type_info; }
57 Int32 owner() const { return m_owner; }
58 Integer nbNode() const { return m_info.size(); }
59 Integer nbFace() const { return m_type_info->nbLocalFace(); }
60 Integer nbEdge() const { return m_type_info->nbLocalEdge(); }
61 Int64 nodeUniqueId(Integer i_node) const { return m_info[i_node]; }
62 Int32 nodeOwner(Integer) const { return m_owner; }
63 Int32 faceOwner(Integer) const { return m_owner; }
64 Int32 edgeOwner(Integer) const { return m_owner; }
65 ItemTypeInfo::LocalFace localFace(Integer i_face) const { return m_type_info->localFace(i_face); }
66 bool allowBuildFace() const { return m_allow_build_face; }
67 bool allowBuildEdge() const { return m_allow_build_face; }
68
69 private:
70
71 ItemTypeInfo* m_type_info = nullptr;
72 Int64 m_cell_uid = NULL_ITEM_UNIQUE_ID;
74 Int32 m_owner = A_NULL_RANK;
75 bool m_allow_build_face = false;
76};
77
78/*---------------------------------------------------------------------------*/
79/*---------------------------------------------------------------------------*/
80
81OneMeshItemAdder::
82OneMeshItemAdder(DynamicMeshIncrementalBuilder* mesh_builder)
83: TraceAccessor(mesh_builder->mesh()->traceMng())
84, m_mesh(mesh_builder->mesh())
85, m_mesh_builder(mesh_builder)
86, m_cell_family(m_mesh->trueCellFamily())
87, m_node_family(m_mesh->trueNodeFamily())
88, m_face_family(m_mesh->trueFaceFamily())
89, m_edge_family(m_mesh->trueEdgeFamily())
90, m_item_type_mng(m_mesh->itemTypeMng())
91, m_mesh_info(m_mesh->meshPartInfo().partRank())
92, m_face_reorderer(m_item_type_mng)
93{
94 //m_work_face_sorted_nodes.reserve(100);
95 m_work_face_orig_nodes_uid.reserve(100);
96}
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101ItemInternal* OneMeshItemAdder::
102addOneNode(Int64 node_uid,Int32 owner)
103{
104 bool is_add = false;
105 ItemInternal* node = m_node_family.findOrAllocOne(node_uid,is_add);
106 if (is_add) {
108 node->setOwner(owner,owner);
109 }
110 return node;
111}
112
113/*---------------------------------------------------------------------------*/
114/*---------------------------------------------------------------------------*/
124{
125 Int32 nb_node = nodes_uid.size();
126 // Vérifie que le nombre de noeuds est le même
127 if (item.nbNode()!=nb_node)
128 ARCANE_FATAL("Trying to add existing item (kind='{0}', uid={1}) with different number of node (existing={2} new={3})",
129 item.kind(), item.uniqueId(), item.nbNode(), nb_node);
130
131 // Vérifie que les noeuds correspondent bien à ceux existants
132 for( Int32 i=0; i<nb_node; ++i ){
133 Int64 new_uid = nodes_uid[i];
134 Int64 current_uid = item.node(i).uniqueId();
135 if (new_uid != current_uid){
136 std::ostringstream ostr;
137 for( Int32 k=0; k<nb_node; ++k )
138 ostr << " " << item.node(k).uniqueId();
139 ARCANE_FATAL("Trying to add existing item (kind='{0}', uid={1}) with different nodes (index={2} existing='{3}' new='{4}')",
140 item.kind(), item.uniqueId(), i, ostr.str(), nodes_uid);
141 }
142 }
143}
144
145/*---------------------------------------------------------------------------*/
146/*---------------------------------------------------------------------------*/
154{
155 if (uid!=NULL_ITEM_UNIQUE_ID)
156 return uid;
158 uid = MeshUtils::generateHashUniqueId(nodes_uid);
159 else
160 uid = m_next_face_uid++;
161 return uid;
162}
163
164/*---------------------------------------------------------------------------*/
165/*---------------------------------------------------------------------------*/
179addOneFace(ItemTypeId type_id, Int64 face_uid, Int32 owner_rank, Int64ConstArrayView nodes_uid)
180{
181 const Integer face_nb_node = nodes_uid.size();
182
183 //m_work_face_sorted_nodes.resize(face_nb_node);
184 //m_work_face_orig_nodes_uid.resize(face_nb_node);
185 //for( Integer z=0; z<face_nb_node; ++z )
186 //m_work_face_orig_nodes_uid[z] = nodes_uid[z];
187 m_face_reorderer.reorder(type_id,nodes_uid);
188 ConstArrayView<Int64> face_sorted_nodes = m_face_reorderer.sortedNodes();
189 // TODO: dans le cas où la face sera orpheline (non connectée à une maille),
190 // vérifier s'il faut réorienter la face car cela risque d'introduire
191 // une incohérence si par la suite on souhaite calculer une normale.
192 //MeshUtils::reorderNodesOfFace(m_work_face_orig_nodes_uid,m_work_face_sorted_nodes);
193 face_uid = _checkGenerateFaceUniqueId(face_uid,face_sorted_nodes);
194 bool is_add_face = false;
195 Face face = m_face_family.findOrAllocOne(face_uid,type_id,is_add_face);
196 // La face n'existe pas
197 if (is_add_face) {
198 ++m_mesh_info.nbFace();
199 face.mutableItemBase().setOwner(owner_rank, m_mesh_info.rank());
200 for(Integer i_node=0; i_node<face_nb_node; ++i_node ){
201 Node node = addOneNode(face_sorted_nodes[i_node], m_mesh_info.rank());
202 m_face_family.replaceNode(face,i_node,node);
203 m_node_family.addFaceToNode(node, face);
204 }
205 }
206 else {
207 if (arcaneIsCheck())
208 _checkSameItemCoherency(face, face_sorted_nodes);
209 }
210
211 return ItemCompatibility::_itemInternal(face);
212}
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
216
217ItemInternal* OneMeshItemAdder::
218addOneEdge(Int64 edge_uid, Int32 rank, Int64ConstArrayView nodes_uid)
219{
220 m_work_edge_sorted_nodes.resize(2);
221 m_work_edge_orig_nodes_uid.resize(2);
222
223 for( Integer z=0; z<2; ++z )
224 m_work_edge_orig_nodes_uid[z] = nodes_uid[z];
225 // reorderNodesOfFace se comporte ici correctement pour des arêtes == face en 2D
226 MeshUtils::reorderNodesOfFace(m_work_edge_orig_nodes_uid,m_work_edge_sorted_nodes);
227
228 bool is_add_edge = false;
229 ItemInternal* edge = m_edge_family.findOrAllocOne(edge_uid,is_add_edge);
230
231 // L'arête n'existe pas
232 if (is_add_edge) {
234 edge->setOwner(rank,m_mesh_info.rank());
235 for(Integer i_node=0; i_node<2; ++i_node ){
236 ItemInternal *current_node_internal = addOneNode(m_work_edge_sorted_nodes[i_node], m_mesh_info.rank());
237 m_edge_family.replaceNode(ItemLocalId(edge),i_node, ItemLocalId(current_node_internal));
238 m_node_family.addEdgeToNode(current_node_internal, edge);
239 }
240 }
241 return edge;
242}
243
244/*---------------------------------------------------------------------------*/
245/*---------------------------------------------------------------------------*/
246
247template<>
248Face OneMeshItemAdder::
249_findInternalFace(Integer i_face, const FullCellInfo& cell_info, bool& is_add)
250{
251 const Int64 face_unique_id = cell_info.faceUniqueId(i_face);
252 ItemTypeInfo* cell_type_info = cell_info.typeInfo();
253 const ItemTypeInfo::LocalFace& lf = cell_type_info->localFace(i_face);
254 ItemTypeInfo* face_type_info = m_item_type_mng->typeFromId(lf.typeId());
255 return m_face_family.findOrAllocOne(face_unique_id,face_type_info,is_add);
256}
257
258/*---------------------------------------------------------------------------*/
259/*---------------------------------------------------------------------------*/
260
261template<>
262Face OneMeshItemAdder::
263_findInternalFace(Integer i_face, const CellInfoProxy& cell_info, bool& is_add)
264{
265 const ItemInternalMap& nodes_map = m_mesh->nodesMap();
266 ItemTypeInfo* cell_type_info = cell_info.typeInfo();
267 const ItemTypeInfo::LocalFace& lf = cell_type_info->localFace(i_face);
268 // Récupère les noeuds orientés de la face
269 // (Il faut avoir appelé une des méthodes d'ajout de face avant)
270 ConstArrayView<Int64> face_sorted_nodes = m_face_reorderer.sortedNodes();
271 Node nbi = nodes_map.findItem(face_sorted_nodes[0]);
272 Face face_internal = ItemTools::findFaceInNode2(nbi,lf.typeId(),face_sorted_nodes);
273 if (face_internal.null()) {
274 // La face n'est pas trouvée. Elle n'existe donc pas dans notre sous-domaine.
275 // Si cela est autorisé, on créée la nouvelle face.
276 if (!cell_info.allowBuildFace() && !m_use_hash_for_edge_and_face_unique_id){
277 info() << "BadCell uid=" << cell_info.uniqueId();
278 for( Int32 i=0; i<cell_info.nbNode(); ++i )
279 info() << "Cell node I=" << i << " uid=" << cell_info.nodeUniqueId(i);
280 ARCANE_FATAL("On the fly face allocation is not allowed here.\n"
281 " You need to add faces with IMeshModifier::addFaces().\n"
282 " CellUid={0} LocalFace={1} FaceNodes={2}",
283 cell_info.uniqueId(),i_face,face_sorted_nodes);
284 }
285 ItemTypeInfo* face_type = m_item_type_mng->typeFromId(lf.typeId());
286 Int64 face_unique_id = _checkGenerateFaceUniqueId(NULL_ITEM_UNIQUE_ID,face_sorted_nodes);
287 is_add = true;
288 return m_face_family.allocOne(face_unique_id,face_type);
289 }
290 else {
291 is_add = false;
292 return face_internal;
293 }
294}
295
296/*---------------------------------------------------------------------------*/
297/*---------------------------------------------------------------------------*/
298
299template<>
300Edge OneMeshItemAdder::
301_findInternalEdge(Integer i_edge, const FullCellInfo& cell_info,
302 Int64 first_node, Int64 second_node, bool& is_add)
303{
304 ARCANE_UNUSED(first_node);
305 ARCANE_UNUSED(second_node);
306
307 const Int64 edge_unique_id = cell_info.edgeUniqueId(i_edge);
308 return m_edge_family.findOrAllocOne(edge_unique_id,is_add);
309}
310
311/*---------------------------------------------------------------------------*/
312/*---------------------------------------------------------------------------*/
313
314template<>
315Edge OneMeshItemAdder::
316_findInternalEdge(Integer i_edge, const CellInfoProxy& cell_info, Int64 first_node, Int64 second_node, bool& is_add)
317{
318 ARCANE_UNUSED(i_edge);
319
320 const ItemInternalMap& nodes_map = m_mesh->nodesMap();
321 Node nbi = nodes_map.findItem(first_node);
322 Edge edge_internal = ItemTools::findEdgeInNode2(nbi,first_node,second_node);
323 if (edge_internal.null()){
324 if (!cell_info.allowBuildEdge() && !m_use_hash_for_edge_and_face_unique_id)
325 ARCANE_FATAL("On the fly edge allocation is not allowed here."
326 " You need to add edges before with IMeshModifier::addEdges()");
327 Int64 edge_unique_id = m_next_edge_uid++;
329 FixedArray<Int64,2> nodes;
330 nodes[0] = first_node;
331 nodes[1] = second_node;
332 edge_unique_id = MeshUtils::generateHashUniqueId(nodes.view());
333 }
334 is_add = true;
335 return m_edge_family.allocOne(edge_unique_id);
336 }
337 else {
338 is_add = false;
339 return edge_internal;
340 }
341}
342
343/*---------------------------------------------------------------------------*/
344/*---------------------------------------------------------------------------*/
362addOneCell(ItemTypeId type_id,
363 Int64 cell_uid,
364 Int32 sub_domain_id,
365 Int64ConstArrayView nodes_uid,
366 bool allow_build_face)
367{
368 CellInfoProxy cell_info_proxy(m_item_type_mng->typeFromId(type_id),cell_uid,sub_domain_id,nodes_uid,allow_build_face);
369
370 return _addOneCell(cell_info_proxy);
371}
372
373/*---------------------------------------------------------------------------*/
374/*---------------------------------------------------------------------------*/
381addOneCell(const FullCellInfo& cell_info)
382{
383 return _addOneCell(cell_info);
384}
385
386/*---------------------------------------------------------------------------*/
387/*---------------------------------------------------------------------------*/
388
389ItemInternal* OneMeshItemAdder::
390addOneItem(IItemFamily* family,
391 IItemFamilyModifier* family_modifier,
392 ItemTypeId type_id,
393 Int64 item_uid,
394 Integer item_owner,
395 Integer sub_domain_id,
396 Integer nb_connected_family,
397 Int64ConstArrayView connectivity_info)
398{
399 ARCANE_ASSERT(m_mesh->itemFamilyNetwork(),("ItemFamilyNetwork is required to call OneMeshItemAdder::addOneItem"));
400 bool is_alloc = true;
401 Item item = family_modifier->findOrAllocOne(item_uid,type_id,m_mesh_info,is_alloc); // don't forget to add print in the class method
402 item.mutableItemBase().setOwner(item_owner,sub_domain_id);
403 // Add connectivities if needed
404 Integer info_index = 0;
405 for (Integer family_index = 0; family_index < nb_connected_family; ++family_index){
406 // get connected family
407 eItemKind family_kind = static_cast<eItemKind>(connectivity_info[info_index++]); // another way ?
408 Int32 nb_connected_item = CheckedConvert::toInt32(connectivity_info[info_index++]);
409 IItemFamily* connected_family = m_mesh->itemFamily(family_kind);
410 // get connectivities family -> connected_family and reverse
411 String connectivity_name = mesh::connectivityName(family,connected_family);
412 String reverse_connectivity_name = mesh::connectivityName(connected_family,family);
413 bool is_dependency = false;
414 IIncrementalItemConnectivity* family_to_connected_family = m_mesh->itemFamilyNetwork()->getStoredConnectivity(family,connected_family,connectivity_name,is_dependency);
415 IIncrementalItemConnectivity* connected_family_to_family = m_mesh->itemFamilyNetwork()->getStoredConnectivity(connected_family,family,reverse_connectivity_name);
416 // Clear connectivities for already allocated items (except dependencies since replace is used)
417 if (!is_alloc) {
418 if(!is_dependency) _clearConnectivity(ItemLocalId(item), family_to_connected_family);
419 if (connected_family_to_family) _clearReverseConnectivity(ItemLocalId(item),family_to_connected_family,connected_family_to_family);
420 }
421 // get connected item lids
422 Int32UniqueArray connected_item_lids(nb_connected_item);
423 connected_family->itemsUniqueIdToLocalId(connected_item_lids,connectivity_info.subView(info_index,nb_connected_item),true);
424 for (Integer connected_item_index = 0; connected_item_index < nb_connected_item; ++connected_item_index){
425 if (family_to_connected_family) {
426 // pre-alloc are done (=> use replace) when a dependency relation ("owning relation") while not when only a relation (use add)
427 if (! is_dependency) family_to_connected_family->addConnectedItem(ItemLocalId(item),ItemLocalId(connected_item_lids[connected_item_index]));
428 else family_to_connected_family->replaceConnectedItem(ItemLocalId(item),connected_item_index,ItemLocalId(connected_item_lids[connected_item_index])); // does not work with face to edges...
429 }
430 if (connected_family_to_family)
431 connected_family_to_family->addConnectedItem(ItemLocalId(connected_item_lids[connected_item_index]),ItemLocalId(item));
432 }
433 info_index+= nb_connected_item;
434 }
435// debug(Trace::Highest) << "[addItems] ADD_ITEM " << ItemPrinter(item) << " in " << family->name();
436 debug(Trace::Highest) << "[addItems] ADD_ITEM " << ItemPrinter(item) << " in " << family->name();
437 return ItemCompatibility::_itemInternal(item);
438}
439
440/*---------------------------------------------------------------------------*/
441
442ItemInternal* OneMeshItemAdder::
443addOneItem2(IItemFamily* family,
444 IItemFamilyModifier* family_modifier,
445 ItemTypeId type_id,
446 Int64 item_uid,
447 Integer item_owner,
448 Integer sub_domain_id,
449 Integer nb_connected_family,
450 Int64ConstArrayView connectivity_info)
451{
452 ARCANE_ASSERT(m_mesh->itemFamilyNetwork(),("ItemFamilyNetwork is required to call OneMeshItemAdder::addOneItem"));
453 bool is_alloc = true;
454 Item item = family_modifier->findOrAllocOne(item_uid,type_id,m_mesh_info,is_alloc); // don't forget to add print in the class method
455 item.mutableItemBase().setOwner(item_owner,sub_domain_id);
456 // Add connectivities if needed
457 Integer info_index = 0;
458 for (Integer family_index = 0; family_index < nb_connected_family; ++family_index) {
459 // Prepare connection
460 // get connected family
461 eItemKind family_kind = static_cast<eItemKind>(connectivity_info[info_index++]); // another way ?
462 Int32 nb_connected_item = CheckedConvert::toInt32(connectivity_info[info_index++]);
463 if (nb_connected_item == 0) continue;
464 IItemFamily* connected_family = nullptr ;
465 switch(family_kind){
466 case IK_Particle:
467 connected_family = m_mesh->findItemFamily(family_kind, ParticleFamily::defaultFamilyName(), false,false);
468 break ;
469 case IK_DoF:
470 if(family->name()==GraphDoFs::dualNodeFamilyName())
471 connected_family = m_mesh->findItemFamily(family_kind, GraphDoFs::linkFamilyName(), false,false);
472 else
473 connected_family = m_mesh->findItemFamily(family_kind, GraphDoFs::dualNodeFamilyName(), false,false);
474 break ;
475 default:
476 connected_family = m_mesh->itemFamily(family_kind);
477 break ;
478 }
479 // get connectivities family -> connected_family and reverse
480 String connectivity_name = mesh::connectivityName(family,connected_family);
481 bool is_dependency = false;
482 IIncrementalItemConnectivity* family_to_connected_family = m_mesh->itemFamilyNetwork()->getConnectivity(family,connected_family,connectivity_name,is_dependency);
483 if (!family_to_connected_family)
484 ARCANE_FATAL("Cannot find connectivity name={0}",connectivity_name);
485 bool is_deep_connectivity = m_mesh->itemFamilyNetwork()->isDeep(family_to_connected_family) ;
486 bool is_relation = !(is_dependency && is_deep_connectivity);
487 // Build connection
488 // get connected item lids
489 Int32UniqueArray connected_item_lids(nb_connected_item);
490 bool do_fatal = is_relation ? false : true; // for relations, connected items may not be present and will be skipped.
491 connected_family->itemsUniqueIdToLocalId(connected_item_lids,connectivity_info.subView(info_index,nb_connected_item),do_fatal);
492 // if connection is relation, connected item not necessarily present: remove absent (ie null) items
493 Integer nb_connected_item_found = nb_connected_item;
494 if (is_relation)
495 {
496 for (Integer index = 0; index < connected_item_lids.size(); )
497 {
498 if (connected_item_lids[index] == NULL_ITEM_LOCAL_ID) {
499 connected_item_lids.remove(index);
500 --nb_connected_item_found;
501 }
502 else ++index;
503 }
504 }
505 for (Integer connected_item_index = 0; connected_item_index < nb_connected_item_found; ++connected_item_index)
506 {
507 if (family_to_connected_family)
508 {
509 // Only strategy : check and add
510 auto connected_item_lid = ItemLocalId{connected_item_lids[connected_item_index]};
511 if (is_relation)
512 {
513 if (!family_to_connected_family->hasConnectedItem(ItemLocalId(item),connected_item_lid))
514 {
515 family_to_connected_family->addConnectedItem(ItemLocalId(item),connected_item_lid);
516 }
517 }
518 else
519 {
520 family_to_connected_family->replaceConnectedItem(ItemLocalId(item),connected_item_index,connected_item_lid);
521 }
522 }
523 }
524 info_index+= nb_connected_item;
525 }
526 if (is_alloc)
527 debug(Trace::Highest) << "[addItems] ADD_ITEM " << ItemPrinter(item) << " in " << family->name();
528 // debug(Trace::Highest) << "[addItems] DEPENDENCIES for " << family->name() << FullItemPrinter(item) ; // debug info
529 // _printRelations(item); // debug info
530 return ItemCompatibility::_itemInternal(item);
531}
532
533/*---------------------------------------------------------------------------*/
534
535void OneMeshItemAdder::
536_printRelations(ItemInternal* item)
537{
538 debug(Trace::Highest) << "[addItems] RELATIONS for " << ItemPrinter(item) << " in " << item->family()->name();
539 for (const auto& relation : m_mesh->itemFamilyNetwork()->getChildRelations(item->family())) {
540// debug(Trace::Highest) << " Relation " << relation->name();
541// debug(Trace::Highest) << " Relation " << relation->nbConnectedItem(ItemLocalId(item));
542 ConnectivityItemVector connected_items(relation);
543 for (const auto& connected_item : connected_items.connectedItems(ItemLocalId(item))) {
544 debug(Trace::Highest) << ItemPrinter(connected_item);
545 }
546 }
547}
548
549/*---------------------------------------------------------------------------*/
550/*---------------------------------------------------------------------------*/
551
552void OneMeshItemAdder::
553_clearConnectivity(ItemLocalId item, IIncrementalItemConnectivity* connectivity)
554{
555
556 ConnectivityItemVector accessor(connectivity);
557 ENUMERATE_ITEM(connected_item, accessor.connectedItems(item)) {
558 connectivity->removeConnectedItem(item,connected_item);
559 }
560}
561
562/*---------------------------------------------------------------------------*/
563/*---------------------------------------------------------------------------*/
564
565void OneMeshItemAdder::
566_clearReverseConnectivity(ItemLocalId item, IIncrementalItemConnectivity* connectivity, IIncrementalItemConnectivity* reverse_connectivity)
567{
568 ConnectivityItemVector accessor(connectivity);
569 ENUMERATE_ITEM(connected_item, accessor.connectedItems(item)) {
570 reverse_connectivity->removeConnectedItem(connected_item,item);
571 }
572}
573
574/*---------------------------------------------------------------------------*/
575/*---------------------------------------------------------------------------*/
576
577template<> void OneMeshItemAdder::
578_AMR_Patch(Cell new_cell, const FullCellInfo& cell_info)
579{
581 if(m_mesh->isAmrActivated()){
582 // FIXME doit-on traiter les mailles de niveau 0
583 //comme celles de niveau superieur
584 if(cell_info.level() != 0){
585 Integer child_rank = cell_info.whichChildAmI();
586 Int64 hParent_uid = cell_info.hParentCellUniqueId();
587 ItemTypeId cell_type = ItemTypeId::fromInteger(cell_info.typeId());
588 bool is_add;
589 Cell hParent_cell= m_cell_family.findOrAllocOne(hParent_uid,cell_type,is_add);
590 m_cell_family._addParentCellToCell(new_cell,hParent_cell);
591 m_cell_family._addChildCellToCell(hParent_cell,child_rank,new_cell);
592 }
593 }
594}
595
596template<> void OneMeshItemAdder::
597_AMR_Patch(Cell cell, const CellInfoProxy& cell_info)
598{
599 ARCANE_UNUSED(cell);
600 ARCANE_UNUSED(cell_info);
601}
602
603/*---------------------------------------------------------------------------*/
604/*---------------------------------------------------------------------------*/
610template<typename CellInfo>
612_addOneCell(const CellInfo& cell_info)
613{
614 bool is_check = arcaneIsCheck();
615
616 ItemTypeInfo* cell_type_info = cell_info.typeInfo();
617 ItemTypeId cell_type_id = cell_type_info->itemTypeId();
618 // Regarde si la maille existe déjà (auquel cas on ne fait rien)
619 Cell inew_cell;
620 {
621 bool is_add; // ce flag est toujours correctement positionné via les findOrAllocOne
622 inew_cell = m_cell_family.findOrAllocOne(cell_info.uniqueId(),cell_type_id,is_add);
623 if (!is_add){
624 if (is_check){
625 Cell cell2(inew_cell);
626 // Vérifie que les noeuds correspondent bien à ceux existants
627 for( Integer i=0, is=cell_info.nbNode(); i<is; ++i )
628 if (cell_info.nodeUniqueId(i)!=cell2.node(i).uniqueId())
629 ARCANE_FATAL("trying to add existing cell (uid={0}) with different nodes",
630 cell_info.uniqueId());
631 }
632 return ItemCompatibility::_itemInternal(inew_cell);
633 }
634 }
635
636 const bool is_verbose = false;
637
638 Cell new_cell(inew_cell);
639
640 ++m_mesh_info.nbCell();
641
642 const bool allow_multi_dim_cell = m_mesh->meshKind().isNonManifold();
643 const Int32 cell_nb_face = cell_info.nbFace();
644
645 inew_cell.mutableItemBase().setOwner(cell_info.owner(), m_mesh_info.rank());
646 // Vérifie la cohérence entre le type local et la maille créée.
647 if (is_check){
648 if (cell_info.nbNode()!=inew_cell.nbNode())
649 ARCANE_FATAL("Incoherent number of nodes v={0} expected={1}",inew_cell.nbNode(),cell_info.nbNode());
650 if (cell_nb_face!=inew_cell.nbFace())
651 ARCANE_FATAL("Incoherent number of faces v={0} expected={1}",inew_cell.nbFace(),cell_nb_face);
652 if (!cell_type_info->isValidForCell())
653 ARCANE_FATAL("Type '{0}' is not allowed for 'Cell' (cell_uid={1})",
654 cell_type_info->typeName(),cell_info.uniqueId());
655 if (!allow_multi_dim_cell){
656 Int32 cell_dimension = cell_type_info->dimension();
657 Int32 mesh_dimension = m_mesh->dimension();
658 if (cell_dimension>=0 && cell_dimension!=mesh_dimension)
659 ARCANE_FATAL("Incoherent dimension for cell uid={0} cell_dim={1} mesh_dim={2} type={3}",
660 cell_info.uniqueId(),cell_dimension,mesh_dimension,cell_type_info->typeName());
661 }
662 }
663
665 ItemInternalMap& nodes_map = m_node_family.itemsMap();
666
667 _addNodesToCell(inew_cell,cell_info);
668
669 if (m_mesh_builder->hasEdge()) {
670 const Int32 cell_nb_edge = cell_info.nbEdge();
671 // Ajoute les nouvelles arêtes ci-nécessaire
672 for( Integer i_edge=0; i_edge<cell_nb_edge; ++i_edge ){
673 const ItemTypeInfo::LocalEdge& le = cell_type_info->localEdge(i_edge);
674 Int64 first_node = cell_info.nodeUniqueId( le.beginNode() );
675 Int64 second_node = cell_info.nodeUniqueId( le.endNode() );
676 if (first_node > second_node)
677 std::swap(first_node,second_node);
678
679 bool is_add = false;
680 Edge edge_internal = _findInternalEdge(i_edge, cell_info, first_node, second_node, is_add);
681 if (is_add){
682 if (is_verbose)
683 info() << "Create edge " << edge_internal.uniqueId() << ' ' << edge_internal.localId();
684
685 edge_internal.mutableItemBase().setOwner(cell_info.edgeOwner(i_edge),m_mesh_info.rank());
686 {
687 Node current_node = nodes_map.findItem(first_node);
688 m_edge_family.replaceNode(ItemLocalId(edge_internal), 0, current_node);
689 m_node_family.addEdgeToNode(current_node, edge_internal);
690 }
691 {
692 Node current_node = nodes_map.findItem(second_node);
693 m_edge_family.replaceNode(ItemLocalId(edge_internal), 1, current_node);
694 m_node_family.addEdgeToNode(current_node, edge_internal);
695 }
696 ++m_mesh_info.nbEdge();
697 }
698
699 m_cell_family.replaceEdge(ItemLocalId(new_cell),i_edge,ItemLocalId(edge_internal));
700 m_edge_family.addCellToEdge(edge_internal,inew_cell);
701 }
702 }
703
704 // Ajoute les nouvelles faces ci-nécessaire
705 for( Integer i_face=0; i_face<cell_nb_face; ++i_face ){
706 const ItemTypeInfo::LocalFace& lf = cell_type_info->localFace(i_face);
707 const Integer face_nb_node = lf.nbNode();
708 // en effet de bord, _isReorder positionne m_face_reorderer.sortedNodes();
709 const bool is_reorder = _isReorder(i_face, lf, cell_info);
710 ConstArrayView<Int64> face_sorted_nodes = m_face_reorderer.sortedNodes();
711
712 bool is_add = false;
713 Face face = _findInternalFace(i_face, cell_info, is_add);
714 if (is_add){
715 if (is_verbose){
716 info() << "Create face " << face.uniqueId() << ' ' << face.localId();
717 info() << "AddCell (uid=" << new_cell.uniqueId() << ": Create face (index=" << i_face
718 << ") uid=" << face.uniqueId()
719 << " lid=" << face.localId();
720 }
721 face.mutableItemBase().setOwner(cell_info.faceOwner(i_face),m_mesh_info.rank());
722
723 for( Integer i_node=0; i_node<face_nb_node; ++i_node ){
724 Node current_node = nodes_map.findItem(face_sorted_nodes[i_node]);
725 m_face_family.replaceNode(face, i_node, current_node);
726 m_node_family.addFaceToNode(current_node, face);
727 }
728
729 if (m_mesh_builder->hasEdge()) {
730 Integer face_nb_edge = lf.nbEdge();
731 for( Integer i_edge=0; i_edge<face_nb_edge; ++i_edge ){
732 Edge current_edge = new_cell.edge( lf.edge(i_edge) );
733 m_face_family.addEdgeToFace(face,current_edge);
734 m_edge_family.addFaceToEdge(current_edge,face);
735 }
736 }
737 ++m_mesh_info.nbFace();
738 }
739 m_cell_family.replaceFace(new_cell,i_face,face);
740
742 if(m_mesh->isAmrActivated()){
743 if (is_reorder){
744 if(face.nbCell() == 2)
745 m_face_family.replaceFrontCellToFace(face,new_cell);
746 else
747 m_face_family.addFrontCellToFace(face,inew_cell);
748 } else{
749 if(face.nbCell() == 2)
750 m_face_family.replaceBackCellToFace(face,new_cell);
751 else
752 m_face_family.addBackCellToFace(face,inew_cell);
753 }
754 } else {
755 if (is_reorder){
756 m_face_family.addFrontCellToFace(face,inew_cell);
757 } else{
758 m_face_family.addBackCellToFace(face,inew_cell);
759 }
760 }
761 }
762
763 _AMR_Patch(inew_cell, cell_info);
764 return ItemCompatibility::_itemInternal(inew_cell);
765}
766
767/*---------------------------------------------------------------------------*/
768/*---------------------------------------------------------------------------*/
786addOneParentItem(const Item & item, const eItemKind submesh_kind, const bool fatal_on_existing_item)
787{
788 //bool is_check = arcaneIsCheck();
789 ItemTypeMng* itm = m_mesh->itemTypeMng();
790 eItemKind kind = item.kind();
791 ItemTypeInfo* type = itm->typeFromId(item.type());
792
793 if (item.type() == IT_Line2 && submesh_kind == IK_Cell)
794 type = itm->typeFromId(IT_CellLine2);
795 if (item.type() == IT_Vertex && submesh_kind == IK_Face)
796 type = itm->typeFromId(IT_FaceVertex);
797 ItemTypeId type_id = type->itemTypeId();
798
799 if (MeshToMeshTransposer::kindTranspose(submesh_kind, m_mesh, m_mesh->parentMesh()) != kind)
800 ARCANE_FATAL("Incompatible kind/sub-kind");
801
802 // Regarde si la maille existe déjà
803 bool is_add; // ce flag est toujours correctement positionné via les findOrAllocOne
804 Item new_item;
805
806 switch (submesh_kind) {
807 case IK_Node:
808 new_item = m_node_family.findOrAllocOne(item.uniqueId(),is_add);
809 ++m_mesh_info.nbNode();
810 break;
811 case IK_Edge:
812 new_item = m_edge_family.findOrAllocOne(item.uniqueId(),is_add);
813 ++m_mesh_info.nbEdge();
814 break;
815 case IK_Face:
816 new_item = m_face_family.findOrAllocOne(item.uniqueId(),type,is_add);
817 ++m_mesh_info.nbFace();
818 break;
819 case IK_Cell:
820 if (kind == IK_Face && !(item.toFace().isSubDomainBoundary()))
821 ARCANE_FATAL("Bad boundary face");
822 new_item = m_cell_family.findOrAllocOne(item.uniqueId(),type_id,is_add);
823 ++m_mesh_info.nbCell();
824 break;
825 default:
826 throw NotSupportedException(A_FUNCINFO,String::format("Kind {0} not supported", submesh_kind));
827 }
828
829 if (!is_add){
830 if (fatal_on_existing_item)
831 ARCANE_FATAL("Cannot add already existing parent item in submesh");
832 else
833 return ItemCompatibility::_itemInternal(new_item);
834 }
835
836 new_item.mutableItemBase().setParent(0,item.localId());
837 new_item.mutableItemBase().setOwner(item.owner(),m_mesh_info.rank());
838
839 // Localise vis-à-vis de l'item à insérer ces sous-items
840 // Par défaut tout à 0, qui correspond aussi au cas submesh_kind==IK_Node
841 Integer item_nb_node = 0;
842 Integer item_nb_face = 0;
843 Integer item_nb_edge = 0;
844
845 switch (submesh_kind) {
846 case IK_Cell:
847 item_nb_face = type->nbLocalFace();
848 item_nb_edge = type->nbLocalEdge();
849 item_nb_node = type->nbLocalNode();
850 break;
851 case IK_Face:
852 item_nb_edge = type->nbLocalEdge();
853 item_nb_node = type->nbLocalNode();
854 break;
855 case IK_Edge:
856 item_nb_node = type->nbLocalNode();
857 default: // les autres sont déjà filtrés avant avec une exception
858 break;
859 }
860
861 // Traitement du cas de désactivation des arêtes
862 if (!m_mesh_builder->hasEdge())
863 item_nb_edge = 0;
864
865#if OLD
866 // Ne fonctionne plus si on désactive les anciennes connectivités
867 if (is_check){
868 for( Integer z=0; z<item_nb_face; ++z )
869 new_item->_setFace(z,NULL_ITEM_ID);
870 for( Integer z=0; z<item_nb_edge; ++z )
871 new_item->_setEdge(z,NULL_ITEM_ID);
872 for( Integer z=0; z<item_nb_node; ++z )
873 new_item->_setNode(z,NULL_ITEM_ID);
874 }
875#endif
876
878 DynamicMeshKindInfos::ItemInternalMap& nodes_map = m_mesh->nodesMap();
879 auto* parent_mesh = ARCANE_CHECK_POINTER(dynamic_cast<DynamicMesh*>(m_mesh->parentMesh()));
880 DynamicMeshKindInfos::ItemInternalMap& parent_nodes_map = parent_mesh->nodesMap();
881
882 // Traitement des nouveaux noeuds
883
884 // Les sommets sont utilisés dans l'ordre de l'item sauf les cellules de sous-maillages surfacique.
885 const bool direct_node_order =
886 !(submesh_kind == IK_Cell
887 && kind == IK_Face
888 && !(item.toFace().isSubDomainBoundaryOutside()));
889
890 Int64UniqueArray nodes_uid(item_nb_node,NULL_ITEM_UNIQUE_ID);
891 for( Integer i_node=0; i_node<item_nb_node; ++i_node ){
892 Item parent_item;
893 if (type->typeId() == IT_FaceVertex)
894 parent_item = item;
895 else{
896 Int32 idx = ((direct_node_order) ? i_node : (item_nb_node-1-i_node));
897 parent_item = item.toItemWithNodes().node(idx);
898 }
899 Int64 new_node_uid = nodes_uid[i_node] = parent_item.uniqueId();
900 ItemInternal* node_internal = m_node_family.findOrAllocOne(new_node_uid,is_add);
901 if (is_add){
902#ifdef ARCANE_DEBUG_DYNAMIC_MESH
903 info() << "Création node " << new_node_uid << ' '
904 << node_internal->uniqueId() << ' ' << node_internal->localId();
905#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
906 node_internal->setParent(0,parent_item.localId());
907 node_internal->setOwner(parent_item.owner(),m_mesh_info.rank());
908 ++m_mesh_info.nbNode();
909 }
910
911 // Connection de l'item aux sommets
912 ItemLocalId node_lid(node_internal);
913 ItemLocalId new_item_lid(new_item);
914 switch (submesh_kind) {
915 case IK_Cell:
916 m_cell_family.replaceNode(new_item_lid,i_node, node_lid);
917 m_node_family.addCellToNode(node_internal, new_item.toCell());
918 break;
919 case IK_Face:
920 m_face_family.replaceNode(new_item_lid,i_node, node_lid);
921 m_node_family.addFaceToNode(node_internal, new_item.toFace());
922 break;
923 case IK_Edge:
924 m_edge_family.replaceNode(new_item_lid,i_node, node_lid);
925 m_node_family.addEdgeToNode(node_internal, new_item.toEdge());
926 break;
927 default: // les autres sont déjà filtrés avant
928 break;
929 }
930 }
931
932 // Traitement des nouvelles arêtes (le filtrage has_edge est déjà pris en compte dans item_nb_edge)
933 for( Integer i_edge=0; i_edge<item_nb_edge; ++i_edge ) {
934 const ItemTypeInfo::LocalEdge& le = type->localEdge(i_edge);
935
936 Int64 first_node = nodes_uid[ le.beginNode() ];
937 Int64 second_node = nodes_uid[ le.endNode() ];
938 if (first_node > second_node)
939 std::swap(first_node,second_node);
940
941 Edge parent_item = item.itemBase().edgeBase(i_edge);
942 if (parent_item.null())
943 ARCANE_FATAL("Cannot find parent edge");
944
945 Int64 new_edge_uid = parent_item.uniqueId();
946
947 ItemInternal* edge_internal = m_edge_family.findOrAllocOne(new_edge_uid,is_add);
948 if (is_add) {
949#ifdef ARCANE_DEBUG_DYNAMIC_MESH
950 info() << "Création edge " << new_edge_uid << ' '
951 << edge_internal->uniqueId() << ' ' << edge_internal->localId();
952#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
953 edge_internal->setParent(0,parent_item.localId());
954 edge_internal->setOwner(parent_item.owner(),m_mesh_info.rank());
955
956 {
957 Node current_node = nodes_map.findItem(first_node);
958 m_edge_family.replaceNode(ItemLocalId(edge_internal), 0, current_node);
959 m_node_family.addEdgeToNode(current_node, edge_internal);
960 }
961 {
962 Node current_node = nodes_map.findItem(second_node);
963 m_edge_family.replaceNode(ItemLocalId(edge_internal), 1, current_node);
964 m_node_family.addEdgeToNode(current_node, edge_internal);
965 }
966 ++m_mesh_info.nbEdge();
967 }
968
969
970 // Connection de l'item aux sommets
971 switch (submesh_kind) {
972 case IK_Cell: {
973 m_cell_family.replaceEdge(ItemLocalId(new_item),i_edge,ItemLocalId(edge_internal));
974 m_edge_family.addCellToEdge(edge_internal, new_item.toCell());
975 } break;
976 case IK_Face: {
977 m_face_family.replaceEdge(ItemLocalId(new_item),i_edge,ItemLocalId(edge_internal));
978 m_edge_family.addFaceToEdge(edge_internal, new_item.toFace());
979 } break;
980 default: // les autres sont déjà filtrés avant
981 break;
982 }
983 }
984
985 // Traitement des nouvelles faces
986 // item_nb_face matérialise déjà que ce contexte ne se produit qu'avec submesh_kind==IK_Cell
987 for( Integer i_face=0; i_face<item_nb_face; ++i_face ) {
988 const ItemTypeInfo::LocalFace& lf = type->localFace(i_face);
989 Integer face_nb_node = lf.nbNode();
990
991 m_work_face_orig_nodes_uid.resize(face_nb_node);
992 for( Integer z=0; z<face_nb_node; ++z )
993 m_work_face_orig_nodes_uid[z] = nodes_uid[ lf.node(z) ];
994 bool is_reorder = false;
995 if (m_mesh->dimension() == 1) { // is 1d mesh
996 is_reorder = m_face_reorderer.reorder1D(i_face, m_work_face_orig_nodes_uid[0]);
997 }
998 else{
999 is_reorder = m_face_reorderer.reorder(ItemTypeId::fromInteger(lf.typeId()), m_work_face_orig_nodes_uid);
1000 }
1001 ConstArrayView<Int64> face_sorted_nodes(m_face_reorderer.sortedNodes());
1002 // find parent item
1003 Item parent_item;
1004 if (kind==IK_Cell) {
1005 parent_item = item.toCell().face(i_face);
1006 }
1007 else if (kind==IK_Face) {
1008 if (m_mesh->dimension() == 1) { // is 1d mesh
1009 parent_item = parent_nodes_map.findItem(face_sorted_nodes[0]);
1010 } else {
1011 // Algo sans CT_FaceToEdge
1012 Int64 first_node = face_sorted_nodes[0];
1013 Int64 second_node = face_sorted_nodes[1];
1014 if (first_node > second_node)
1015 std::swap(first_node,second_node);
1016 Node nbi = parent_nodes_map.findItem(first_node);
1017 parent_item = ItemTools::findEdgeInNode2(nbi,first_node,second_node);
1018 }
1019 }
1020
1021 if (parent_item.null())
1022 ARCANE_FATAL("Cannot find parent face");
1023 Int64 new_face_uid = parent_item.uniqueId();
1024 ItemTypeInfo* face_type = itm->typeFromId(lf.typeId());
1025
1026 ItemInternal* face_internal = m_face_family.findOrAllocOne(new_face_uid,face_type,is_add);
1027 if (is_add){
1028#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1029 info() << "Création face " << new_face_uid << ' '
1030 << face_internal->uniqueId() << ' ' << face_internal->localId();
1031#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
1032 face_internal->setParent(0,parent_item.localId());
1033 face_internal->setOwner(parent_item.owner(),m_mesh_info.rank());
1034
1035 for( Integer i_node=0; i_node<face_nb_node; ++i_node ){
1036 Node current_node = nodes_map.findItem(face_sorted_nodes[i_node]);
1037 m_face_family.replaceNode(ItemLocalId(face_internal), i_node, current_node);
1038 m_node_family.addFaceToNode(current_node, face_internal);
1039 }
1040
1041 if (m_mesh_builder->hasEdge()) {
1042 Integer face_nb_edge = lf.nbEdge();
1043 for( Integer i_edge=0; i_edge<face_nb_edge; ++i_edge ){
1044 Int32 edge_idx = lf.edge(i_edge);
1045 Edge current_edge = new_item.itemBase().edgeBase(edge_idx);
1046 m_face_family.addEdgeToFace(face_internal,current_edge);
1047 m_edge_family.addFaceToEdge(current_edge,face_internal);
1048 }
1049 }
1050 ++m_mesh_info.nbFace();
1051 }
1052 m_cell_family.replaceFace(ItemLocalId(new_item),i_face,ItemLocalId(face_internal));
1053 if (is_reorder){
1054 m_face_family.addFrontCellToFace(face_internal,new_item.toCell());
1055 } else{
1056 m_face_family.addBackCellToFace(face_internal,new_item.toCell());
1057 }
1058 }
1059
1060 return ItemCompatibility::_itemInternal(new_item);
1061}
1062
1063/*---------------------------------------------------------------------------*/
1064/*---------------------------------------------------------------------------*/
1068template<typename CellInfo>
1070_addNodesToCell(Cell cell, const CellInfo& cell_info)
1071{
1072 Integer cell_nb_node = cell_info.nbNode();
1073
1074 // Ajoute les nouveaux noeuds si nécessaire
1075 for( Integer i_node=0; i_node<cell_nb_node; ++i_node ){
1076 Int64 node_unique_id = cell_info.nodeUniqueId(i_node);
1077 bool is_add = false;
1078 ItemInternal* node_internal = m_node_family.findOrAllocOne(node_unique_id,is_add);
1079 if (is_add){
1080 ++m_mesh_info.nbNode();
1081 node_internal->setOwner(cell_info.nodeOwner(i_node),m_mesh_info.rank());
1082 }
1083 m_node_family.addCellToNode(node_internal,cell);
1084 m_cell_family.replaceNode(cell,i_node,ItemLocalId(node_internal));
1085 }
1086}
1087
1088/*---------------------------------------------------------------------------*/
1089/*---------------------------------------------------------------------------*/
1090
1091template<typename CellInfo>
1092bool OneMeshItemAdder::
1093_isReorder(Integer i_face, const ItemTypeInfo::LocalFace& lf, const CellInfo& cell_info)
1094{
1095 const Integer face_nb_node = lf.nbNode();
1096 m_work_face_orig_nodes_uid.resize(face_nb_node);
1097 for(Integer i_node=0; i_node < face_nb_node; ++i_node)
1098 m_work_face_orig_nodes_uid[i_node] = cell_info.nodeUniqueId(lf.node(i_node));
1099 bool is_reorder = false;
1100 if (m_mesh->dimension() == 1) { // is 1d mesh
1101 is_reorder = m_face_reorderer.reorder1D(i_face, m_work_face_orig_nodes_uid[0]);
1102 }
1103 else{
1104 is_reorder = m_face_reorderer.reorder(ItemTypeId::fromInteger(lf.typeId()), m_work_face_orig_nodes_uid);
1105 }
1106
1107 return is_reorder;
1108}
1109
1110/*---------------------------------------------------------------------------*/
1111/*---------------------------------------------------------------------------*/
1112
1116{
1117 m_next_face_uid = 0;
1118 m_next_edge_uid = 0;
1119 m_mesh_info.reset();
1120}
1121
1122/*---------------------------------------------------------------------------*/
1123/*---------------------------------------------------------------------------*/
1124
1127{
1128 if (m_next_face_uid!=0 || m_next_edge_uid!=0)
1129 ARCANE_FATAL("Can not call this method when edge or face are already created");
1131 info() << "Is Generate Edge and Face uniqueId() from Nodes=" << m_use_hash_for_edge_and_face_unique_id;
1132}
1133
1134/*---------------------------------------------------------------------------*/
1135/*---------------------------------------------------------------------------*/
1136
1137} // End namespace Arcane::mesh
1138
1139/*---------------------------------------------------------------------------*/
1140/*---------------------------------------------------------------------------*/
#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_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
Fonctions utilitaires sur le maillage.
bool reorderNodesOfFace(Int64ConstArrayView before_ids, Int64ArrayView after_ids)
Réordonne les noeuds d'une face.
Int64 generateHashUniqueId(SmallSpan< const Int64 > nodes_unique_id)
Génère un identifiant unique à partir d'une liste d'identifiants de noeuds.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
Maille d'un maillage.
Definition Item.h:1191
Face face(Int32 i) const
i-ème face de la maille
Definition Item.h:1269
Int32 nbFace() const
Nombre de faces de la maille.
Definition Item.h:1266
Edge edge(Int32 i) const
i-ème arête de la maille
Definition Item.h:1284
Vue constante d'un tableau de type T.
constexpr ConstArrayView< T > subView(Integer abegin, Integer asize) const noexcept
Sous-vue (constante) à partir de l'élément abegin et contenant asize éléments.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Arête d'une maille.
Definition Item.h:809
Face d'une maille.
Definition Item.h:944
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
Definition Item.h:1019
bool isSubDomainBoundary() const
Indique si la face est au bord du sous-domaine (i.e nbCell()==1)
Definition Item.h:1038
Interface pour gérer une connectivité incrémentale.
virtual void replaceConnectedItem(ItemLocalId source_item, Integer index, ItemLocalId target_local_id)=0
Remplace l'entité d'index index de source_item par l'entité de localId() target_local_id.
virtual void addConnectedItem(ItemLocalId source_item, ItemLocalId target_local_id)=0
Ajoute l'entité de localId() target_local_id à la connectivité de source_item.
Interface de modification d'une famille.
virtual IIncrementalItemConnectivity * getStoredConnectivity(IItemFamily *source_family, IItemFamily *target_family, const String &name)=0
Retourne, si elle est associée à un stockage, la connectivité entre les familles source_family et tar...
Interface d'une famille d'entités.
Definition IItemFamily.h:84
virtual String name() const =0
Nom de la famille.
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.
ItemUniqueId uniqueId() const
Numéro unique de l'entité
ItemTypeInfo * typeInfo() const
Type de l'entité.
Int32 localId() const
Numéro local (au sous-domaine) de l'entité
Structure interne d'une entité de maillage.
Index d'un Item dans une variable.
Definition ItemLocalId.h:41
Type d'une entité (Item).
Definition ItemTypeId.h:32
static ItemTypeId fromInteger(Int64 v)
Créé une instance à partir d'un entier.
Informations locales sur une arête d'une maille.
Integer endNode() const
Indice local à la maille du sommet extrémité de l'arête.
Integer beginNode() const
Indice local à la maille du sommet origine de l'arête.
Informations locales sur une face d'une maille.
Integer node(Integer i) const
Indice locale dans la maille du i-ème noeud de la face.
Integer nbEdge() const
Nombre d'arête de la face.
Integer typeId() const
Type de l'entité face.
Integer edge(Integer i) const
Arête de la face.
Integer nbNode() const
Nombre de noeuds de la face.
Infos sur un type d'entité du maillage.
LocalEdge localEdge(Integer id) const
Connectivité locale de la i-ème arête de la maille.
LocalFace localFace(Integer id) const
Connectivité locale de la i-ème face de la maille.
Int16 dimension() const
Dimension de l'élément (<0 si inconnu)
String typeName() const
Nom du type.
bool isValidForCell() const
Indique si le type est valide pour créér une maille (Cell)
ItemTypeId itemTypeId() const
Numéro du type.
Gestionnaire des types d'entités de maillage.
Definition ItemTypeMng.h:66
ItemTypeInfo * typeFromId(Integer id) const
Type correspondant au numéro id.
Elément de maillage s'appuyant sur des noeuds (Edge,Face,Cell).
Definition Item.h:724
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:779
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:776
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:374
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
Edge toEdge() const
Converti l'entité en le genre Edge.
Definition Item.h:1656
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
Definition Item.h:238
ItemWithNodes toItemWithNodes() const
Converti l'entité en le genre ItemWithNodes.
Definition Item.h:1642
Cell toCell() const
Converti l'entité en le genre Cell.
Definition Item.h:1670
eItemKind kind() const
Genre de l'entité
Definition Item.h:250
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Definition Item.h:216
Face toFace() const
Converti l'entité en le genre Edge.
Definition Item.h:1663
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:363
Int16 type() const
Type de l'entité
Definition Item.h:241
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é.
void setParent(Int32 aindex, Int32 parent_local_id)
Positionne le i-ème parent (actuellement aindex doit valoir 0)
Noeud d'un maillage.
Definition Item.h:573
Exception lorsqu'une opération n'est pas supportée.
Chaîne de caractères unicode.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
Construction d'un maillage de manière incrémentale.
Implémentation d'un maillage.
Definition DynamicMesh.h:97
IItemFamily * itemFamily(eItemKind ik) override
Retourne la famille d'entité de type ik.
Integer dimension() override
Dimension du maillage (1D, 2D ou 3D).
IItemFamilyNetwork * itemFamilyNetwork() override
Interface du réseau de familles (familles connectées)
Item findOrAllocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info, bool &is_alloc) override
Récupère ou alloue une arête de numéro unique uid et de type type.Ajout générique d'item.
void replaceNode(ItemLocalId edge, Integer index, ItemLocalId node)
Remplace le noeud d'index index de l'arête edge avec celui de localId() node_lid.
Infos pour créer/sérialiser une maille connaissant les uniqueId() et owner() de toutes ces sous-entit...
Integer level() const
AMR.
Tableau associatif de ItemInternal.
impl::ItemBase findItem(Int64 uid) const
Retourne l'entité de numéro unique uid.
static Edge findEdgeInNode2(Node node, Int64 begin_node, Int64 end_node)
Definition ItemTools.cc:73
static Face findFaceInNode2(Node node, Integer face_type_id, Int64ConstArrayView face_nodes_uid)
Definition ItemTools.cc:44
Int32 rank() const
Numéro de ce sous-domaine.
Definition MeshInfos.h:53
Integer & nbEdge()
Nombre d'arêtes dans le maillage.
Definition MeshInfos.h:60
Integer & nbNode()
Nombre de noeuds dans le maillage.
Definition MeshInfos.h:56
void _checkSameItemCoherency(ItemWithNodes item, ConstArrayView< Int64 > nodes_uid)
Vérifie la cohérence des noeuds d'une entité ajouté déjà présente.
void _addNodesToCell(Cell cell, const CellInfo &cell_info)
Ajoute les noeuds nodes_uid à la maille cell.
NodesOfItemReorderer m_face_reorderer
Tableaux de travail.
ItemInternal * _addOneCell(const CellInfo &cell_info)
Ajoute une maille.
ItemInternal * addOneCell(ItemTypeId type_id, Int64 cell_uid, Int32 sub_domain_id, Int64ConstArrayView nodes_uid, bool allow_build_face)
Ajoute une maille.
MeshInfos m_mesh_info
Info générale sur le maillage (numéro de sous-domaine, nombre d'items...)
Int64 _checkGenerateFaceUniqueId(Int64 uid, ConstArrayView< Int64 > nodes_uid)
Génère un uniqueId() pour la face si uid est nul.
Int64 m_next_edge_uid
Numéro du uniqueId() suivant utilisé pour générer les arêtes.
void setUseNodeUniqueIdToGenerateEdgeAndFaceUniqueId(bool v)
Positionne le mécanisme de numérotation des uniqueId().
void resetAfterDeallocate()
Remise à zéro des structures pour pouvoir faire à nouveau une allocation.
bool m_use_hash_for_edge_and_face_unique_id
Si vrai, génère les uniqueId() des faces à partir de ceux des noeuds.
Int64 m_next_face_uid
Numéro du uniqueId() suivant utilisé pour générer les faces.
ItemInternal * addOneParentItem(const Item &item, const eItemKind submesh_kind, const bool fatal_on_existing_item=true)
Ajoute d'un item parent.
ItemInternal * addOneFace(ItemTypeId type_id, Int64 face_uid, Int32 owner_rank, Int64ConstArrayView nodes_uid)
Ajoute une face.
Int32 toInt32(Int64 v)
Converti un Int64 en un Int32.
bool arcaneIsCheck()
Vrai si on est en mode vérification.
Definition Misc.cc:68
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:426
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:567
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:428
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_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.
std::int32_t Int32
Type entier signé sur 32 bits.