Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
IncrementalItemConnectivity.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* IncrementalItemConnectivity.cc (C) 2000-2024 */
9/* */
10/* Connectivité incrémentale des entités. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/IncrementalItemConnectivity.h"
15
16#include "arcane/utils/StringBuilder.h"
17#include "arcane/utils/ArgumentException.h"
18#include "arcane/utils/PlatformUtils.h"
19
20#include "arcane/core/IMesh.h"
21#include "arcane/core/IItemFamily.h"
22#include "arcane/core/ConnectivityItemVector.h"
24#include "arcane/core/ObserverPool.h"
25#include "arcane/core/Properties.h"
26#include "arcane/core/IndexedItemConnectivityView.h"
27#include "arcane/core/internal/IDataInternal.h"
28#include "arcane/core/internal/IItemFamilyInternal.h"
29#include "arcane/core/internal/IIncrementalItemConnectivityInternal.h"
30
31#include "arcane/mesh/IndexedItemConnectivityAccessor.h"
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane::mesh
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
42IndexedItemConnectivityAccessor::
43IndexedItemConnectivityAccessor(IndexedItemConnectivityViewBase view, IItemFamily* target_item_family)
44: IndexedItemConnectivityViewBase(view)
45, m_item_shared_info(target_item_family->_internalApi()->commonItemSharedInfo())
46{}
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
51IndexedItemConnectivityAccessor::
52IndexedItemConnectivityAccessor(IIncrementalItemConnectivity* connectivity)
53: m_item_shared_info(connectivity->targetFamily()->_internalApi()->commonItemSharedInfo())
54{
55 auto* ptr = dynamic_cast<mesh::IncrementalItemConnectivityBase*>(connectivity);
56 if (ptr)
57 IndexedItemConnectivityViewBase::set(ptr->connectivityView()) ;
58}
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63AbstractIncrementalItemConnectivity::
64AbstractIncrementalItemConnectivity(IItemFamily* source_family,
65 IItemFamily* target_family,
66 const String& connectivity_name)
67: TraceAccessor(source_family->traceMng())
68, m_source_family(source_family)
69, m_target_family(target_family)
70, m_name(connectivity_name)
71{
72 m_families.add(m_source_family);
73 m_families.add(m_target_family);
74
75 //TODO: il faudra supprimer ces références lors de la destruction.
76 source_family->_internalApi()->addSourceConnectivity(this);
77 target_family->_internalApi()->addTargetConnectivity(this);
78}
79
80/*---------------------------------------------------------------------------*/
81/*---------------------------------------------------------------------------*/
82
83Ref<IIncrementalItemSourceConnectivity> AbstractIncrementalItemConnectivity::
84toSourceReference()
85{
86 return Arccore::makeRef<IIncrementalItemSourceConnectivity>(this);
87}
88
89/*---------------------------------------------------------------------------*/
90/*---------------------------------------------------------------------------*/
91
92Ref<IIncrementalItemTargetConnectivity> AbstractIncrementalItemConnectivity::
93toTargetReference()
94{
95 return Arccore::makeRef<IIncrementalItemTargetConnectivity>(this);
96}
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101/*---------------------------------------------------------------------------*/
102/*---------------------------------------------------------------------------*/
103
105{
106 public:
107
109 : m_var_name(var_name),
110 m_connectivity_nb_item_variable(VariableBuildInfo(mesh,var_name+"Nb",IVariable::PPrivate)),
111 m_connectivity_index_variable(VariableBuildInfo(mesh,var_name+"Index",IVariable::PPrivate)),
112 m_connectivity_list_variable(VariableBuildInfo(mesh,var_name+"List",IVariable::PPrivate)),
113 m_connectivity_nb_item_array(m_connectivity_nb_item_variable._internalTrueData()->_internalDeprecatedValue()),
114 m_connectivity_index_array(m_connectivity_index_variable._internalTrueData()->_internalDeprecatedValue()),
115 m_connectivity_list_array(m_connectivity_list_variable._internalTrueData()->_internalDeprecatedValue())
116 {
117 // Ajoute un tag pour indiquer que ce sont des variables associées à la connectivité.
118 // Pour l'instant cela n'est utilisé que pour les statistiques d'affichage.
119
120 String tag_name = "ArcaneConnectivity";
121 m_connectivity_nb_item_variable.addTag(tag_name,"1");
122 m_connectivity_index_variable.addTag(tag_name,"1");
123 m_connectivity_list_variable.addTag(tag_name,"1");
124 }
125
126 String m_var_name;
127
128 VariableArrayInt32 m_connectivity_nb_item_variable;
129 VariableArrayInt32 m_connectivity_index_variable;
130 VariableArrayInt32 m_connectivity_list_variable;
131
132 VariableArrayInt32::ContainerType& m_connectivity_nb_item_array;
133 VariableArrayInt32::ContainerType& m_connectivity_index_array;
134 VariableArrayInt32::ContainerType& m_connectivity_list_array;
135
136 ObserverPool m_observers;
137
145 Int32 m_max_nb_item = 0;
146
147 public:
148
149 Integer size() const { return m_connectivity_nb_item_array.size(); }
150
151 bool isAllocated() const { return size()>0; }
152
153 void _checkResize(Int32 lid)
154 {
155 //TODO: réutiliser le code de ItemFamily::_setUniqueId().
156 Integer size = m_connectivity_nb_item_array.size();
157 Integer wanted_size = lid + 1;
158 if (wanted_size<size)
159 return;
160 Integer capacity = m_connectivity_nb_item_array.capacity();
161 if (wanted_size<capacity){
162 // Pas besoin d'augmenter la capacité.
163 }
164 else{
165 Integer reserve_size = 1000;
166 while (lid>reserve_size){
167 reserve_size *= 2;
168 }
169 m_connectivity_nb_item_array.reserve(reserve_size);
170 m_connectivity_index_array.reserve(reserve_size);
171 }
172 m_connectivity_nb_item_array.resize(wanted_size);
173 m_connectivity_index_array.resize(wanted_size);
174 }
175
176 void reserveForItems(Int32 capacity)
177 {
178 m_connectivity_nb_item_array.reserve(capacity);
179 m_connectivity_index_array.reserve(capacity);
180 }
181
182 public:
183
184};
185
186/*---------------------------------------------------------------------------*/
187/*---------------------------------------------------------------------------*/
188
191{
192 public:
193
195 : m_internal_api(v)
196 {}
197
198 public:
199
200 void shrinkMemory() override { return m_internal_api->_shrinkMemory(); }
202 {
203 m_internal_api->_addMemoryInfos(mem_info);
204 }
205
206 private:
207
208 IncrementalItemConnectivityBase* m_internal_api = nullptr;
209};
210
211/*---------------------------------------------------------------------------*/
212/*---------------------------------------------------------------------------*/
213
214IncrementalItemConnectivityBase::
215IncrementalItemConnectivityBase(IItemFamily* source_family,IItemFamily* target_family,
216 const String& aname)
218, m_internal_api(std::make_unique<InternalApi>(this))
219{
220 StringBuilder var_name("Connectivity");
221 var_name += aname;
222 var_name += source_family->name();
223 var_name += target_family->name();
224
225 IMesh* mesh = source_family->mesh();
227
228 using ThatClass = IncrementalItemConnectivityBase;
229 // Récupère les évènements de lecture pour indiquer qu'il faut mettre
230 // à jour les vues.
231 m_p->m_observers.addObserver(this,&ThatClass::_notifyConnectivityNbItemChangedFromObservable,
232 m_p->m_connectivity_nb_item_variable.variable()->readObservable());
233
234 m_p->m_observers.addObserver(this,&ThatClass::_notifyConnectivityIndexChanged,
235 m_p->m_connectivity_index_variable.variable()->readObservable());
236
237 m_p->m_observers.addObserver(this,&ThatClass::_notifyConnectivityListChanged,
238 m_p->m_connectivity_list_variable.variable()->readObservable());
239
240 // Met à jour les vues à partir des tableaux associées.
241 // Il faut le faire dès que la taille d'un tableau change car alors
242 // il peut être réalloué et donc la vue associée devenir invalide.
243 _notifyConnectivityListChanged();
244 _notifyConnectivityIndexChanged();
246}
247
248/*---------------------------------------------------------------------------*/
249/*---------------------------------------------------------------------------*/
250
251IncrementalItemConnectivityBase::
252~IncrementalItemConnectivityBase()
253{
254 delete m_p;
255}
256
257/*---------------------------------------------------------------------------*/
258/*---------------------------------------------------------------------------*/
259
262{
263 if (n<=0)
264 return;
265
266 m_p->reserveForItems(n);
267 _notifyConnectivityIndexChanged();
268 _notifyConnectivityNbItemChanged();
269
272 if (pre_alloc_size>0){
273 m_p->m_connectivity_list_array.reserve(n * pre_alloc_size);
274 _notifyConnectivityListChanged();
275 }
276 }
277}
278
279/*---------------------------------------------------------------------------*/
280/*---------------------------------------------------------------------------*/
281
282void IncrementalItemConnectivityBase::
283_notifyConnectivityListChanged()
284{
285 m_connectivity_list = m_p->m_connectivity_list_array.view();
286 if (m_item_connectivity_list)
287 m_item_connectivity_list->_setConnectivityList(m_item_connectivity_index,m_connectivity_list);
288}
289
290/*---------------------------------------------------------------------------*/
291/*---------------------------------------------------------------------------*/
292
293void IncrementalItemConnectivityBase::
294_notifyConnectivityIndexChanged()
295{
296 m_connectivity_index = m_p->m_connectivity_index_array.view();
297 if (m_item_connectivity_list)
298 m_item_connectivity_list->_setConnectivityIndex(m_item_connectivity_index,m_connectivity_index);
299}
300
301/*---------------------------------------------------------------------------*/
302/*---------------------------------------------------------------------------*/
303
304void IncrementalItemConnectivityBase::
305_notifyConnectivityNbItemChanged()
306{
307 m_connectivity_nb_item = m_p->m_connectivity_nb_item_array.view();
308 if (m_item_connectivity_list)
309 m_item_connectivity_list->_setConnectivityNbItem(m_item_connectivity_index,m_connectivity_nb_item);
310}
311
312/*---------------------------------------------------------------------------*/
313/*---------------------------------------------------------------------------*/
314
315void IncrementalItemConnectivityBase::
316_setMaxNbConnectedItemsInConnectivityList()
317{
318 if (m_item_connectivity_list)
319 m_item_connectivity_list->_setMaxNbConnectedItem(m_item_connectivity_index,m_p->m_max_nb_item);
320}
321
322/*---------------------------------------------------------------------------*/
323/*---------------------------------------------------------------------------*/
330{
331 _notifyConnectivityNbItemChanged();
332 _computeMaxNbConnectedItem();
333}
334
335/*---------------------------------------------------------------------------*/
336/*---------------------------------------------------------------------------*/
337
338void IncrementalItemConnectivityBase::
339_setNewMaxNbConnectedItems(Int32 new_max)
340{
341 if (new_max > m_p->m_max_nb_item){
342 m_p->m_max_nb_item = new_max;
343 _setMaxNbConnectedItemsInConnectivityList();
344 }
345}
346
347/*---------------------------------------------------------------------------*/
348/*---------------------------------------------------------------------------*/
349
350void IncrementalItemConnectivityBase::
351_computeMaxNbConnectedItem()
352{
353 // Force la remise à zéro pour être sur qu'il sera mis à jour
354 m_p->m_max_nb_item = -1;
355 Int32 max_nb_item = 0;
356 for( Int32 x : m_connectivity_nb_item )
357 if (x>max_nb_item)
358 max_nb_item = x;
359 _setNewMaxNbConnectedItems(max_nb_item);
360}
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
364
366maxNbConnectedItem() const
367{
368 return m_p->m_max_nb_item;
369}
370
371/*---------------------------------------------------------------------------*/
372/*---------------------------------------------------------------------------*/
382{
383 info(4) << "setItemConnectivityList name=" << name() << " ilist=" << ilist << " index=" << index;
384 m_item_connectivity_list = ilist;
385 m_item_connectivity_index = index;
386 _notifyConnectivityListChanged();
387 _notifyConnectivityIndexChanged();
388 _notifyConnectivityNbItemChanged();
389 _setMaxNbConnectedItemsInConnectivityList();
390}
391
392/*---------------------------------------------------------------------------*/
393/*---------------------------------------------------------------------------*/
394
397{
398 if(m_p->isAllocated()){
399 m_p->m_connectivity_nb_item_variable.variable()->compact(new_to_old_ids);
400 m_p->m_connectivity_index_variable.variable()->compact(new_to_old_ids);
401 _notifyConnectivityNbItemChanged();
402 _notifyConnectivityIndexChanged();
403 }
404}
405
406/*---------------------------------------------------------------------------*/
407/*---------------------------------------------------------------------------*/
408
411{
412 Int32ArrayView ids = m_connectivity_list;
413 const Integer n = ids.size();
414 for( Integer i=0; i<n; ++i )
415 if (ids[i]!=NULL_ITEM_LOCAL_ID)
416 ids[i] = old_to_new_ids[ ids[i] ];
417}
418
419/*---------------------------------------------------------------------------*/
420/*---------------------------------------------------------------------------*/
421
424{
425 return con_items.resizeAndCopy(_connectedItemsLocalId(item));
426}
427
428/*---------------------------------------------------------------------------*/
429/*---------------------------------------------------------------------------*/
430
431ItemConnectivityContainerView IncrementalItemConnectivityBase::
432connectivityContainerView() const
433{
434 return { m_connectivity_list, m_connectivity_index, m_connectivity_nb_item };
435}
436
437/*---------------------------------------------------------------------------*/
438/*---------------------------------------------------------------------------*/
439
440IndexedItemConnectivityViewBase IncrementalItemConnectivityBase::
441connectivityView() const
442{
443 return { connectivityContainerView(), _sourceFamily()->itemKind(), _targetFamily()->itemKind()};
444}
445
446/*---------------------------------------------------------------------------*/
447/*---------------------------------------------------------------------------*/
448
449IndexedItemConnectivityAccessor IncrementalItemConnectivityBase::
450connectivityAccessor() const
451{
452 return IndexedItemConnectivityAccessor(connectivityView(),_targetFamily());
453}
454
455/*---------------------------------------------------------------------------*/
456/*---------------------------------------------------------------------------*/
457
463
464/*---------------------------------------------------------------------------*/
465/*---------------------------------------------------------------------------*/
466
467void IncrementalItemConnectivityBase::
468dumpInfos()
469{
470 info() << "Infos index=" << m_connectivity_index;
471 info() << "Infos nb_item=" << m_connectivity_nb_item;
472 info() << "Infos list=" << m_connectivity_list;
473}
474
475/*---------------------------------------------------------------------------*/
476/*---------------------------------------------------------------------------*/
477
478/*---------------------------------------------------------------------------*/
479/*---------------------------------------------------------------------------*/
480
481IncrementalItemConnectivity::
482IncrementalItemConnectivity(IItemFamily* source_family,IItemFamily* target_family,
483 const String& aname)
484: IncrementalItemConnectivityBase(source_family,target_family,aname)
485, m_nb_add(0)
486, m_nb_remove(0)
487, m_nb_memcopy(0)
488, m_pre_allocated_size(0)
489{
490 m_pre_allocated_size = _sourceFamily()->properties()->getIntegerWithDefault(name()+"PreallocSize",0);
491 info(4) << "PreallocSize1 var=" << m_p->m_var_name << " v=" << m_pre_allocated_size;
492
493 // Vérifie s'il faut ajouter l'entité nulle en début de liste.
494 _checkAddNullItem();
495}
496
497/*---------------------------------------------------------------------------*/
498/*---------------------------------------------------------------------------*/
499
500IncrementalItemConnectivity::
501~IncrementalItemConnectivity()
502{
503 info(4) << " connectivity name=" << name()
504 << " prealloc_size=" << m_pre_allocated_size
505 << " nb_add=" << m_nb_add
506 << " nb_remove=" << m_nb_remove
507 << " nb_memcopy=" << m_nb_memcopy;
508}
509
510/*---------------------------------------------------------------------------*/
511/*---------------------------------------------------------------------------*/
512
513inline Integer IncrementalItemConnectivity::
514_increaseConnectivityList(Int32 new_lid)
515{
516 Integer pos_in_list = m_connectivity_list.size();
517 m_p->m_connectivity_list_array.add(new_lid);
518 _notifyConnectivityListChanged();
519 return pos_in_list;
520}
521
522/*---------------------------------------------------------------------------*/
523/*---------------------------------------------------------------------------*/
524
525inline Integer IncrementalItemConnectivity::
526_increaseConnectivityList(Int32 new_lid,Integer nb_value)
527{
528 Integer pos_in_list = m_connectivity_list.size();
529 m_p->m_connectivity_list_array.addRange(new_lid,nb_value);
530 _notifyConnectivityListChanged();
531 return pos_in_list;
532}
533
534/*---------------------------------------------------------------------------*/
535/*---------------------------------------------------------------------------*/
536
537void IncrementalItemConnectivity::
538_resetConnectivityList()
539{
540 m_p->m_connectivity_list_array.clear();
541 _notifyConnectivityListChanged();
542 _checkAddNullItem();
543}
544
545/*---------------------------------------------------------------------------*/
546/*---------------------------------------------------------------------------*/
547
548void IncrementalItemConnectivity::
549_increaseIndexList(Int32 lid,Integer size,Int32 target_lid)
550{
551 Integer added_range = (m_pre_allocated_size>0) ? m_pre_allocated_size : 1;
552 ++m_nb_memcopy;
553 Integer pos_in_index = m_connectivity_index[lid];
554 Integer new_pos_in_list = _increaseConnectivityList(NULL_ITEM_LOCAL_ID,size+added_range);
555 ArrayView<Int32> current_list(size,&(m_connectivity_list[pos_in_index]));
556 ArrayView<Int32> new_list(size+1,&(m_connectivity_list[new_pos_in_list]));
557 new_list.copy(current_list);
558 // Ajoute la nouvelle entité à la fin de la liste des connectivités
559 // TODO: regarder pour le tri dans l'ordre des uid() croissant.
560 new_list[size] = target_lid;
561 m_connectivity_index[lid] = new_pos_in_list;
562}
563
564/*---------------------------------------------------------------------------*/
565/*---------------------------------------------------------------------------*/
566
569{
570 ++m_nb_add;
571 const Int32 lid = source_item.localId();
572 const Int32 target_lid = target_item.localId();
573 Integer size = m_connectivity_nb_item[lid];
574 // Ajoute une entité connectée.
575 // Pour l'instant, le fonctionnement est basique.
576 // On ajoute toujours les entités à la fin de m_p->m_connectivity_list.
577 // S'il n'y en a pas, il suffit d'ajouter à la fin.
578 // S'il y en a déjà, il faut allouer à la fin de
579 // m_p->m_connectivity_list assez \a size+1 éléments et
580 // on recopie la précédente connectivité dans le nouvel emplacement.
581 // Forcément, avec le temps la liste va toujours grossir
582 // car les trous ne sont pas réutilisés.
583 if (m_pre_allocated_size!=0){
584 // En cas de préallocation, on alloue par bloc de taille 'm_pre_allocated_size'.
585 // Il faut donc réallouer si la taille est un multiple de m_pre_allocated_size
586 if (size==0){
587 Integer new_pos_in_list = _increaseConnectivityList(NULL_ITEM_LOCAL_ID,m_pre_allocated_size);
588 m_connectivity_index[lid] = new_pos_in_list;
589 m_connectivity_list[new_pos_in_list] = target_lid;
590 }
591 else{
592 if (size<m_pre_allocated_size || (size%m_pre_allocated_size)!=0){
593 Integer index = m_connectivity_index[lid];
594 m_connectivity_list[index+size] = target_lid;
595 }
596 else{
597 _increaseIndexList(lid,size,target_lid);
598 }
599 }
600 }
601 else{
602 if (size==0){
603 Integer new_pos_in_list = _increaseConnectivityList(target_lid);
604 m_connectivity_index[lid] = new_pos_in_list;
605 }
606 else{
607 _increaseIndexList(lid,size,target_lid);
608 }
609 }
610 ++(m_connectivity_nb_item[lid]);
611 _setNewMaxNbConnectedItems(m_connectivity_nb_item[lid]);
612}
613
614/*---------------------------------------------------------------------------*/
615/*---------------------------------------------------------------------------*/
616
617Integer IncrementalItemConnectivity::
618_computeAllocSize(Integer nb_item)
619{
620 if (m_pre_allocated_size!=0){
621 // Alloue un multiple de \a m_pre_allocated_size
622 Integer alloc_size = nb_item / m_pre_allocated_size;
623 if (alloc_size==0)
624 return m_pre_allocated_size;
625 if ((nb_item%m_pre_allocated_size)==0)
626 return nb_item;
627 return m_pre_allocated_size * (alloc_size + 1);
628 }
629 return nb_item;
630}
631
632/*---------------------------------------------------------------------------*/
633/*---------------------------------------------------------------------------*/
634
635void IncrementalItemConnectivity::
636addConnectedItems(ItemLocalId source_item,Integer nb_item)
637{
638 const Int32 lid = source_item.localId();
639 Integer size = m_connectivity_nb_item[lid];
640 if (size!=0)
641 ARCANE_FATAL("source_item already have connected items");
642 Integer alloc_size = _computeAllocSize(nb_item);
643 Integer new_pos_in_list = _increaseConnectivityList(NULL_ITEM_LOCAL_ID,alloc_size);
644 m_connectivity_index[lid] = new_pos_in_list;
645 m_connectivity_nb_item[lid] += nb_item;
646 _setNewMaxNbConnectedItems(m_connectivity_nb_item[lid]);
647}
648
649/*---------------------------------------------------------------------------*/
650/*---------------------------------------------------------------------------*/
651
659
660/*---------------------------------------------------------------------------*/
661/*---------------------------------------------------------------------------*/
662
665{
666 Int32 lid = source_item.localId();
667 m_connectivity_nb_item[lid] = 0;
668}
669
670/*---------------------------------------------------------------------------*/
671/*---------------------------------------------------------------------------*/
672
675{
676 ++m_nb_remove;
677 Int32 lid = source_item.localId();
678 Int32 target_lid = target_item.localId();
679 Integer size = m_connectivity_nb_item[lid];
680 Int32* items = &(m_connectivity_list[ m_connectivity_index[lid] ]);
681 mesh_utils::removeItemAndKeepOrder(Int32ArrayView(size,items),target_lid);
682 --(m_connectivity_nb_item[lid]);
683}
684
685/*---------------------------------------------------------------------------*/
686/*---------------------------------------------------------------------------*/
687
690{
691 Int32 lid = source_item.localId();
692 Int32 target_lid = target_item.localId();
693 ARCANE_CHECK_AT(index,m_connectivity_nb_item[lid]);
694 m_connectivity_list[ m_connectivity_index[lid] + index ] = target_lid;
695}
696
697/*---------------------------------------------------------------------------*/
698/*---------------------------------------------------------------------------*/
699
702{
703 Int32 lid = source_item.localId();
704 Int32 n = target_local_ids.size();
705 if (n > 0) {
706 ARCANE_CHECK_AT(n - 1, m_connectivity_nb_item[lid]);
707 const Int32 pos = m_connectivity_index[lid];
708 for (Integer i = 0; i < n; ++i)
709 m_connectivity_list[pos + i] = target_local_ids[i];
710 }
711}
712
713/*---------------------------------------------------------------------------*/
714/*---------------------------------------------------------------------------*/
715
718{
719 bool has_connection = false;
720 auto connected_items = _connectedItemsLocalId(source_item);
721 if (std::find(connected_items.begin(), connected_items.end(), target_local_id) != connected_items.end())
722 has_connection = true;
723 return has_connection;
724}
725
726
727/*---------------------------------------------------------------------------*/
728/*---------------------------------------------------------------------------*/
729
732{
733 Int32 lid = item.localId();
734 m_p->_checkResize(lid);
735 _notifyConnectivityIndexChanged();
736 _notifyConnectivityNbItemChanged();
737
738 m_connectivity_nb_item[lid] = 0;
739 m_connectivity_index[lid] = 0;
740}
741
742/*---------------------------------------------------------------------------*/
743/*---------------------------------------------------------------------------*/
744
747{
748 // Pré-calcule le maximum des local_ids pour le redimensionnement.
749 Int32 nb_item = local_ids.size();
750 if (nb_item <= 0)
751 return;
752 Int32 max_lid = local_ids[0];
753 for (Int32 lid : local_ids)
755
756 m_p->_checkResize(max_lid);
757 _notifyConnectivityIndexChanged();
758 _notifyConnectivityNbItemChanged();
759
760 for (Int32 lid : local_ids) {
761 m_connectivity_nb_item[lid] = 0;
762 m_connectivity_index[lid] = 0;
763 }
764}
765
766/*---------------------------------------------------------------------------*/
767/*---------------------------------------------------------------------------*/
768
771{
772 m_pre_allocated_size = _sourceFamily()->properties()->getIntegerWithDefault(name()+"PreallocSize",0);
773 info(4) << "PreallocSize2 var=" << m_p->m_var_name << " v=" << m_pre_allocated_size;
774
775 // Il n'y a priori rien à faire pour les variables car via les observables sur les
776 // variables les vues sont correctement mises à jour.
777}
778
779/*---------------------------------------------------------------------------*/
780/*---------------------------------------------------------------------------*/
781
784{
785 if (m_pre_allocated_size<0)
786 throw ArgumentException(A_FUNCINFO,
787 String::format("Invalid prealloc_size v={0}",
789
790 // Ne fait rien si on a déjà alloué des entités sinon cela rendrait
791 // incohérent les allocations.
792 // NOTE: on pourrait l'autoriser, mais cela nécessiterait de reconstruire
793 // les indices des connectivités. A priori un appel à compactConnectivityList()
794 // suffirait.
795 if (m_connectivity_nb_item.size()!=0)
796 return;
797
798 m_pre_allocated_size = prealloc_size;
799 _sourceFamily()->properties()->setInteger(name()+"PreallocSize",prealloc_size);
800
801 // Même s'il n'y a pas d'entités, m_p->m_connectivity_list_array n'est pas
802 // vide car on appelé _checkkAddNulItem() dans le constructeur. Il faut
803 // maintenant le réallouer avec la nouvelle valeur de pré-allocation.
804 _resetConnectivityList();
805}
806
807/*---------------------------------------------------------------------------*/
808/*---------------------------------------------------------------------------*/
809
811dumpStats(std::ostream& out) const
812{
813 Int64 mem1 = m_p->m_connectivity_list_array.capacity();
814 Int64 mem2 = m_p->m_connectivity_index_array.capacity();
815 Int64 mem3 = m_p->m_connectivity_nb_item_array.capacity();
816 Int64 allocated_size = mem1 + mem2 + mem3;
817 allocated_size *= sizeof(Int32);
818
819 out << " connectiviy name=" << name()
820 << " prealloc_size=" << m_pre_allocated_size
821 << " nb_add=" << m_nb_add
822 << " nb_remove=" << m_nb_remove
823 << " nb_memcopy=" << m_nb_memcopy
824 << " list_size=" << m_connectivity_list.size()
825 << " list_capacity=" << mem1
826 << " index_size=" << m_connectivity_index.size()
827 << " index_capacity=" << mem2
828 << " nb_item_size=" << m_connectivity_nb_item.size()
829 << " nb_item_capacity=" << mem3
830 << " allocated_size=" << allocated_size;
831}
832
833/*---------------------------------------------------------------------------*/
834/*---------------------------------------------------------------------------*/
835
836void IncrementalItemConnectivityBase::
837_shrinkMemory()
838{
839 m_p->m_connectivity_list_array.shrink();
840 m_p->m_connectivity_index_array.shrink();
841 m_p->m_connectivity_nb_item_array.shrink();
842 _notifyConnectivityIndexChanged();
843 _notifyConnectivityNbItemChanged();
844 _notifyConnectivityListChanged();
845}
846
847/*---------------------------------------------------------------------------*/
848/*---------------------------------------------------------------------------*/
849
850void IncrementalItemConnectivityBase::
851_addMemoryInfos(ItemConnectivityMemoryInfo& mem_info)
852{
853 Int64 s1 = m_p->m_connectivity_list_array.size();
854 Int64 s2 = m_p->m_connectivity_index_array.size();
855 Int64 s3 = m_p->m_connectivity_nb_item_array.size();
856 mem_info.m_total_size += s1 + s2 + s3;
857
858 Int64 c1 = m_p->m_connectivity_list_array.capacity();
859 Int64 c2 = m_p->m_connectivity_index_array.capacity();
860 Int64 c3 = m_p->m_connectivity_nb_item_array.capacity();
861 mem_info.m_total_capacity += c1 + c2 + c3;
862}
863
864/*---------------------------------------------------------------------------*/
865/*---------------------------------------------------------------------------*/
866
867void IncrementalItemConnectivity::
868_checkAddNullItem()
869{
870 // Si la liste des connectivités est vide, créé un élément
871 // (ou plusieurs si m_pre_allocated_size>0) pour contenir l'entité nulle.
872 // Cela permet de récupérer pour une entité la liste des connectivités même si
873 // elle est vide.
874 if (m_connectivity_list.size()==0){
875 if (m_pre_allocated_size>0){
876 _increaseConnectivityList(NULL_ITEM_LOCAL_ID,m_pre_allocated_size);
877 }
878 else{
879 _increaseConnectivityList(NULL_ITEM_LOCAL_ID);
880 }
881 }
882}
883
884/*---------------------------------------------------------------------------*/
885/*---------------------------------------------------------------------------*/
899{
900 info(4) << "Begin Compacting IncrementalItemConnectivity name=" << name()
901 << " new_size=" << m_connectivity_list.size()
902 << " prealloc_size=" << m_pre_allocated_size;
903 // TODO: essayer de trouver un moyen de ne faire le compactage que si
904 // cela est nécessaire. Une facon serait de compter le nombre d'appel à
905 // _increaseIndexList() depuis le dernier compactage.
906 UniqueArray<Int32> old_connectivity_list(m_connectivity_list);
907 Integer old_size = old_connectivity_list.size();
908 Integer nb_item = m_connectivity_nb_item.size();
909 m_p->m_connectivity_list_array.clear();
910 _notifyConnectivityListChanged();
911 _checkAddNullItem();
912 Integer new_pos_in_list = m_p->m_connectivity_list_array.size();
913 Int32 pre_allocated_size = m_pre_allocated_size;
914 for( Integer i=0; i<nb_item; ++i ){
915 Int32 lid = i;
916 Int32 nb = m_connectivity_nb_item[lid];
917 if (nb==0){
918 m_connectivity_index[lid] = 0;
919 continue;
920 }
921 Int32 index = m_connectivity_index[lid];
923 Integer alloc_size = _computeAllocSize(nb);
924 m_connectivity_index[lid] = new_pos_in_list;
926 //info() << "NEW_POS_IN_LIST=" << new_pos_in_list << " nb=" << nb << " alloc_size=" << alloc_size;
927 // Vérifie que la position est bien un multiple de pre_allocated_size.
928 if (pre_allocated_size!=0){
930 if (pos_modulo!=0)
931 ARCANE_FATAL("Bad position i={0} pos={1} pre_alloc_size={2} modulo={3}",
933 }
934 m_p->m_connectivity_list_array.addRange(con_list);
935 // Si préallocation, complète le reste des éléments avec l'entité nulle..
936 if (alloc_size!=nb)
937 m_p->m_connectivity_list_array.addRange(NULL_ITEM_LOCAL_ID,alloc_size-nb);
938 if (m_pre_allocated_size==0 && nb==0)
939 m_connectivity_index[lid] = 0;
940 }
941 _notifyConnectivityListChanged();
942 _computeMaxNbConnectedItem();
943 info(4) << "Compacting IncrementalItemConnectivity name=" << name()
944 << " nb_item=" << nb_item << " old_size=" << old_size
945 << " new_size=" << m_connectivity_list.size()
946 << " prealloc_size=" << m_pre_allocated_size;
947}
948
949/*---------------------------------------------------------------------------*/
950/*---------------------------------------------------------------------------*/
951
952/*---------------------------------------------------------------------------*/
953/*---------------------------------------------------------------------------*/
954
955/*---------------------------------------------------------------------------*/
956/*---------------------------------------------------------------------------*/
957
958OneItemIncrementalItemConnectivity::
959OneItemIncrementalItemConnectivity(IItemFamily* source_family,IItemFamily* target_family,
960 const String& aname)
962{
963 info(4) << "Using fixed OneItem connectivity for name=" << name();
964}
965
966/*---------------------------------------------------------------------------*/
967/*---------------------------------------------------------------------------*/
968
969OneItemIncrementalItemConnectivity::
970~OneItemIncrementalItemConnectivity()
971{
972}
973
974/*---------------------------------------------------------------------------*/
975/*---------------------------------------------------------------------------*/
976
979{
980 Int32 lid = source_item.localId();
981 Integer size = m_connectivity_nb_item[lid];
982 if (size!=0)
983 ARCANE_FATAL("source_item already have connected items");
984 Int32 target_lid = target_item.localId();
985 m_connectivity_list[lid] = target_lid;
986 m_connectivity_nb_item[lid] = 1;
987 _setNewMaxNbConnectedItems(1);
988}
989
990/*---------------------------------------------------------------------------*/
991/*---------------------------------------------------------------------------*/
992
995{
996 Int32 lid = source_item.localId();
997 m_connectivity_nb_item[lid] = 0;
998}
999
1000/*---------------------------------------------------------------------------*/
1001/*---------------------------------------------------------------------------*/
1002
1005{
1006 Int32 lid = source_item.localId();
1007 Int32 target_local_id = target_item.localId();
1008 Integer size = m_connectivity_nb_item[lid];
1009 if (size!=1)
1010 ARCANE_FATAL("source_item has no connected item");
1011 Int32 target_lid = m_connectivity_list[lid];
1013 ARCANE_FATAL("source_item is not connected to item with wanted_lid={0} current_lid={1}",
1015 m_connectivity_nb_item[lid] = 0;
1016 m_connectivity_list[lid] = NULL_ITEM_LOCAL_ID;
1017}
1018
1019/*---------------------------------------------------------------------------*/
1020/*---------------------------------------------------------------------------*/
1021
1024{
1025 if (index!=0)
1026 ARCANE_FATAL("index has to be '0'");
1027 Int32 lid = source_item.localId();
1028 Int32 target_lid = target_item.localId();
1029 m_connectivity_list[lid] = target_lid;
1030}
1031
1032/*---------------------------------------------------------------------------*/
1033/*---------------------------------------------------------------------------*/
1034
1037{
1038 Int32 lid = source_item.localId();
1039 Integer n = target_local_ids.size();
1040 if (n==0)
1041 return;
1042 if (n!=1)
1043 ARCANE_FATAL("Invalid size for target_list. value={0} (expected 1)",n);
1044 m_connectivity_list[lid] = target_local_ids[0];
1045}
1046
1047/*---------------------------------------------------------------------------*/
1048/*---------------------------------------------------------------------------*/
1049
1053{
1054 if (m_connectivity_list[source_item.localId()] == target_local_id.localId())
1055 return true;
1056 else
1057 return false;
1058}
1059
1060/*---------------------------------------------------------------------------*/
1061/*---------------------------------------------------------------------------*/
1062
1063void OneItemIncrementalItemConnectivity::
1064_checkResizeConnectivityList()
1065{
1066 // Redimensionne la liste des connectivités avec le même nombre d'éléments
1067 // que le nombre d'entités.
1068 Integer wanted_size = m_connectivity_nb_item.size();
1069 Integer list_size = m_connectivity_list.size();
1071 return;
1072 Integer capacity = m_p->m_connectivity_list_array.capacity();
1073 if (wanted_size>=capacity){
1074 m_p->m_connectivity_list_array.reserve(m_p->m_connectivity_nb_item_array.capacity());
1075 }
1076 m_p->m_connectivity_list_array.resize(wanted_size);
1077 _notifyConnectivityListChanged();
1078}
1079
1080/*---------------------------------------------------------------------------*/
1081/*---------------------------------------------------------------------------*/
1082
1085{
1086 Int32 lid = item.localId();
1087 m_p->_checkResize(lid);
1088 _notifyConnectivityIndexChanged();
1089 _notifyConnectivityNbItemChanged();
1090 _checkResizeConnectivityList();
1091
1092 m_connectivity_nb_item[lid] = 0;
1093 m_connectivity_index[lid] = lid;
1094 m_connectivity_list[lid] = NULL_ITEM_LOCAL_ID;
1095}
1096
1097/*---------------------------------------------------------------------------*/
1098/*---------------------------------------------------------------------------*/
1099
1102{
1103 // Pour cette implémentation, il ne faut pas mettre à jour
1104 // les index car sinon on n'aura plus m_connectivity_index[lid] = lid.
1105 // TODO: comme à priori m_connectivity_nb_item vaut 1 partout, cela
1106 // n'est pas utile non plus de le faire sur cette variable mais
1107 // comme il peut y avoir des entités pour lesquelles nb_item vaut 0 si
1108 // on n'a pas ajouté d'entité connecté, il vaut mieux faire le compactage.
1109
1110 m_p->m_connectivity_nb_item_variable.variable()->compact(new_to_old_ids);
1111 _notifyConnectivityNbItemChanged();
1112
1113 // Comme avec cette implémentation la liste des connectivités est indexée
1114 // par le localId() de l'entité source, il faut la compacter
1115 // m_p->m_connectivity_list_variable.
1116 m_p->m_connectivity_list_variable.variable()->compact(new_to_old_ids);
1117 _notifyConnectivityListChanged();
1118
1119 // Ne compacte pas les index mais mets tout de même à jour la taille
1120 // du tableau.
1121 m_p->m_connectivity_index_array.resize(m_connectivity_nb_item.size());
1122 _notifyConnectivityIndexChanged();
1123}
1124
1125/*---------------------------------------------------------------------------*/
1126/*---------------------------------------------------------------------------*/
1127
1132
1133/*---------------------------------------------------------------------------*/
1134/*---------------------------------------------------------------------------*/
1135
1137dumpStats(std::ostream& out) const
1138{
1139 size_t allocated_size = m_p->m_connectivity_list_array.capacity()
1140 + m_p->m_connectivity_index_array.capacity()
1141 + m_p->m_connectivity_nb_item_array.capacity();
1142 allocated_size *= sizeof(Int32);
1143
1144 out << " connectiviy name=" << name()
1145 << " list_size=" << m_connectivity_list.size()
1146 << " index_size=" << m_connectivity_index.size()
1147 << " nb_item_size=" << m_connectivity_nb_item.size()
1148 << " allocated_size=" << allocated_size;
1149}
1150
1151/*---------------------------------------------------------------------------*/
1152/*---------------------------------------------------------------------------*/
1153
1154void OneItemIncrementalItemConnectivity::
1155compactConnectivityList()
1156{
1157 _computeMaxNbConnectedItem();
1158}
1159
1160/*---------------------------------------------------------------------------*/
1161/*---------------------------------------------------------------------------*/
1162
1163} // End namespace Arcane::mesh
1164
1165/*---------------------------------------------------------------------------*/
1166/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions utilitaires sur le maillage.
Tableau d'items de types quelconques.
Gère la récupération des informations de connectivité.
API interne à Arcane de IIncrementalItemConnectivity.
virtual Integer preAllocatedSize() const =0
Nombre d'entités pré-alloués pour la connectivité de chaque entité
Interface d'une famille d'entités.
virtual eItemKind itemKind() const =0
Genre des entités.
virtual Properties * properties()=0
Propriétés associées à cette famille.
virtual void compact(Int32ConstArrayView new_to_old_ids)=0
Compacte les valeurs de la variable.
Vues sur les conteneurs contenant les connectivités. Cette classe permet de rendre opaque en dehors d...
Informations sur l'utilisation mémoire pour les connectivités.
Informations de connectivité, pour une famille d'entité, permettant la transition entre les anciennes...
void _setConnectivityNbItem(Int32 item_kind, ConstArrayView< Int32 > v)
Positionne le tableau contenant le nombre d'entités connectées.
void _setConnectivityList(Int32 item_kind, ConstArrayView< Int32 > v)
Positionne le tableau contenant la liste des connectivités.
void _setConnectivityIndex(Int32 item_kind, ConstArrayView< Int32 > v)
Positionne le tableau d'index des connectivités.
void _setMaxNbConnectedItem(Int32 item_kind, Int32 v)
Positionne le nombre maximum d'entités connectées.
Index d'un Item dans une variable.
Definition ItemLocalId.h:40
Vue sur un vecteur d'entités.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Liste d'observateurs.
Paramètres nécessaires à la construction d'une variable.
IVariable * variable() const
Variable associée.
Classe abstraite de gestion des connectivités.
String name() const final
Nom de la connectivité
void addMemoryInfos(ItemConnectivityMemoryInfo &mem_info) override
Ajoute mem_info les informations mémoire de l'instance.
void shrinkMemory() override
Réduit au minimum l'utilisation mémoire pour les connectivités.
Classe de base pour les connectivités incrémentales item->item[].
void notifySourceFamilyLocalIdChanged(Int32ConstArrayView new_to_old_ids) override
Notifie la connectivité que la famille source est compactée.
Int32 maxNbConnectedItem() const override
Nombre maximum d'entités connectées à une entité source.
void setItemConnectivityList(ItemInternalConnectivityList *ilist, Int32 index)
Indique que cette connectivité est associée à une des connectivités de ItemInternal.
void reserveMemoryForNbSourceItems(Int32 n, bool pre_alloc_connectivity) override
Réserve la mémoire pour n entités sources.
ItemVectorView _connectedItems(ItemLocalId item, ConnectivityItemVector &con_items) const final
Remplit con_items avec les entités connectées à item.
IIncrementalItemConnectivityInternal * _internalApi() override
API interne à Arcane.
void notifyTargetFamilyLocalIdChanged(Int32ConstArrayView old_to_new_ids) override
Notifie la connectivité que la famille cible est compactée.
Int32 m_max_nb_item
Nombre maximum d'entités connectées.
bool hasConnectedItem(ItemLocalId source_item, ItemLocalId target_local_id) const override
Test l'existence d'un connectivité entre source_item et l'entité de localId() target_local_id.
void setConnectedItems(ItemLocalId source_item, Int32ConstArrayView target_local_ids) override
Alloue et positionne les entités connectées à source_item.
void compactConnectivityList()
Compacte la liste des connectivités.
void removeConnectedItem(ItemLocalId source_item, ItemLocalId target_local_id) override
Supprime l'entité de localId() target_local_id à la connectivité de source_item.
void notifySourceItemAdded(ItemLocalId item) override
Notifie la connectivité qu'une entité a été ajoutée à la famille source.
void addConnectedItem(ItemLocalId source_item, ItemLocalId target_local_id) override
Ajoute l'entité de localId() target_local_id à la connectivité de source_item.
void removeConnectedItems(ItemLocalId source_item) override
Supprime toute les entités connectées à source_item.
void notifyReadFromDump() override
Notifie la connectivité qu'on a effectué une relecture à partir d'une protection.
void dumpStats(std::ostream &out) const override
Sort sur le flot out des statistiques sur l'utilisation et la mémoire utilisée.
void replaceConnectedItems(ItemLocalId source_item, Int32ConstArrayView target_local_ids) override
Remplace les entités de source_item par les entités de localId() target_local_ids.
void _internalNotifySourceItemsAdded(ConstArrayView< Int32 > local_ids) override
Notifie la connectivité que les entités items ont été ajoutées à la famille source.
void replaceConnectedItem(ItemLocalId source_item, Integer index, ItemLocalId target_local_id) override
Remplace l'entité d'index index de source_item par l'entité de localId() target_local_id.
void setPreAllocatedSize(Integer value) final
Positionne le nombre d'entités à pré-allouer pour la connectivité de chaque entité
void removeConnectedItem(ItemLocalId source_item, ItemLocalId target_local_id) override
Supprime l'entité de localId() target_local_id à la connectivité de source_item.
void replaceConnectedItems(ItemLocalId source_item, Int32ConstArrayView target_local_ids) override
Remplace les entités de source_item par les entités de localId() target_local_ids.
void addConnectedItem(ItemLocalId source_item, ItemLocalId target_local_id) override
Ajoute l'entité de localId() target_local_id à la connectivité de source_item.
void notifyReadFromDump() override
Notifie la connectivité qu'on a effectué une relecture à partir d'une protection.
bool hasConnectedItem(ItemLocalId source_item, ItemLocalId target_local_id) const override
Test l'existence d'un connectivité entre source_item et l'entité de localId() target_local_id.
void notifySourceFamilyLocalIdChanged(Int32ConstArrayView new_to_old_ids) override
Notifie la connectivité que la famille source est compactée.
void replaceConnectedItem(ItemLocalId source_item, Integer index, ItemLocalId target_local_id) override
Remplace l'entité d'index index de source_item par l'entité de localId() target_local_id.
void notifySourceItemAdded(ItemLocalId item) override
Notifie la connectivité qu'une entité a été ajoutée à la famille source.
void removeConnectedItems(ItemLocalId source_item) override
Supprime toute les entités connectées à source_item.
void dumpStats(std::ostream &out) const override
Sort sur le flot out des statistiques sur l'utilisation et la mémoire utilisée.
Exception lorsqu'un argument est invalide.
Vue modifiable d'un tableau d'un type T.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
Vue constante d'un tableau de type T.
Constructeur de chaîne de caractère unicode.
Chaîne de caractères unicode.
TraceMessage info() const
Flot pour un message d'information.
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
Definition MathUtils.h:392
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:611
Int32 Integer
Type représentant un entier.