Arcane  v4.1.2.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-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ItemGroupImpl.cc (C) 2000-2025 */
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/*---------------------------------------------------------------------------*/
45class ItemGroupImplNull
46: public ItemGroupImpl
47{
48 public:
49
50 ItemGroupImplNull() : ItemGroupImpl() {}
51
52 public:
53
55 const String& name() const { return m_name; }
56 const String& fullName() const { return m_name; }
57
58 public:
59
60 virtual void convert(NodeGroup& g) { g = NodeGroup(); }
61 virtual void convert(EdgeGroup& g) { g = EdgeGroup(); }
62 virtual void convert(FaceGroup& g) { g = FaceGroup(); }
63 virtual void convert(CellGroup& g) { g = CellGroup(); }
64
65 private:
66
67 String m_name;
68};
69
70/*---------------------------------------------------------------------------*/
71/*---------------------------------------------------------------------------*/
72
73ItemGroupImpl* ItemGroupImpl::shared_null = nullptr;
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77
78class ItemGroupImplItemGroupComputeFunctor
79: public ItemGroupComputeFunctor
80{
81 private:
82
83 typedef void (ItemGroupImpl::*FuncPtr)();
84
85 public:
86
87 ItemGroupImplItemGroupComputeFunctor(ItemGroupImpl* parent, FuncPtr funcPtr)
88 : ItemGroupComputeFunctor()
89 , m_parent(parent)
90 , m_function(funcPtr) { }
91
92 public:
93
94 void executeFunctor() override
95 {
96 (m_parent->*m_function)();
97 }
98
99 private:
100
101 ItemGroupImpl * m_parent;
102 FuncPtr m_function;
103};
104
105/*---------------------------------------------------------------------------*/
106/*---------------------------------------------------------------------------*/
107
108ItemGroupImpl* ItemGroupImpl::
109checkSharedNull()
110{
111 // Normalement ce test n'est vrai que si on a une instance globale
112 // de 'ItemGroup' ce qui est déconseillé. Sinon, _buildSharedNull() a été
113 // automatiquement appelé lors de l'initialisation (dans arcaneInitialize()).
114 if (!shared_null)
116 return shared_null;
117}
118
119/*---------------------------------------------------------------------------*/
120/*---------------------------------------------------------------------------*/
121
123ItemGroupImpl(IItemFamily* family,const String& name)
124: m_p (new ItemGroupInternal(family,name))
125{
126 m_p->m_sub_parts_by_type.setImpl(this);
127}
128
129/*---------------------------------------------------------------------------*/
130/*---------------------------------------------------------------------------*/
131
134: m_p(new ItemGroupInternal(family,parent,name))
135{
136 m_p->m_sub_parts_by_type.setImpl(this);
137}
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
144: m_p (new ItemGroupInternal())
145{
146 m_p->m_sub_parts_by_type.setImpl(this);
147}
148
149/*---------------------------------------------------------------------------*/
150/*---------------------------------------------------------------------------*/
151
154{
155 delete m_p;
156}
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
160
162name() const
163{
164 return m_p->name();
165}
166
167/*---------------------------------------------------------------------------*/
168/*---------------------------------------------------------------------------*/
169
171fullName() const
172{
173 return m_p->fullName();
174}
175
176/*---------------------------------------------------------------------------*/
177/*---------------------------------------------------------------------------*/
178
180size() const
181{
182 return m_p->itemsLocalId().size();
183}
184
185/*---------------------------------------------------------------------------*/
186/*---------------------------------------------------------------------------*/
187
189empty() const
190{
191 return m_p->itemsLocalId().empty();
192}
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
196
198itemsLocalId() const
199{
200 return m_p->itemsLocalId();
201}
202
203/*---------------------------------------------------------------------------*/
204/*---------------------------------------------------------------------------*/
205
208{
209 if (m_p->m_transaction_mode)
210 ARCANE_FATAL("Transaction mode already started");
211 m_p->m_transaction_mode = true;
212}
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
216
219{
220 if (!m_p->m_transaction_mode)
221 ARCANE_FATAL("Transaction mode not started");
222 m_p->m_transaction_mode = false;
223 if (m_p->m_need_recompute) {
224 m_p->m_need_recompute = false;
225 m_p->m_need_invalidate_on_recompute = false;
226 m_p->notifyInvalidateObservers();
227 }
228}
229
230/*---------------------------------------------------------------------------*/
231/*---------------------------------------------------------------------------*/
232
234unguardedItemsLocalId(const bool self_invalidate)
235{
236 ITraceMng* trace = m_p->m_mesh->traceMng();
237 trace->debug(Trace::Medium) << "ItemGroupImpl::unguardedItemsLocalId on group " << name()
238 << " with self_invalidate=" << self_invalidate;
239
240 if (m_p->m_compute_functor && !m_p->m_transaction_mode)
241 ARCANE_FATAL("Direct access for computed group in only available during a transaction");
242
243 _forceInvalidate(self_invalidate);
244 return m_p->mutableItemsLocalId();
245}
246
247/*---------------------------------------------------------------------------*/
248/*---------------------------------------------------------------------------*/
249
251parent() const
252{
253 return m_p->m_parent;
254}
255
256/*---------------------------------------------------------------------------*/
257/*---------------------------------------------------------------------------*/
258
260mesh() const
261{
262 return m_p->mesh();
263}
264
265/*---------------------------------------------------------------------------*/
266/*---------------------------------------------------------------------------*/
267
269itemFamily() const
270{
271 return m_p->m_item_family;
272}
273
274/*---------------------------------------------------------------------------*/
275/*---------------------------------------------------------------------------*/
276
278null() const
279{
280 return m_p->null();
281}
282
283/*---------------------------------------------------------------------------*/
284/*---------------------------------------------------------------------------*/
285
287isOwn() const
288{
289 return m_p->m_is_own;
290}
291
292/*---------------------------------------------------------------------------*/
293/*---------------------------------------------------------------------------*/
294
296setOwn(bool v)
297{
298 const bool is_own = m_p->m_is_own;
299 if (is_own == v)
300 return;
301 if (!is_own) {
302 if (m_p->m_own_group)
303 ARCANE_THROW(NotSupportedException,"Setting Own with 'Own' sub-group already defined");
304 }
305 else {
306 // On a le droit de remettre setOwn() à 'false' pour le groupe de toutes
307 // les entités. Cela est nécessaire en reprise si le nombre de parties
308 // du maillage est différent du IParallelMng associé à la famille
309 if (!isAllItems())
310 ARCANE_THROW(NotSupportedException,"Un-setting Own on a own group");
311 }
312 m_p->m_is_own = v;
313 // (HP) TODO: Faut il notifier des observers ?
314}
315
316/*---------------------------------------------------------------------------*/
317/*---------------------------------------------------------------------------*/
318
320itemKind() const
321{
322 return m_p->kind();
323}
324
325/*---------------------------------------------------------------------------*/
326/*---------------------------------------------------------------------------*/
327
329ownGroup()
330{
331 ItemGroupImpl* ii = m_p->m_own_group;
332 // Le flag est déjà positionné dans le ItemGroupInternal::_init ou ItemGroupImpl::setOwn
333 if (!ii) {
334 if (m_p->m_is_own){
335 ii = this;
336 m_p->m_own_group = ii;
337 } else {
338 ii = createSubGroup("Own",m_p->m_item_family,new OwnItemGroupComputeFunctor());
339 m_p->m_own_group = ii;
340 ii->setOwn(true);
341 }
342 }
343 return ii;
344}
345
346/*---------------------------------------------------------------------------*/
347/*---------------------------------------------------------------------------*/
348
351{
352 ItemGroupImpl* ii = m_p->m_ghost_group;
353 if (!ii) {
354 ii = createSubGroup("Ghost",m_p->m_item_family,new GhostItemGroupComputeFunctor());
355 m_p->m_ghost_group = ii;
356 }
357 return ii;
358}
359
360/*---------------------------------------------------------------------------*/
361/*---------------------------------------------------------------------------*/
362
363ItemGroupImpl* ItemGroupImpl::
364interfaceGroup()
365{
366 if (itemKind()!=IK_Face)
367 return checkSharedNull();
369 if (!ii) {
372 }
373 return ii;
374}
375
376/*---------------------------------------------------------------------------*/
377/*---------------------------------------------------------------------------*/
378
380nodeGroup()
381{
382 if (itemKind()==IK_Node)
383 return this;
384 ItemGroupImpl* ii = m_p->m_node_group;
385 if (!ii){
386 ii = createSubGroup("Nodes",m_p->m_mesh->nodeFamily(),new ItemItemGroupComputeFunctor<Node>());
387 m_p->m_node_group = ii;
388 }
389 return ii;
390}
391
392/*---------------------------------------------------------------------------*/
393/*---------------------------------------------------------------------------*/
394
396edgeGroup()
397{
398 if (itemKind()==IK_Edge)
399 return this;
400 ItemGroupImpl* ii = m_p->m_edge_group;
401 if (!ii){
402 ii = createSubGroup("Edges",m_p->m_mesh->edgeFamily(),new ItemItemGroupComputeFunctor<Edge>());
403 m_p->m_edge_group = ii;
404 }
405 return ii;
406}
407
408/*---------------------------------------------------------------------------*/
409/*---------------------------------------------------------------------------*/
410
412faceGroup()
413{
414 if (itemKind()==IK_Face)
415 return this;
416 ItemGroupImpl* ii = m_p->m_face_group;
417 if (!ii){
418 ii = createSubGroup("Faces",m_p->m_mesh->faceFamily(),new ItemItemGroupComputeFunctor<Face>());
419 m_p->m_face_group = ii;
420 }
421 return ii;
422}
423
424/*---------------------------------------------------------------------------*/
425/*---------------------------------------------------------------------------*/
426
428cellGroup()
429{
430 if (itemKind()==IK_Cell)
431 return this;
432 ItemGroupImpl* ii = m_p->m_cell_group;
433 if (!ii){
434 ii = createSubGroup("Cells",m_p->m_mesh->cellFamily(),new ItemItemGroupComputeFunctor<Cell>());
435 m_p->m_cell_group = ii;
436 }
437 return ii;
438}
439
440/*---------------------------------------------------------------------------*/
441/*---------------------------------------------------------------------------*/
442
445{
446 if (itemKind()!=IK_Cell)
447 return checkSharedNull();
448 ItemGroupImpl* ii = m_p->m_inner_face_group;
449 if (!ii){
450 ii = createSubGroup("InnerFaces",m_p->m_mesh->faceFamily(),
452 m_p->m_inner_face_group = ii;
453 }
454 return ii;
455}
456
457/*---------------------------------------------------------------------------*/
458/*---------------------------------------------------------------------------*/
459
462{
463 if (itemKind()!=IK_Cell)
464 return checkSharedNull();
465 ItemGroupImpl* ii = m_p->m_outer_face_group;
466 if (!ii){
467 ii = createSubGroup("OuterFaces",m_p->m_mesh->faceFamily(),
469 m_p->m_outer_face_group = ii;
470 }
471 return ii;
472}
473/*---------------------------------------------------------------------------*/
474/*---------------------------------------------------------------------------*/
476
477/*---------------------------------------------------------------------------*/
478/*---------------------------------------------------------------------------*/
479
482{
483 if (itemKind()!=IK_Cell)
484 return checkSharedNull();
485 ItemGroupImpl* ii = m_p->m_active_cell_group;
486
487 if (!ii){
488 ii = createSubGroup("ActiveCells",m_p->m_mesh->cellFamily(),
490 m_p->m_active_cell_group = ii;
491 }
492 return ii;
493}
494
495/*---------------------------------------------------------------------------*/
496/*---------------------------------------------------------------------------*/
497
500{
501 if (itemKind()!=IK_Cell)
502 return checkSharedNull();
503 ItemGroupImpl* ii = m_p->m_own_active_cell_group;
504 // Le flag est déjà positionné dans le ItemGroupInternal::_init ou ItemGroupImpl::setOwn
505 if (!ii) {
506 ii = createSubGroup("OwnActiveCells",m_p->m_mesh->cellFamily(),
508 m_p->m_own_active_cell_group = ii;
509 ii->setOwn(true);
510 }
511 return ii;
512}
513/*---------------------------------------------------------------------------*/
514/*---------------------------------------------------------------------------*/
515
517levelCellGroup(const Integer& level)
518{
519 if (itemKind()!=IK_Cell)
520 return checkSharedNull();
521 ItemGroupImpl* ii = m_p->m_level_cell_group[level];
522 if (!ii){
523 ii = createSubGroup(String::format("LevelCells{0}",level),
524 m_p->m_mesh->cellFamily(),
526 m_p->m_level_cell_group[level] = ii;
527 }
528 return ii;
529}
530
531/*---------------------------------------------------------------------------*/
532/*---------------------------------------------------------------------------*/
533
535ownLevelCellGroup(const Integer& level)
536{
537 if (itemKind()!=IK_Cell)
538 return checkSharedNull();
539 ItemGroupImpl* ii = m_p->m_own_level_cell_group[level];
540 // Le flag est déjà positionné dans le ItemGroupInternal::_init ou ItemGroupImpl::setOwn
541 if (!ii) {
542 ii = createSubGroup(String::format("OwnLevelCells{0}",level),
543 m_p->m_mesh->cellFamily(),
545 m_p->m_own_level_cell_group[level] = ii;
546 ii->setOwn(true);
547 }
548 return ii;
549}
550/*---------------------------------------------------------------------------*/
551/*---------------------------------------------------------------------------*/
552
555{
556 if (itemKind()!=IK_Cell)
557 return checkSharedNull();
558 ItemGroupImpl* ii = m_p->m_active_face_group;
559 if (!ii){
560 ii = createSubGroup("ActiveFaces",m_p->m_mesh->faceFamily(),
562 m_p->m_active_face_group = ii;
563 }
564 return ii;
565}
566
567/*---------------------------------------------------------------------------*/
568/*---------------------------------------------------------------------------*/
569
572{
573 if (itemKind()!=IK_Cell)
574 return checkSharedNull();
575 ItemGroupImpl* ii = m_p->m_own_active_face_group;
576 if (!ii){
577 ii = createSubGroup("OwnActiveFaces",m_p->m_mesh->faceFamily(),
579 m_p->m_own_active_face_group = ii;
580 }
581 return ii;
582}
583/*---------------------------------------------------------------------------*/
584/*---------------------------------------------------------------------------*/
585
588{
589 if (itemKind()!=IK_Cell)
590 return checkSharedNull();
591 ItemGroupImpl* ii = m_p->m_inner_active_face_group;
592 if (!ii){
593 ii = createSubGroup("InnerActiveFaces",m_p->m_mesh->faceFamily(),
595 m_p->m_inner_active_face_group = ii;
596 }
597 return ii;
598}
599
600/*---------------------------------------------------------------------------*/
601/*---------------------------------------------------------------------------*/
602
605{
606 if (itemKind()!=IK_Cell)
607 return checkSharedNull();
608 ItemGroupImpl* ii = m_p->m_outer_active_face_group;
609 if (!ii){
610 ii = createSubGroup("OuterActiveFaces",m_p->m_mesh->faceFamily(),
612 m_p->m_outer_active_face_group = ii;
613 }
614 return ii;
615}
616/*---------------------------------------------------------------------------*/
617/*---------------------------------------------------------------------------*/
618
620createSubGroup(const String& suffix, IItemFamily* family, ItemGroupComputeFunctor * functor)
621{
622 String sub_name = name() + "_" + suffix;
623 auto finder = m_p->m_sub_groups.find(sub_name);
624 if (finder != m_p->m_sub_groups.end()) {
625 ARCANE_FATAL("Cannot create already existing sub-group ({0}) in group ({1})",
626 suffix, name());
627 }
628 ItemGroup ig = family->createGroup(sub_name,ItemGroup(this));
629 ItemGroupImpl* ii = ig.internal();
630 ii->setComputeFunctor(functor);
631 functor->setGroup(ii);
632 // Observer par défaut : le sous groupe n'est pas intéressé par les infos détaillées de transition
635 m_p->m_sub_groups[sub_name] = ii;
636 ii->invalidate(false);
637 return ii;
638}
639
640/*---------------------------------------------------------------------------*/
641/*---------------------------------------------------------------------------*/
642
644findSubGroup(const String& suffix)
645{
646 String sub_name = name() + "_" + suffix;
647 auto finder = m_p->m_sub_groups.find(sub_name);
648 if (finder != m_p->m_sub_groups.end()) {
649 return finder->second.get();
650 }
651 else {
652 // ou bien erreur ?
653 return checkSharedNull();
654 }
655}
656
657/*---------------------------------------------------------------------------*/
658/*---------------------------------------------------------------------------*/
659
661changeIds(Int32ConstArrayView old_to_new_ids)
662{
663 ITraceMng* trace = m_p->m_mesh->traceMng();
664 if (m_p->m_compute_functor) {
665 trace->debug(Trace::High) << "ItemGroupImpl::changeIds on "
666 << name() << " : skip computed group";
667 return;
668 }
669
670 // ItemGroupImpl ne fait d'habitude pas le checkNeedUpdate lui meme, plutot le ItemGroup
672 if (isAllItems()) {
673 // Int32ArrayView items_lid = m_p->itemsLocalId();
674 // for( Integer i=0, is=items_lid.size(); i<is; ++i ) {
675 // Integer lid = items_lid[i];
676 // ARCANE_ASSERT((lid = old_to_new_ids[lid]),("Non uniform order on allItems"));;
677 // }
678 // m_p->notifyCompactObservers(&old_to_new_ids);
679 m_p->notifyInvalidateObservers();
680 return;
681 }
682
683 Int32ArrayView items_lid = m_p->itemsLocalId();
684 for( Integer i=0, is=items_lid.size(); i<is; ++i ){
685 Integer old_id = items_lid[i];
686 items_lid[i] = old_to_new_ids[old_id];
687 }
688
689 m_p->updateTimestamp();
690 // Pour l'instant, il ne faut pas trier les entités des variables
691 // partielles car les valeurs correspondantes des variables ne sont
692 // pas mises à jour (il faut implémenter changeGroupIds pour cela)
693 // NOTE: est-ce utile de le faire ?
694 // NOTE: faut-il le faire pour les autre aussi ? A priori, cela n'est
695 // utile que pour garantir le meme resultat parallele/sequentiel
696 if (m_p->m_observer_need_info) {
697 m_p->notifyCompactObservers(&old_to_new_ids);
698 } else {
699 // Pas besoin d'infos, on peut changer arbitrairement leur ordre
700 // TODO: #warning "(HP) Connexion de ce triage d'item avec la famille ?"
701 std::sort(std::begin(items_lid),std::end(items_lid));
702 m_p->notifyCompactObservers(nullptr);
703 }
704}
705
706/*---------------------------------------------------------------------------*/
707/*---------------------------------------------------------------------------*/
708
710invalidate(bool force_recompute)
711{
712#ifdef ARCANE_DEBUG
713 // if (force_recompute){
714 ITraceMng* msg = m_p->m_mesh->traceMng();
715 msg->debug(Trace::High) << "ItemGroupImpl::invalidate(force=" << force_recompute << ")"
716 << " name=" << name();
717// }
718#endif
719
720 m_p->updateTimestamp();
721 m_p->setNeedRecompute();
722 if (force_recompute)
724 m_p->notifyInvalidateObservers();
725}
726
727/*---------------------------------------------------------------------------*/
728/*---------------------------------------------------------------------------*/
729
731itemsInternal() const
732{
733 return m_p->items();
734}
735
736/*---------------------------------------------------------------------------*/
737/*---------------------------------------------------------------------------*/
738
740itemInfoListView() const
741{
742 return m_p->itemInfoListView();
743}
744
745/*---------------------------------------------------------------------------*/
746/*---------------------------------------------------------------------------*/
747
749isLocalToSubDomain() const
750{
751 return m_p->m_is_local_to_sub_domain;
752}
753
754/*---------------------------------------------------------------------------*/
755/*---------------------------------------------------------------------------*/
756
759{
760 m_p->m_is_local_to_sub_domain = v;
761}
762
763/*---------------------------------------------------------------------------*/
764/*---------------------------------------------------------------------------*/
765
767addItems(Int32ConstArrayView items_local_id,bool check_if_present)
768{
769 ARCANE_ASSERT(( (!m_p->m_need_recompute && !isAllItems()) || (m_p->m_transaction_mode && isAllItems()) ),
770 ("Operation on invalid group"));
771 if (m_p->m_compute_functor && !m_p->m_transaction_mode)
772 ARCANE_FATAL("Cannot add items on computed group ({0})", name());
773 IMesh* amesh = mesh();
774 if (!amesh)
775 throw ArgumentException(A_FUNCINFO,"null group");
776 ITraceMng* trace = amesh->traceMng();
777
778 Integer nb_item_to_add = items_local_id.size();
779 if (nb_item_to_add==0)
780 return;
781
782 Int32Array& items_lid = m_p->mutableItemsLocalId();
783 const Integer current_size = items_lid.size();
784 Integer nb_added = 0;
785
786 if(isAllItems()) {
787 // Ajoute les nouveaux items à la fin
788 Integer nb_items_id = current_size;
789 m_p->m_items_index_in_all_group.resize(m_p->maxLocalId());
790 for( Integer i=0, is=nb_item_to_add; i<is; ++i ){
791 Int32 local_id = items_local_id[i];
792 items_lid.add(local_id);
793 m_p->m_items_index_in_all_group[local_id] = nb_items_id+i;
794 }
795 nb_added = nb_item_to_add;
796 }
797 else if (check_if_present) {
798 // Vérifie que les entités à ajouter ne sont pas déjà présentes
799 UniqueArray<bool> presence_checks(m_p->maxLocalId());
800 presence_checks.fill(false);
801 for( Integer i=0, is=items_lid.size(); i<is; ++i ){
802 presence_checks[items_lid[i]] = true;
803 }
804
805 for( Integer i=0; i<nb_item_to_add; ++i ) {
806 const Integer lid = items_local_id[i];
807 if (!presence_checks[lid]){
808 items_lid.add(lid);
809 // Met à \a true comme cela si l'entité est présente plusieurs fois
810 // dans \a items_local_id cela fonctionne quand même.
811 presence_checks[lid] = true;
812 ++nb_added;
813 }
814 }
815 }
816 else {
817 nb_added = nb_item_to_add;
818 MemoryUtils::checkResizeArrayWithCapacity(items_lid,current_size+nb_added,false);
819 SmallSpan<Int32> ptr = items_lid.subView(current_size,nb_added);
820 MemoryUtils::copy<Int32>(ptr, items_local_id);
821 }
822
823 if (arcaneIsCheck()){
824 trace->info(5) << "ItemGroupImpl::addItems() group <" << name() << "> "
825 << " checkpresent=" << check_if_present
826 << " nb_current=" << current_size
827 << " want_to_add=" << nb_item_to_add
828 << " effective_added=" << nb_added;
829 checkValid();
830 }
831
832 if (nb_added!=0) {
833 m_p->updateTimestamp();
834 Int32ConstArrayView observation_info(nb_added, items_lid.unguardedBasePointer()+current_size);
835 m_p->notifyExtendObservers(&observation_info);
836 }
837}
838
839/*---------------------------------------------------------------------------*/
840/*---------------------------------------------------------------------------*/
841
843removeItems(Int32ConstArrayView items_local_id,[[maybe_unused]] bool check_if_present)
844{
845 m_p->_removeItems(items_local_id);
846}
847
848/*---------------------------------------------------------------------------*/
849/*---------------------------------------------------------------------------*/
850
852removeAddItems(Int32ConstArrayView removed_items_lids,
853 Int32ConstArrayView added_items_lids,
854 bool check_if_present)
855{
856 ARCANE_ASSERT(( (!m_p->m_need_recompute && !isAllItems()) || (m_p->m_transaction_mode && isAllItems()) ),
857 ("Operation on invalid group"));
858 if (m_p->m_compute_functor && !m_p->m_transaction_mode)
859 ARCANE_FATAL("Cannot remove items on computed group ({0})", name());
860 IMesh* amesh = mesh();
861 if (!amesh)
862 throw ArgumentException(A_FUNCINFO,"null group");
863 ITraceMng* trace = amesh->traceMng();
864 if (isOwn() && amesh->meshPartInfo().nbPart()!=1){
865 ARCANE_THROW(NotSupportedException,"Cannot remove items if isOwn() is true");
866 }
867
868 Int32Array & items_lid = m_p->mutableItemsLocalId();
869
870 if(isAllItems()) {
871 ItemInternalList internals = itemsInternal();
872 const Integer internal_size = internals.size();
873 const Integer new_size = m_p->m_item_family->nbItem();
874 items_lid.resize(new_size);
875 m_p->m_items_index_in_all_group.resize(m_p->maxLocalId());
876 if (new_size==internal_size){
877 // Il n'y a pas de trous dans la numérotation
878 for( Integer i=0; i<internal_size; ++i ){
879 Int32 local_id = internals[i]->localId();
880 items_lid[i] = local_id;
881 m_p->m_items_index_in_all_group[local_id] = i;
882 }
883 }
884 else{
885 Integer index = 0;
886 for( Integer i=0; i<internal_size; ++i ){
887 ItemInternal* item = internals[i];
888 if (!item->isSuppressed()){
889 Int32 local_id = item->localId();
890 items_lid[index] = local_id;
891 m_p->m_items_index_in_all_group[local_id] = index;
892 ++index;
893 }
894 }
895 if (index!=new_size)
896 ARCANE_FATAL("Inconsistent number of elements in the generation of the group '{0}' expected={1} present={2}",
897 name(), new_size, index);
898 }
899
900 // On ne peut pas savoir ce qui a changé donc dans le doute on
901 // incrémente le timestamp.
902 m_p->updateTimestamp();
903 }
904 else {
905 removeItems(removed_items_lids,check_if_present);
906 addItems(added_items_lids,check_if_present);
907 }
908
909 if(arcaneIsCheck()){
910 trace->info(5) << "ItemGroupImpl::removeAddItems() group <" << name() << "> "
911 << " old_size=" << m_p->m_item_family->nbItem()
912 << " new_size=" << size()
913 << " nb_removed=" << removed_items_lids.size()
914 << " nb_added=" << added_items_lids.size();
915 checkValid();
916 }
917}
918
919
920/*---------------------------------------------------------------------------*/
921/*---------------------------------------------------------------------------*/
922
924setItems(Int32ConstArrayView items_local_id)
925{
926 if (m_p->m_compute_functor && !m_p->m_transaction_mode)
927 ARCANE_FATAL("Cannot set items on computed group ({0})", name());
928 Int32Array& buf = m_p->mutableItemsLocalId();
929 buf.resize(items_local_id.size());
930 Int32ArrayView buf_view(buf);
931 buf_view.copy(items_local_id);
932 m_p->updateTimestamp();
933 m_p->m_need_recompute = false;
934 if (arcaneIsCheck()){
935 ITraceMng* trace = m_p->mesh()->traceMng();
936 trace->debug(Trace::High) << "ItemGroupImpl::setItems() group <" << name() << "> "
937 << " size=" << size();
938 checkValid();
939 }
940
941 // On tolére encore le setItems initial en le convertissant en un addItems
942 if (size() != 0)
943 m_p->notifyInvalidateObservers();
944 else
945 m_p->notifyExtendObservers(&items_local_id);
946}
947
948/*---------------------------------------------------------------------------*/
949/*---------------------------------------------------------------------------*/
950
952{
953 public:
954 ItemSorter(ItemInfoListView items) : m_items(items){}
955 public:
956 void sort(Int32ArrayView local_ids) const
957 {
958 std::sort(std::begin(local_ids),std::end(local_ids),*this);
959 }
960 bool operator()(Int32 lid1,Int32 lid2) const
961 {
962 return m_items[lid1].uniqueId() < m_items[lid2].uniqueId();
963 }
964 private:
965 ItemInfoListView m_items;
966};
967
968/*---------------------------------------------------------------------------*/
969/*---------------------------------------------------------------------------*/
970
972setItems(Int32ConstArrayView items_local_id,bool do_sort)
973{
974 if (!do_sort){
975 setItems(items_local_id);
976 return;
977 }
978 UniqueArray<Int32> sorted_lid(items_local_id);
980 sorter.sort(sorted_lid);
981 setItems(sorted_lid);
982}
983
984/*---------------------------------------------------------------------------*/
985/*---------------------------------------------------------------------------*/
986
989{
990 m_p->m_is_all_items = true;
991}
992
993/*---------------------------------------------------------------------------*/
994/*---------------------------------------------------------------------------*/
995
997isAllItems() const
998{
999 return m_p->m_is_all_items;
1000}
1001
1002/*---------------------------------------------------------------------------*/
1003/*---------------------------------------------------------------------------*/
1004
1005class ItemCheckSuppressedFunctor
1006{
1007 public:
1008 ItemCheckSuppressedFunctor(ItemInternalList items)
1009 : m_items(items)
1010 {
1011 }
1012 public:
1013 bool operator()(Integer item_lid)
1014 {
1015 return m_items[item_lid]->isSuppressed();
1016 }
1017 private:
1018 ItemInternalList m_items;
1019};
1020
1021/*---------------------------------------------------------------------------*/
1022/*---------------------------------------------------------------------------*/
1023
1026{
1027 // TODO: (HP) Assertion need fix"
1028 // ARCANE_ASSERT((!m_p->m_need_recompute),("Operation on invalid group"));
1029 ITraceMng* trace = m_p->mesh()->traceMng();
1030 if (m_p->m_compute_functor) {
1031 trace->debug(Trace::High) << "ItemGroupImpl::removeSuppressedItems on " << name() << " : skip computed group";
1032 return;
1033 }
1034
1035 ItemInternalList items = m_p->items();
1036 Integer nb_item = items.size();
1037 Int32Array& items_lid = m_p->mutableItemsLocalId();
1038 Integer current_size = items_lid.size();
1039 if (arcaneIsCheck()){
1040 for( Integer i=0; i<current_size; ++i ){
1041 if (items_lid[i]>=nb_item){
1042 trace->fatal() << "ItemGroupImpl::removeSuppressedItems(): bad range "
1043 << " name=" << name()
1044 << " i=" << i << " lid=" << items_lid[i]
1045 << " max=" << nb_item;
1046 }
1047 }
1048 }
1049
1050 Int32UniqueArray removed_ids, removed_lids;
1051 Int32ConstArrayView * observation_info = NULL;
1052 Int32ConstArrayView * observation_info2 = NULL;
1053 Integer new_size;
1054 // Si le groupe posséde des observers ayant besoin d'info, il faut les calculer
1055 if (m_p->m_observer_need_info){
1056 removed_ids.reserve(current_size); // préparation à taille max
1057 Integer index = 0;
1058 for( Integer i=0; i<current_size; ++i ){
1059 if (!items[items_lid[i]]->isSuppressed()){
1060 items_lid[index] = items_lid[i];
1061 ++index;
1062 } else {
1063 // trace->debug(Trace::Highest) << "Remove from group " << name() << " item " << i << " " << items_lid[i] << " " << ItemPrinter(items[items_lid[i]]);
1064 removed_lids.add(items_lid[i]);
1065 }
1066 }
1067 new_size = index;
1068 if (new_size!=current_size){
1069 items_lid.resize(new_size);
1070 observation_info = new Int32ConstArrayView(removed_lids.size(), removed_lids.unguardedBasePointer());
1071 }
1072 }
1073 else{
1074 ItemCheckSuppressedFunctor f(m_p->items());
1075 auto ibegin = std::begin(items_lid);
1076 auto new_end = std::remove_if(ibegin,std::end(items_lid),f);
1077 new_size = (Integer)(new_end-ibegin);
1078 items_lid.resize(new_size);
1079 }
1080
1081 if (arcaneIsCheck()) {
1082 trace->debug(Trace::High) << "ItemGroupImpl::removeSupressedItems() group <" << name()
1083 << "> NEW SIZE=" << new_size << " OLD=" << current_size;
1084 checkValid();
1085 }
1086
1087 // Ne met à jour que si le groupe a été modifié
1088 if (current_size != new_size) {
1089 m_p->updateTimestamp();
1090 m_p->notifyReduceObservers(observation_info);
1091 delete observation_info;
1092 delete observation_info2;
1093 }
1094}
1095
1096/*---------------------------------------------------------------------------*/
1097/*---------------------------------------------------------------------------*/
1098
1100checkValid()
1101{
1102 m_p->checkValid();
1103}
1104
1105/*---------------------------------------------------------------------------*/
1106/*---------------------------------------------------------------------------*/
1107
1108bool ItemGroupImpl::
1109_checkNeedUpdate(bool do_padding)
1110{
1111 // NOTE: l'utilisation de verrou est pour l'instant expérimentale (juin 2025)
1112 // On met le verrou sur toute la méthode pour que ce soit plus simple, mais
1113 // on pourrait ne le faire qu'après vérification que la mise à jour
1114 // est vraiment utile.
1116
1117 // En cas de problème sur des re-calculs très imbriqués, une proposition est
1118 // de désactiver les lignes #A pour activer les lignes #B
1119 bool has_recompute = false;
1120 if (m_p->m_need_recompute) {
1121 m_p->m_need_recompute = false;
1122 // bool need_invalidate_on_recompute = m_p->m_need_invalidate_on_recompute; // #B
1123 // m_p->m_need_invalidate_on_recompute = false; // #B
1124 if (m_p->m_compute_functor) {
1126 }
1127 // if (need_invalidate_on_recompute) { // #B
1128 // m_p->notifyInvalidateObservers(); // #B
1129 // } // #B
1130
1132 m_p->m_need_invalidate_on_recompute = false; // #A
1133 m_p->notifyInvalidateObservers(); // #A
1134 } // #A
1135 has_recompute = true;
1136 }
1137 if (do_padding)
1138 _checkUpdateSimdPadding();
1139 return has_recompute;
1140}
1141
1142/*---------------------------------------------------------------------------*/
1143/*---------------------------------------------------------------------------*/
1144
1145bool ItemGroupImpl::
1146_checkNeedUpdateNoPadding()
1147{
1148 return _checkNeedUpdate(false);
1149}
1150
1151/*---------------------------------------------------------------------------*/
1152/*---------------------------------------------------------------------------*/
1153
1154bool ItemGroupImpl::
1155_checkNeedUpdateWithPadding()
1156{
1157 return _checkNeedUpdate(true);
1158}
1159
1160/*---------------------------------------------------------------------------*/
1161/*---------------------------------------------------------------------------*/
1162
1165{
1166 return _checkNeedUpdate(false);
1167}
1168
1169/*---------------------------------------------------------------------------*/
1170/*---------------------------------------------------------------------------*/
1171
1172void ItemGroupImpl::
1173_checkUpdateSimdPadding()
1174{
1176}
1177
1178/*---------------------------------------------------------------------------*/
1179/*---------------------------------------------------------------------------*/
1180
1182clear()
1183{
1184 Int32Array& items_lid = m_p->mutableItemsLocalId();
1185 if (!items_lid.empty())
1186 // Incrémente uniquement si le groupe n'est pas déjà vide
1187 m_p->updateTimestamp();
1188 items_lid.clear();
1189 m_p->m_need_recompute = false;
1190 for( const auto& i : m_p->m_sub_groups )
1191 i.second->clear();
1192 m_p->notifyInvalidateObservers();
1193}
1194
1195/*---------------------------------------------------------------------------*/
1196/*---------------------------------------------------------------------------*/
1197
1200{
1201 if (m_p->m_parent)
1202 return ItemGroup(m_p->m_parent);
1203 return ItemGroup();
1204}
1205
1206/*---------------------------------------------------------------------------*/
1207/*---------------------------------------------------------------------------*/
1208
1211{
1212 ARCANE_ASSERT((!m_p->m_need_recompute),("Operation on invalid group"));
1213 m_p->m_sub_parts_by_type.applyOperation(operation);
1214}
1215
1216void ItemGroupSubPartsByType::
1217applyOperation(IItemOperationByBasicType* operation)
1218{
1219 bool is_verbose = m_is_debug_apply_operation;
1220
1221 ITraceMng* tm = m_group_internal->mesh()->traceMng();
1222 if (is_verbose)
1223 tm->info() << "applyOperation name=" << m_group_internal->name() << " nb_item=" << m_group_internal->nbItem();
1224 if (isUseV2ForApplyOperation()) {
1225 if (m_children_by_type_ids.empty()) {
1226 _initChildrenByTypeV2();
1227 }
1228 Int64 t = m_group_internal->timestamp();
1229 if (is_verbose)
1230 tm->info() << "applyOperation timestamp=" << t << " last=" << m_children_by_type_ids_computed_timestamp;
1232 _computeChildrenByTypeV2();
1234 }
1235 }
1236 else {
1237 if (m_children_by_type.empty())
1238 _initChildrenByTypeV1();
1239 }
1240 IItemFamily* family = m_group_internal->m_item_family;
1241 const bool has_only_one_type = (m_unique_children_type != IT_NullType);
1242 if (is_verbose)
1243 tm->info() << "applyOperation has_only_one_type=" << has_only_one_type << " value=" << m_unique_children_type;
1244 // TODO: Supprimer la macro et la remplacer par une fonction.
1245
1246#define APPLY_OPERATION_ON_TYPE(ITEM_TYPE) \
1247 if (isUseV2ForApplyOperation()) { \
1248 Int16 type_id = IT_##ITEM_TYPE; \
1249 Int32ConstArrayView sub_ids = m_children_by_type_ids[type_id]; \
1250 if (has_only_one_type && type_id == m_unique_children_type) \
1251 sub_ids = m_group_internal->itemsLocalId(); \
1252 if (is_verbose && sub_ids.size()>0) \
1253 tm->info() << "Type=" << (int)IT_##ITEM_TYPE << " nb=" << sub_ids.size(); \
1254 if (sub_ids.size()!=0){\
1255 operation->apply##ITEM_TYPE(family->view(sub_ids)); \
1256 } \
1257 } \
1258 else { \
1259 ItemGroup group(m_children_by_type[IT_##ITEM_TYPE]); \
1260 if (!group.empty()) \
1261 operation->apply##ITEM_TYPE(group.view()); \
1262 }
1263
1264 APPLY_OPERATION_ON_TYPE(Vertex);
1265 APPLY_OPERATION_ON_TYPE(Line2);
1266 APPLY_OPERATION_ON_TYPE(Triangle3);
1267 APPLY_OPERATION_ON_TYPE(Quad4);
1268 APPLY_OPERATION_ON_TYPE(Pentagon5);
1269 APPLY_OPERATION_ON_TYPE(Hexagon6);
1270 APPLY_OPERATION_ON_TYPE(Tetraedron4);
1271 APPLY_OPERATION_ON_TYPE(Pyramid5);
1272 APPLY_OPERATION_ON_TYPE(Pentaedron6);
1273 APPLY_OPERATION_ON_TYPE(Hexaedron8);
1274 APPLY_OPERATION_ON_TYPE(Heptaedron10);
1275 APPLY_OPERATION_ON_TYPE(Octaedron12);
1276 APPLY_OPERATION_ON_TYPE(HemiHexa7);
1277 APPLY_OPERATION_ON_TYPE(HemiHexa6);
1278 APPLY_OPERATION_ON_TYPE(HemiHexa5);
1279 APPLY_OPERATION_ON_TYPE(HemiHexa7);
1280 APPLY_OPERATION_ON_TYPE(AntiWedgeLeft6);
1281 APPLY_OPERATION_ON_TYPE(AntiWedgeRight6);
1282 APPLY_OPERATION_ON_TYPE(DiTetra5);
1283 APPLY_OPERATION_ON_TYPE(DualNode);
1284 APPLY_OPERATION_ON_TYPE(DualEdge);
1285 APPLY_OPERATION_ON_TYPE(DualFace);
1286 APPLY_OPERATION_ON_TYPE(DualCell);
1287 APPLY_OPERATION_ON_TYPE(Link);
1288
1289#undef APPLY_OPERATION_ON_TYPE
1290}
1291
1292/*---------------------------------------------------------------------------*/
1293/*---------------------------------------------------------------------------*/
1294
1296needSynchronization() const
1297{
1298 return !(m_p->m_compute_functor != 0 ||
1299 m_p->m_is_local_to_sub_domain ||
1300 m_p->m_is_own);
1301}
1302
1303/*---------------------------------------------------------------------------*/
1304/*---------------------------------------------------------------------------*/
1305
1307timestamp() const
1308{
1309 return m_p->timestamp();
1310}
1311
1312/*---------------------------------------------------------------------------*/
1313/*---------------------------------------------------------------------------*/
1314
1316attachObserver(const void * ref, IItemGroupObserver * obs)
1317{
1318 auto finder = m_p->m_observers.find(ref);
1319 auto end = m_p->m_observers.end();
1320 if (finder != end) {
1321 delete finder->second;
1322 finder->second = obs;
1323 return;
1324 }
1325 else {
1326 m_p->m_observers[ref] = obs;
1327 }
1328
1329 // Mise à jour du flag de demande d'info
1330 _updateNeedInfoFlag(m_p->m_observer_need_info | obs->needInfo());
1331}
1332
1333/*---------------------------------------------------------------------------*/
1334/*---------------------------------------------------------------------------*/
1335
1337detachObserver(const void * ref)
1338{
1339 auto finder = m_p->m_observers.find(ref);
1340 auto end = m_p->m_observers.end();
1341
1342 if (finder == end)
1343 return;
1344
1345 IItemGroupObserver * obs = finder->second;
1346 delete obs;
1347 m_p->m_observers.erase(finder);
1348 // Mise à jour du flag de demande d'info
1349 bool new_observer_need_info = false;
1350 auto i = m_p->m_observers.begin();
1351 for( ; i != end ; ++i ) {
1352 IItemGroupObserver * obs = i->second;
1353 new_observer_need_info |= obs->needInfo();
1354 }
1355 _updateNeedInfoFlag(new_observer_need_info);
1356
1357 // On invalide la table de hachage éventuelle
1358 // des variables partielles si il n'y a plus
1359 // de référence.
1360 if(m_p->m_group_index_table.isUsed() && m_p->m_group_index_table.isUnique()) {
1361 m_p->m_group_index_table.reset();
1362 m_p->m_synchronizer.reset();
1363 }
1364}
1365
1366/*---------------------------------------------------------------------------*/
1367/*---------------------------------------------------------------------------*/
1368
1370hasInfoObserver() const
1371{
1372 return m_p->m_observer_need_info;
1373}
1374
1375/*---------------------------------------------------------------------------*/
1376/*---------------------------------------------------------------------------*/
1377
1380{
1381 delete m_p->m_compute_functor;
1382 m_p->m_compute_functor = functor;
1383}
1384
1385/*---------------------------------------------------------------------------*/
1386/*---------------------------------------------------------------------------*/
1387
1389hasComputeFunctor() const
1390{
1391 return (m_p->m_compute_functor);
1392}
1393
1394/*---------------------------------------------------------------------------*/
1395/*---------------------------------------------------------------------------*/
1396
1399{
1400 m_p->m_sub_parts_by_type._computeChildrenByTypeV1();
1401}
1402
1403/*---------------------------------------------------------------------------*/
1404/*---------------------------------------------------------------------------*/
1405
1406void ItemGroupSubPartsByType::
1407_computeChildrenByTypeV1()
1408{
1409 ItemGroup that_group(m_group_impl);
1410 ITraceMng * trace = that_group.mesh()->traceMng();
1411 trace->debug(Trace::High) << "ItemGroupImpl::_computeChildrenByType for " << m_group_internal->name();
1412
1413 Integer nb_basic_item_type = ItemTypeMng::nbBasicItemType();
1414
1415 UniqueArray< SharedArray<Int32> > items_by_type(nb_basic_item_type);
1416 for (Integer i = 0; i < nb_basic_item_type; ++i) {
1418 impl->beginTransaction();
1419 }
1420
1421 ENUMERATE_ (Item, iitem, that_group) {
1422 Item item = *iitem;
1423 Integer item_type = item.type();
1424 if (item_type<nb_basic_item_type)
1425 items_by_type[item_type].add(iitem.itemLocalId());
1426 }
1427
1428 for (Integer i = 0; i < nb_basic_item_type; ++i) {
1429 ItemGroupImpl* impl = m_children_by_type[i];
1430 impl->setItems(items_by_type[i]);
1431 impl->endTransaction();
1432 }
1433}
1434
1435/*---------------------------------------------------------------------------*/
1436/*---------------------------------------------------------------------------*/
1437
1438
1439/*---------------------------------------------------------------------------*/
1440/*---------------------------------------------------------------------------*/
1441
1444{
1445 ARCANE_UNUSED(info);
1446 // On ne sait encore calculer appliquer des transformations à des groupes calculés
1447 // On choisit l'invalidation systématique
1448 m_p->notifyInvalidateObservers();
1449}
1450
1451/*---------------------------------------------------------------------------*/
1452/*---------------------------------------------------------------------------*/
1453
1456{
1457 ARCANE_UNUSED(info);
1458 // On ne sait encore calculer appliquer des transformations à des groupes calculés
1459 // On choisit l'invalidation systématique
1460 m_p->notifyInvalidateObservers();
1461}
1462
1463/*---------------------------------------------------------------------------*/
1464/*---------------------------------------------------------------------------*/
1465
1468{
1469 ARCANE_UNUSED(info);
1470 // On ne sait encore calculer appliquer des transformations à des groupes calculés
1471 // On choisit l'invalidation systématique en différé (évaluée lors du prochain checkNeedUpdate)
1472 m_p->notifyInvalidateObservers();
1473}
1474
1475/*---------------------------------------------------------------------------*/
1476/*---------------------------------------------------------------------------*/
1477
1480{
1481 m_p->setNeedRecompute();
1482 m_p->notifyInvalidateObservers();
1483}
1484
1485/*---------------------------------------------------------------------------*/
1486/*---------------------------------------------------------------------------*/
1487
1489_updateNeedInfoFlag(const bool flag)
1490{
1491 if (m_p->m_observer_need_info == flag)
1492 return;
1493 m_p->m_observer_need_info = flag;
1494 // Si change, change aussi l'observer du parent pour qu'il adapte les besoins en info de transition
1495 ItemGroupImpl * parent = m_p->m_parent;
1496 if (parent) {
1497 parent->detachObserver(this);
1498 if (m_p->m_observer_need_info) {
1499 parent->attachObserver(this,newItemGroupObserverT(this,
1504 } else {
1505 parent->attachObserver(this,newItemGroupObserverT(this,
1507 }
1508 }
1509}
1510
1511/*---------------------------------------------------------------------------*/
1512/*---------------------------------------------------------------------------*/
1513
1515_forceInvalidate(const bool self_invalidate)
1516{
1517 // (HP) TODO: Mettre un observer forceInvalidate pour prévenir tout le monde ?
1518 // avec forceInvalidate on doit invalider mais ne rien calculer
1519 if (self_invalidate) {
1520 m_p->setNeedRecompute();
1521 m_p->m_need_invalidate_on_recompute = true;
1522 }
1523
1524 for( const auto& i : m_p->m_sub_groups )
1525 i.second->_forceInvalidate(true);
1526}
1527
1528/*---------------------------------------------------------------------------*/
1529/*---------------------------------------------------------------------------*/
1530
1532destroy()
1533{
1534 // Détache les observateurs. Cela modifie \a m_observers donc il faut
1535 // en faire une copie
1536 {
1537 std::vector<const void*> ptrs;
1538 for( const auto& i : m_p->m_observers )
1539 ptrs.push_back(i.first);
1540 for( const void* i : ptrs )
1541 detachObserver(i);
1542 }
1543
1544 // Le groupe de toutes les entités est spécial. Il ne faut jamais le détruire
1545 // vraiement.
1546 if (m_p->m_is_all_items)
1547 m_p->resetSubGroups();
1548 else{
1549 delete m_p;
1550 m_p = new ItemGroupInternal();
1551 }
1552}
1553
1554/*---------------------------------------------------------------------------*/
1555/*---------------------------------------------------------------------------*/
1556
1559{
1560 if(!m_p->m_group_index_table.isUsed()) {
1561 m_p->m_group_index_table = SharedPtrT<GroupIndexTable>(new GroupIndexTable(this));
1562 ITraceMng* trace = m_p->m_mesh->traceMng();
1563 trace->debug(Trace::High) << "** CREATION OF LOCAL ID TO INDEX TABLE OF GROUP : " << m_p->m_name;
1564 m_p->m_group_index_table->update();
1565 }
1566 return m_p->m_group_index_table;
1567}
1568
1569/*---------------------------------------------------------------------------*/
1570/*---------------------------------------------------------------------------*/
1571
1574{
1575 if(!m_p->m_synchronizer.get()) {
1576 IParallelMng* pm = m_p->m_mesh->parallelMng();
1577 ItemGroup this_group(this);
1578 m_p->m_synchronizer = ParallelMngUtils::createSynchronizerRef(pm,this_group);
1579 ITraceMng* trace = m_p->m_mesh->traceMng();
1580 trace->debug(Trace::High) << "** CREATION OF SYNCHRONIZER OF GROUP : " << m_p->m_name;
1581 m_p->m_synchronizer->compute();
1582 }
1583 return m_p->m_synchronizer.get();
1584}
1585
1586/*---------------------------------------------------------------------------*/
1587/*---------------------------------------------------------------------------*/
1588
1591{
1592 return m_p->m_synchronizer.get();
1593}
1594
1595/*---------------------------------------------------------------------------*/
1596/*---------------------------------------------------------------------------*/
1597
1599checkIsSorted() const
1600{
1601 if (null())
1602 return true;
1603
1604 // TODO: stocker l'info dans un flag et ne refaire le test que si
1605 // la liste des entités a changer (utiliser timestamp()).
1606 ItemInternalList items(m_p->items());
1607 Int32ConstArrayView items_lid(m_p->itemsLocalId());
1608 Integer nb_item = items_lid.size();
1609 // On est toujours trié si une seule entité ou moins.
1610 if (nb_item<=1)
1611 return true;
1612 // Compare chaque uniqueId() avec le précédent et vérifie qu'il est
1613 // supérieur.
1614 ItemUniqueId last_uid = items[items_lid[0]]->uniqueId();
1615 for( Integer i=1; i<nb_item; ++i ){
1616 ItemUniqueId uid = items[items_lid[i]]->uniqueId();
1617 if (uid<last_uid)
1618 return false;
1619 last_uid = uid;
1620 }
1621 return true;
1622}
1623
1624/*---------------------------------------------------------------------------*/
1625/*---------------------------------------------------------------------------*/
1626
1628deleteMe()
1629{
1630 // S'il s'agit de 'shared_null'. Il faut le positionner à nullptr pour qu'il
1631 // soit réalloué éventuellement par _buildSharedNull().
1632 if (this==shared_null){
1633 shared_null = nullptr;
1634 }
1635 delete this;
1636}
1637
1638/*---------------------------------------------------------------------------*/
1639/*---------------------------------------------------------------------------*/
1640
1643{
1644 if (!shared_null){
1645 shared_null = new ItemGroupImplNull();
1646 shared_null->addRef();
1647 }
1648}
1649
1650/*---------------------------------------------------------------------------*/
1651/*---------------------------------------------------------------------------*/
1652
1655{
1656 // Supprime une référence à 'shared_null'. Si le nombre de référence
1657 // devient égal à 0, alors l'instance 'shared_null' est détruite.
1658 if (shared_null)
1659 shared_null->removeRef();
1660}
1661
1662/*---------------------------------------------------------------------------*/
1663/*---------------------------------------------------------------------------*/
1664
1667{
1668 return m_p->isContiguous();
1669}
1670
1671/*---------------------------------------------------------------------------*/
1672/*---------------------------------------------------------------------------*/
1673
1676{
1677 m_p->checkIsContiguous();
1678}
1679
1680/*---------------------------------------------------------------------------*/
1681/*---------------------------------------------------------------------------*/
1682
1684capacity() const
1685{
1686 Int32Array& items_lid = m_p->mutableItemsLocalId();
1687 return items_lid.capacity();
1688}
1689
1690/*---------------------------------------------------------------------------*/
1691/*---------------------------------------------------------------------------*/
1692
1695{
1696 if (hasComputeFunctor()){
1697 // Groupe calculé. On l'invalide et on supprime ses éléments
1698 invalidate(false);
1699 m_p->mutableItemsLocalId().clear();
1700 }
1701
1702 if (m_p->variableItemsLocalid())
1703 m_p->variableItemsLocalid()->variable()->shrinkMemory();
1704 else
1705 m_p->mutableItemsLocalId().shrink();
1706
1707 m_p->applySimdPadding();
1708}
1709
1710/*---------------------------------------------------------------------------*/
1711/*---------------------------------------------------------------------------*/
1712
1714_internalApi() const
1715{
1716 return &m_p->m_internal_api;
1717}
1718
1719
1720/*---------------------------------------------------------------------------*/
1721/*---------------------------------------------------------------------------*/
1722
1723//TODO a supprimer lorsque la V1 ne sera plus disponible
1724void ItemGroupSubPartsByType::
1725_initChildrenByTypeV1()
1726{
1727 IItemFamily* family = m_group_internal->m_item_family;
1728 ItemTypeMng* type_mng = family->mesh()->itemTypeMng();
1729 Integer nb_basic_item_type = ItemTypeMng::nbBasicItemType(); //NB_BASIC_ITEM_TYPE
1730 m_children_by_type.resize(nb_basic_item_type);
1731 for (Integer i = 0; i < nb_basic_item_type; ++i) {
1732 String child_name(type_mng->typeName(i));
1734 ItemGroupImpl* igi = m_group_impl->createSubGroup(child_name, family, functor);
1735 m_children_by_type[i] = igi;
1736 }
1737}
1738
1739/*---------------------------------------------------------------------------*/
1740/*---------------------------------------------------------------------------*/
1741
1742} // End namespace Arcane
1743
1744/*---------------------------------------------------------------------------*/
1745/*---------------------------------------------------------------------------*/
#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é
Integer capacity() const
Capacité (nombre d'éléments alloués) du vecteur.
Integer size() const
Nombre d'éléments du vecteur.
bool empty() const
Capacité (nombre d'éléments alloués) du vecteur.
Exception lorsqu'un argument est invalide.
void copy(const U &copy_array)
Recopie le tableau copy_array dans l'instance.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
void fill(const DataType &data)
Remplissage du tableau.
void clear()
Supprime les éléments du tableau.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
ArrayView< T > subView(Int64 abegin, Integer asize)
Sous-vue à partir de l'élément abegin et contenant asize éléments.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Classe de base d'une table de hachage entre les items d'un groupe et leurs positions dans la table.
virtual void executeFunctor()=0
Exécute la méthode associé
Interface d'une famille d'entités.
Definition IItemFamily.h:84
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 IMesh * mesh() const =0
Maillage associé
virtual bool needInfo() const =0
Indique si l'observer aura besoin d'information de transition.
Interface d'un opérateur sur des entités rangées par type.
virtual ITraceMng * traceMng()=0
Gestionnaire de message associé
virtual ItemTypeMng * itemTypeMng() const =0
Gestionnaire de types d'entités associé
virtual const MeshPartInfo & meshPartInfo() const =0
Informations sur les parties du maillage.
Interface du gestionnaire de parallélisme pour un sous-domaine.
Interface du gestionnaire de traces.
virtual TraceMessage fatal()=0
Flot pour un message d'erreur fatale.
virtual TraceMessage info()=0
Flot pour un message d'information.
virtual TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium)=0
Flot pour un message de debug.
Interface d'un service de synchronisation de variable.
bool isSuppressed() const
Vrai si l'entité est supprimée.
Int32 localId() const
Numéro local (au sous-domaine) de l'entité
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.
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é
void checkLocalIdsAreContiguous() const
Vérifie si les entités du groupe ont des localIds() contigüs.
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)
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.
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.
bool isContiguousLocalIds() const
Indique 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.
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 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_interface_group
Items on the boundary of two subdomains.
bool m_need_invalidate_on_recompute
Vrai si l'on doit activer les invalidate observers en cas de recalcul.
bool m_need_recompute
Vrai si le groupe doit être recalculé
void checkUpdateSimdPadding()
Remplit les derniers éléments du groupe pour avoir un vecteur SIMD complet.
IItemFamily * m_item_family
Famille associée.
IFunctor * m_compute_functor
Fonction de calcul du groupe.
CheckNeedUpdateMutex m_check_need_update_mutex
Mutex pour protéger la mise à jour.
ItemGroupImpl * m_group_impl
A supprimer quand la version V1 sera supprimée.
UniqueArray< UniqueArray< Int32 > > m_children_by_type_ids
Liste des localId() par type d'entité.
Int64 m_children_by_type_ids_computed_timestamp
Timestamp indiquant quand a été calculé la liste des ids des enfants.
UniqueArray< ItemGroupImpl * > m_children_by_type
Liste des fils de ce groupe par type d'entité.
ItemTypeId m_unique_children_type
Indique le type des entités du groupe.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
ItemGroupImpl * internal() const
Retourne l'implémentation du groupe.
Definition ItemGroup.h:120
Vue sur une liste pour obtenir des informations sur les entités.
Structure interne d'une entité de maillage.
Gestionnaire des types d'entités d'un maillage.
Definition ItemTypeMng.h:65
static Integer nbBasicItemType()
nombre de types disponibles
String typeName(Integer id) const
Nom du type correspondant au numéro id.
Identifiant unique d'une entité.
Exception lorsqu'une opération n'est pas supportée.
Vue d'un tableau d'éléments de type T.
Definition Span.h:801
Chaîne de caractères unicode.
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
Int32 checkResizeArrayWithCapacity(Array< DataType > &array, Int64 new_size, bool force_resize)
Redimensionne un tableau en ajoutant une réserve de mémoire.
ARCCORE_COMMON_EXPORT void copy(MutableMemoryView destination, eMemoryResource destination_mem, ConstMemoryView source, eMemoryResource source_mem, const RunQueue *queue=nullptr)
Copie de source vers destination en utilisant la file queue.
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:68
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:486
ConstArrayView< ItemInternal * > ItemInternalList
Type de la liste interne des entités.
Definition ItemTypes.h:466
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:345
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:457
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.
Array< Int32 > Int32Array
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:131
std::int32_t Int32
Type entier signé sur 32 bits.