Arcane  v3.16.2.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 MeshKind& mesh_kind = m_mesh->meshKind();
643 const bool allow_multi_dim_cell = !mesh_kind.isMonoDimension();
644 const Int32 cell_nb_face = cell_info.nbFace();
645 MutableItemBase mut_cell = new_cell.mutableItemBase();
646 if (cell_type_info->dimension() == 2 && cell_type_info->nbLocalFace() == 0)
647 mut_cell.addFlags(ItemFlags::II_HasEdgeFor1DItems);
648 mut_cell.setOwner(cell_info.owner(), m_mesh_info.rank());
649 // Vérifie la cohérence entre le type local et la maille créée.
650 if (is_check){
651 if (cell_info.nbNode()!=inew_cell.nbNode())
652 ARCANE_FATAL("Incoherent number of nodes v={0} expected={1}",inew_cell.nbNode(),cell_info.nbNode());
653 if (cell_nb_face!=inew_cell.nbFace())
654 ARCANE_FATAL("Incoherent number of faces v={0} expected={1}",inew_cell.nbFace(),cell_nb_face);
655 if (!cell_type_info->isValidForCell())
656 ARCANE_FATAL("Type '{0}' is not allowed for 'Cell' (cell_uid={1})",
657 cell_type_info->typeName(),cell_info.uniqueId());
658 if (!allow_multi_dim_cell){
659 Int32 cell_dimension = cell_type_info->dimension();
660 Int32 mesh_dimension = m_mesh->dimension();
661 if (cell_dimension>=0 && cell_dimension!=mesh_dimension)
662 ARCANE_FATAL("Incoherent dimension for cell uid={0} cell_dim={1} mesh_dim={2} type={3}",
663 cell_info.uniqueId(),cell_dimension,mesh_dimension,cell_type_info->typeName());
664 }
665 }
666
668 ItemInternalMap& nodes_map = m_node_family.itemsMap();
669
670 _addNodesToCell(inew_cell,cell_info);
671
672 if (m_mesh_builder->hasEdge()) {
673 const Int32 cell_nb_edge = cell_info.nbEdge();
674 // Ajoute les nouvelles arêtes ci-nécessaire
675 for( Integer i_edge=0; i_edge<cell_nb_edge; ++i_edge ){
676 const ItemTypeInfo::LocalEdge& le = cell_type_info->localEdge(i_edge);
677 Int64 first_node = cell_info.nodeUniqueId( le.beginNode() );
678 Int64 second_node = cell_info.nodeUniqueId( le.endNode() );
679 if (first_node > second_node)
680 std::swap(first_node,second_node);
681
682 bool is_add = false;
683 Edge edge_internal = _findInternalEdge(i_edge, cell_info, first_node, second_node, is_add);
684 if (is_add){
685 if (is_verbose)
686 info() << "Create edge " << edge_internal.uniqueId() << ' ' << edge_internal.localId();
687
688 edge_internal.mutableItemBase().setOwner(cell_info.edgeOwner(i_edge),m_mesh_info.rank());
689 {
690 Node current_node = nodes_map.findItem(first_node);
691 m_edge_family.replaceNode(ItemLocalId(edge_internal), 0, current_node);
692 m_node_family.addEdgeToNode(current_node, edge_internal);
693 }
694 {
695 Node current_node = nodes_map.findItem(second_node);
696 m_edge_family.replaceNode(ItemLocalId(edge_internal), 1, current_node);
697 m_node_family.addEdgeToNode(current_node, edge_internal);
698 }
699 ++m_mesh_info.nbEdge();
700 }
701
702 m_cell_family.replaceEdge(ItemLocalId(new_cell),i_edge,ItemLocalId(edge_internal));
703 m_edge_family.addCellToEdge(edge_internal,inew_cell);
704 }
705 }
706
707 // Ajoute les nouvelles faces ci-nécessaire
708 for( Integer i_face=0; i_face<cell_nb_face; ++i_face ){
709 const ItemTypeInfo::LocalFace& lf = cell_type_info->localFace(i_face);
710 const Integer face_nb_node = lf.nbNode();
711 // en effet de bord, _isReorder positionne m_face_reorderer.sortedNodes();
712 const bool is_reorder = _isReorder(i_face, lf, cell_info);
713 ConstArrayView<Int64> face_sorted_nodes = m_face_reorderer.sortedNodes();
714 bool is_add = false;
715 Face face = _findInternalFace(i_face, cell_info, is_add);
716 if (is_add){
717 if (is_verbose){
718 info() << "AddFaceToCell (cell_uid=" << new_cell.uniqueId() << ": Create face (index=" << i_face
719 << ") uid=" << face.uniqueId()
720 << " lid=" << face.localId();
721 }
722 face.mutableItemBase().setOwner(cell_info.faceOwner(i_face),m_mesh_info.rank());
723 // Pour les éléments d'ordre supérieur à 1, on ajoute les faces qu'aux noeuds
724 // qui correspondent à l'élément d'ordre 1 (linéaire) associé.
725 ItemTypeInfo* face_type_info = m_item_type_mng->typeFromId(lf.typeId());
726
727 const Int32 face_nb_linear_node = face_type_info->linearTypeInfo()->nbLocalNode();
728 for( Integer i_node=0; i_node<face_nb_node; ++i_node ){
729 Node current_node = nodes_map.findItem(face_sorted_nodes[i_node]);
730 m_face_family.replaceNode(face, i_node, current_node);
731 if (i_node<face_nb_linear_node){
732 m_node_family.addFaceToNode(current_node, face);
733 }
734 }
735
736 if (m_mesh_builder->hasEdge()) {
737 Integer face_nb_edge = lf.nbEdge();
738 for( Integer i_edge=0; i_edge<face_nb_edge; ++i_edge ){
739 Edge current_edge = new_cell.edge( lf.edge(i_edge) );
740 m_face_family.addEdgeToFace(face,current_edge);
741 m_edge_family.addFaceToEdge(current_edge,face);
742 }
743 }
744 ++m_mesh_info.nbFace();
745 }
746 m_cell_family.replaceFace(new_cell,i_face,face);
747
749 if(m_mesh->isAmrActivated()){
750 if (is_reorder){
751 if(face.nbCell() == 2)
752 m_face_family.replaceFrontCellToFace(face,new_cell);
753 else
754 m_face_family.addFrontCellToFace(face,inew_cell);
755 } else{
756 if(face.nbCell() == 2)
757 m_face_family.replaceBackCellToFace(face,new_cell);
758 else
759 m_face_family.addBackCellToFace(face,inew_cell);
760 }
761 } else {
762 if (is_reorder){
763 m_face_family.addFrontCellToFace(face,inew_cell);
764 } else{
765 m_face_family.addBackCellToFace(face,inew_cell);
766 }
767 }
768 }
769
770 _AMR_Patch(inew_cell, cell_info);
771 return ItemCompatibility::_itemInternal(inew_cell);
772}
773
774/*---------------------------------------------------------------------------*/
775/*---------------------------------------------------------------------------*/
793addOneParentItem(const Item & item, const eItemKind submesh_kind, const bool fatal_on_existing_item)
794{
795 //bool is_check = arcaneIsCheck();
796 ItemTypeMng* itm = m_mesh->itemTypeMng();
797 eItemKind kind = item.kind();
798 ItemTypeInfo* type = itm->typeFromId(item.type());
799
800 if (item.type() == IT_Line2 && submesh_kind == IK_Cell)
801 type = itm->typeFromId(IT_CellLine2);
802 if (item.type() == IT_Vertex && submesh_kind == IK_Face)
803 type = itm->typeFromId(IT_FaceVertex);
804 ItemTypeId type_id = type->itemTypeId();
805
806 if (MeshToMeshTransposer::kindTranspose(submesh_kind, m_mesh, m_mesh->parentMesh()) != kind)
807 ARCANE_FATAL("Incompatible kind/sub-kind");
808
809 // Regarde si la maille existe déjà
810 bool is_add; // ce flag est toujours correctement positionné via les findOrAllocOne
811 Item new_item;
812
813 switch (submesh_kind) {
814 case IK_Node:
815 new_item = m_node_family.findOrAllocOne(item.uniqueId(),is_add);
816 ++m_mesh_info.nbNode();
817 break;
818 case IK_Edge:
819 new_item = m_edge_family.findOrAllocOne(item.uniqueId(),is_add);
820 ++m_mesh_info.nbEdge();
821 break;
822 case IK_Face:
823 new_item = m_face_family.findOrAllocOne(item.uniqueId(),type,is_add);
824 ++m_mesh_info.nbFace();
825 break;
826 case IK_Cell:
827 if (kind == IK_Face && !(item.toFace().isSubDomainBoundary()))
828 ARCANE_FATAL("Bad boundary face");
829 new_item = m_cell_family.findOrAllocOne(item.uniqueId(),type_id,is_add);
830 ++m_mesh_info.nbCell();
831 break;
832 default:
833 throw NotSupportedException(A_FUNCINFO,String::format("Kind {0} not supported", submesh_kind));
834 }
835
836 if (!is_add){
837 if (fatal_on_existing_item)
838 ARCANE_FATAL("Cannot add already existing parent item in submesh");
839 else
840 return ItemCompatibility::_itemInternal(new_item);
841 }
842
843 new_item.mutableItemBase().setParent(0,item.localId());
844 new_item.mutableItemBase().setOwner(item.owner(),m_mesh_info.rank());
845
846 // Localise vis-à-vis de l'item à insérer ces sous-items
847 // Par défaut tout à 0, qui correspond aussi au cas submesh_kind==IK_Node
848 Integer item_nb_node = 0;
849 Integer item_nb_face = 0;
850 Integer item_nb_edge = 0;
851
852 switch (submesh_kind) {
853 case IK_Cell:
854 item_nb_face = type->nbLocalFace();
855 item_nb_edge = type->nbLocalEdge();
856 item_nb_node = type->nbLocalNode();
857 break;
858 case IK_Face:
859 item_nb_edge = type->nbLocalEdge();
860 item_nb_node = type->nbLocalNode();
861 break;
862 case IK_Edge:
863 item_nb_node = type->nbLocalNode();
864 default: // les autres sont déjà filtrés avant avec une exception
865 break;
866 }
867
868 // Traitement du cas de désactivation des arêtes
869 if (!m_mesh_builder->hasEdge())
870 item_nb_edge = 0;
871
872#if OLD
873 // Ne fonctionne plus si on désactive les anciennes connectivités
874 if (is_check){
875 for( Integer z=0; z<item_nb_face; ++z )
876 new_item->_setFace(z,NULL_ITEM_ID);
877 for( Integer z=0; z<item_nb_edge; ++z )
878 new_item->_setEdge(z,NULL_ITEM_ID);
879 for( Integer z=0; z<item_nb_node; ++z )
880 new_item->_setNode(z,NULL_ITEM_ID);
881 }
882#endif
883
885 DynamicMeshKindInfos::ItemInternalMap& nodes_map = m_mesh->nodesMap();
886 auto* parent_mesh = ARCANE_CHECK_POINTER(dynamic_cast<DynamicMesh*>(m_mesh->parentMesh()));
887 DynamicMeshKindInfos::ItemInternalMap& parent_nodes_map = parent_mesh->nodesMap();
888
889 // Traitement des nouveaux noeuds
890
891 // Les sommets sont utilisés dans l'ordre de l'item sauf les cellules de sous-maillages surfacique.
892 const bool direct_node_order =
893 !(submesh_kind == IK_Cell
894 && kind == IK_Face
895 && !(item.toFace().isSubDomainBoundaryOutside()));
896
897 Int64UniqueArray nodes_uid(item_nb_node,NULL_ITEM_UNIQUE_ID);
898 for( Integer i_node=0; i_node<item_nb_node; ++i_node ){
899 Item parent_item;
900 if (type->typeId() == IT_FaceVertex)
901 parent_item = item;
902 else{
903 Int32 idx = ((direct_node_order) ? i_node : (item_nb_node-1-i_node));
904 parent_item = item.toItemWithNodes().node(idx);
905 }
906 Int64 new_node_uid = nodes_uid[i_node] = parent_item.uniqueId();
907 ItemInternal* node_internal = m_node_family.findOrAllocOne(new_node_uid,is_add);
908 if (is_add){
909#ifdef ARCANE_DEBUG_DYNAMIC_MESH
910 info() << "Création node " << new_node_uid << ' '
911 << node_internal->uniqueId() << ' ' << node_internal->localId();
912#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
913 node_internal->setParent(0,parent_item.localId());
914 node_internal->setOwner(parent_item.owner(),m_mesh_info.rank());
915 ++m_mesh_info.nbNode();
916 }
917
918 // Connection de l'item aux sommets
919 ItemLocalId node_lid(node_internal);
920 ItemLocalId new_item_lid(new_item);
921 switch (submesh_kind) {
922 case IK_Cell:
923 m_cell_family.replaceNode(new_item_lid,i_node, node_lid);
924 m_node_family.addCellToNode(node_internal, new_item.toCell());
925 break;
926 case IK_Face:
927 m_face_family.replaceNode(new_item_lid,i_node, node_lid);
928 m_node_family.addFaceToNode(node_internal, new_item.toFace());
929 break;
930 case IK_Edge:
931 m_edge_family.replaceNode(new_item_lid,i_node, node_lid);
932 m_node_family.addEdgeToNode(node_internal, new_item.toEdge());
933 break;
934 default: // les autres sont déjà filtrés avant
935 break;
936 }
937 }
938
939 // Traitement des nouvelles arêtes (le filtrage has_edge est déjà pris en compte dans item_nb_edge)
940 for( Integer i_edge=0; i_edge<item_nb_edge; ++i_edge ) {
941 const ItemTypeInfo::LocalEdge& le = type->localEdge(i_edge);
942
943 Int64 first_node = nodes_uid[ le.beginNode() ];
944 Int64 second_node = nodes_uid[ le.endNode() ];
945 if (first_node > second_node)
946 std::swap(first_node,second_node);
947
948 Edge parent_item = item.itemBase().edgeBase(i_edge);
949 if (parent_item.null())
950 ARCANE_FATAL("Cannot find parent edge");
951
952 Int64 new_edge_uid = parent_item.uniqueId();
953
954 ItemInternal* edge_internal = m_edge_family.findOrAllocOne(new_edge_uid,is_add);
955 if (is_add) {
956#ifdef ARCANE_DEBUG_DYNAMIC_MESH
957 info() << "Création edge " << new_edge_uid << ' '
958 << edge_internal->uniqueId() << ' ' << edge_internal->localId();
959#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
960 edge_internal->setParent(0,parent_item.localId());
961 edge_internal->setOwner(parent_item.owner(),m_mesh_info.rank());
962
963 {
964 Node current_node = nodes_map.findItem(first_node);
965 m_edge_family.replaceNode(ItemLocalId(edge_internal), 0, current_node);
966 m_node_family.addEdgeToNode(current_node, edge_internal);
967 }
968 {
969 Node current_node = nodes_map.findItem(second_node);
970 m_edge_family.replaceNode(ItemLocalId(edge_internal), 1, current_node);
971 m_node_family.addEdgeToNode(current_node, edge_internal);
972 }
973 ++m_mesh_info.nbEdge();
974 }
975
976
977 // Connection de l'item aux sommets
978 switch (submesh_kind) {
979 case IK_Cell: {
980 m_cell_family.replaceEdge(ItemLocalId(new_item),i_edge,ItemLocalId(edge_internal));
981 m_edge_family.addCellToEdge(edge_internal, new_item.toCell());
982 } break;
983 case IK_Face: {
984 m_face_family.replaceEdge(ItemLocalId(new_item),i_edge,ItemLocalId(edge_internal));
985 m_edge_family.addFaceToEdge(edge_internal, new_item.toFace());
986 } break;
987 default: // les autres sont déjà filtrés avant
988 break;
989 }
990 }
991
992 // Traitement des nouvelles faces
993 // item_nb_face matérialise déjà que ce contexte ne se produit qu'avec submesh_kind==IK_Cell
994 for( Integer i_face=0; i_face<item_nb_face; ++i_face ) {
995 const ItemTypeInfo::LocalFace& lf = type->localFace(i_face);
996 Integer face_nb_node = lf.nbNode();
997
998 m_work_face_orig_nodes_uid.resize(face_nb_node);
999 for( Integer z=0; z<face_nb_node; ++z )
1000 m_work_face_orig_nodes_uid[z] = nodes_uid[ lf.node(z) ];
1001 bool is_reorder = false;
1002 if (m_mesh->dimension() == 1) { // is 1d mesh
1003 is_reorder = m_face_reorderer.reorder1D(i_face, m_work_face_orig_nodes_uid[0]);
1004 }
1005 else{
1006 is_reorder = m_face_reorderer.reorder(ItemTypeId::fromInteger(lf.typeId()), m_work_face_orig_nodes_uid);
1007 }
1008 ConstArrayView<Int64> face_sorted_nodes(m_face_reorderer.sortedNodes());
1009 // find parent item
1010 Item parent_item;
1011 if (kind==IK_Cell) {
1012 parent_item = item.toCell().face(i_face);
1013 }
1014 else if (kind==IK_Face) {
1015 if (m_mesh->dimension() == 1) { // is 1d mesh
1016 parent_item = parent_nodes_map.findItem(face_sorted_nodes[0]);
1017 } else {
1018 // Algo sans CT_FaceToEdge
1019 Int64 first_node = face_sorted_nodes[0];
1020 Int64 second_node = face_sorted_nodes[1];
1021 if (first_node > second_node)
1022 std::swap(first_node,second_node);
1023 Node nbi = parent_nodes_map.findItem(first_node);
1024 parent_item = ItemTools::findEdgeInNode2(nbi,first_node,second_node);
1025 }
1026 }
1027
1028 if (parent_item.null())
1029 ARCANE_FATAL("Cannot find parent face");
1030 Int64 new_face_uid = parent_item.uniqueId();
1031 ItemTypeInfo* face_type = itm->typeFromId(lf.typeId());
1032
1033 ItemInternal* face_internal = m_face_family.findOrAllocOne(new_face_uid,face_type,is_add);
1034 if (is_add){
1035#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1036 info() << "Création face " << new_face_uid << ' '
1037 << face_internal->uniqueId() << ' ' << face_internal->localId();
1038#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
1039 face_internal->setParent(0,parent_item.localId());
1040 face_internal->setOwner(parent_item.owner(),m_mesh_info.rank());
1041
1042 for( Integer i_node=0; i_node<face_nb_node; ++i_node ){
1043 Node current_node = nodes_map.findItem(face_sorted_nodes[i_node]);
1044 m_face_family.replaceNode(ItemLocalId(face_internal), i_node, current_node);
1045 m_node_family.addFaceToNode(current_node, face_internal);
1046 }
1047
1048 if (m_mesh_builder->hasEdge()) {
1049 Integer face_nb_edge = lf.nbEdge();
1050 for( Integer i_edge=0; i_edge<face_nb_edge; ++i_edge ){
1051 Int32 edge_idx = lf.edge(i_edge);
1052 Edge current_edge = new_item.itemBase().edgeBase(edge_idx);
1053 m_face_family.addEdgeToFace(face_internal,current_edge);
1054 m_edge_family.addFaceToEdge(current_edge,face_internal);
1055 }
1056 }
1057 ++m_mesh_info.nbFace();
1058 }
1059 m_cell_family.replaceFace(ItemLocalId(new_item),i_face,ItemLocalId(face_internal));
1060 if (is_reorder){
1061 m_face_family.addFrontCellToFace(face_internal,new_item.toCell());
1062 } else{
1063 m_face_family.addBackCellToFace(face_internal,new_item.toCell());
1064 }
1065 }
1066
1067 return ItemCompatibility::_itemInternal(new_item);
1068}
1069
1070/*---------------------------------------------------------------------------*/
1071/*---------------------------------------------------------------------------*/
1075template<typename CellInfo>
1077_addNodesToCell(Cell cell, const CellInfo& cell_info)
1078{
1079 Integer cell_nb_node = cell_info.nbNode();
1080
1081 // Ajoute les nouveaux noeuds si nécessaire
1082 for( Integer i_node=0; i_node<cell_nb_node; ++i_node ){
1083 Int64 node_unique_id = cell_info.nodeUniqueId(i_node);
1084 bool is_add = false;
1085 ItemInternal* node_internal = m_node_family.findOrAllocOne(node_unique_id,is_add);
1086 if (is_add){
1087 ++m_mesh_info.nbNode();
1088 node_internal->setOwner(cell_info.nodeOwner(i_node),m_mesh_info.rank());
1089 }
1090 m_node_family.addCellToNode(node_internal,cell);
1091 m_cell_family.replaceNode(cell,i_node,ItemLocalId(node_internal));
1092 }
1093}
1094
1095/*---------------------------------------------------------------------------*/
1096/*---------------------------------------------------------------------------*/
1097
1098template<typename CellInfo>
1099bool OneMeshItemAdder::
1100_isReorder(Integer i_face, const ItemTypeInfo::LocalFace& lf, const CellInfo& cell_info)
1101{
1102 const Integer face_nb_node = lf.nbNode();
1103 m_work_face_orig_nodes_uid.resize(face_nb_node);
1104 for(Integer i_node=0; i_node < face_nb_node; ++i_node)
1105 m_work_face_orig_nodes_uid[i_node] = cell_info.nodeUniqueId(lf.node(i_node));
1106 bool is_reorder = false;
1107 if (m_mesh->dimension() == 1) { // is 1d mesh
1108 is_reorder = m_face_reorderer.reorder1D(i_face, m_work_face_orig_nodes_uid[0]);
1109 }
1110 else{
1111 is_reorder = m_face_reorderer.reorder(ItemTypeId::fromInteger(lf.typeId()), m_work_face_orig_nodes_uid);
1112 }
1113
1114 return is_reorder;
1115}
1116
1117/*---------------------------------------------------------------------------*/
1118/*---------------------------------------------------------------------------*/
1119
1123{
1124 m_next_face_uid = 0;
1125 m_next_edge_uid = 0;
1126 m_mesh_info.reset();
1127}
1128
1129/*---------------------------------------------------------------------------*/
1130/*---------------------------------------------------------------------------*/
1131
1134{
1135 if (m_next_face_uid!=0 || m_next_edge_uid!=0)
1136 ARCANE_FATAL("Can not call this method when edge or face are already created");
1138 info() << "Is Generate Edge and Face uniqueId() from Nodes=" << m_use_hash_for_edge_and_face_unique_id;
1139}
1140
1141/*---------------------------------------------------------------------------*/
1142/*---------------------------------------------------------------------------*/
1143
1144} // End namespace Arcane::mesh
1145
1146/*---------------------------------------------------------------------------*/
1147/*---------------------------------------------------------------------------*/
#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: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.