Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
DynamicMeshKindInfos.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/* DynamicMeshKindInfos.cc (C) 2000-2024 */
9/* */
10/* Infos de maillage pour un genre d'entité donnée. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/FatalErrorException.h"
15#include "arcane/utils/PlatformUtils.h"
16#include "arcane/utils/NotImplementedException.h"
17#include "arcane/utils/StringBuilder.h"
18
19#include "arcane/core/IMesh.h"
20#include "arcane/core/IItemFamily.h"
22#include "arcane/core/IParallelMng.h"
23#include "arcane/core/ItemPrinter.h"
24#include "arcane/core/VariableTypes.h"
25#include "arcane/core/Timer.h"
26#include "arcane/core/IItemInternalSortFunction.h"
27#include "arcane/core/ItemFamilyCompactInfos.h"
28#include "arcane/core/IMeshCompacter.h"
29#include "arcane/core/MeshPartInfo.h"
30
31#include "arcane/mesh/DynamicMeshKindInfos.h"
32#include "arcane/mesh/ItemFamily.h"
33
34#include <algorithm>
35#include <set>
36
37// #define ARCANE_DEBUG_MESH
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
42namespace Arcane::mesh
43{
44
45/*---------------------------------------------------------------------------*/
46/*---------------------------------------------------------------------------*/
47
50: TraceAccessor(mesh->traceMng())
51, m_mesh(mesh)
52, m_item_family(nullptr)
53, m_kind(kind)
54, m_kind_name(kind_name)
55, m_nb_item(0)
56, m_is_verbose(false)
57, m_use_new_finalize(true)
58, m_is_first_finalize(true)
59, m_has_unique_id_map(true)
60, m_compact_infos(nullptr)
61, m_item_internals_buffer(new MultiBufferT<ItemInternal>(5000))
62{
63}
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
73
74/*---------------------------------------------------------------------------*/
75/*---------------------------------------------------------------------------*/
76
77void DynamicMeshKindInfos::
78build()
79{
80 // Créé le groupe contenant toutes les entités de ce genre
81 {
82 // Si le nom de ce groupe change, il faut mettre a jour
83 // le nom equivalent dans VariableInfo.cc
84 StringBuilder str("All");
85 str += m_kind_name;
86 str += "s";
87 m_all_group_name = str.toString();
89 m_all_group.internal()->setIsAllItems();
90 m_all_group.setLocalToSubDomain(true);
91 }
92 if (!platform::getEnvironmentVariable("ARCANE_OLD_FINALIZE").null()){
93 m_use_new_finalize = false;
94 pwarning() << "USE OLD FINALIZE";
95 }
96 m_is_first_finalize = true;
97}
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
105{
106 Trace::Setter mci(traceMng(),"Mesh");
107
108 ItemGroupImpl& impl = *m_all_group.internal();
109 Integer internal_size = m_internals.size();
110
111 {
112 info(5) << A_FUNCNAME << " " << m_kind_name
113 << " nb_item=" << m_nb_item
114 << " internal size= " << internal_size
115 << " max_local_id=" << maxUsedLocalId();
116#if 0
117 for( Integer i=0; i<internal_size; ++i ){
118 ItemInternal* item = m_internals[i];
119 info() << "Item " << i << " lib=" << item->localId()
120 << " uid=" << item->uniqueId() << " owner=" << item->owner()
121 << " item=" << item
122 << " removed?=" << item->isSuppressed();
123 }
124#endif
125
126 }
127
128 Integer nb_added_items = m_added_items.size();
129 Integer nb_removed_items = m_removed_items.size();
130 bool test_mode = m_use_new_finalize;
131
132 info(5) << A_FUNCNAME << " " << m_kind_name
133 << " nb_item " << m_nb_item
134 << " internal size " << internal_size
135 << " nb_add=" << nb_added_items
136 << " nb_remove=" << nb_removed_items;
137
138 // GG: passage en OLD le 11/2018. Si tout est OK du côté IFPEN
139 // on pourra définitivement supprimer cela.
140#if OLD
142 // En séquentiel, positionne le champs m_owner de chaque entité.
143 // TODO: ne doit pas être fait ici, mais dans le lecteur de maillage...
144 if (!pm->isParallel() && nb_added_items!=0){
145 const Integer sid = pm->commRank();
146 for( Integer i=0; i<nb_added_items; ++i )
147 m_internals[ m_added_items[i] ]->setOwner(sid,sid);
148 }
149#endif
150 // (HP) TODO: On peut surement optimiser la réorganisation via des
151 // addItems, removeItems, changeIds...
152 // Le problème est qu'ici il ne faut pas impacter les sous-groupes calculés
153 impl.beginTransaction();
155 impl.removeItems(m_removed_items,true);
156 } else if (nb_added_items!=0 && nb_removed_items==0 && test_mode){
157 impl.addItems(m_added_items,true);
158 } else {
159 impl.removeAddItems(m_removed_items,m_added_items,true);
160 }
161 impl.endTransaction();
162
163 // restore integrity of allItems group after this agressive modification
164 impl.checkNeedUpdate();
165
166#if defined(ARCANE_DEBUG_MESH)
167 if (arcaneIsCheck())
168 m_all_group.checkValid();
169#endif
170 // Il faut aussi changer les groupes des entités propres
171 // (A faire uniquement en parallele ?)
173
174#if defined(ARCANE_DEBUG_MESH)
175 if (arcaneIsCheck())
176 checkValid();
177#endif
178
179 m_removed_items.clear();
180 m_added_items.clear();
181}
182
183/*---------------------------------------------------------------------------*/
184/*---------------------------------------------------------------------------*/
185
186void DynamicMeshKindInfos::
187itemsUniqueIdToLocalId(ArrayView<Int64> ids,bool do_fatal) const
188{
189 if (!m_has_unique_id_map)
190 _badUniqueIdMap();
191 if (!arcaneIsCheck()){
192 if (do_fatal){
193 for( Integer i=0, s=ids.size(); i<s; ++i ){
194 Int64 unique_id = ids[i];
196 }
197 }
198 else{
199 for( Integer i=0, s=ids.size(); i<s; ++i ){
200 Int64 unique_id = ids[i];
201 ids[i] = m_items_map.tryFindLocalId(unique_id);
202 }
203 }
204 }
205 else{
206 Integer nb_error = 0;
207 for( Integer i=0, s=ids.size(); i<s; ++i ){
208 Int64 unique_id = ids[i];
209 ids[i] = m_items_map.tryFindLocalId(unique_id);
210 if ((ids[i] == NULL_ITEM_LOCAL_ID) && do_fatal) {
211 if (nb_error<10){
212 error() << "DynamicMeshKindInfos::itemsUniqueIdToLocalId() can't find "
213 << "entity " << m_kind_name << " with global id "
214 << unique_id << " in the subdomain.";
215 }
216 ++nb_error;
217 }
218 }
219 if (nb_error!=0){
220 if (do_fatal)
221 ARCANE_FATAL("{0} entities not found",nb_error);
222 }
223 }
224}
225
226/*---------------------------------------------------------------------------*/
227/*---------------------------------------------------------------------------*/
228
229void DynamicMeshKindInfos::
230itemsUniqueIdToLocalId(Int32ArrayView local_ids,
231 Int64ConstArrayView unique_ids,bool do_fatal) const
232{
233 if (!m_has_unique_id_map)
234 _badUniqueIdMap();
235 if (!arcaneIsCheck()){
236 if (do_fatal){
237 for( Integer i=0, s=unique_ids.size(); i<s; ++i ){
238 Int64 unique_id = unique_ids[i];
239 local_ids[i] = (unique_id == NULL_ITEM_UNIQUE_ID) ? NULL_ITEM_LOCAL_ID : m_items_map.findLocalId(unique_id);
240 }
241 }
242 else{
243 for( Integer i=0, s=unique_ids.size(); i<s; ++i ){
244 Int64 unique_id = unique_ids[i];
245 local_ids[i] = m_items_map.tryFindLocalId(unique_id);
246 }
247 }
248 }
249 else{
250 Integer nb_error = 0;
251 for( Integer i=0, s=unique_ids.size(); i<s; ++i ){
252 Int64 unique_id = unique_ids[i];
253 local_ids[i] = m_items_map.tryFindLocalId(unique_id);
254 if ((local_ids[i] == NULL_ITEM_LOCAL_ID) && do_fatal && unique_id != NULL_ITEM_UNIQUE_ID) {
255 if (nb_error<10){
256 error() << "DynamicMeshKindInfos::itemsUniqueIdToLocalId() can't find "
257 << "entity " << m_kind_name << " with global id "
258 << unique_id << " in the subdomain.";
259 }
260 ++nb_error;
261 }
262 }
263 if (nb_error!=0){
264 if (do_fatal)
265 ARCANE_FATAL("{0} entities not found",nb_error);
266 }
267 }
268}
269
270/*---------------------------------------------------------------------------*/
271/*---------------------------------------------------------------------------*/
272
273void DynamicMeshKindInfos::
274itemsUniqueIdToLocalId(Int32ArrayView local_ids,
275 ConstArrayView<ItemUniqueId> unique_ids,bool do_fatal) const
276{
277 if (!m_has_unique_id_map)
278 _badUniqueIdMap();
279 if (!arcaneIsCheck()){
280 if (do_fatal){
281 for( Integer i=0, s=unique_ids.size(); i<s; ++i ){
282 Int64 unique_id = unique_ids[i];
283 local_ids[i] = m_items_map.findLocalId(unique_id);
284 }
285 }
286 else{
287 for( Integer i=0, s=unique_ids.size(); i<s; ++i ){
288 Int64 unique_id = unique_ids[i];
289 local_ids[i] = m_items_map.tryFindLocalId(unique_id);
290 }
291 }
292 }
293 else{
294 Integer nb_error = 0;
295 for( Integer i=0, s=unique_ids.size(); i<s; ++i ){
296 Int64 unique_id = unique_ids[i];
297 local_ids[i] = m_items_map.tryFindLocalId(unique_id);
298 if ((local_ids[i] == NULL_ITEM_LOCAL_ID) && do_fatal) {
299 if (nb_error<10){
300 error() << "DynamicMeshKindInfos::itemsUniqueIdToLocalId() can't find "
301 << "entity " << m_kind_name << " with global id "
302 << unique_id << " in the subdomain.";
303 }
304 ++nb_error;
305 }
306 }
307 if (nb_error!=0){
308 if (do_fatal)
309 ARCANE_FATAL("{0} entities not found",nb_error);
310 }
311 }
312}
313
314/*---------------------------------------------------------------------------*/
315/*---------------------------------------------------------------------------*/
316
321
322/*---------------------------------------------------------------------------*/
323/*---------------------------------------------------------------------------*/
324
327{
328 m_all_group = m_mesh->findGroup(m_all_group_name);
329 // Supprime toutes les entités
330 m_nb_item = 0;
332 _updateItemSharedInfoInternalView();
337 m_free_internals_in_multi_buffer.clear();
338}
339
340/*---------------------------------------------------------------------------*/
341/*---------------------------------------------------------------------------*/
342
345{
346 Int32 sid = m_mesh->meshPartInfo().partRank();
347
348 debug() << "DynamicMeshKindInfos::checkValid(): " << m_kind_name;
349
350 Integer nb_killed_item = 0;
351 Integer nb_internal = m_internals.size();
352 Integer nb_error = 0;
353
354 // Premièrement, le item->localId() doit correspondre à l'indice
355 // dans le tableau m_internal
356 for( Integer i=0; i<nb_internal; ++i ){
357 ItemInternal* item = m_internals[i];
358 if (item->localId()!=i && nb_error<10){
359 error() << "The local id (" << item->localId() << ") of the entity "
360 << m_kind_name << ':' << item->uniqueId() << " is not "
361 << "consistent with its internal value (" << i << ")";
362 ++nb_error;
363 }
364 if (item->isSuppressed()){
366 continue;
367 }
368 if (item->owner()==NULL_SUB_DOMAIN_ID && nb_error<10){
369 error() << "entity " << m_kind_name << ":lid=" << item->localId()
370 << ":uid=" << item->uniqueId() << " belongs to no subdomain";
371 ++nb_error;
372 }
373
374 if (item->owner()!=sid && item->isOwn() && nb_error<10){
375 error() << "entity " << m_kind_name << ":lid=" << item->localId()
376 << ":uid=" << item->uniqueId() << " incoherence between isOwn() and owner()"
377 << " " << item->owner() << ' ' << sid;
378 ++nb_error;
379 }
380
381 }
382 Integer nb_free = m_free_internals.size();
384 error() << "DynamicMeshKindInfos::checkValid(): " << m_kind_name
385 << ": incoherence between killed and free entities"
386 << " free=" << nb_free
387 << " killed=" << nb_killed_item
388 << " internal=" << nb_internal
389 << " count=" << m_nb_item;
390 ++nb_error;
391 }
392
393 if (nb_error!=0)
394 ARCANE_FATAL("Internal error in the mesh structure mesh={0} part={1}",
395 m_mesh->name(),sid);
396}
397
398/*---------------------------------------------------------------------------*/
399/*---------------------------------------------------------------------------*/
400
401#ifdef OLD
403{
404 public:
405 bool operator()(const ItemInternal* item1,const ItemInternal* item2) const
406 {
407 // Il faut mettre les entités détruites en fin de liste
408 //cout << "Compare: " << item1->uniqueId() << " " << item2->uniqueId() << '\n';
409 bool s1 = item1->isSuppressed();
410 bool s2 = item2->isSuppressed();
411 if (s1 && !s2)
412 return false;
413 if (!s1 && s2)
414 return true;
415 Int64 uid1 = Particle(item1).cell(0)->uniqueId();
416 Int64 uid2 = Particle(item2).cell(0)->uniqueId();
417 if (uid1==uid2)
418 return item1->uniqueId() < item2->uniqueId();
419 return uid1<uid2;
420 }
421};
422#endif
423
424/*---------------------------------------------------------------------------*/
425/*---------------------------------------------------------------------------*/
426
428{
429 public:
430 bool operator()(const ItemLocalIdAndUniqueId& item1,const ItemLocalIdAndUniqueId item2) const
431 {
432 return item1.m_unique_id < item2.m_unique_id;
433 }
434 Integer m_local_id;
435 Integer m_unique_id;
436};
437
438/*---------------------------------------------------------------------------*/
439/*---------------------------------------------------------------------------*/
440
448
449/*---------------------------------------------------------------------------*/
450/*---------------------------------------------------------------------------*/
451
459
460/*---------------------------------------------------------------------------*/
461/*---------------------------------------------------------------------------*/
477{
479 bool do_sort = compact_infos.compacter()->isSorted();
480
481 if (arcaneIsCheck())
482 checkValid();
483
484 Integer nb_internal = m_internals.size();
485 info(4) << m_kind_name << " beginCompactItems() Family Internal Size=" << nb_internal
486 << " max_id=" << maxUsedLocalId()
487 << " nb_item=" << m_nb_item
488 << " do_sort=" << do_sort;
489
490 if (nb_internal==0)
491 return;
492
495 // m_new_to_old_local_ids[lid] contient l'ancien numéro local de l'entité dont le nouveau numéro local est \a lid
496 // m_old_to_new_local_ids[lid] contient le nouveau numéro local de l'entité dont l'ancien numéro local est \a lid
497 old_to_new_local_ids.fill(NULL_ITEM_LOCAL_ID);
498 // après compactage, il ne peut y avoir que m_nb_item items actifs (et forcément en tête de numérotation)
499 new_to_old_local_ids.fill(NULL_ITEM_LOCAL_ID);
500
501 if (do_sort){
502 // Fait une copie temporaire des ItemInternal pour le tri
504
505 debug() << "BEGIN = " << items.data() << " " << m_internals.data()
506 << " S1=" << items.size() << " S2=" << m_internals.size();
507 const bool print_infos = false;
508 {
509 ITimerMng* tm = m_mesh->parallelMng()->timerMng();
510 Timer timer(tm,"DynamicMeshKindInfos::beginCompactItems()",Timer::TimerReal);
512 if (print_infos){
513 for( Integer i=0, is=items.size(); i<is; ++i ){
514 info() << "Before Sort: " << i << " uid=" << items[i]->uniqueId()
515 << " lid=" << items[i]->localId()
516 << " destroyed?=" << items[i]->isSuppressed();
517 }
518 }
519 {
521 sort_func->sortItems(items);
522 }
523 info(4) << "Temps pour trier les entités <" << m_kind_name << "> "
524 << timer.lastActivationTime()
525 << " sort_func_name=" << sort_func->name();
526 info(4) << "Sort Infos: size=" << items.size() << " nb_item=" << m_nb_item;
527 if (print_infos){
528 for( Integer i=0, n=items.size(); i<n; ++i ){
529 info() << "After Sort: " << i << " uid=" << items[i]->uniqueId()
530 << " lid=" << items[i]->localId()
531 << " destroyed?=" << items[i]->isSuppressed();
532 }
533 }
534 }
535
536#ifdef ARCANE_TEST_ADD_MESH
537 typedef std::set<ItemInternal*,ItemCompare> ItemSet;
541 {
542 ItemSet::const_iterator b = items_set.begin();
543 ItemSet::const_iterator e = items_set.end();
544 for( Integer z=0; b!=e; ++b, ++z)
545 items[z] = *b;
546 }
547#endif
548
549 for( Integer i=0, n=m_nb_item; i<n; ++i ){
550 Integer current_local_id = items[i]->localId();
551 //info() << "Item: " << " uid=" << items[i]->uniqueId() << " lid="
552 //<< current_local_id << " newid=" << i;
555 }
556 }
557 else{
558 const bool use_old = true;
559 if (use_old){
560 info(4) << "USE_OLD_METHOD";
562
563 for( Integer i=0; i<m_nb_item; ++i ){
564 Integer current_local_id = existing_items[i];
567 }
568
569 // Place les éléments détruits en fin de liste et vérifie
570 // que le nombre de trous + le nombre d'entités est égal à #nb_internal
571 {
572 Integer old_index = m_nb_item;
573 Integer total_nb = maxUsedLocalId();
574 for( Integer i=0, n=total_nb; i<n; ++i ){
575 //bool is_destroyed = false;
576 if (old_to_new_local_ids[i]==NULL_ITEM_ID){
577 //is_destroyed = true;
579 //m_new_to_old_local_ids[old_index] = i;
580 ++old_index;
581 }
582 //debug() << "OLD_TO_NEW i=" << i
583 // << " old=" << m_old_to_new_local_ids[i]
584 // << " destroyed=" << is_destroyed;
585 }
586 if (old_index!=total_nb){
587 ARCANE_FATAL("Family '{0}' bad indices: expected={1} found={2} (nb_internal={3})",
588 itemFamily()->name(),old_index,total_nb,nb_internal);
589 }
590 }
591 }
592 else{
593 // Compactage sans triage, ce qui revient à déplacer les trous à la fin
594
595 // Place les éléments détruits en fin de liste et vérifie
596 // que l'on a bien tout rangé (on conserve l'ordre relatif des items)
597 Integer new_index = 0;
598 Integer free_index = m_nb_item;
599 for( Integer i=0, n=maxUsedLocalId(); i<n; ++i ){
600 if (m_internals[i]->isSuppressed()) {
602 // m_new_to_old_local_ids[free_index] = i; // non utilisé quand m_new_to_old_local_ids restreint à m_nb_item
603 ++free_index;
604 } else {
607 ++new_index;
608 }
609 //debug() << "OLD_TO_NEW i=" << i
610 // << " old=" << m_old_to_new_local_ids[i]
611 // << " destroyed=" << m_internals[i]->isSuppressed();
612 }
613 if (new_index!=m_nb_item){
614 ARCANE_FATAL("Family '{0}' bad indices: expected={1} found={2}",
615 itemFamily()->name(),m_nb_item,new_index);
616 }
617 }
618 }
619 compact_infos.setOldToNewLocalIds(std::move(old_to_new_local_ids));
620 compact_infos.setNewToOldLocalIds(std::move(new_to_old_local_ids));
621}
622
623/*---------------------------------------------------------------------------*/
624/*---------------------------------------------------------------------------*/
625
626void DynamicMeshKindInfos::
627finishCompactItems(ItemFamilyCompactInfos& compact_infos)
628{
629 if (arcaneIsCheck())
630 checkValid();
631
634
635 Integer nb_internal = m_internals.size();
636
637 info(4) << m_kind_name << " Family Compression: nb_item=" << m_nb_item
638 << " nb_internal=" << nb_internal
639 << " buf_size=" << m_item_internals_buffer->bufferSize()
640 << " nb_allocated_buf=" << m_item_internals_buffer->nbAllocatedBuffer()
641 << " nb_free" << m_free_internals_in_multi_buffer.size();
642
643 if (nb_internal==0)
644 return;
645
646 // Finalise la réorganisation des structures après un tri
647 // 1. Il faut mettre à jour la structure m_items_map pour référencer
648 // le nouveau local_id
649 // 2. Il faut recopier les valeurs de chaque ItemInternal pour qu'il
650 // soit bien placé dans la nouvelle numérotation.
651 // IMPORTANT: Cette opération doit toujours être la dernière car ensuite
652 // on perd la relation entre les anciens local_ids et les nouveaux à
653 // travers cette structure
655
656 if (m_is_verbose){
657 info() << "DumpItemsBefore:";
658 _dumpList();
659 }
660
661 // Pour l'instant, utilise un tableau temporaire
662 // TODO: tableau a supprimer
668
669 for( Integer i=0, n=m_nb_item; i<n; ++i ) {
671 new_uids[i] = old_item->uniqueId().asInt64();
672 new_owners[i] = old_item->owner();
673 new_flags[i] = old_item->flags();
674 new_typeids[i] = old_item->typeId();
675 new_items[i] = *old_item;
676 }
677
678 Integer nb_error = 0;
679 Int32 sid = m_mesh->meshPartInfo().partRank();
680
681 for( Integer i=0; i<m_nb_item; ++i ){
682 ItemInternal* ii = m_internals[i];
683 *ii = new_items[i];
684 ii->setLocalId(i);
685 ii->setFlags(new_flags[i]);
686 ii->setOwner(new_owners[i],sid);
687 ii->setUniqueId(new_uids[i]);
688 ItemSharedInfo* isi = ItemInternalCompatibility::_getSharedInfo(ii);
689 ii->_setSharedInfo(isi,ItemTypeId(new_typeids[i]));
690 // L'entité est marqué comme créée
691 //_setAdded(ii);
692#ifdef ARCANE_CHECK
693 if (ii->isSuppressed()){
694 if (nb_error<10)
695 error() << "Entity deleted from the list of created entities "
696 << ItemPrinter(ii) << " index=" << i;
697 ++nb_error;
698 }
699#endif /* ARCANE_CHECK */
700 }
701
702 // Il faut remplir les m_free_internals_in_multi_buffer avec les entités supprimées
703 // pour qu'elles puissent être réutilisées sinon on va réallouer
704 // des blocs dans m_item_internals_buffer à chaque recréation des
705 // entités
706 for( Integer i=m_nb_item, n=m_internals.size(); i<n; ++i ){
707 // Empile dans l'ordre inverse pour que allocOne()
708 // dépile dans l'ordre des m_internals et profite des
709 // effets de cache.
710 ItemInternal* removed_item = m_internals[m_nb_item + n-(i+1)];
711 m_free_internals_in_multi_buffer.add(removed_item);
712 }
713
714 // Retaillage optimal des tableaux
716 _updateItemSharedInfoInternalView();
718
719 if (m_is_verbose){
720 info() << "DumpItemsAfter:";
721 _dumpList();
722 }
723
724 if (nb_error!=0)
725 ARCANE_FATAL("Error in compacting nb_error={0}",nb_error);
726
727 debug() << "Compression: old=" << nb_internal << " new=" << m_nb_item
728 << " internal=" << m_internals.size()
729 << " free=" << m_free_internals.size();
730
731 // Vide les tableaux de 'compact_infos' car ils ne sont plus valides.
732 compact_infos.clear();
733
734 m_compact_infos = nullptr;
736}
737
738/*---------------------------------------------------------------------------*/
739/*---------------------------------------------------------------------------*/
740
741namespace{
742 class _Inverse
743 {
744 public:
745 bool operator()(Int32 i1,Int32 i2) const
746 {
747 return i1>i2;
748 }
749 };
750}
751
752/*---------------------------------------------------------------------------*/
753/*---------------------------------------------------------------------------*/
754
756clear()
757{
759
760 // Pour réutiliser au moins les m_free_internals afin
761 // d'avoir des localId() consécutifs, il faut trier
762 // les ids par ordre décroissant.
764 std::sort(std::begin(ids),std::end(ids),_Inverse());
765
766 removeMany(ids);
767 //printFreeInternals(10000);
768}
769
770/*---------------------------------------------------------------------------*/
771/*---------------------------------------------------------------------------*/
772
773void DynamicMeshKindInfos::
774printFreeInternals(Integer max_print)
775{
776 Integer nb_free = m_free_internals.size();
778 for( Integer i=0; i<max_print; ++i ){
779 Integer pos = (nb_free-1)-i;
780 Int32 index = m_free_internals[pos];
782 info() << "I=" << i << " pos=" << pos << " index=" << index
783 << " local_id=" << iitem->localId();
784 }
785}
786
787/*---------------------------------------------------------------------------*/
788/*---------------------------------------------------------------------------*/
789
792{
793 Int64ArrayView uids = *(m_item_family->uniqueIds());
794 Integer nb_item = local_ids.size();
795
796 if (m_has_unique_id_map){
797 for( Integer i=0; i<nb_item; ++i ){
798 Int32 lid = local_ids[i];
800#ifdef ARCANE_CHECK
801 _checkActiveItem(item);
802#endif
803 _setSuppressed(item);
804 if (uids[lid] != NULL_ITEM_UNIQUE_ID)
805 m_items_map.remove(uids[lid]);
806 }
807 }
808 else{
809 for( Integer i=0; i<nb_item; ++i ){
810 Int32 lid = local_ids[i];
812#ifdef ARCANE_CHECK
813 _checkActiveItem(item);
814#endif
815 _setSuppressed(item);
816 }
817 }
818
820 Integer nb_removed = m_removed_items.size();
821 m_removed_items.resize(nb_removed + nb_item);
822 memcpy(m_removed_items.data()+nb_removed,local_ids.data(),sizeof(Int32)*nb_item);
823 Integer nb_free = m_free_internals.size();
825 memcpy(m_free_internals.data()+nb_free,local_ids.data(),sizeof(Int32)*nb_item);
826}
827
828/*---------------------------------------------------------------------------*/
829/*---------------------------------------------------------------------------*/
830
831void DynamicMeshKindInfos::
832setHasUniqueIdMap(bool v)
833{
834 if (m_nb_item!=0)
835 ARCANE_FATAL("family is not empty");
836 m_has_unique_id_map = v;
837}
838
839/*---------------------------------------------------------------------------*/
840/*---------------------------------------------------------------------------*/
841
842void DynamicMeshKindInfos::
843_checkActiveItem(ItemInternal* item)
844{
845 if (item->isSuppressed())
846 ARCANE_FATAL("Attempting to remove an entity already deleted item={0}",
847 ItemPrinter(item));
848}
849
850/*---------------------------------------------------------------------------*/
851/*---------------------------------------------------------------------------*/
852
853void DynamicMeshKindInfos::
854_dumpList()
855{
856 Integer nb_internal = m_internals.size();
857 Integer computed_nb_item = 0;
858 for( Integer i=0; i<nb_internal; ++i ){
859 ItemInternal* item = m_internals[i];
860 bool is_suppressed = item->isSuppressed();
861 if (is_suppressed)
862 ++computed_nb_item;
863 info() << "Item: INDEX=" << i
864 << " LID=" << item->localId()
865 << " UID=" << item->uniqueId()
866 << " KILLED=" << is_suppressed;
867 }
868 info() << "EndOfDump: "
869 << " nb_internal=" << nb_internal
870 << " nb_item=" << m_nb_item
871 << " computed_nb_item= " << (nb_internal-computed_nb_item);
872}
873
874/*---------------------------------------------------------------------------*/
875/*---------------------------------------------------------------------------*/
876
877void DynamicMeshKindInfos::
878_badSameUniqueId(Int64 unique_id) const
879{
880 ARCANE_FATAL("duplicate unique id family={0} uid={1}",
881 m_item_family->name(),unique_id);
882}
883
884/*---------------------------------------------------------------------------*/
885/*---------------------------------------------------------------------------*/
886
887void DynamicMeshKindInfos::
888_badUniqueIdMap() const
889{
890 if (m_has_unique_id_map)
891 ARCANE_FATAL("family have unique id map");
892 else
893 ARCANE_FATAL("family does not have unique id map");
894}
895
896/*---------------------------------------------------------------------------*/
897/*---------------------------------------------------------------------------*/
898
899void DynamicMeshKindInfos::
900setItemFamily(ItemFamily* item_family)
901{
902 m_item_family = item_family;
903 m_common_item_shared_info = item_family->commonItemSharedInfo();
904}
905
906/*---------------------------------------------------------------------------*/
907/*---------------------------------------------------------------------------*/
908
909void DynamicMeshKindInfos::
910_updateItemSharedInfoInternalView()
911{
912 if (m_common_item_shared_info)
913 m_common_item_shared_info->m_items_internal = m_internals.constView();
914}
915
916/*---------------------------------------------------------------------------*/
917/*---------------------------------------------------------------------------*/
918
919} // End namespace Arcane::mesh
920
921/*---------------------------------------------------------------------------*/
922/*---------------------------------------------------------------------------*/
923
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Types et macros pour itérer sur les entités du maillage.
Interface d'une fonction de tri des entités.
virtual String name() const =0
Nom du maillage.
virtual IParallelMng * parallelMng()=0
Gestionnaire de parallèlisme.
virtual ItemGroup findGroup(const String &name)=0
Retourne le groupe de nom name ou le groupe nul s'il n'y en a pas.
virtual const MeshPartInfo & meshPartInfo() const =0
Informations sur les parties du maillage.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual bool isParallel() const =0
Retourne true si l'exécution est parallèle.
Interface d'un gestionnaire de timer.
Definition ITimerMng.h:53
bool isSuppressed() const
Vrai si l'entité est supprimée.
ItemUniqueId uniqueId() const
Numéro unique de l'entité
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
bool isOwn() const
Vrai si l'entité appartient au sous-domaine.
Int32 localId() const
Numéro local (au sous-domaine) de l'entité
Informations pour gérer le compactage des entités d'une famille.
Int32ConstArrayView newToOldLocalIds() const
Conversion entre les nouveaux et les anciens id locaux.
Int32ConstArrayView oldToNewLocalIds() const
Conversion entre les anciens et les nouveaux id locaux.
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.
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.
void endTransaction()
Termine une transaction.
void addItems(Int32ConstArrayView items_local_id, bool check_if_present)
Ajoute les entités de numéros locaux items_local_id.
void setIsAllItems()
Indique à ce groupe qu'il s'agit du groupe de toutes les entités de la famille.
Int32ConstArrayView itemsLocalId() const
Liste des numéros locaux des entités de ce groupe.
void beginTransaction()
Débute une transaction.
void setLocalToSubDomain(bool v)
Positionne le booléen indiquant si le groupe est local au sous-domaine.
Definition ItemGroup.h:238
ItemGroupImpl * internal() const
Retourne l'implémentation du groupe.
Definition ItemGroup.h:120
void checkValid()
Vérification interne de la validité du groupe.
Definition ItemGroup.cc:521
Structure interne d'une entité de maillage.
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:35
ConstArrayView< ItemInternal * > m_items_internal
ItemInternal des entités.
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:216
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Tampon pour allocation multiple.
Definition MultiBuffer.h:44
Particule.
Definition Item.h:1383
Cell cell() const
Maille à laquelle appartient la particule. Il faut appeler setCell() avant d'appeler cette fonction....
Definition Item.h:1444
Sentinelle pour le timer. La sentinelle associée à un timer permet de déclancher celui-ci au moment d...
Definition Timer.h:89
Gestion d'un timer.
Definition Timer.h:62
@ TimerReal
Timer utilisant le temps réel.
Definition Timer.h:76
Integer m_nb_item
Groupe de toutes les entités.
String m_kind_name
Nom du genre des entités (Node, Cell, ...)
Integer maxUsedLocalId() const
Numéro local le plus grand utilisé.
MultiBufferT< ItemInternal > * m_item_internals_buffer
Tampon pour stocker une instance de ItemInternal.
void finalizeMeshChanged()
Réalloue et recalcule les structures après modification du maillage.
void removeMany(Int32ConstArrayView local_ids)
Supprime une liste d'entités.
void prepareForDump()
Prépare les variables pour les sauvegardes.
void beginCompactItems(ItemFamilyCompactInfos &compact_infos)
Calcule les nouveaux id locaux des entités pour qu'ils soient consécutifs.
ARCANE_DEPRECATED_240 Int32ConstArrayView oldToNewLocalIds() const
Conversion entre les anciens et les nouveaux id locaux.
UniqueArray< ItemInternal * > m_internals
ItemInternal des entités.
void readFromDump()
Restaure les infos à partir des dumps.
DynamicMeshKindInfos(IMesh *mesh, eItemKind kind, const String &kind_name)
Créé une instance pour un maillage et un genre donnée.
ARCANE_DEPRECATED_240 Int32ConstArrayView newToOldLocalIds() const
Conversion entre les nouveaux et les anciens id locaux.
ItemFamilyCompactInfos * m_compact_infos
Temporaire tant que oldToNewLocalIds() et newToOldLocalIds() existent.
void checkValid()
Vérifie si les structures internes de l'instance sont valides.
~DynamicMeshKindInfos()
Libère les ressources.
String m_all_group_name
Nom du groupe contenant toutes les entités.
ItemInternalMap m_items_map
Table de hachage conversion uniqueId() -> ItemInternal*.
Int32UniqueArray m_free_internals
Liste des ItemInternal de m_item_internals_buffer libres.
void clear()
Supprime toutes les entités.
ItemFamily * m_item_family
Famille de maillage associée.
ItemGroup createGroup(const String &name, Int32ConstArrayView elements, bool do_override=false) override
Créé un groupe d'entités de nom name contenant les entités local_ids.
IItemInternalSortFunction * itemSortFunction() const override
Fonction de tri des entités.
void notifyItemsOwnerChanged() override
Notifie que les entités propres au sous-domaine de la famille ont été modifiées.
String name() const override
Nom de la famille.
Definition ItemFamily.h:125
void remove(Int64 key)
Supprime la valeur associée à la clé key.
Int32 tryFindLocalId(Int64 key) const
Retourne le localId() associé à key si trouvé ou NULL_ITEM_LOCAL_ID sinon aucun.
Int32 findLocalId(Int64 uid) const
Retourne le numéro local de l'entité de numéro unique uid.
void _changeLocalIds(ArrayView< ItemInternal * > items_internal, ConstArrayView< Int32 > old_to_new_local_ids)
Change la valeurs des localId()
void clear()
Supprime tous les éléments de la table.
Integer size() const
Nombre d'éléments du vecteur.
Vue modifiable d'un tableau d'un type T.
const T * data() const
Accès à la racine du tableau hors toute protection.
iterator begin()
Itérateur sur le premier élément du tableau.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
ConstArrayView< T > constView() const
Vue constante sur ce tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
void clear()
Supprime les éléments du tableau.
iterator end()
Itérateur sur le premier élément après la fin du tableau.
Vue constante d'un tableau de type T.
Constructeur de chaîne de caractère unicode.
Chaîne de caractères unicode.
TraceMessage pwarning() const
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage error() const
Flot pour un message d'erreur.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
Positionne une classe de message.
Vecteur 1D de données avec sémantique par valeur (style STL).
ARCCORE_HOST_DEVICE Real2 min(Real2 a, Real2 b)
Retourne le minimum de deux Real2.
Definition MathUtils.h:336
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.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:638
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:611
Int32 Integer
Type représentant un entier.