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