Arcane  v3.16.10.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 ConstArrayView<Int64> face_sorted_nodes = m_face_reorderer.sortedNodes();
269 Int64 face_unique_id = NULL_ITEM_UNIQUE_ID;
270 Face face_internal;
271 const bool use_hash = m_use_hash_for_edge_and_face_unique_id;
272 // Si on calcule les uniqueId() des faces à partir des noeuds,
273 // on peut directement savoir la face existe déjà. Sinon, on
274 // appelle ItemTools::findFaceInNode2() mais cette fonction est plus
275 // couteuse car elle recherche la face en parcourant les faces connectées
276 // au premier noeud de la face.
277 if (use_hash){
278 face_unique_id = _checkGenerateFaceUniqueId(NULL_ITEM_UNIQUE_ID,face_sorted_nodes);
279 face_internal = m_face_family.itemsMap().tryFind(face_unique_id);
280 }
281 else{
282 // Récupère les noeuds orientés de la face
283 // (Il faut avoir appelé une des méthodes d'ajout de face avant)
284 Node nbi = nodes_map.findItem(face_sorted_nodes[0]);
285 face_internal = ItemTools::findFaceInNode2(nbi,lf.typeId(),face_sorted_nodes);
286 }
287 if (face_internal.null()) {
288 // La face n'est pas trouvée. Elle n'existe donc pas dans notre sous-domaine.
289 // Si cela est autorisé, on créée la nouvelle face.
290 if (!cell_info.allowBuildFace() && !m_use_hash_for_edge_and_face_unique_id){
291 info() << "BadCell uid=" << cell_info.uniqueId();
292 for( Int32 i=0; i<cell_info.nbNode(); ++i )
293 info() << "Cell node I=" << i << " uid=" << cell_info.nodeUniqueId(i);
294 ARCANE_FATAL("On the fly face allocation is not allowed here.\n"
295 " You need to add faces with IMeshModifier::addFaces().\n"
296 " CellUid={0} LocalFace={1} FaceNodes={2}",
297 cell_info.uniqueId(),i_face,face_sorted_nodes);
298 }
299 // Ne recalcule le hash que si ce n'est pas déjà fait.
300 if (!use_hash)
301 face_unique_id = _checkGenerateFaceUniqueId(NULL_ITEM_UNIQUE_ID,face_sorted_nodes);
302 is_add = true;
303 ItemTypeInfo* face_type = m_item_type_mng->typeFromId(lf.typeId());
304 return m_face_family.allocOne(face_unique_id,face_type);
305 }
306 else {
307 is_add = false;
308 return face_internal;
309 }
310}
311
312/*---------------------------------------------------------------------------*/
313/*---------------------------------------------------------------------------*/
314
315template<>
316Edge OneMeshItemAdder::
317_findInternalEdge(Integer i_edge, const FullCellInfo& cell_info,
318 Int64 first_node, Int64 second_node, bool& is_add)
319{
320 ARCANE_UNUSED(first_node);
321 ARCANE_UNUSED(second_node);
322
323 const Int64 edge_unique_id = cell_info.edgeUniqueId(i_edge);
324 return m_edge_family.findOrAllocOne(edge_unique_id,is_add);
325}
326
327/*---------------------------------------------------------------------------*/
328/*---------------------------------------------------------------------------*/
329
330template<>
331Edge OneMeshItemAdder::
332_findInternalEdge(Integer i_edge, const CellInfoProxy& cell_info, Int64 first_node, Int64 second_node, bool& is_add)
333{
334 ARCANE_UNUSED(i_edge);
335
336 const bool use_hash = m_use_hash_for_edge_and_face_unique_id;
337 FixedArray<Int64,2> nodes;
338 Int64 edge_unique_id = NULL_ITEM_UNIQUE_ID;
339 Edge edge_internal;
340 if (use_hash){
341 nodes[0] = first_node;
342 nodes[1] = second_node;
343 edge_unique_id = MeshUtils::generateHashUniqueId(nodes.view());
344 edge_internal = m_edge_family.itemsMap().tryFind(edge_unique_id);
345 }
346 else{
347 const ItemInternalMap& nodes_map = m_mesh->nodesMap();
348 Node nbi = nodes_map.findItem(first_node);
349 edge_internal = ItemTools::findEdgeInNode2(nbi,first_node,second_node);
350 }
351 if (edge_internal.null()){
352 if (!cell_info.allowBuildEdge() && !use_hash)
353 ARCANE_FATAL("On the fly edge allocation is not allowed here."
354 " You need to add edges before with IMeshModifier::addEdges()");
355 if (!use_hash)
356 edge_unique_id = m_next_edge_uid++;
357 is_add = true;
358 return m_edge_family.allocOne(edge_unique_id);
359 }
360 else {
361 is_add = false;
362 return edge_internal;
363 }
364}
365
366/*---------------------------------------------------------------------------*/
367/*---------------------------------------------------------------------------*/
385addOneCell(ItemTypeId type_id,
386 Int64 cell_uid,
387 Int32 sub_domain_id,
388 Int64ConstArrayView nodes_uid,
389 bool allow_build_face)
390{
391 CellInfoProxy cell_info_proxy(m_item_type_mng->typeFromId(type_id),cell_uid,sub_domain_id,nodes_uid,allow_build_face);
392
393 return _addOneCell(cell_info_proxy);
394}
395
396/*---------------------------------------------------------------------------*/
397/*---------------------------------------------------------------------------*/
404addOneCell(const FullCellInfo& cell_info)
405{
406 return _addOneCell(cell_info);
407}
408
409/*---------------------------------------------------------------------------*/
410/*---------------------------------------------------------------------------*/
411
412ItemInternal* OneMeshItemAdder::
413addOneItem(IItemFamily* family,
414 IItemFamilyModifier* family_modifier,
415 ItemTypeId type_id,
416 Int64 item_uid,
417 Integer item_owner,
418 Integer sub_domain_id,
419 Integer nb_connected_family,
420 Int64ConstArrayView connectivity_info)
421{
422 ARCANE_ASSERT(m_mesh->itemFamilyNetwork(),("ItemFamilyNetwork is required to call OneMeshItemAdder::addOneItem"));
423 bool is_alloc = true;
424 Item item = family_modifier->findOrAllocOne(item_uid,type_id,m_mesh_info,is_alloc); // don't forget to add print in the class method
425 item.mutableItemBase().setOwner(item_owner,sub_domain_id);
426 // Add connectivities if needed
427 Integer info_index = 0;
428 for (Integer family_index = 0; family_index < nb_connected_family; ++family_index){
429 // get connected family
430 eItemKind family_kind = static_cast<eItemKind>(connectivity_info[info_index++]); // another way ?
431 Int32 nb_connected_item = CheckedConvert::toInt32(connectivity_info[info_index++]);
432 IItemFamily* connected_family = m_mesh->itemFamily(family_kind);
433 // get connectivities family -> connected_family and reverse
434 String connectivity_name = mesh::connectivityName(family,connected_family);
435 String reverse_connectivity_name = mesh::connectivityName(connected_family,family);
436 bool is_dependency = false;
437 IIncrementalItemConnectivity* family_to_connected_family = m_mesh->itemFamilyNetwork()->getStoredConnectivity(family,connected_family,connectivity_name,is_dependency);
438 IIncrementalItemConnectivity* connected_family_to_family = m_mesh->itemFamilyNetwork()->getStoredConnectivity(connected_family,family,reverse_connectivity_name);
439 // Clear connectivities for already allocated items (except dependencies since replace is used)
440 if (!is_alloc) {
441 if(!is_dependency) _clearConnectivity(ItemLocalId(item), family_to_connected_family);
442 if (connected_family_to_family) _clearReverseConnectivity(ItemLocalId(item),family_to_connected_family,connected_family_to_family);
443 }
444 // get connected item lids
445 Int32UniqueArray connected_item_lids(nb_connected_item);
446 connected_family->itemsUniqueIdToLocalId(connected_item_lids,connectivity_info.subView(info_index,nb_connected_item),true);
447 for (Integer connected_item_index = 0; connected_item_index < nb_connected_item; ++connected_item_index){
448 if (family_to_connected_family) {
449 // pre-alloc are done (=> use replace) when a dependency relation ("owning relation") while not when only a relation (use add)
450 if (! is_dependency) family_to_connected_family->addConnectedItem(ItemLocalId(item),ItemLocalId(connected_item_lids[connected_item_index]));
451 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...
452 }
453 if (connected_family_to_family)
454 connected_family_to_family->addConnectedItem(ItemLocalId(connected_item_lids[connected_item_index]),ItemLocalId(item));
455 }
456 info_index+= nb_connected_item;
457 }
458// debug(Trace::Highest) << "[addItems] ADD_ITEM " << ItemPrinter(item) << " in " << family->name();
459 debug(Trace::Highest) << "[addItems] ADD_ITEM " << ItemPrinter(item) << " in " << family->name();
460 return ItemCompatibility::_itemInternal(item);
461}
462
463/*---------------------------------------------------------------------------*/
464
465ItemInternal* OneMeshItemAdder::
466addOneItem2(IItemFamily* family,
467 IItemFamilyModifier* family_modifier,
468 ItemTypeId type_id,
469 Int64 item_uid,
470 Integer item_owner,
471 Integer sub_domain_id,
472 Integer nb_connected_family,
473 Int64ConstArrayView connectivity_info)
474{
475 ARCANE_ASSERT(m_mesh->itemFamilyNetwork(),("ItemFamilyNetwork is required to call OneMeshItemAdder::addOneItem"));
476 bool is_alloc = true;
477 Item item = family_modifier->findOrAllocOne(item_uid,type_id,m_mesh_info,is_alloc); // don't forget to add print in the class method
478 item.mutableItemBase().setOwner(item_owner,sub_domain_id);
479 // Add connectivities if needed
480 Integer info_index = 0;
481 for (Integer family_index = 0; family_index < nb_connected_family; ++family_index) {
482 // Prepare connection
483 // get connected family
484 eItemKind family_kind = static_cast<eItemKind>(connectivity_info[info_index++]); // another way ?
485 Int32 nb_connected_item = CheckedConvert::toInt32(connectivity_info[info_index++]);
486 if (nb_connected_item == 0) continue;
487 IItemFamily* connected_family = nullptr ;
488 switch(family_kind){
489 case IK_Particle:
490 connected_family = m_mesh->findItemFamily(family_kind, ParticleFamily::defaultFamilyName(), false,false);
491 break ;
492 case IK_DoF:
493 if(family->name()==GraphDoFs::dualNodeFamilyName())
494 connected_family = m_mesh->findItemFamily(family_kind, GraphDoFs::linkFamilyName(), false,false);
495 else
496 connected_family = m_mesh->findItemFamily(family_kind, GraphDoFs::dualNodeFamilyName(), false,false);
497 break ;
498 default:
499 connected_family = m_mesh->itemFamily(family_kind);
500 break ;
501 }
502 // get connectivities family -> connected_family and reverse
503 String connectivity_name = mesh::connectivityName(family,connected_family);
504 bool is_dependency = false;
505 IIncrementalItemConnectivity* family_to_connected_family = m_mesh->itemFamilyNetwork()->getConnectivity(family,connected_family,connectivity_name,is_dependency);
506 if (!family_to_connected_family)
507 ARCANE_FATAL("Cannot find connectivity name={0}",connectivity_name);
508 bool is_deep_connectivity = m_mesh->itemFamilyNetwork()->isDeep(family_to_connected_family) ;
509 bool is_relation = !(is_dependency && is_deep_connectivity);
510 // Build connection
511 // get connected item lids
512 Int32UniqueArray connected_item_lids(nb_connected_item);
513 bool do_fatal = is_relation ? false : true; // for relations, connected items may not be present and will be skipped.
514 connected_family->itemsUniqueIdToLocalId(connected_item_lids,connectivity_info.subView(info_index,nb_connected_item),do_fatal);
515 // if connection is relation, connected item not necessarily present: remove absent (ie null) items
516 Integer nb_connected_item_found = nb_connected_item;
517 if (is_relation)
518 {
519 for (Integer index = 0; index < connected_item_lids.size(); )
520 {
521 if (connected_item_lids[index] == NULL_ITEM_LOCAL_ID) {
522 connected_item_lids.remove(index);
523 --nb_connected_item_found;
524 }
525 else ++index;
526 }
527 }
528 for (Integer connected_item_index = 0; connected_item_index < nb_connected_item_found; ++connected_item_index)
529 {
530 if (family_to_connected_family)
531 {
532 // Only strategy : check and add
533 auto connected_item_lid = ItemLocalId{connected_item_lids[connected_item_index]};
534 if (is_relation)
535 {
536 if (!family_to_connected_family->hasConnectedItem(ItemLocalId(item),connected_item_lid))
537 {
538 family_to_connected_family->addConnectedItem(ItemLocalId(item),connected_item_lid);
539 }
540 }
541 else
542 {
543 family_to_connected_family->replaceConnectedItem(ItemLocalId(item),connected_item_index,connected_item_lid);
544 }
545 }
546 }
547 info_index+= nb_connected_item;
548 }
549 if (is_alloc)
550 debug(Trace::Highest) << "[addItems] ADD_ITEM " << ItemPrinter(item) << " in " << family->name();
551 // debug(Trace::Highest) << "[addItems] DEPENDENCIES for " << family->name() << FullItemPrinter(item) ; // debug info
552 // _printRelations(item); // debug info
553 return ItemCompatibility::_itemInternal(item);
554}
555
556/*---------------------------------------------------------------------------*/
557
558void OneMeshItemAdder::
559_printRelations(ItemInternal* item)
560{
561 debug(Trace::Highest) << "[addItems] RELATIONS for " << ItemPrinter(item) << " in " << item->family()->name();
562 for (const auto& relation : m_mesh->itemFamilyNetwork()->getChildRelations(item->family())) {
563// debug(Trace::Highest) << " Relation " << relation->name();
564// debug(Trace::Highest) << " Relation " << relation->nbConnectedItem(ItemLocalId(item));
565 ConnectivityItemVector connected_items(relation);
566 for (const auto& connected_item : connected_items.connectedItems(ItemLocalId(item))) {
567 debug(Trace::Highest) << ItemPrinter(connected_item);
568 }
569 }
570}
571
572/*---------------------------------------------------------------------------*/
573/*---------------------------------------------------------------------------*/
574
575void OneMeshItemAdder::
576_clearConnectivity(ItemLocalId item, IIncrementalItemConnectivity* connectivity)
577{
578
579 ConnectivityItemVector accessor(connectivity);
580 ENUMERATE_ITEM(connected_item, accessor.connectedItems(item)) {
581 connectivity->removeConnectedItem(item,connected_item);
582 }
583}
584
585/*---------------------------------------------------------------------------*/
586/*---------------------------------------------------------------------------*/
587
588void OneMeshItemAdder::
589_clearReverseConnectivity(ItemLocalId item, IIncrementalItemConnectivity* connectivity, IIncrementalItemConnectivity* reverse_connectivity)
590{
591 ConnectivityItemVector accessor(connectivity);
592 ENUMERATE_ITEM(connected_item, accessor.connectedItems(item)) {
593 reverse_connectivity->removeConnectedItem(connected_item,item);
594 }
595}
596
597/*---------------------------------------------------------------------------*/
598/*---------------------------------------------------------------------------*/
599
600template<> void OneMeshItemAdder::
601_AMR_Patch(Cell new_cell, const FullCellInfo& cell_info)
602{
604 if(m_mesh->isAmrActivated()){
605 // FIXME doit-on traiter les mailles de niveau 0
606 //comme celles de niveau superieur
607 if(cell_info.level() != 0){
608 Integer child_rank = cell_info.whichChildAmI();
609 Int64 hParent_uid = cell_info.hParentCellUniqueId();
610 ItemTypeId cell_type = ItemTypeId::fromInteger(cell_info.typeId());
611 bool is_add;
612 Cell hParent_cell= m_cell_family.findOrAllocOne(hParent_uid,cell_type,is_add);
613 m_cell_family._addParentCellToCell(new_cell,hParent_cell);
614 m_cell_family._addChildCellToCell(hParent_cell,child_rank,new_cell);
615 }
616 }
617}
618
619template<> void OneMeshItemAdder::
620_AMR_Patch(Cell cell, const CellInfoProxy& cell_info)
621{
622 ARCANE_UNUSED(cell);
623 ARCANE_UNUSED(cell_info);
624}
625
626/*---------------------------------------------------------------------------*/
627/*---------------------------------------------------------------------------*/
633template<typename CellInfo>
635_addOneCell(const CellInfo& cell_info)
636{
637 bool is_check = arcaneIsCheck();
638
639 ItemTypeInfo* cell_type_info = cell_info.typeInfo();
640 ItemTypeId cell_type_id = cell_type_info->itemTypeId();
641 const bool is_verbose = false;
642 if (is_verbose)
643 info() << "AddNewCell type_id=" << cell_type_id << " nb_node=" << cell_info.nbNode()
644 << " type=" << cell_type_info->typeName();
645 // Regarde si la maille existe déjà (auquel cas on ne fait rien)
646 Cell inew_cell;
647 {
648 bool is_add; // ce flag est toujours correctement positionné via les findOrAllocOne
649 inew_cell = m_cell_family.findOrAllocOne(cell_info.uniqueId(),cell_type_id,is_add);
650 if (!is_add){
651 if (is_check){
652 Cell cell2(inew_cell);
653 // Vérifie que les noeuds correspondent bien à ceux existants
654 for( Integer i=0, is=cell_info.nbNode(); i<is; ++i )
655 if (cell_info.nodeUniqueId(i)!=cell2.node(i).uniqueId())
656 ARCANE_FATAL("trying to add existing cell (uid={0}) with different nodes",
657 cell_info.uniqueId());
658 }
659 return ItemCompatibility::_itemInternal(inew_cell);
660 }
661 }
662
663 Cell new_cell(inew_cell);
664
665 ++m_mesh_info.nbCell();
666
667 const MeshKind& mesh_kind = m_mesh->meshKind();
668 const bool allow_multi_dim_cell = !mesh_kind.isMonoDimension();
669 const Int32 cell_nb_face = cell_info.nbFace();
670 MutableItemBase mut_cell = new_cell.mutableItemBase();
671 if (cell_type_info->dimension() == 2 && cell_type_info->nbLocalFace() == 0)
672 mut_cell.addFlags(ItemFlags::II_HasEdgeFor1DItems);
673 mut_cell.setOwner(cell_info.owner(), m_mesh_info.rank());
674 // Vérifie la cohérence entre le type local et la maille créée.
675 if (is_check){
676 if (cell_info.nbNode()!=inew_cell.nbNode())
677 ARCANE_FATAL("Incoherent number of nodes v={0} expected={1}",inew_cell.nbNode(),cell_info.nbNode());
678 if (cell_nb_face!=inew_cell.nbFace())
679 ARCANE_FATAL("Incoherent number of faces v={0} expected={1}",inew_cell.nbFace(),cell_nb_face);
680 if (!cell_type_info->isValidForCell())
681 ARCANE_FATAL("Type '{0}' is not allowed for 'Cell' (cell_uid={1})",
682 cell_type_info->typeName(),cell_info.uniqueId());
683 if (!allow_multi_dim_cell){
684 Int32 cell_dimension = cell_type_info->dimension();
685 Int32 mesh_dimension = m_mesh->dimension();
686 if (cell_dimension>=0 && cell_dimension!=mesh_dimension)
687 ARCANE_FATAL("Incoherent dimension for cell uid={0} cell_dim={1} mesh_dim={2} type={3}",
688 cell_info.uniqueId(),cell_dimension,mesh_dimension,cell_type_info->typeName());
689 }
690 }
691
693 ItemInternalMap& nodes_map = m_node_family.itemsMap();
694
695 _addNodesToCell(inew_cell,cell_info);
696
697 if (m_mesh_builder->hasEdge()) {
698 const Int32 cell_nb_edge = cell_info.nbEdge();
699 // Ajoute les nouvelles arêtes ci-nécessaire
700 for( Integer i_edge=0; i_edge<cell_nb_edge; ++i_edge ){
701 const ItemTypeInfo::LocalEdge& le = cell_type_info->localEdge(i_edge);
702 Int64 first_node = cell_info.nodeUniqueId( le.beginNode() );
703 Int64 second_node = cell_info.nodeUniqueId( le.endNode() );
704 if (first_node > second_node)
705 std::swap(first_node,second_node);
706
707 bool is_add = false;
708 Edge edge_internal = _findInternalEdge(i_edge, cell_info, first_node, second_node, is_add);
709 if (is_add){
710 if (is_verbose)
711 info() << "Create edge " << edge_internal.uniqueId() << ' ' << edge_internal.localId();
712
713 edge_internal.mutableItemBase().setOwner(cell_info.edgeOwner(i_edge),m_mesh_info.rank());
714 {
715 Node current_node = nodes_map.findItem(first_node);
716 m_edge_family.replaceNode(ItemLocalId(edge_internal), 0, current_node);
717 m_node_family.addEdgeToNode(current_node, edge_internal);
718 }
719 {
720 Node current_node = nodes_map.findItem(second_node);
721 m_edge_family.replaceNode(ItemLocalId(edge_internal), 1, current_node);
722 m_node_family.addEdgeToNode(current_node, edge_internal);
723 }
724 ++m_mesh_info.nbEdge();
725 }
726
727 m_cell_family.replaceEdge(ItemLocalId(new_cell),i_edge,ItemLocalId(edge_internal));
728 m_edge_family.addCellToEdge(edge_internal,inew_cell);
729 }
730 }
731
732 // Ajoute les nouvelles faces ci-nécessaire
733 for( Integer i_face=0; i_face<cell_nb_face; ++i_face ){
734 const ItemTypeInfo::LocalFace& lf = cell_type_info->localFace(i_face);
735 const Integer face_nb_node = lf.nbNode();
736 // en effet de bord, _isReorder positionne m_face_reorderer.sortedNodes();
737 const bool is_reorder = _isReorder(i_face, lf, cell_info);
738 ConstArrayView<Int64> face_sorted_nodes = m_face_reorderer.sortedNodes();
739 bool is_add = false;
740 Face face = _findInternalFace(i_face, cell_info, is_add);
741 if (is_add){
742 // Pour les éléments d'ordre supérieur à 1, on ajoute les faces qu'aux noeuds
743 // qui correspondent à l'élément d'ordre 1 (linéaire) associé.
744 const ItemTypeInfo* face_type_info = m_item_type_mng->typeFromId(lf.typeId());
745 const Int32 face_nb_linear_node = face_type_info->linearTypeInfo()->nbLocalNode();
746 if (is_verbose){
747 info() << "AddFaceToCell (cell_uid=" << new_cell.uniqueId() << ": Create face (index=" << i_face
748 << ") uid=" << face.uniqueId()
749 << " lid=" << face.localId()
750 << " type=" << face_type_info->typeName()
751 << " face_nb_linear_node=" << face_nb_linear_node
752 << " sorted_nodes=" << face_sorted_nodes;
753 }
754 face.mutableItemBase().setOwner(cell_info.faceOwner(i_face),m_mesh_info.rank());
755
756 for (Integer i_node = 0; i_node < face_nb_node; ++i_node) {
757 if (is_verbose)
758 info() << "AddNodeToFace i_node=" << i_node << " uid=" << face_sorted_nodes[i_node];
759 Node current_node = nodes_map.findItem(face_sorted_nodes[i_node]);
760 m_face_family.replaceNode(face, i_node, current_node);
761 if (i_node<face_nb_linear_node){
762 m_node_family.addFaceToNode(current_node, face);
763 }
764 }
765
766 if (m_mesh_builder->hasEdge()) {
767 Integer face_nb_edge = lf.nbEdge();
768 for( Integer i_edge=0; i_edge<face_nb_edge; ++i_edge ){
769 Edge current_edge = new_cell.edge( lf.edge(i_edge) );
770 m_face_family.addEdgeToFace(face,current_edge);
771 m_edge_family.addFaceToEdge(current_edge,face);
772 }
773 }
774 ++m_mesh_info.nbFace();
775 }
776 m_cell_family.replaceFace(new_cell,i_face,face);
777
779 if(m_mesh->isAmrActivated()){
780 if (is_reorder){
781 if(face.nbCell() == 2)
782 m_face_family.replaceFrontCellToFace(face,new_cell);
783 else
784 m_face_family.addFrontCellToFace(face,inew_cell);
785 } else{
786 if(face.nbCell() == 2)
787 m_face_family.replaceBackCellToFace(face,new_cell);
788 else
789 m_face_family.addBackCellToFace(face,inew_cell);
790 }
791 } else {
792 if (is_reorder){
793 m_face_family.addFrontCellToFace(face,inew_cell);
794 } else{
795 m_face_family.addBackCellToFace(face,inew_cell);
796 }
797 }
798 }
799
800 _AMR_Patch(inew_cell, cell_info);
801 return ItemCompatibility::_itemInternal(inew_cell);
802}
803
804/*---------------------------------------------------------------------------*/
805/*---------------------------------------------------------------------------*/
823addOneParentItem(const Item & item, const eItemKind submesh_kind, const bool fatal_on_existing_item)
824{
825 //bool is_check = arcaneIsCheck();
826 ItemTypeMng* itm = m_mesh->itemTypeMng();
827 eItemKind kind = item.kind();
828 ItemTypeInfo* type = itm->typeFromId(item.type());
829
830 if (item.type() == IT_Line2 && submesh_kind == IK_Cell)
831 type = itm->typeFromId(IT_CellLine2);
832 if (item.type() == IT_Vertex && submesh_kind == IK_Face)
833 type = itm->typeFromId(IT_FaceVertex);
834 ItemTypeId type_id = type->itemTypeId();
835
836 if (MeshToMeshTransposer::kindTranspose(submesh_kind, m_mesh, m_mesh->parentMesh()) != kind)
837 ARCANE_FATAL("Incompatible kind/sub-kind");
838
839 // Regarde si la maille existe déjà
840 bool is_add; // ce flag est toujours correctement positionné via les findOrAllocOne
841 Item new_item;
842
843 switch (submesh_kind) {
844 case IK_Node:
845 new_item = m_node_family.findOrAllocOne(item.uniqueId(),is_add);
846 ++m_mesh_info.nbNode();
847 break;
848 case IK_Edge:
849 new_item = m_edge_family.findOrAllocOne(item.uniqueId(),is_add);
850 ++m_mesh_info.nbEdge();
851 break;
852 case IK_Face:
853 new_item = m_face_family.findOrAllocOne(item.uniqueId(),type,is_add);
854 ++m_mesh_info.nbFace();
855 break;
856 case IK_Cell:
857 if (kind == IK_Face && !(item.toFace().isSubDomainBoundary()))
858 ARCANE_FATAL("Bad boundary face");
859 new_item = m_cell_family.findOrAllocOne(item.uniqueId(),type_id,is_add);
860 ++m_mesh_info.nbCell();
861 break;
862 default:
863 throw NotSupportedException(A_FUNCINFO,String::format("Kind {0} not supported", submesh_kind));
864 }
865
866 if (!is_add){
867 if (fatal_on_existing_item)
868 ARCANE_FATAL("Cannot add already existing parent item in submesh");
869 else
870 return ItemCompatibility::_itemInternal(new_item);
871 }
872
873 new_item.mutableItemBase().setParent(0,item.localId());
874 new_item.mutableItemBase().setOwner(item.owner(),m_mesh_info.rank());
875
876 // Localise vis-à-vis de l'item à insérer ces sous-items
877 // Par défaut tout à 0, qui correspond aussi au cas submesh_kind==IK_Node
878 Integer item_nb_node = 0;
879 Integer item_nb_face = 0;
880 Integer item_nb_edge = 0;
881
882 switch (submesh_kind) {
883 case IK_Cell:
884 item_nb_face = type->nbLocalFace();
885 item_nb_edge = type->nbLocalEdge();
886 item_nb_node = type->nbLocalNode();
887 break;
888 case IK_Face:
889 item_nb_edge = type->nbLocalEdge();
890 item_nb_node = type->nbLocalNode();
891 break;
892 case IK_Edge:
893 item_nb_node = type->nbLocalNode();
894 default: // les autres sont déjà filtrés avant avec une exception
895 break;
896 }
897
898 // Traitement du cas de désactivation des arêtes
899 if (!m_mesh_builder->hasEdge())
900 item_nb_edge = 0;
901
902#if OLD
903 // Ne fonctionne plus si on désactive les anciennes connectivités
904 if (is_check){
905 for( Integer z=0; z<item_nb_face; ++z )
906 new_item->_setFace(z,NULL_ITEM_ID);
907 for( Integer z=0; z<item_nb_edge; ++z )
908 new_item->_setEdge(z,NULL_ITEM_ID);
909 for( Integer z=0; z<item_nb_node; ++z )
910 new_item->_setNode(z,NULL_ITEM_ID);
911 }
912#endif
913
915 DynamicMeshKindInfos::ItemInternalMap& nodes_map = m_mesh->nodesMap();
916 auto* parent_mesh = ARCANE_CHECK_POINTER(dynamic_cast<DynamicMesh*>(m_mesh->parentMesh()));
917 DynamicMeshKindInfos::ItemInternalMap& parent_nodes_map = parent_mesh->nodesMap();
918
919 // Traitement des nouveaux noeuds
920
921 // Les sommets sont utilisés dans l'ordre de l'item sauf les cellules de sous-maillages surfacique.
922 const bool direct_node_order =
923 !(submesh_kind == IK_Cell
924 && kind == IK_Face
925 && !(item.toFace().isSubDomainBoundaryOutside()));
926
927 Int64UniqueArray nodes_uid(item_nb_node,NULL_ITEM_UNIQUE_ID);
928 for( Integer i_node=0; i_node<item_nb_node; ++i_node ){
929 Item parent_item;
930 if (type->typeId() == IT_FaceVertex)
931 parent_item = item;
932 else{
933 Int32 idx = ((direct_node_order) ? i_node : (item_nb_node-1-i_node));
934 parent_item = item.toItemWithNodes().node(idx);
935 }
936 Int64 new_node_uid = nodes_uid[i_node] = parent_item.uniqueId();
937 ItemInternal* node_internal = m_node_family.findOrAllocOne(new_node_uid,is_add);
938 if (is_add){
939#ifdef ARCANE_DEBUG_DYNAMIC_MESH
940 info() << "Création node " << new_node_uid << ' '
941 << node_internal->uniqueId() << ' ' << node_internal->localId();
942#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
943 node_internal->setParent(0,parent_item.localId());
944 node_internal->setOwner(parent_item.owner(),m_mesh_info.rank());
945 ++m_mesh_info.nbNode();
946 }
947
948 // Connection de l'item aux sommets
949 ItemLocalId node_lid(node_internal);
950 ItemLocalId new_item_lid(new_item);
951 switch (submesh_kind) {
952 case IK_Cell:
953 m_cell_family.replaceNode(new_item_lid,i_node, node_lid);
954 m_node_family.addCellToNode(node_internal, new_item.toCell());
955 break;
956 case IK_Face:
957 m_face_family.replaceNode(new_item_lid,i_node, node_lid);
958 m_node_family.addFaceToNode(node_internal, new_item.toFace());
959 break;
960 case IK_Edge:
961 m_edge_family.replaceNode(new_item_lid,i_node, node_lid);
962 m_node_family.addEdgeToNode(node_internal, new_item.toEdge());
963 break;
964 default: // les autres sont déjà filtrés avant
965 break;
966 }
967 }
968
969 // Traitement des nouvelles arêtes (le filtrage has_edge est déjà pris en compte dans item_nb_edge)
970 for( Integer i_edge=0; i_edge<item_nb_edge; ++i_edge ) {
971 const ItemTypeInfo::LocalEdge& le = type->localEdge(i_edge);
972
973 Int64 first_node = nodes_uid[ le.beginNode() ];
974 Int64 second_node = nodes_uid[ le.endNode() ];
975 if (first_node > second_node)
976 std::swap(first_node,second_node);
977
978 Edge parent_item = item.itemBase().edgeBase(i_edge);
979 if (parent_item.null())
980 ARCANE_FATAL("Cannot find parent edge");
981
982 Int64 new_edge_uid = parent_item.uniqueId();
983
984 ItemInternal* edge_internal = m_edge_family.findOrAllocOne(new_edge_uid,is_add);
985 if (is_add) {
986#ifdef ARCANE_DEBUG_DYNAMIC_MESH
987 info() << "Création edge " << new_edge_uid << ' '
988 << edge_internal->uniqueId() << ' ' << edge_internal->localId();
989#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
990 edge_internal->setParent(0,parent_item.localId());
991 edge_internal->setOwner(parent_item.owner(),m_mesh_info.rank());
992
993 {
994 Node current_node = nodes_map.findItem(first_node);
995 m_edge_family.replaceNode(ItemLocalId(edge_internal), 0, current_node);
996 m_node_family.addEdgeToNode(current_node, edge_internal);
997 }
998 {
999 Node current_node = nodes_map.findItem(second_node);
1000 m_edge_family.replaceNode(ItemLocalId(edge_internal), 1, current_node);
1001 m_node_family.addEdgeToNode(current_node, edge_internal);
1002 }
1003 ++m_mesh_info.nbEdge();
1004 }
1005
1006
1007 // Connection de l'item aux sommets
1008 switch (submesh_kind) {
1009 case IK_Cell: {
1010 m_cell_family.replaceEdge(ItemLocalId(new_item),i_edge,ItemLocalId(edge_internal));
1011 m_edge_family.addCellToEdge(edge_internal, new_item.toCell());
1012 } break;
1013 case IK_Face: {
1014 m_face_family.replaceEdge(ItemLocalId(new_item),i_edge,ItemLocalId(edge_internal));
1015 m_edge_family.addFaceToEdge(edge_internal, new_item.toFace());
1016 } break;
1017 default: // les autres sont déjà filtrés avant
1018 break;
1019 }
1020 }
1021
1022 // Traitement des nouvelles faces
1023 // item_nb_face matérialise déjà que ce contexte ne se produit qu'avec submesh_kind==IK_Cell
1024 for( Integer i_face=0; i_face<item_nb_face; ++i_face ) {
1025 const ItemTypeInfo::LocalFace& lf = type->localFace(i_face);
1026 Integer face_nb_node = lf.nbNode();
1027
1028 m_work_face_orig_nodes_uid.resize(face_nb_node);
1029 for( Integer z=0; z<face_nb_node; ++z )
1030 m_work_face_orig_nodes_uid[z] = nodes_uid[ lf.node(z) ];
1031 bool is_reorder = false;
1032 if (m_mesh->dimension() == 1) { // is 1d mesh
1033 is_reorder = m_face_reorderer.reorder1D(i_face, m_work_face_orig_nodes_uid[0]);
1034 }
1035 else{
1036 is_reorder = m_face_reorderer.reorder(ItemTypeId::fromInteger(lf.typeId()), m_work_face_orig_nodes_uid);
1037 }
1038 ConstArrayView<Int64> face_sorted_nodes(m_face_reorderer.sortedNodes());
1039 // find parent item
1040 Item parent_item;
1041 if (kind==IK_Cell) {
1042 parent_item = item.toCell().face(i_face);
1043 }
1044 else if (kind==IK_Face) {
1045 if (m_mesh->dimension() == 1) { // is 1d mesh
1046 parent_item = parent_nodes_map.findItem(face_sorted_nodes[0]);
1047 } else {
1048 // Algo sans CT_FaceToEdge
1049 Int64 first_node = face_sorted_nodes[0];
1050 Int64 second_node = face_sorted_nodes[1];
1051 if (first_node > second_node)
1052 std::swap(first_node,second_node);
1053 Node nbi = parent_nodes_map.findItem(first_node);
1054 parent_item = ItemTools::findEdgeInNode2(nbi,first_node,second_node);
1055 }
1056 }
1057
1058 if (parent_item.null())
1059 ARCANE_FATAL("Cannot find parent face");
1060 Int64 new_face_uid = parent_item.uniqueId();
1061 ItemTypeInfo* face_type = itm->typeFromId(lf.typeId());
1062
1063 ItemInternal* face_internal = m_face_family.findOrAllocOne(new_face_uid,face_type,is_add);
1064 if (is_add){
1065#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1066 info() << "Création face " << new_face_uid << ' '
1067 << face_internal->uniqueId() << ' ' << face_internal->localId();
1068#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
1069 face_internal->setParent(0,parent_item.localId());
1070 face_internal->setOwner(parent_item.owner(),m_mesh_info.rank());
1071
1072 for( Integer i_node=0; i_node<face_nb_node; ++i_node ){
1073 Node current_node = nodes_map.findItem(face_sorted_nodes[i_node]);
1074 m_face_family.replaceNode(ItemLocalId(face_internal), i_node, current_node);
1075 m_node_family.addFaceToNode(current_node, face_internal);
1076 }
1077
1078 if (m_mesh_builder->hasEdge()) {
1079 Integer face_nb_edge = lf.nbEdge();
1080 for( Integer i_edge=0; i_edge<face_nb_edge; ++i_edge ){
1081 Int32 edge_idx = lf.edge(i_edge);
1082 Edge current_edge = new_item.itemBase().edgeBase(edge_idx);
1083 m_face_family.addEdgeToFace(face_internal,current_edge);
1084 m_edge_family.addFaceToEdge(current_edge,face_internal);
1085 }
1086 }
1087 ++m_mesh_info.nbFace();
1088 }
1089 m_cell_family.replaceFace(ItemLocalId(new_item),i_face,ItemLocalId(face_internal));
1090 if (is_reorder){
1091 m_face_family.addFrontCellToFace(face_internal,new_item.toCell());
1092 } else{
1093 m_face_family.addBackCellToFace(face_internal,new_item.toCell());
1094 }
1095 }
1096
1097 return ItemCompatibility::_itemInternal(new_item);
1098}
1099
1100/*---------------------------------------------------------------------------*/
1101/*---------------------------------------------------------------------------*/
1105template<typename CellInfo>
1107_addNodesToCell(Cell cell, const CellInfo& cell_info)
1108{
1109 Integer cell_nb_node = cell_info.nbNode();
1110
1111 // Ajoute les nouveaux noeuds si nécessaire
1112 for( Integer i_node=0; i_node<cell_nb_node; ++i_node ){
1113 Int64 node_unique_id = cell_info.nodeUniqueId(i_node);
1114 bool is_add = false;
1115 ItemInternal* node_internal = m_node_family.findOrAllocOne(node_unique_id,is_add);
1116 if (is_add){
1117 ++m_mesh_info.nbNode();
1118 node_internal->setOwner(cell_info.nodeOwner(i_node),m_mesh_info.rank());
1119 }
1120 m_node_family.addCellToNode(node_internal,cell);
1121 m_cell_family.replaceNode(cell,i_node,ItemLocalId(node_internal));
1122 }
1123}
1124
1125/*---------------------------------------------------------------------------*/
1126/*---------------------------------------------------------------------------*/
1127
1128template<typename CellInfo>
1129bool OneMeshItemAdder::
1130_isReorder(Integer i_face, const ItemTypeInfo::LocalFace& lf, const CellInfo& cell_info)
1131{
1132 const Integer face_nb_node = lf.nbNode();
1133 m_work_face_orig_nodes_uid.resize(face_nb_node);
1134 for(Integer i_node=0; i_node < face_nb_node; ++i_node)
1135 m_work_face_orig_nodes_uid[i_node] = cell_info.nodeUniqueId(lf.node(i_node));
1136 bool is_reorder = false;
1137 if (m_mesh->dimension() == 1) { // is 1d mesh
1138 is_reorder = m_face_reorderer.reorder1D(i_face, m_work_face_orig_nodes_uid[0]);
1139 }
1140 else{
1141 is_reorder = m_face_reorderer.reorder(ItemTypeId::fromInteger(lf.typeId()), m_work_face_orig_nodes_uid);
1142 }
1143
1144 return is_reorder;
1145}
1146
1147/*---------------------------------------------------------------------------*/
1148/*---------------------------------------------------------------------------*/
1149
1153{
1154 m_next_face_uid = 0;
1155 m_next_edge_uid = 0;
1156 m_mesh_info.reset();
1157}
1158
1159/*---------------------------------------------------------------------------*/
1160/*---------------------------------------------------------------------------*/
1161
1164{
1165 if (m_next_face_uid!=0 || m_next_edge_uid!=0)
1166 ARCANE_FATAL("Can not call this method when edge or face are already created");
1168 info() << "Is Generate Edge and Face uniqueId() from Nodes=" << m_use_hash_for_edge_and_face_unique_id;
1169}
1170
1171/*---------------------------------------------------------------------------*/
1172/*---------------------------------------------------------------------------*/
1173
1174} // End namespace Arcane::mesh
1175
1176/*---------------------------------------------------------------------------*/
1177/*---------------------------------------------------------------------------*/
#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:1205
Face face(Int32 i) const
i-ème face de la maille
Definition Item.h:1283
Int32 nbFace() const
Nombre de faces de la maille.
Definition Item.h:1280
Edge edge(Int32 i) const
i-ème arête de la maille
Definition Item.h:1298
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:823
Face d'une maille.
Definition Item.h:958
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
Definition Item.h:1033
bool isSubDomainBoundary() const
Indique si la face est au bord du sous-domaine (i.e nbCell()==1)
Definition Item.h:1052
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.
const ItemTypeInfo * linearTypeInfo() const
Type de l'élément linéaire correspondant.
Int16 dimension() const
Dimension de l'élément (<0 si inconnu)
Integer nbLocalNode() const
Nombre de noeuds de l'entité
String typeName() const
Nom du type.
Integer nbLocalFace() const
Nombre de faces de l'entité
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 d'un maillage.
Definition ItemTypeMng.h:65
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:733
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:788
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:785
Classe de base d'un élément de maillage.
Definition Item.h:83
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
Definition Item.h:380
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
Edge toEdge() const
Converti l'entité en le genre Edge.
Definition Item.h:1670
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:1656
Cell toCell() const
Converti l'entité en le genre Cell.
Definition Item.h:1684
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:1677
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:369
Int16 type() const
Type de l'entité
Definition Item.h:241
Caractéristiques d'un maillage.
Definition MeshKind.h:104
static eItemKind kindTranspose(eItemKind kindA, IMesh *meshA, IMesh *meshB)
Transpose le genre kindA du maillage meshA en le genre associé dans meshB.
Méthodes permettant de modifier ItemBase.
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)
void addFlags(Int32 added_flags)
Ajoute les flags added_flags à ceux de l'entité
Noeud d'un maillage.
Definition Item.h:582
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:98
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.