Arcane  v3.14.10.0
Documentation utilisateur
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
42/*!
43 * \internal
44 * \brief Classe d'un groupe nul.
45 */
47: public ItemGroupImpl
48{
49 public:
50
52 virtual ~ItemGroupImplNull() {} //!< Libére les ressources
53
54 public:
55
56 //! Retourne le nom du groupe
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)
121 _buildSharedNull();
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
148: m_p (new ItemGroupInternal())
149{
150}
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{
212 if (m_p->m_transaction_mode)
213 ARCANE_FATAL("Transaction mode already started");
214 m_p->m_transaction_mode = true;
215}
216
217/*---------------------------------------------------------------------------*/
218/*---------------------------------------------------------------------------*/
219
222{
223 if (!m_p->m_transaction_mode)
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;
228 m_p->m_need_invalidate_on_recompute = false;
229 m_p->notifyInvalidateObservers();
230 }
231}
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
236Int32Array& ItemGroupImpl::
237unguardedItemsLocalId(const bool self_invalidate)
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
243 if (m_p->m_compute_functor && !m_p->m_transaction_mode)
244 ARCANE_FATAL("Direct access for computed group in only available during a transaction");
245
246 _forceInvalidate(self_invalidate);
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{
334 ItemGroupImpl* ii = m_p->m_own_group;
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 {
341 ii = createSubGroup("Own",m_p->m_item_family,new OwnItemGroupComputeFunctor());
342 m_p->m_own_group = ii;
343 ii->setOwn(true);
344 }
345 }
346 return ii;
347}
348
349/*---------------------------------------------------------------------------*/
350/*---------------------------------------------------------------------------*/
351
354{
355 ItemGroupImpl* ii = m_p->m_ghost_group;
356 if (!ii) {
357 ii = createSubGroup("Ghost",m_p->m_item_family,new GhostItemGroupComputeFunctor());
358 m_p->m_ghost_group = ii;
359 }
360 return ii;
361}
362
363/*---------------------------------------------------------------------------*/
364/*---------------------------------------------------------------------------*/
365
366ItemGroupImpl* ItemGroupImpl::
367interfaceGroup()
368{
369 if (itemKind()!=IK_Face)
370 return checkSharedNull();
371 ItemGroupImpl* ii = m_p->m_interface_group;
372 if (!ii) {
373 ii = createSubGroup("Interface",m_p->m_item_family,new InterfaceItemGroupComputeFunctor());
374 m_p->m_interface_group = ii;
375 }
376 return ii;
377}
378
379/*---------------------------------------------------------------------------*/
380/*---------------------------------------------------------------------------*/
381
383nodeGroup()
384{
385 if (itemKind()==IK_Node)
386 return this;
387 ItemGroupImpl* ii = m_p->m_node_group;
388 if (!ii){
389 ii = createSubGroup("Nodes",m_p->m_mesh->nodeFamily(),new ItemItemGroupComputeFunctor<Node>());
390 m_p->m_node_group = ii;
391 }
392 return ii;
393}
394
395/*---------------------------------------------------------------------------*/
396/*---------------------------------------------------------------------------*/
397
399edgeGroup()
400{
401 if (itemKind()==IK_Edge)
402 return this;
403 ItemGroupImpl* ii = m_p->m_edge_group;
404 if (!ii){
405 ii = createSubGroup("Edges",m_p->m_mesh->edgeFamily(),new ItemItemGroupComputeFunctor<Edge>());
406 m_p->m_edge_group = ii;
407 }
408 return ii;
409}
410
411/*---------------------------------------------------------------------------*/
412/*---------------------------------------------------------------------------*/
413
415faceGroup()
416{
417 if (itemKind()==IK_Face)
418 return this;
419 ItemGroupImpl* ii = m_p->m_face_group;
420 if (!ii){
421 ii = createSubGroup("Faces",m_p->m_mesh->faceFamily(),new ItemItemGroupComputeFunctor<Face>());
422 m_p->m_face_group = ii;
423 }
424 return ii;
425}
426
427/*---------------------------------------------------------------------------*/
428/*---------------------------------------------------------------------------*/
429
431cellGroup()
432{
433 if (itemKind()==IK_Cell)
434 return this;
435 ItemGroupImpl* ii = m_p->m_cell_group;
436 if (!ii){
437 ii = createSubGroup("Cells",m_p->m_mesh->cellFamily(),new ItemItemGroupComputeFunctor<Cell>());
438 m_p->m_cell_group = ii;
439 }
440 return ii;
441}
442
443/*---------------------------------------------------------------------------*/
444/*---------------------------------------------------------------------------*/
445
448{
449 if (itemKind()!=IK_Cell)
450 return checkSharedNull();
451 ItemGroupImpl* ii = m_p->m_inner_face_group;
452 if (!ii){
453 ii = createSubGroup("InnerFaces",m_p->m_mesh->faceFamily(),
455 m_p->m_inner_face_group = ii;
456 }
457 return ii;
458}
459
460/*---------------------------------------------------------------------------*/
461/*---------------------------------------------------------------------------*/
462
465{
466 if (itemKind()!=IK_Cell)
467 return checkSharedNull();
468 ItemGroupImpl* ii = m_p->m_outer_face_group;
469 if (!ii){
470 ii = createSubGroup("OuterFaces",m_p->m_mesh->faceFamily(),
472 m_p->m_outer_face_group = ii;
473 }
474 return ii;
475}
476/*---------------------------------------------------------------------------*/
477/*---------------------------------------------------------------------------*/
478//! AMR
479
480/*---------------------------------------------------------------------------*/
481/*---------------------------------------------------------------------------*/
482
485{
486 if (itemKind()!=IK_Cell)
487 return checkSharedNull();
488 ItemGroupImpl* ii = m_p->m_active_cell_group;
489
490 if (!ii){
491 ii = createSubGroup("ActiveCells",m_p->m_mesh->cellFamily(),
493 m_p->m_active_cell_group = ii;
494 }
495 return ii;
496}
497
498/*---------------------------------------------------------------------------*/
499/*---------------------------------------------------------------------------*/
500
503{
504 if (itemKind()!=IK_Cell)
505 return checkSharedNull();
506 ItemGroupImpl* ii = m_p->m_own_active_cell_group;
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(),
511 m_p->m_own_active_cell_group = ii;
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();
524 ItemGroupImpl* ii = m_p->m_level_cell_group[level];
525 if (!ii){
526 ii = createSubGroup(String::format("LevelCells{0}",level),
527 m_p->m_mesh->cellFamily(),
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();
542 ItemGroupImpl* ii = m_p->m_own_level_cell_group[level];
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),
546 m_p->m_mesh->cellFamily(),
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();
561 ItemGroupImpl* ii = m_p->m_active_face_group;
562 if (!ii){
563 ii = createSubGroup("ActiveFaces",m_p->m_mesh->faceFamily(),
565 m_p->m_active_face_group = ii;
566 }
567 return ii;
568}
569
570/*---------------------------------------------------------------------------*/
571/*---------------------------------------------------------------------------*/
572
575{
576 if (itemKind()!=IK_Cell)
577 return checkSharedNull();
578 ItemGroupImpl* ii = m_p->m_own_active_face_group;
579 if (!ii){
580 ii = createSubGroup("OwnActiveFaces",m_p->m_mesh->faceFamily(),
582 m_p->m_own_active_face_group = ii;
583 }
584 return ii;
585}
586/*---------------------------------------------------------------------------*/
587/*---------------------------------------------------------------------------*/
588
591{
592 if (itemKind()!=IK_Cell)
593 return checkSharedNull();
594 ItemGroupImpl* ii = m_p->m_inner_active_face_group;
595 if (!ii){
596 ii = createSubGroup("InnerActiveFaces",m_p->m_mesh->faceFamily(),
598 m_p->m_inner_active_face_group = ii;
599 }
600 return ii;
601}
602
603/*---------------------------------------------------------------------------*/
604/*---------------------------------------------------------------------------*/
605
608{
609 if (itemKind()!=IK_Cell)
610 return checkSharedNull();
611 ItemGroupImpl* ii = m_p->m_outer_active_face_group;
612 if (!ii){
613 ii = createSubGroup("OuterActiveFaces",m_p->m_mesh->faceFamily(),
615 m_p->m_outer_active_face_group = ii;
616 }
617 return ii;
618}
619/*---------------------------------------------------------------------------*/
620/*---------------------------------------------------------------------------*/
621
623createSubGroup(const String& suffix, IItemFamily* family, ItemGroupComputeFunctor * functor)
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
637 &ItemGroupImpl::_executeInvalidate));
638 m_p->m_sub_groups[sub_name] = ii;
639 ii->invalidate(false);
640 return ii;
641}
642
643/*---------------------------------------------------------------------------*/
644/*---------------------------------------------------------------------------*/
645
647findSubGroup(const String& suffix)
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
664changeIds(Int32ConstArrayView old_to_new_ids)
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];
689 items_lid[i] = old_to_new_ids[old_id];
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
699 if (m_p->m_observer_need_info) {
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
713invalidate(bool force_recompute)
714{
715#ifdef ARCANE_DEBUG
716 // if (force_recompute){
717 ITraceMng* msg = m_p->m_mesh->traceMng();
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{
754 return m_p->m_is_local_to_sub_domain;
755}
756
757/*---------------------------------------------------------------------------*/
758/*---------------------------------------------------------------------------*/
759
762{
763 m_p->m_is_local_to_sub_domain = v;
764}
765
766/*---------------------------------------------------------------------------*/
767/*---------------------------------------------------------------------------*/
768
770addItems(Int32ConstArrayView items_local_id,bool check_if_present)
771{
772 ARCANE_ASSERT(( (!m_p->m_need_recompute && !isAllItems()) || (m_p->m_transaction_mode && isAllItems()) ),
773 ("Operation on invalid group"));
774 if (m_p->m_compute_functor && !m_p->m_transaction_mode)
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 }
798 nb_added = nb_item_to_add;
799 }
800 else if (check_if_present) {
801 // Vérifie que les entités à ajouter ne sont pas déjà présentes
802 UniqueArray<bool> presence_checks(m_p->maxLocalId());
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 {
820 nb_added = nb_item_to_add;
821 MemoryUtils::checkResizeArrayWithCapacity(items_lid,current_size+nb_added,false);
822 SmallSpan<Int32> ptr = items_lid.subView(current_size,nb_added);
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();
837 Int32ConstArrayView observation_info(nb_added, items_lid.unguardedBasePointer()+current_size);
838 m_p->notifyExtendObservers(&observation_info);
839 }
840}
841
842/*---------------------------------------------------------------------------*/
843/*---------------------------------------------------------------------------*/
844
846removeItems(Int32ConstArrayView items_local_id,[[maybe_unused]] bool check_if_present)
847{
848 m_p->_removeItems(items_local_id);
849}
850
851/*---------------------------------------------------------------------------*/
852/*---------------------------------------------------------------------------*/
853
855removeAddItems(Int32ConstArrayView removed_items_lids,
856 Int32ConstArrayView added_items_lids,
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"));
861 if (m_p->m_compute_functor && !m_p->m_transaction_mode)
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()) {
874 ItemInternalList internals = itemsInternal();
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());
879 if (new_size==internal_size){
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 {
908 removeItems(removed_items_lids,check_if_present);
909 addItems(added_items_lids,check_if_present);
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
927setItems(Int32ConstArrayView items_local_id)
928{
929 if (m_p->m_compute_functor && !m_p->m_transaction_mode)
930 ARCANE_FATAL("Cannot set items on computed group ({0})", name());
931 Int32Array& buf = m_p->mutableItemsLocalId();
932 buf.resize(items_local_id.size());
933 Int32ArrayView buf_view(buf);
934 buf_view.copy(items_local_id);
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
975setItems(Int32ConstArrayView items_local_id,bool do_sort)
976{
977 if (!do_sort){
978 setItems(items_local_id);
979 return;
980 }
981 UniqueArray<Int32> sorted_lid(items_local_id);
983 sorter.sort(sorted_lid);
984 setItems(sorted_lid);
985}
986
987/*---------------------------------------------------------------------------*/
988/*---------------------------------------------------------------------------*/
989
990void ItemGroupImpl::
991setIsAllItems()
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
1053 Int32UniqueArray removed_ids, removed_lids;
1054 Int32ConstArrayView * observation_info = NULL;
1055 Int32ConstArrayView * observation_info2 = NULL;
1056 Integer new_size;
1057 // Si le groupe posséde des observers ayant besoin d'info, il faut les calculer
1058 if (m_p->m_observer_need_info){
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) {
1122 m_p->m_compute_functor->executeFunctor();
1123 }
1124 // if (need_invalidate_on_recompute) { // #B
1125 // m_p->notifyInvalidateObservers(); // #B
1126 // } // #B
1127
1128 if (m_p->m_need_invalidate_on_recompute) { // #A
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{
1172 m_p->checkUpdateSimdPadding();
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()){
1217 _initChildrenByTypeV2();
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;
1222 if (m_p->m_children_by_type_ids_computed_timestamp != t){
1223 _computeChildrenByTypeV2();
1224 m_p->m_children_by_type_ids_computed_timestamp = t;
1225 }
1226 }
1227 else{
1228 if (m_p->m_children_by_type.empty())
1229 _initChildrenByType();
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 ||
1290 m_p->m_is_local_to_sub_domain ||
1291 m_p->m_is_own);
1292}
1293
1294/*---------------------------------------------------------------------------*/
1295/*---------------------------------------------------------------------------*/
1296
1298timestamp() const
1299{
1300 return m_p->timestamp();
1301}
1302
1303/*---------------------------------------------------------------------------*/
1304/*---------------------------------------------------------------------------*/
1305
1307attachObserver(const void * ref, IItemGroupObserver * obs)
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
1321 _updateNeedInfoFlag(m_p->m_observer_need_info | obs->needInfo());
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 }
1346 _updateNeedInfoFlag(new_observer_need_info);
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
1388void ItemGroupImpl::
1389_initChildrenByType()
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
1394 m_p->m_children_by_type.resize(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));
1398 ItemGroupImpl* igi = createSubGroup(child_name,family,
1399 new ItemGroupImplItemGroupComputeFunctor(this,&ItemGroupImpl::_computeChildrenByType));
1400 m_p->m_children_by_type[i] = igi;
1401 }
1402}
1403
1404/*---------------------------------------------------------------------------*/
1405/*---------------------------------------------------------------------------*/
1406
1407void ItemGroupImpl::
1408_initChildrenByTypeV2()
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
1414 Int32 nb_basic_item_type= ItemTypeMng::nbBasicItemType();
1415 m_p->m_children_by_type_ids.resize(nb_basic_item_type);
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
1424void ItemGroupImpl::
1425_computeChildrenByType()
1426{
1427 ItemGroup that_group(this);
1428 ITraceMng * trace = that_group.mesh()->traceMng();
1429 trace->debug(Trace::High) << "ItemGroupImpl::_computeChildrenByType for " << name();
1430
1431 Integer nb_basic_item_type = ItemTypeMng::nbBasicItemType();
1432
1433 UniqueArray< SharedArray<Int32> > items_by_type(nb_basic_item_type);
1434 for( Integer i=0; i<nb_basic_item_type; ++i ){
1435 ItemGroupImpl * impl = m_p->m_children_by_type[i];
1436 impl->beginTransaction();
1437 }
1438
1439 ENUMERATE_ITEM(iitem,that_group){
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 ){
1447 ItemGroupImpl * impl = m_p->m_children_by_type[i];
1448 impl->setItems(items_by_type[i]);
1449 impl->endTransaction();
1450 }
1451}
1452
1453/*---------------------------------------------------------------------------*/
1454/*---------------------------------------------------------------------------*/
1455
1456void ItemGroupImpl::
1457_computeChildrenByTypeV2()
1458{
1459 ItemGroup that_group(this);
1460 Int32 nb_item = size();
1461 IMesh* mesh = m_p->mesh();
1462 ItemTypeMng* type_mng = mesh->itemTypeMng();
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){
1470 ItemInfoListView lv(m_p->m_item_family->itemInfoListView());
1471 m_p->m_unique_children_type = ItemTypeId{lv.typeId(m_p->itemsLocalId()[0])};
1472 return;
1473 }
1474
1475 Int32 nb_basic_item_type = ItemTypeMng::nbBasicItemType();
1476 m_p->m_unique_children_type = ItemTypeId{IT_NullType};
1477
1478 UniqueArray<Int32> nb_items_by_type(nb_basic_item_type);
1479 nb_items_by_type.fill(0);
1480 ENUMERATE_(Item,iitem,that_group){
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)
1493 ++nb_different_type;
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){
1506 ItemInfoListView lv(m_p->m_item_family->itemInfoListView());
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
1514 ENUMERATE_(Item,iitem,that_group){
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
1528void ItemGroupImpl::
1529_executeExtend(const Int32ConstArrayView* info)
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
1540void ItemGroupImpl::
1541_executeReduce(const Int32ConstArrayView* info)
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
1552void ItemGroupImpl::
1553_executeCompact(const Int32ConstArrayView* info)
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
1564void ItemGroupImpl::
1565_executeInvalidate()
1566{
1567 m_p->setNeedRecompute();
1568 m_p->notifyInvalidateObservers();
1569}
1570
1571/*---------------------------------------------------------------------------*/
1572/*---------------------------------------------------------------------------*/
1573
1574void ItemGroupImpl::
1575_updateNeedInfoFlag(const bool flag)
1576{
1577 if (m_p->m_observer_need_info == flag)
1578 return;
1579 m_p->m_observer_need_info = flag;
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);
1584 if (m_p->m_observer_need_info) {
1586 &ItemGroupImpl::_executeExtend,
1587 &ItemGroupImpl::_executeReduce,
1588 &ItemGroupImpl::_executeCompact,
1589 &ItemGroupImpl::_executeInvalidate));
1590 } else {
1592 &ItemGroupImpl::_executeInvalidate));
1593 }
1594 }
1595}
1596
1597/*---------------------------------------------------------------------------*/
1598/*---------------------------------------------------------------------------*/
1599
1600void ItemGroupImpl::
1601_forceInvalidate(const bool self_invalidate)
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();
1607 m_p->m_need_invalidate_on_recompute = true;
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()) {
1647 m_p->m_group_index_table = SharedPtrT<GroupIndexTable>(new GroupIndexTable(this));
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()) {
1662 IParallelMng* pm = m_p->m_mesh->parallelMng();
1663 ItemGroup this_group(this);
1664 m_p->m_synchronizer = ParallelMngUtils::createSynchronizerRef(pm,this_group);
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
1713void ItemGroupImpl::
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
1727void ItemGroupImpl::
1728_buildSharedNull()
1729{
1730 if (!shared_null){
1731 shared_null = new ItemGroupImplNull();
1732 shared_null->addRef();
1733 }
1734}
1735
1736/*---------------------------------------------------------------------------*/
1737/*---------------------------------------------------------------------------*/
1738
1739void ItemGroupImpl::
1740_destroySharedNull()
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
1762{
1763 m_p->checkIsContigous();
1764}
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
1793 m_p->applySimdPadding();
1794}
1795
1796/*---------------------------------------------------------------------------*/
1797/*---------------------------------------------------------------------------*/
1798
1799ItemGroupImplInternal* ItemGroupImpl::
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.
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 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 const MeshKind meshKind() const =0
Caractéristiques du maillage.
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 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é
__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.
void executeFunctor() override
Exécute la méthode associé
const String & name() const
Retourne le nom du groupe.
virtual ~ItemGroupImplNull()
Libére les ressources.
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.
ItemGroupImpl * parent() const
Groupe parent (0 si aucun)
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 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.
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)
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.
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 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.
ItemGroupImpl * activeFaceGroup()
Groupe des faces actives propres au domaine.
const String & name() const
Nom du groupe.
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.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
Vue sur une liste pour obtenir des informations sur les entités.
Gestionnaire des types d'entités de maillage.
Definition ItemTypeMng.h:66
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é.
void addRef() override
Incrémente le compteur de référence.
void removeRef() override
Décrémente le compteur de référence.
bool empty() const
Capacité (nombre d'éléments alloués) du vecteur.
Integer capacity() const
Capacité (nombre d'éléments alloués) du vecteur.
Integer size() const
Nombre d'éléments du vecteur.
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.
void copy(const U &copy_array)
Recopie le tableau copy_array dans l'instance.
Classe de base des vecteurs 1D de données.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
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 fill(ConstReferenceType value)
Remplit le tableau avec la valeur value.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
void clear()
Supprime les éléments du tableau.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
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.
Vue d'un tableau d'éléments de type T.
Definition Span.h:670
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
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.
Int32 Integer
Type représentant un entier.