Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ItemGroupImpl.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/* ItemGroupImpl.cc (C) 2000-2024 */
9/* */
10/* Implémentation d'un groupe d'entités de maillage. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/core/ItemGroupImpl.h"
15
16#include "arcane/utils/String.h"
17#include "arcane/utils/ITraceMng.h"
18#include "arcane/utils/ArgumentException.h"
19
20#include "arcane/core/ItemGroupObserver.h"
21#include "arcane/core/IItemFamily.h"
22#include "arcane/core/ItemGroup.h"
23#include "arcane/core/IMesh.h"
24#include "arcane/core/MeshPartInfo.h"
25#include "arcane/core/MeshKind.h"
26#include "arcane/core/ItemPrinter.h"
27#include "arcane/core/IItemOperationByBasicType.h"
28#include "arcane/core/ItemGroupComputeFunctor.h"
29#include "arcane/core/IVariableSynchronizer.h"
30#include "arcane/core/ParallelMngUtils.h"
31#include "arcane/core/internal/ItemGroupInternal.h"
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
47: public ItemGroupImpl
48{
49 public:
50
52 virtual ~ItemGroupImplNull() {}
53
54 public:
55
57 const String& name() const { return m_name; }
58 const String& fullName() const { return m_name; }
59
60 public:
61
62 public:
63
64 virtual void convert(NodeGroup& g) { g = NodeGroup(); }
65 virtual void convert(EdgeGroup& g) { g = EdgeGroup(); }
66 virtual void convert(FaceGroup& g) { g = FaceGroup(); }
67 virtual void convert(CellGroup& g) { g = CellGroup(); }
68
69 public:
70
71 private:
72
73 String m_name;
74};
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
79ItemGroupImpl* ItemGroupImpl::shared_null= 0;
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
86{
87 private:
88
89 typedef void (ItemGroupImpl::*FuncPtr)();
90
91 public:
92
95 , m_parent(parent)
96 , m_function(funcPtr) { }
97
98 public:
99
100 void executeFunctor() override
101 {
102 (m_parent->*m_function)();
103 }
104
105 private:
106
107 ItemGroupImpl * m_parent;
108 FuncPtr m_function;
109};
110
111/*---------------------------------------------------------------------------*/
112/*---------------------------------------------------------------------------*/
113
114ItemGroupImpl* ItemGroupImpl::
115checkSharedNull()
116{
117 // Normalement ce test n'est vrai que si on a une instance globale
118 // de 'ItemGroup' ce qui est déconseillé. Sinon, _buildSharedNull() a été
119 // automatiquement appelé lors de l'initialisation (dans arcaneInitialize()).
120 if (!shared_null)
122 return shared_null;
123}
124
125/*---------------------------------------------------------------------------*/
126/*---------------------------------------------------------------------------*/
127
129ItemGroupImpl(IItemFamily* family,const String& name)
130: m_p (new ItemGroupInternal(family,name))
131{
132}
133
134/*---------------------------------------------------------------------------*/
135/*---------------------------------------------------------------------------*/
136
138ItemGroupImpl(IItemFamily* family,ItemGroupImpl* parent,const String& name)
139: m_p(new ItemGroupInternal(family,parent,name))
140{
141}
142
143/*---------------------------------------------------------------------------*/
144/*---------------------------------------------------------------------------*/
145
151
152/*---------------------------------------------------------------------------*/
153/*---------------------------------------------------------------------------*/
154
157{
158 delete m_p;
159}
160
161/*---------------------------------------------------------------------------*/
162/*---------------------------------------------------------------------------*/
163
165name() const
166{
167 return m_p->name();
168}
169
170/*---------------------------------------------------------------------------*/
171/*---------------------------------------------------------------------------*/
172
174fullName() const
175{
176 return m_p->fullName();
177}
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
181
183size() const
184{
185 return m_p->itemsLocalId().size();
186}
187
188/*---------------------------------------------------------------------------*/
189/*---------------------------------------------------------------------------*/
190
192empty() const
193{
194 return m_p->itemsLocalId().empty();
195}
196
197/*---------------------------------------------------------------------------*/
198/*---------------------------------------------------------------------------*/
199
201itemsLocalId() const
202{
203 return m_p->itemsLocalId();
204}
205
206/*---------------------------------------------------------------------------*/
207/*---------------------------------------------------------------------------*/
208
211{
213 ARCANE_FATAL("Transaction mode already started");
214 m_p->m_transaction_mode = true;
215}
216
217/*---------------------------------------------------------------------------*/
218/*---------------------------------------------------------------------------*/
219
222{
224 ARCANE_FATAL("Transaction mode not started");
225 m_p->m_transaction_mode = false;
226 if (m_p->m_need_recompute) {
227 m_p->m_need_recompute = false;
229 m_p->notifyInvalidateObservers();
230 }
231}
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
238{
239 ITraceMng* trace = m_p->m_mesh->traceMng();
240 trace->debug(Trace::Medium) << "ItemGroupImpl::unguardedItemsLocalId on group " << name()
241 << " with self_invalidate=" << self_invalidate;
242
244 ARCANE_FATAL("Direct access for computed group in only available during a transaction");
245
247 return m_p->mutableItemsLocalId();
248}
249
250/*---------------------------------------------------------------------------*/
251/*---------------------------------------------------------------------------*/
252
254parent() const
255{
256 return m_p->m_parent;
257}
258
259/*---------------------------------------------------------------------------*/
260/*---------------------------------------------------------------------------*/
261
263mesh() const
264{
265 return m_p->mesh();
266}
267
268/*---------------------------------------------------------------------------*/
269/*---------------------------------------------------------------------------*/
270
272itemFamily() const
273{
274 return m_p->m_item_family;
275}
276
277/*---------------------------------------------------------------------------*/
278/*---------------------------------------------------------------------------*/
279
281null() const
282{
283 return m_p->null();
284}
285
286/*---------------------------------------------------------------------------*/
287/*---------------------------------------------------------------------------*/
288
290isOwn() const
291{
292 return m_p->m_is_own;
293}
294
295/*---------------------------------------------------------------------------*/
296/*---------------------------------------------------------------------------*/
297
299setOwn(bool v)
300{
301 const bool is_own = m_p->m_is_own;
302 if (is_own == v)
303 return;
304 if (!is_own) {
305 if (m_p->m_own_group)
306 ARCANE_THROW(NotSupportedException,"Setting Own with 'Own' sub-group already defined");
307 }
308 else {
309 // On a le droit de remettre setOwn() à 'false' pour le groupe de toutes
310 // les entités. Cela est nécessaire en reprise si le nombre de parties
311 // du maillage est différent du IParallelMng associé à la famille
312 if (!isAllItems())
313 ARCANE_THROW(NotSupportedException,"Un-setting Own on a own group");
314 }
315 m_p->m_is_own = v;
316 // (HP) TODO: Faut il notifier des observers ?
317}
318
319/*---------------------------------------------------------------------------*/
320/*---------------------------------------------------------------------------*/
321
323itemKind() const
324{
325 return m_p->kind();
326}
327
328/*---------------------------------------------------------------------------*/
329/*---------------------------------------------------------------------------*/
330
332ownGroup()
333{
335 // Le flag est déjà positionné dans le ItemGroupInternal::_init ou ItemGroupImpl::setOwn
336 if (!ii) {
337 if (m_p->m_is_own){
338 ii = this;
339 m_p->m_own_group = ii;
340 } else {
342 m_p->m_own_group = ii;
343 ii->setOwn(true);
344 }
345 }
346 return ii;
347}
348
349/*---------------------------------------------------------------------------*/
350/*---------------------------------------------------------------------------*/
351
362
363/*---------------------------------------------------------------------------*/
364/*---------------------------------------------------------------------------*/
365
366ItemGroupImpl* ItemGroupImpl::
367interfaceGroup()
368{
369 if (itemKind()!=IK_Face)
370 return checkSharedNull();
372 if (!ii) {
375 }
376 return ii;
377}
378
379/*---------------------------------------------------------------------------*/
380/*---------------------------------------------------------------------------*/
381
383nodeGroup()
384{
385 if (itemKind()==IK_Node)
386 return this;
388 if (!ii){
391 }
392 return ii;
393}
394
395/*---------------------------------------------------------------------------*/
396/*---------------------------------------------------------------------------*/
397
399edgeGroup()
400{
401 if (itemKind()==IK_Edge)
402 return this;
404 if (!ii){
407 }
408 return ii;
409}
410
411/*---------------------------------------------------------------------------*/
412/*---------------------------------------------------------------------------*/
413
415faceGroup()
416{
417 if (itemKind()==IK_Face)
418 return this;
420 if (!ii){
423 }
424 return ii;
425}
426
427/*---------------------------------------------------------------------------*/
428/*---------------------------------------------------------------------------*/
429
431cellGroup()
432{
433 if (itemKind()==IK_Cell)
434 return this;
436 if (!ii){
439 }
440 return ii;
441}
442
443/*---------------------------------------------------------------------------*/
444/*---------------------------------------------------------------------------*/
445
448{
449 if (itemKind()!=IK_Cell)
450 return checkSharedNull();
452 if (!ii){
453 ii = createSubGroup("InnerFaces",m_p->m_mesh->faceFamily(),
456 }
457 return ii;
458}
459
460/*---------------------------------------------------------------------------*/
461/*---------------------------------------------------------------------------*/
462
465{
466 if (itemKind()!=IK_Cell)
467 return checkSharedNull();
469 if (!ii){
470 ii = createSubGroup("OuterFaces",m_p->m_mesh->faceFamily(),
473 }
474 return ii;
475}
476/*---------------------------------------------------------------------------*/
477/*---------------------------------------------------------------------------*/
479
480/*---------------------------------------------------------------------------*/
481/*---------------------------------------------------------------------------*/
482
485{
486 if (itemKind()!=IK_Cell)
487 return checkSharedNull();
489
490 if (!ii){
491 ii = createSubGroup("ActiveCells",m_p->m_mesh->cellFamily(),
494 }
495 return ii;
496}
497
498/*---------------------------------------------------------------------------*/
499/*---------------------------------------------------------------------------*/
500
503{
504 if (itemKind()!=IK_Cell)
505 return checkSharedNull();
507 // Le flag est déjà positionné dans le ItemGroupInternal::_init ou ItemGroupImpl::setOwn
508 if (!ii) {
509 ii = createSubGroup("OwnActiveCells",m_p->m_mesh->cellFamily(),
512 ii->setOwn(true);
513 }
514 return ii;
515}
516/*---------------------------------------------------------------------------*/
517/*---------------------------------------------------------------------------*/
518
520levelCellGroup(const Integer& level)
521{
522 if (itemKind()!=IK_Cell)
523 return checkSharedNull();
525 if (!ii){
526 ii = createSubGroup(String::format("LevelCells{0}",level),
529 m_p->m_level_cell_group[level] = ii;
530 }
531 return ii;
532}
533
534/*---------------------------------------------------------------------------*/
535/*---------------------------------------------------------------------------*/
536
538ownLevelCellGroup(const Integer& level)
539{
540 if (itemKind()!=IK_Cell)
541 return checkSharedNull();
543 // Le flag est déjà positionné dans le ItemGroupInternal::_init ou ItemGroupImpl::setOwn
544 if (!ii) {
545 ii = createSubGroup(String::format("OwnLevelCells{0}",level),
548 m_p->m_own_level_cell_group[level] = ii;
549 ii->setOwn(true);
550 }
551 return ii;
552}
553/*---------------------------------------------------------------------------*/
554/*---------------------------------------------------------------------------*/
555
558{
559 if (itemKind()!=IK_Cell)
560 return checkSharedNull();
562 if (!ii){
563 ii = createSubGroup("ActiveFaces",m_p->m_mesh->faceFamily(),
566 }
567 return ii;
568}
569
570/*---------------------------------------------------------------------------*/
571/*---------------------------------------------------------------------------*/
572
575{
576 if (itemKind()!=IK_Cell)
577 return checkSharedNull();
579 if (!ii){
580 ii = createSubGroup("OwnActiveFaces",m_p->m_mesh->faceFamily(),
583 }
584 return ii;
585}
586/*---------------------------------------------------------------------------*/
587/*---------------------------------------------------------------------------*/
588
591{
592 if (itemKind()!=IK_Cell)
593 return checkSharedNull();
595 if (!ii){
596 ii = createSubGroup("InnerActiveFaces",m_p->m_mesh->faceFamily(),
599 }
600 return ii;
601}
602
603/*---------------------------------------------------------------------------*/
604/*---------------------------------------------------------------------------*/
605
608{
609 if (itemKind()!=IK_Cell)
610 return checkSharedNull();
612 if (!ii){
613 ii = createSubGroup("OuterActiveFaces",m_p->m_mesh->faceFamily(),
616 }
617 return ii;
618}
619/*---------------------------------------------------------------------------*/
620/*---------------------------------------------------------------------------*/
621
624{
625 String sub_name = name() + "_" + suffix;
626 auto finder = m_p->m_sub_groups.find(sub_name);
627 if (finder != m_p->m_sub_groups.end()) {
628 ARCANE_FATAL("Cannot create already existing sub-group ({0}) in group ({1})",
629 suffix, name());
630 }
631 ItemGroup ig = family->createGroup(sub_name,ItemGroup(this));
632 ItemGroupImpl* ii = ig.internal();
633 ii->setComputeFunctor(functor);
634 functor->setGroup(ii);
635 // Observer par défaut : le sous groupe n'est pas intéressé par les infos détaillées de transition
639 ii->invalidate(false);
640 return ii;
641}
642
643/*---------------------------------------------------------------------------*/
644/*---------------------------------------------------------------------------*/
645
648{
649 String sub_name = name() + "_" + suffix;
650 auto finder = m_p->m_sub_groups.find(sub_name);
651 if (finder != m_p->m_sub_groups.end()) {
652 return finder->second.get();
653 }
654 else {
655 // ou bien erreur ?
656 return checkSharedNull();
657 }
658}
659
660/*---------------------------------------------------------------------------*/
661/*---------------------------------------------------------------------------*/
662
665{
666 ITraceMng* trace = m_p->m_mesh->traceMng();
667 if (m_p->m_compute_functor) {
668 trace->debug(Trace::High) << "ItemGroupImpl::changeIds on "
669 << name() << " : skip computed group";
670 return;
671 }
672
673 // ItemGroupImpl ne fait d'habitude pas le checkNeedUpdate lui meme, plutot le ItemGroup
675 if (isAllItems()) {
676 // Int32ArrayView items_lid = m_p->itemsLocalId();
677 // for( Integer i=0, is=items_lid.size(); i<is; ++i ) {
678 // Integer lid = items_lid[i];
679 // ARCANE_ASSERT((lid = old_to_new_ids[lid]),("Non uniform order on allItems"));;
680 // }
681 // m_p->notifyCompactObservers(&old_to_new_ids);
682 m_p->notifyInvalidateObservers();
683 return;
684 }
685
686 Int32ArrayView items_lid = m_p->itemsLocalId();
687 for( Integer i=0, is=items_lid.size(); i<is; ++i ){
688 Integer old_id = items_lid[i];
690 }
691
692 m_p->updateTimestamp();
693 // Pour l'instant, il ne faut pas trier les entités des variables
694 // partielles car les valeurs correspondantes des variables ne sont
695 // pas mises à jour (il faut implémenter changeGroupIds pour cela)
696 // NOTE: est-ce utile de le faire ?
697 // NOTE: faut-il le faire pour les autre aussi ? A priori, cela n'est
698 // utile que pour garantir le meme resultat parallele/sequentiel
700 m_p->notifyCompactObservers(&old_to_new_ids);
701 } else {
702 // Pas besoin d'infos, on peut changer arbitrairement leur ordre
703 // TODO: #warning "(HP) Connexion de ce triage d'item avec la famille ?"
704 std::sort(std::begin(items_lid),std::end(items_lid));
705 m_p->notifyCompactObservers(nullptr);
706 }
707}
708
709/*---------------------------------------------------------------------------*/
710/*---------------------------------------------------------------------------*/
711
714{
715#ifdef ARCANE_DEBUG
716 // if (force_recompute){
718 msg->debug(Trace::High) << "ItemGroupImpl::invalidate(force=" << force_recompute << ")"
719 << " name=" << name();
720// }
721#endif
722
723 m_p->updateTimestamp();
724 m_p->setNeedRecompute();
725 if (force_recompute)
727 m_p->notifyInvalidateObservers();
728}
729
730/*---------------------------------------------------------------------------*/
731/*---------------------------------------------------------------------------*/
732
734itemsInternal() const
735{
736 return m_p->items();
737}
738
739/*---------------------------------------------------------------------------*/
740/*---------------------------------------------------------------------------*/
741
743itemInfoListView() const
744{
745 return m_p->itemInfoListView();
746}
747
748/*---------------------------------------------------------------------------*/
749/*---------------------------------------------------------------------------*/
750
752isLocalToSubDomain() const
753{
755}
756
757/*---------------------------------------------------------------------------*/
758/*---------------------------------------------------------------------------*/
759
765
766/*---------------------------------------------------------------------------*/
767/*---------------------------------------------------------------------------*/
768
771{
772 ARCANE_ASSERT(( (!m_p->m_need_recompute && !isAllItems()) || (m_p->m_transaction_mode && isAllItems()) ),
773 ("Operation on invalid group"));
775 ARCANE_FATAL("Cannot add items on computed group ({0})", name());
776 IMesh* amesh = mesh();
777 if (!amesh)
778 throw ArgumentException(A_FUNCINFO,"null group");
779 ITraceMng* trace = amesh->traceMng();
780
781 Integer nb_item_to_add = items_local_id.size();
782 if (nb_item_to_add==0)
783 return;
784
785 Int32Array& items_lid = m_p->mutableItemsLocalId();
786 const Integer current_size = items_lid.size();
787 Integer nb_added = 0;
788
789 if(isAllItems()) {
790 // Ajoute les nouveaux items à la fin
791 Integer nb_items_id = current_size;
792 m_p->m_items_index_in_all_group.resize(m_p->maxLocalId());
793 for( Integer i=0, is=nb_item_to_add; i<is; ++i ){
794 Int32 local_id = items_local_id[i];
795 items_lid.add(local_id);
796 m_p->m_items_index_in_all_group[local_id] = nb_items_id+i;
797 }
799 }
800 else if (check_if_present) {
801 // Vérifie que les entités à ajouter ne sont pas déjà présentes
803 presence_checks.fill(false);
804 for( Integer i=0, is=items_lid.size(); i<is; ++i ){
805 presence_checks[items_lid[i]] = true;
806 }
807
808 for( Integer i=0; i<nb_item_to_add; ++i ) {
809 const Integer lid = items_local_id[i];
810 if (!presence_checks[lid]){
811 items_lid.add(lid);
812 // Met à \a true comme cela si l'entité est présente plusieurs fois
813 // dans \a items_local_id cela fonctionne quand même.
814 presence_checks[lid] = true;
815 ++nb_added;
816 }
817 }
818 }
819 else {
821 MemoryUtils::checkResizeArrayWithCapacity(items_lid,current_size+nb_added,false);
823 MemoryUtils::copy<Int32>(ptr, items_local_id);
824 }
825
826 if (arcaneIsCheck()){
827 trace->info(5) << "ItemGroupImpl::addItems() group <" << name() << "> "
828 << " checkpresent=" << check_if_present
829 << " nb_current=" << current_size
830 << " want_to_add=" << nb_item_to_add
831 << " effective_added=" << nb_added;
832 checkValid();
833 }
834
835 if (nb_added!=0) {
836 m_p->updateTimestamp();
838 m_p->notifyExtendObservers(&observation_info);
839 }
840}
841
842/*---------------------------------------------------------------------------*/
843/*---------------------------------------------------------------------------*/
844
850
851/*---------------------------------------------------------------------------*/
852/*---------------------------------------------------------------------------*/
853
857 bool check_if_present)
858{
859 ARCANE_ASSERT(( (!m_p->m_need_recompute && !isAllItems()) || (m_p->m_transaction_mode && isAllItems()) ),
860 ("Operation on invalid group"));
862 ARCANE_FATAL("Cannot remove items on computed group ({0})", name());
863 IMesh* amesh = mesh();
864 if (!amesh)
865 throw ArgumentException(A_FUNCINFO,"null group");
866 ITraceMng* trace = amesh->traceMng();
867 if (isOwn() && amesh->meshPartInfo().nbPart()!=1){
868 ARCANE_THROW(NotSupportedException,"Cannot remove items if isOwn() is true");
869 }
870
871 Int32Array & items_lid = m_p->mutableItemsLocalId();
872
873 if(isAllItems()) {
875 const Integer internal_size = internals.size();
876 const Integer new_size = m_p->m_item_family->nbItem();
877 items_lid.resize(new_size);
878 m_p->m_items_index_in_all_group.resize(m_p->maxLocalId());
880 // Il n'y a pas de trous dans la numérotation
881 for( Integer i=0; i<internal_size; ++i ){
882 Int32 local_id = internals[i]->localId();
883 items_lid[i] = local_id;
884 m_p->m_items_index_in_all_group[local_id] = i;
885 }
886 }
887 else{
888 Integer index = 0;
889 for( Integer i=0; i<internal_size; ++i ){
890 ItemInternal* item = internals[i];
891 if (!item->isSuppressed()){
892 Int32 local_id = item->localId();
893 items_lid[index] = local_id;
894 m_p->m_items_index_in_all_group[local_id] = index;
895 ++index;
896 }
897 }
898 if (index!=new_size)
899 ARCANE_FATAL("Inconsistent number of elements in the generation of the group '{0}' expected={1} present={2}",
900 name(), new_size, index);
901 }
902
903 // On ne peut pas savoir ce qui a changé donc dans le doute on
904 // incrémente le timestamp.
905 m_p->updateTimestamp();
906 }
907 else {
910 }
911
912 if(arcaneIsCheck()){
913 trace->info(5) << "ItemGroupImpl::removeAddItems() group <" << name() << "> "
914 << " old_size=" << m_p->m_item_family->nbItem()
915 << " new_size=" << size()
916 << " nb_removed=" << removed_items_lids.size()
917 << " nb_added=" << added_items_lids.size();
918 checkValid();
919 }
920}
921
922
923/*---------------------------------------------------------------------------*/
924/*---------------------------------------------------------------------------*/
925
928{
930 ARCANE_FATAL("Cannot set items on computed group ({0})", name());
931 Int32Array& buf = m_p->mutableItemsLocalId();
932 buf.resize(items_local_id.size());
935 m_p->updateTimestamp();
936 m_p->m_need_recompute = false;
937 if (arcaneIsCheck()){
938 ITraceMng* trace = m_p->mesh()->traceMng();
939 trace->debug(Trace::High) << "ItemGroupImpl::setItems() group <" << name() << "> "
940 << " size=" << size();
941 checkValid();
942 }
943
944 // On tolére encore le setItems initial en le convertissant en un addItems
945 if (size() != 0)
946 m_p->notifyInvalidateObservers();
947 else
948 m_p->notifyExtendObservers(&items_local_id);
949}
950
951/*---------------------------------------------------------------------------*/
952/*---------------------------------------------------------------------------*/
953
955{
956 public:
957 ItemSorter(ItemInfoListView items) : m_items(items){}
958 public:
959 void sort(Int32ArrayView local_ids) const
960 {
961 std::sort(std::begin(local_ids),std::end(local_ids),*this);
962 }
963 bool operator()(Int32 lid1,Int32 lid2) const
964 {
965 return m_items[lid1].uniqueId() < m_items[lid2].uniqueId();
966 }
967 private:
968 ItemInfoListView m_items;
969};
970
971/*---------------------------------------------------------------------------*/
972/*---------------------------------------------------------------------------*/
973
986
987/*---------------------------------------------------------------------------*/
988/*---------------------------------------------------------------------------*/
989
992{
993 m_p->m_is_all_items = true;
994}
995
996/*---------------------------------------------------------------------------*/
997/*---------------------------------------------------------------------------*/
998
1000isAllItems() const
1001{
1002 return m_p->m_is_all_items;
1003}
1004
1005/*---------------------------------------------------------------------------*/
1006/*---------------------------------------------------------------------------*/
1007
1009{
1010 public:
1012 : m_items(items)
1013 {
1014 }
1015 public:
1016 bool operator()(Integer item_lid)
1017 {
1018 return m_items[item_lid]->isSuppressed();
1019 }
1020 private:
1021 ItemInternalList m_items;
1022};
1023
1024/*---------------------------------------------------------------------------*/
1025/*---------------------------------------------------------------------------*/
1026
1029{
1030 // TODO: (HP) Assertion need fix"
1031 // ARCANE_ASSERT((!m_p->m_need_recompute),("Operation on invalid group"));
1032 ITraceMng* trace = m_p->mesh()->traceMng();
1033 if (m_p->m_compute_functor) {
1034 trace->debug(Trace::High) << "ItemGroupImpl::removeSuppressedItems on " << name() << " : skip computed group";
1035 return;
1036 }
1037
1038 ItemInternalList items = m_p->items();
1039 Integer nb_item = items.size();
1040 Int32Array& items_lid = m_p->mutableItemsLocalId();
1041 Integer current_size = items_lid.size();
1042 if (arcaneIsCheck()){
1043 for( Integer i=0; i<current_size; ++i ){
1044 if (items_lid[i]>=nb_item){
1045 trace->fatal() << "ItemGroupImpl::removeSuppressedItems(): bad range "
1046 << " name=" << name()
1047 << " i=" << i << " lid=" << items_lid[i]
1048 << " max=" << nb_item;
1049 }
1050 }
1051 }
1052
1056 Integer new_size;
1057 // Si le groupe posséde des observers ayant besoin d'info, il faut les calculer
1059 removed_ids.reserve(current_size); // préparation à taille max
1060 Integer index = 0;
1061 for( Integer i=0; i<current_size; ++i ){
1062 if (!items[items_lid[i]]->isSuppressed()){
1063 items_lid[index] = items_lid[i];
1064 ++index;
1065 } else {
1066 // trace->debug(Trace::Highest) << "Remove from group " << name() << " item " << i << " " << items_lid[i] << " " << ItemPrinter(items[items_lid[i]]);
1067 removed_lids.add(items_lid[i]);
1068 }
1069 }
1070 new_size = index;
1071 if (new_size!=current_size){
1072 items_lid.resize(new_size);
1073 observation_info = new Int32ConstArrayView(removed_lids.size(), removed_lids.unguardedBasePointer());
1074 }
1075 }
1076 else{
1077 ItemCheckSuppressedFunctor f(m_p->items());
1078 auto ibegin = std::begin(items_lid);
1079 auto new_end = std::remove_if(ibegin,std::end(items_lid),f);
1080 new_size = (Integer)(new_end-ibegin);
1081 items_lid.resize(new_size);
1082 }
1083
1084 if (arcaneIsCheck()) {
1085 trace->debug(Trace::High) << "ItemGroupImpl::removeSupressedItems() group <" << name()
1086 << "> NEW SIZE=" << new_size << " OLD=" << current_size;
1087 checkValid();
1088 }
1089
1090 // Ne met à jour que si le groupe a été modifié
1091 if (current_size != new_size) {
1092 m_p->updateTimestamp();
1093 m_p->notifyReduceObservers(observation_info);
1094 delete observation_info;
1095 delete observation_info2;
1096 }
1097}
1098
1099/*---------------------------------------------------------------------------*/
1100/*---------------------------------------------------------------------------*/
1101
1103checkValid()
1104{
1105 m_p->checkValid();
1106}
1107
1108/*---------------------------------------------------------------------------*/
1109/*---------------------------------------------------------------------------*/
1110
1111bool ItemGroupImpl::
1112_checkNeedUpdate(bool do_padding)
1113{
1114 // En cas de problème sur des recalculs très imbriqués, une proposition est
1115 // de désactiver les lignes #A pour activer les lignes #B
1116 bool has_recompute = false;
1117 if (m_p->m_need_recompute) {
1118 m_p->m_need_recompute = false;
1119 // bool need_invalidate_on_recompute = m_p->m_need_invalidate_on_recompute; // #B
1120 // m_p->m_need_invalidate_on_recompute = false; // #B
1121 if (m_p->m_compute_functor) {
1123 }
1124 // if (need_invalidate_on_recompute) { // #B
1125 // m_p->notifyInvalidateObservers(); // #B
1126 // } // #B
1127
1129 m_p->m_need_invalidate_on_recompute = false; // #A
1130 m_p->notifyInvalidateObservers(); // #A
1131 } // #A
1132 has_recompute = true;
1133 }
1134 if (do_padding)
1135 _checkUpdateSimdPadding();
1136 return has_recompute;
1137}
1138
1139/*---------------------------------------------------------------------------*/
1140/*---------------------------------------------------------------------------*/
1141
1142bool ItemGroupImpl::
1143_checkNeedUpdateNoPadding()
1144{
1145 return _checkNeedUpdate(false);
1146}
1147
1148/*---------------------------------------------------------------------------*/
1149/*---------------------------------------------------------------------------*/
1150
1151bool ItemGroupImpl::
1152_checkNeedUpdateWithPadding()
1153{
1154 return _checkNeedUpdate(true);
1155}
1156
1157/*---------------------------------------------------------------------------*/
1158/*---------------------------------------------------------------------------*/
1159
1162{
1163 return _checkNeedUpdate(false);
1164}
1165
1166/*---------------------------------------------------------------------------*/
1167/*---------------------------------------------------------------------------*/
1168
1169void ItemGroupImpl::
1170_checkUpdateSimdPadding()
1171{
1173}
1174
1175/*---------------------------------------------------------------------------*/
1176/*---------------------------------------------------------------------------*/
1177
1179clear()
1180{
1181 Int32Array& items_lid = m_p->mutableItemsLocalId();
1182 if (!items_lid.empty())
1183 // Incrémente uniquement si le groupe n'est pas déjà vide
1184 m_p->updateTimestamp();
1185 items_lid.clear();
1186 m_p->m_need_recompute = false;
1187 for( const auto& i : m_p->m_sub_groups )
1188 i.second->clear();
1189 m_p->notifyInvalidateObservers();
1190}
1191
1192/*---------------------------------------------------------------------------*/
1193/*---------------------------------------------------------------------------*/
1194
1197{
1198 if (m_p->m_parent)
1199 return ItemGroup(m_p->m_parent);
1200 return ItemGroup();
1201}
1202
1203/*---------------------------------------------------------------------------*/
1204/*---------------------------------------------------------------------------*/
1205
1208{
1209 ARCANE_ASSERT((!m_p->m_need_recompute),("Operation on invalid group"));
1210 bool is_verbose = m_p->m_is_debug_apply_operation;
1211
1212 ITraceMng* tm = m_p->mesh()->traceMng();
1213 if (is_verbose)
1214 tm->info() << "applyOperation name=" << name() << " nb_item=" << size();
1215 if (m_p->isUseV2ForApplyOperation()){
1216 if (m_p->m_children_by_type_ids.empty()){
1218 }
1219 Int64 t = m_p->timestamp();
1220 if (is_verbose)
1221 tm->info() << "applyOperation timestamp=" << t << " last=" << m_p->m_children_by_type_ids_computed_timestamp;
1225 }
1226 }
1227 else{
1228 if (m_p->m_children_by_type.empty())
1230 }
1231 IItemFamily* family = m_p->m_item_family;
1232 const bool has_only_one_type = (m_p->m_unique_children_type != IT_NullType);
1233 if (is_verbose)
1234 tm->info() << "applyOperation has_only_one_type=" << has_only_one_type << " value=" << m_p->m_unique_children_type;
1235 // TODO: Supprimer la macro et la remplacer par une fonction.
1236
1237#define APPLY_OPERATION_ON_TYPE(ITEM_TYPE) \
1238 if (m_p->isUseV2ForApplyOperation()){\
1239 Int16 type_id = IT_##ITEM_TYPE;\
1240 Int32ConstArrayView sub_ids = m_p->m_children_by_type_ids[type_id]; \
1241 if (has_only_one_type && type_id==m_p->m_unique_children_type)\
1242 sub_ids = itemsLocalId(); \
1243 if (is_verbose && sub_ids.size()>0) \
1244 tm->info() << "Type=" << (int)IT_##ITEM_TYPE << " nb=" << sub_ids.size(); \
1245 if (sub_ids.size()!=0){\
1246 operation->apply##ITEM_TYPE(family->view(sub_ids)); \
1247 }\
1248 }\
1249 else { \
1250 ItemGroup group(m_p->m_children_by_type[IT_##ITEM_TYPE]); \
1251 if (!group.empty()) \
1252 operation->apply##ITEM_TYPE(group.view()); \
1253 }
1254
1255 APPLY_OPERATION_ON_TYPE(Vertex);
1256 APPLY_OPERATION_ON_TYPE(Line2);
1257 APPLY_OPERATION_ON_TYPE(Triangle3);
1258 APPLY_OPERATION_ON_TYPE(Quad4);
1259 APPLY_OPERATION_ON_TYPE(Pentagon5);
1260 APPLY_OPERATION_ON_TYPE(Hexagon6);
1261 APPLY_OPERATION_ON_TYPE(Tetraedron4);
1262 APPLY_OPERATION_ON_TYPE(Pyramid5);
1263 APPLY_OPERATION_ON_TYPE(Pentaedron6);
1264 APPLY_OPERATION_ON_TYPE(Hexaedron8);
1265 APPLY_OPERATION_ON_TYPE(Heptaedron10);
1266 APPLY_OPERATION_ON_TYPE(Octaedron12);
1267 APPLY_OPERATION_ON_TYPE(HemiHexa7);
1268 APPLY_OPERATION_ON_TYPE(HemiHexa6);
1269 APPLY_OPERATION_ON_TYPE(HemiHexa5);
1270 APPLY_OPERATION_ON_TYPE(HemiHexa7);
1271 APPLY_OPERATION_ON_TYPE(AntiWedgeLeft6);
1272 APPLY_OPERATION_ON_TYPE(AntiWedgeRight6);
1273 APPLY_OPERATION_ON_TYPE(DiTetra5);
1274 APPLY_OPERATION_ON_TYPE(DualNode);
1275 APPLY_OPERATION_ON_TYPE(DualEdge);
1276 APPLY_OPERATION_ON_TYPE(DualFace);
1277 APPLY_OPERATION_ON_TYPE(DualCell);
1278 APPLY_OPERATION_ON_TYPE(Link);
1279
1280#undef APPLY_OPERATION_ON_TYPE
1281}
1282
1283/*---------------------------------------------------------------------------*/
1284/*---------------------------------------------------------------------------*/
1285
1287needSynchronization() const
1288{
1289 return !(m_p->m_compute_functor != 0 ||
1291 m_p->m_is_own);
1292}
1293
1294/*---------------------------------------------------------------------------*/
1295/*---------------------------------------------------------------------------*/
1296
1298timestamp() const
1299{
1300 return m_p->timestamp();
1301}
1302
1303/*---------------------------------------------------------------------------*/
1304/*---------------------------------------------------------------------------*/
1305
1308{
1309 auto finder = m_p->m_observers.find(ref);
1310 auto end = m_p->m_observers.end();
1311 if (finder != end) {
1312 delete finder->second;
1313 finder->second = obs;
1314 return;
1315 }
1316 else {
1317 m_p->m_observers[ref] = obs;
1318 }
1319
1320 // Mise à jour du flag de demande d'info
1322}
1323
1324/*---------------------------------------------------------------------------*/
1325/*---------------------------------------------------------------------------*/
1326
1328detachObserver(const void * ref)
1329{
1330 auto finder = m_p->m_observers.find(ref);
1331 auto end = m_p->m_observers.end();
1332
1333 if (finder == end)
1334 return;
1335
1336 IItemGroupObserver * obs = finder->second;
1337 delete obs;
1338 m_p->m_observers.erase(finder);
1339 // Mise à jour du flag de demande d'info
1340 bool new_observer_need_info = false;
1341 auto i = m_p->m_observers.begin();
1342 for( ; i != end ; ++i ) {
1343 IItemGroupObserver * obs = i->second;
1344 new_observer_need_info |= obs->needInfo();
1345 }
1347
1348 // On invalide la table de hachage éventuelle
1349 // des variables partielles si il n'y a plus
1350 // de référence.
1351 if(m_p->m_group_index_table.isUsed() && m_p->m_group_index_table.isUnique()) {
1352 m_p->m_group_index_table.reset();
1353 m_p->m_synchronizer.reset();
1354 }
1355}
1356
1357/*---------------------------------------------------------------------------*/
1358/*---------------------------------------------------------------------------*/
1359
1361hasInfoObserver() const
1362{
1363 return m_p->m_observer_need_info;
1364}
1365
1366/*---------------------------------------------------------------------------*/
1367/*---------------------------------------------------------------------------*/
1368
1371{
1372 delete m_p->m_compute_functor;
1373 m_p->m_compute_functor = functor;
1374}
1375
1376/*---------------------------------------------------------------------------*/
1377/*---------------------------------------------------------------------------*/
1378
1380hasComputeFunctor() const
1381{
1382 return (m_p->m_compute_functor);
1383}
1384
1385/*---------------------------------------------------------------------------*/
1386/*---------------------------------------------------------------------------*/
1387
1390{
1391 IItemFamily* family = m_p->m_item_family;
1392 ItemTypeMng* type_mng = family->mesh()->itemTypeMng();
1393 Integer nb_basic_item_type= ItemTypeMng::nbBasicItemType(); //NB_BASIC_ITEM_TYPE
1395 for( Integer i=0; i<nb_basic_item_type; ++i ){
1396 // String child_name(name()+i);
1397 String child_name(type_mng->typeName(i));
1401 }
1402}
1403
1404/*---------------------------------------------------------------------------*/
1405/*---------------------------------------------------------------------------*/
1406
1409{
1410 bool is_verbose = m_p->m_is_debug_apply_operation;
1411 if (is_verbose)
1412 m_p->mesh()->traceMng()->info() << "ItemGroupImpl::_initChildrenByTypeV2() name=" << name();
1413
1416 for( Integer i=0; i<nb_basic_item_type; ++i ){
1417 m_p->m_children_by_type_ids[i] = UniqueArray<Int32>{MemoryUtils::getDefaultDataAllocator()};
1418 }
1419}
1420
1421/*---------------------------------------------------------------------------*/
1422/*---------------------------------------------------------------------------*/
1423
1426{
1427 ItemGroup that_group(this);
1428 ITraceMng * trace = that_group.mesh()->traceMng();
1429 trace->debug(Trace::High) << "ItemGroupImpl::_computeChildrenByType for " << name();
1430
1432
1434 for( Integer i=0; i<nb_basic_item_type; ++i ){
1436 impl->beginTransaction();
1437 }
1438
1440 const Item& item = *iitem;
1441 Integer item_type = item.type();
1442 if (item_type<nb_basic_item_type)
1443 items_by_type[item_type].add(iitem.itemLocalId());
1444 }
1445
1446 for( Integer i=0; i<nb_basic_item_type; ++i ){
1448 impl->setItems(items_by_type[i]);
1449 impl->endTransaction();
1450 }
1451}
1452
1453/*---------------------------------------------------------------------------*/
1454/*---------------------------------------------------------------------------*/
1455
1458{
1459 ItemGroup that_group(this);
1460 Int32 nb_item = size();
1461 IMesh* mesh = m_p->mesh();
1463 ITraceMng* trace = mesh->traceMng();
1464 bool is_verbose = m_p->m_is_debug_apply_operation;
1465 if (is_verbose)
1466 trace->info() << "ItemGroupImpl::_computeChildrenByTypeV2 for " << name();
1467
1468 // Si le maillage est cartésien, on sait que toutes les entités ont le même type
1469 if (nb_item>0 && mesh->meshKind().meshStructure()==eMeshStructure::Cartesian){
1471 m_p->m_unique_children_type = ItemTypeId{lv.typeId(m_p->itemsLocalId()[0])};
1472 return;
1473 }
1474
1476 m_p->m_unique_children_type = ItemTypeId{IT_NullType};
1477
1479 nb_items_by_type.fill(0);
1481 Item item = *iitem;
1482 Int16 item_type = item.type();
1483 if (item_type<nb_basic_item_type)
1484 ++nb_items_by_type[item_type];
1485 }
1486
1487 Int32 nb_different_type = 0;
1488 for( Int32 i=0; i<nb_basic_item_type; ++i ){
1489 m_p->m_children_by_type_ids[i].clear();
1490 const Int32 n = nb_items_by_type[i];
1491 m_p->m_children_by_type_ids[i].reserve(n);
1492 if (n>0)
1494 if (is_verbose)
1495 trace->info() << "ItemGroupImpl::_computeChildrenByTypeV2 for " << name()
1496 << " type=" << type_mng->typeName(i) << " nb=" << n;
1497 }
1498 if (is_verbose)
1499 trace->info() << "ItemGroupImpl::_computeChildrenByTypeV2 for " << name()
1500 << " nb_item=" << nb_item << " nb_different_type=" << nb_different_type;
1501
1502 // Si nb_different_type == 1, cela signifie qu'il n'y a qu'un seul
1503 // type d'entité et on conserve juste ce type car dans ce cas on passera
1504 // directement le groupe en argument de applyOperation().
1505 if (nb_item>0 && nb_different_type==1){
1507 m_p->m_unique_children_type = ItemTypeId{lv.typeId(m_p->itemsLocalId()[0])};
1508 if (is_verbose)
1509 trace->info() << "ItemGroupImpl::_computeChildrenByTypeV2 for " << name()
1510 << " unique_type=" << type_mng->typeName(m_p->m_unique_children_type);
1511 return;
1512 }
1513
1515 Item item = *iitem;
1516 Integer item_type = item.type();
1517 if (item_type<nb_basic_item_type)
1518 m_p->m_children_by_type_ids[item_type].add(iitem.itemLocalId());
1519 }
1520
1521 for( Int32 i=0; i<nb_basic_item_type; ++i )
1522 applySimdPadding(m_p->m_children_by_type_ids[i]);
1523}
1524
1525/*---------------------------------------------------------------------------*/
1526/*---------------------------------------------------------------------------*/
1527
1530{
1531 ARCANE_UNUSED(info);
1532 // On ne sait encore calculer appliquer des transformations à des groupes calculés
1533 // On choisit l'invalidation systématique
1534 m_p->notifyInvalidateObservers();
1535}
1536
1537/*---------------------------------------------------------------------------*/
1538/*---------------------------------------------------------------------------*/
1539
1542{
1543 ARCANE_UNUSED(info);
1544 // On ne sait encore calculer appliquer des transformations à des groupes calculés
1545 // On choisit l'invalidation systématique
1546 m_p->notifyInvalidateObservers();
1547}
1548
1549/*---------------------------------------------------------------------------*/
1550/*---------------------------------------------------------------------------*/
1551
1554{
1555 ARCANE_UNUSED(info);
1556 // On ne sait encore calculer appliquer des transformations à des groupes calculés
1557 // On choisit l'invalidation systématique en différé (évaluée lors du prochain checkNeedUpdate)
1558 m_p->notifyInvalidateObservers();
1559}
1560
1561/*---------------------------------------------------------------------------*/
1562/*---------------------------------------------------------------------------*/
1563
1566{
1567 m_p->setNeedRecompute();
1568 m_p->notifyInvalidateObservers();
1569}
1570
1571/*---------------------------------------------------------------------------*/
1572/*---------------------------------------------------------------------------*/
1573
1575_updateNeedInfoFlag(const bool flag)
1576{
1578 return;
1580 // Si change, change aussi l'observer du parent pour qu'il adapte les besoins en info de transition
1581 ItemGroupImpl * parent = m_p->m_parent;
1582 if (parent) {
1583 parent->detachObserver(this);
1590 } else {
1593 }
1594 }
1595}
1596
1597/*---------------------------------------------------------------------------*/
1598/*---------------------------------------------------------------------------*/
1599
1602{
1603 // (HP) TODO: Mettre un observer forceInvalidate pour prévenir tout le monde ?
1604 // avec forceInvalidate on doit invalider mais ne rien calculer
1605 if (self_invalidate) {
1606 m_p->setNeedRecompute();
1608 }
1609
1610 for( const auto& i : m_p->m_sub_groups )
1611 i.second->_forceInvalidate(true);
1612}
1613
1614/*---------------------------------------------------------------------------*/
1615/*---------------------------------------------------------------------------*/
1616
1618destroy()
1619{
1620 // Détache les observateurs. Cela modifie \a m_observers donc il faut
1621 // en faire une copie
1622 {
1623 std::vector<const void*> ptrs;
1624 for( const auto& i : m_p->m_observers )
1625 ptrs.push_back(i.first);
1626 for( const void* i : ptrs )
1627 detachObserver(i);
1628 }
1629
1630 // Le groupe de toutes les entités est spécial. Il ne faut jamais le détruire
1631 // vraiement.
1632 if (m_p->m_is_all_items)
1633 m_p->resetSubGroups();
1634 else{
1635 delete m_p;
1636 m_p = new ItemGroupInternal();
1637 }
1638}
1639
1640/*---------------------------------------------------------------------------*/
1641/*---------------------------------------------------------------------------*/
1642
1645{
1646 if(!m_p->m_group_index_table.isUsed()) {
1648 ITraceMng* trace = m_p->m_mesh->traceMng();
1649 trace->debug(Trace::High) << "** CREATION OF LOCAL ID TO INDEX TABLE OF GROUP : " << m_p->m_name;
1650 m_p->m_group_index_table->update();
1651 }
1652 return m_p->m_group_index_table;
1653}
1654
1655/*---------------------------------------------------------------------------*/
1656/*---------------------------------------------------------------------------*/
1657
1660{
1661 if(!m_p->m_synchronizer.get()) {
1663 ItemGroup this_group(this);
1665 ITraceMng* trace = m_p->m_mesh->traceMng();
1666 trace->debug(Trace::High) << "** CREATION OF SYNCHRONIZER OF GROUP : " << m_p->m_name;
1667 m_p->m_synchronizer->compute();
1668 }
1669 return m_p->m_synchronizer.get();
1670}
1671
1672/*---------------------------------------------------------------------------*/
1673/*---------------------------------------------------------------------------*/
1674
1677{
1678 return m_p->m_synchronizer.get();
1679}
1680
1681/*---------------------------------------------------------------------------*/
1682/*---------------------------------------------------------------------------*/
1683
1685checkIsSorted() const
1686{
1687 if (null())
1688 return true;
1689
1690 // TODO: stocker l'info dans un flag et ne refaire le test que si
1691 // la liste des entités a changer (utiliser timestamp()).
1692 ItemInternalList items(m_p->items());
1693 Int32ConstArrayView items_lid(m_p->itemsLocalId());
1694 Integer nb_item = items_lid.size();
1695 // On est toujours trié si une seule entité ou moins.
1696 if (nb_item<=1)
1697 return true;
1698 // Compare chaque uniqueId() avec le précédent et vérifie qu'il est
1699 // supérieur.
1700 ItemUniqueId last_uid = items[items_lid[0]]->uniqueId();
1701 for( Integer i=1; i<nb_item; ++i ){
1702 ItemUniqueId uid = items[items_lid[i]]->uniqueId();
1703 if (uid<last_uid)
1704 return false;
1705 last_uid = uid;
1706 }
1707 return true;
1708}
1709
1710/*---------------------------------------------------------------------------*/
1711/*---------------------------------------------------------------------------*/
1712
1714deleteMe()
1715{
1716 // S'il s'agit de 'shared_null'. Il faut le positionner à nullptr pour qu'il
1717 // soit réalloué éventuellement par _buildSharedNull().
1718 if (this==shared_null){
1719 shared_null = nullptr;
1720 }
1721 delete this;
1722}
1723
1724/*---------------------------------------------------------------------------*/
1725/*---------------------------------------------------------------------------*/
1726
1729{
1730 if (!shared_null){
1731 shared_null = new ItemGroupImplNull();
1732 shared_null->addRef();
1733 }
1734}
1735
1736/*---------------------------------------------------------------------------*/
1737/*---------------------------------------------------------------------------*/
1738
1741{
1742 // Supprime une référence à 'shared_null'. Si le nombre de référence
1743 // devient égal à 0, alors l'instance 'shared_null' est détruite.
1744 if (shared_null)
1745 shared_null->removeRef();
1746}
1747
1748/*---------------------------------------------------------------------------*/
1749/*---------------------------------------------------------------------------*/
1750
1752isContigousLocalIds() const
1753{
1754 return m_p->isContigous();
1755}
1756
1757/*---------------------------------------------------------------------------*/
1758/*---------------------------------------------------------------------------*/
1759
1765
1766/*---------------------------------------------------------------------------*/
1767/*---------------------------------------------------------------------------*/
1768
1770capacity() const
1771{
1772 Int32Array& items_lid = m_p->mutableItemsLocalId();
1773 return items_lid.capacity();
1774}
1775
1776/*---------------------------------------------------------------------------*/
1777/*---------------------------------------------------------------------------*/
1778
1781{
1782 if (hasComputeFunctor()){
1783 // Groupe calculé. On l'invalide et on supprime ses éléments
1784 invalidate(false);
1785 m_p->mutableItemsLocalId().clear();
1786 }
1787
1788 if (m_p->variableItemsLocalid())
1789 m_p->variableItemsLocalid()->variable()->shrinkMemory();
1790 else
1791 m_p->mutableItemsLocalId().shrink();
1792
1794}
1795
1796/*---------------------------------------------------------------------------*/
1797/*---------------------------------------------------------------------------*/
1798
1800_internalApi() const
1801{
1802 return &m_p->m_internal_api;
1803}
1804
1805/*---------------------------------------------------------------------------*/
1806/*---------------------------------------------------------------------------*/
1807
1808} // End namespace Arcane
1809
1810/*---------------------------------------------------------------------------*/
1811/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
Tableau d'items de types quelconques.
Classe de base d'une table de hachage entre les items d'un groupe et leurs positions dans la table.
Interface d'une famille d'entités.
virtual ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Créé un groupe d'entités de nom name contenant les entités local_ids.
virtual ItemInfoListView itemInfoListView()=0
Vue sur la liste d'informations sur les entités.
virtual IMesh * mesh() const =0
Maillage associé
virtual Integer nbItem() const =0
Nombre d'entités.
Interface d'un opérateur sur des entités rangées par type.
virtual ITraceMng * traceMng()=0
Gestionnaire de message associé
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual IItemFamily * edgeFamily()=0
Retourne la famille des arêtes.
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
virtual IParallelMng * parallelMng()=0
Gestionnaire de parallèlisme.
virtual const MeshKind meshKind() const =0
Caractéristiques du maillage.
virtual ItemTypeMng * itemTypeMng() const =0
Gestionnaire de types d'entités associé
Interface du gestionnaire de parallélisme pour un sous-domaine.
Interface d'un service de synchronisation de variable.
virtual void shrinkMemory()=0
Libère l'éventuelle mémoire supplémentaire allouée pour les données.
bool isSuppressed() const
Vrai si l'entité est supprimée.
Int32 localId() const
Numéro local (au sous-domaine) de l'entité
ARCCORE_HOST_DEVICE ItemUniqueId uniqueId(Int32 local_id) const
uniqueId() de l'entité de numéro local local_id
Fonctor pour le calcul des éléments d'un groupe.
API interne à Arcane de ItemGroupImpl.
void executeFunctor() override
Exécute la méthode associé
Classe d'un groupe nul.
const String & name() const
Retourne le nom du groupe.
virtual ~ItemGroupImplNull()
Libére les ressources.
Implémentation d'un groupe d'entités de maillage.
void removeItems(Int32ConstArrayView items_local_id, bool check_if_present)
Supprime les entités items_local_id du groupe.
bool checkNeedUpdate()
Réactualise le groupe si nécessaire.
ItemGroupImpl * activeCellGroup()
AMR.
void removeAddItems(Int32ConstArrayView removed_local_id, Int32ConstArrayView added_local_id, bool check_if_present)
Supprime et ajoute les entités removed_local_id et added_local_id du groupe.
ItemGroupImplInternal * _internalApi() const
API interne à Arcane.
void setItems(Int32ConstArrayView items_local_id)
Positionne les entités du groupe à items_local_id.
void setOwn(bool v)
Positionne la propriété de groupe local ou non.
Int64 timestamp() const
Retourne le temps du groupe. Ce temps est incrémenté après chaque modification.
ItemInternalList itemsInternal() const
Liste des entités sur lesquelles s'appuie le groupe.
void endTransaction()
Termine une transaction.
void invalidate(bool force_recompute)
Invalide le groupe.
ItemGroupImpl * nodeGroup()
Groupe des noeuds des éléments de ce groupe.
void addItems(Int32ConstArrayView items_local_id, bool check_if_present)
Ajoute les entités de numéros locaux items_local_id.
bool isAllItems() const
Indique si le groupe est celui de toutes les entités.
void _executeExtend(const Int32ConstArrayView *info)
Invalidation des sous-groupes.
ItemGroupImpl * parent() const
Groupe parent (0 si aucun)
Int32Array & unguardedItemsLocalId(const bool self_invalidate=true)
Liste des numéros locaux des entités de ce groupe.
ItemGroupImpl * cellGroup()
Groupe des mailles des éléments de ce groupe.
ItemGroupImpl * innerFaceGroup()
Groupe des faces internes des éléments de ce groupe.
eItemKind itemKind() const
Genre du groupe. Il s'agit du genre de ses éléments.
ItemGroupImpl * createSubGroup(const String &suffix, IItemFamily *family, ItemGroupComputeFunctor *functor)
Crée un sous-groupe calculé
virtual ~ItemGroupImpl()
Libère les ressources.
ItemGroupImpl * edgeGroup()
Groupe des arêtes des éléments de ce groupe.
bool null() const
Retourne true si le groupe est nul.
void clear()
Supprime les entités du groupe.
ItemGroupImpl * faceGroup()
Groupe des faces des éléments de ce groupe.
void destroy()
Détruit le groupe. Après cet appel, le groupe devient un groupe nul.
void setLocalToSubDomain(bool v)
Positionne le booléen indiquant si le groupe est local au sous-domaine.
void setIsAllItems()
Indique à ce groupe qu'il s'agit du groupe de toutes les entités de la famille.
void _executeReduce(const Int32ConstArrayView *info)
Invalidation des sous-groupes.
void removeSuppressedItems()
Supprime du groupe les entités dont le flag isSuppressed() est vrai.
const String & fullName() const
Nom complet du groupe (avec maillage + famille)
void _computeChildrenByTypeV2()
Méthode de calcul des sous-groupes par type.
ItemGroupImpl * ownGroup()
Groupe des entité propres des entités de ce groupe.
void _updateNeedInfoFlag(const bool flag)
Mise à jour forcée du flag d'information de restructuration.
IMesh * mesh() const
Maillage auquel appartient le groupe (0 pour le groupe nul).
bool checkIsSorted() const
Vérifie et retourne si le groupe est trié par uniqueId() croissants.
void checkValid()
Vérifie que le groupe est valide.
void _initChildrenByType()
Initialisation des sous-groupes par types.
IVariableSynchronizer * synchronizer()
Synchronizer du groupe.
Integer size() const
Nombre d'entités du groupe.
Int32ConstArrayView itemsLocalId() const
Liste des numéros locaux des entités de ce groupe.
bool needSynchronization() const
Indique si le groupe a structurellement besoin d'une synchro parallèle.
ItemGroupImpl * ownActiveCellGroup()
Groupe des mailles propres actives de ce groupe.
SharedPtrT< GroupIndexTable > localIdToIndex()
Table des local ids vers une position pour toutes les entités du groupe.
ItemInfoListView itemInfoListView() const
Liste des entités sur lesquelles s'appuie le groupe.
void attachObserver(const void *ref, IItemGroupObserver *obs)
Attache un observer.
ItemGroupImpl * outerActiveFaceGroup()
Groupe des faces externes actives des éléments de ce groupe.
void detachObserver(const void *ref)
Détache un observer.
IItemFamily * itemFamily() const
Familly à laquelle appartient le groupe (ou 0 si aucune)
void _executeInvalidate()
Invalidation des sous-groupes.
virtual void deleteMe()
Notification de SharedReference indiquant qu'il faut détruire l'instance.
void _executeCompact(const Int32ConstArrayView *info)
Invalidation des sous-groupes.
bool isLocalToSubDomain() const
AMR OFF.
ItemGroupImpl * ghostGroup()
Items in the group not owned by the subdomain.
ItemGroupImpl * ownLevelCellGroup(const Integer &level)
Groupe des mailles propres actives de ce groupe.
Int64 capacity() const
Nombre d'éléments alloués.
void checkLocalIdsAreContigous() const
Vérifie si les entités du groupe ont des localIds() contigüs.
static void _buildSharedNull()
ItemGroupImpl * innerActiveFaceGroup()
Groupe des faces internes actives des éléments de ce groupe.
void applyOperation(IItemOperationByBasicType *operation)
Applique l'opération operation sur les entités du groupe.
bool isContigousLocalIds() const
Indique si les entités du groupe ont des localIds() contigüs.
void beginTransaction()
Débute une transaction.
ItemGroupImpl * levelCellGroup(const Integer &level)
Groupe des mailles actives de ce groupe.
bool hasComputeFunctor() const
Indique si le groupe est calculé
bool hasSynchronizer()
Indique si ce groupe possède un synchroniser.
bool hasInfoObserver() const
Indique si le contenu de ce groupe est observé.
void _initChildrenByTypeV2()
Initialisation des sous-groupes par types.
void setComputeFunctor(IFunctor *functor)
Définit une fonction de calcul de groupe.
ItemGroupImpl * ownActiveFaceGroup()
Groupe des faces externes actives des éléments de ce groupe.
bool isOwn() const
Retourne si le groupe contient uniquement des éléments propres au sous-domaine.
ItemGroupImpl()
Construit un groupe nul.
ItemGroup parentGroup()
Groupe parent.
bool empty() const
Vrai si le groupe est vide.
void _forceInvalidate(const bool self_invalidate)
Invalidate forcée récursive.
ItemGroupInternal * m_p
Implémentation du groupe.
static void _destroySharedNull()
ItemGroupImpl * activeFaceGroup()
Groupe des faces actives propres au domaine.
const String & name() const
Nom du groupe.
void _computeChildrenByType()
Méthode de calcul des sous-groupes par type.
ItemGroupImpl * outerFaceGroup()
Groupe des faces externes des éléments de ce groupe.
void shrinkMemory()
Limite au maximum la mémoire utilisée par le groupe.
ItemGroupImpl * findSubGroup(const String &suffix)
Accède à un sous-groupe calculé
void changeIds(Int32ConstArrayView old_to_new_ids)
Change les indices des entités du groupe.
Implémentation de la classe ItemGroupImpl.
ItemGroupImpl * m_node_group
Groupe des noeuds.
std::map< Integer, ItemGroupImpl * > m_own_level_cell_group
Groupe des mailles propres de niveau.
IMesh * m_mesh
Gestionnare de groupe associé
UniqueArray< ItemGroupImpl * > m_children_by_type
Liste des fils de ce groupe par type d'entité
SharedPtrT< GroupIndexTable > m_group_index_table
Table de hachage du local id des items vers leur position en enumeration.
ItemGroupImpl * m_interface_group
Items on the boundary of two subdomains.
UniqueArray< UniqueArray< Int32 > > m_children_by_type_ids
Liste des localId() par type d'entité.
bool m_need_invalidate_on_recompute
Vrai si l'on doit activer les invalidate observers en cas de recalcul.
void checkIsContigous()
Vérifie que les localIds() sont contigüs.
bool m_need_recompute
Vrai si le groupe doit être recalculé
ItemGroupImpl * m_inner_face_group
Groupe des faces internes.
std::map< String, AutoRefT< ItemGroupImpl > > m_sub_groups
Ensemble de tous les sous-groupes.
bool m_transaction_mode
Vrai si le groupe est en mode de transaction directe.
bool m_is_own
true si groupe local.
Ref< IVariableSynchronizer > m_synchronizer
Synchronizer du groupe.
void checkUpdateSimdPadding()
Remplit les derniers éléments du groupe pour avoir un vecteur SIMD complet.
bool m_observer_need_info
Synthése de besoin de observers en informations de transition.
void applySimdPadding()
Applique le padding pour la vectorisation.
ItemGroupImpl * m_ghost_group
Items not owned by the subdomain.
bool m_is_local_to_sub_domain
Vrai si le groupe est local au sous-domaine.
bool m_is_all_items
Indique s'il s'agit du groupe de toutes les entités.
ItemGroupImpl * m_own_group
Items owned by the subdomain.
ItemTypeId m_unique_children_type
Indique le type des entités du groupe.
IItemFamily * m_item_family
Famille associée.
ItemGroupImpl * m_edge_group
Groupe des arêtes.
ItemGroupImpl * m_face_group
Groupe des faces.
std::map< Integer, ItemGroupImpl * > m_level_cell_group
Groupe des mailles de niveau.
std::map< const void *, IItemGroupObserver * > m_observers
localids -> index (UNIQUEMENT ALLITEMS)
Int64 m_children_by_type_ids_computed_timestamp
Timestamp indiquant quand a été calculé la liste des ids des enfants.
IFunctor * m_compute_functor
Fonction de calcul du groupe.
ItemGroupImpl * m_inner_active_face_group
Groupe des faces internes actives.
ItemGroupImpl * m_own_active_cell_group
Groupe des mailles propres actives.
ItemGroupImpl * m_cell_group
Groupe des mailles.
ItemGroupImpl * m_active_cell_group
AMR.
ItemGroupImpl * m_own_active_face_group
Groupe des faces actives propres.
ItemGroupImpl * m_active_face_group
Groupe des faces actives.
ItemGroupImpl * m_outer_active_face_group
Groupe des faces externes actives.
String m_name
Nom du groupe.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
Vue sur une liste pour obtenir des informations sur les entités.
Structure interne d'une entité de maillage.
Type d'une entité (Item).
Definition ItemTypeId.h:32
Gestionnaire des types d'entités de maillage.
Definition ItemTypeMng.h:66
static Integer nbBasicItemType()
nombre de types disponibles
Identifiant unique d'une entité.
Classe de base d'un élément de maillage.
Definition Item.h:83
Int16 type() const
Type de l'entité
Definition Item.h:232
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
IVariable * variable() const
Variable associé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.
constexpr bool empty() const noexcept
Retourne true si le tableau est vide (dimension nulle)
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
virtual void executeFunctor()=0
Exécute la méthode associé
Interface du gestionnaire de traces.
virtual TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium)=0
Flot pour un message de debug.
virtual TraceMessage info()=0
Flot pour un message d'information.
virtual TraceMessage fatal()=0
Flot pour un message d'erreur fatale.
Exception lorsqu'une opération n'est pas supportée.
Chaîne de caractères unicode.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
ItemGroupT< Cell > CellGroup
Groupe de mailles.
Definition ItemTypes.h:183
ItemGroupT< Face > FaceGroup
Groupe de faces.
Definition ItemTypes.h:178
ItemGroupT< Edge > EdgeGroup
Groupe d'arêtes.
Definition ItemTypes.h:173
ItemGroupT< Node > NodeGroup
Groupe de noeuds.
Definition ItemTypes.h:167
Ref< IVariableSynchronizer > createSynchronizerRef(IParallelMng *pm, IItemFamily *family)
Retourne une interface pour synchroniser des variables sur le groupe de la famille family.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
bool arcaneIsCheck()
Vrai si on est en mode vérification.
Definition Misc.cc:151
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:640
eItemKind
Genre d'entité de maillage.
@ 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_Edge
Entité de maillage de genre arête.
IItemGroupObserver * newItemGroupObserverT(T *object, typename IItemGroupObserver::FuncTraits< T >::FuncPtr funcptr)
Utilitaire pour création simplifié de ItemGroupObserverT.