Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
MeshRefinement.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/* MeshRefinement.cc (C) 2000-2024 */
9/* */
10/* Manipulation d'un maillage AMR. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#ifndef AMRMAXCONSISTENCYITER
15#define AMRMAXCONSISTENCYITER 10
16#endif
17
18// \brief classe de méthodes de raffinement des maillages déstructurés
20
21
23#include "arcane/utils/Real3.h"
24#include "arcane/utils/ArgumentException.h"
25
26#include "arcane/core/IParallelMng.h"
27#include "arcane/core/IMesh.h"
28#include "arcane/core/IItemFamily.h"
29#include "arcane/core/Item.h"
30
31#include "arcane/core/VariableTypes.h"
32#include "arcane/core/ItemPrinter.h"
33#include "arcane/core/SharedVariable.h"
34#include "arcane/core/ItemRefinementPattern.h"
35#include "arcane/core/Properties.h"
36#include "arcane/core/IGhostLayerMng.h"
37
38#include "arcane/mesh/DynamicMesh.h"
39#include "arcane/mesh/ItemRefinement.h"
40#include "arcane/mesh/MeshRefinement.h"
41
42#include "arcane/mesh/ParallelAMRConsistency.h"
43#include "arcane/mesh/FaceReorienter.h"
44
45#include "arcane/mesh/NodeFamily.h"
46#include "arcane/mesh/EdgeFamily.h"
47#include "arcane/core/ItemVector.h"
48
49#include <vector>
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
54namespace Arcane::mesh
55{
56
57namespace
58{
59void _setRefineFlags(Item v)
60{
61 Integer f = v.itemBase().flags();
62 f &= ~ItemFlags::II_Coarsen;
64 v.mutableItemBase().setFlags(f);
65}
66void _setCoarseFlags(Item v)
67{
68 Integer f = v.itemBase().flags();
69 f &= ~ItemFlags::II_Refine;
71 v.mutableItemBase().setFlags(f);
72}
73
74}
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
79#ifdef ACTIVATE_PERF_COUNTER
80const std::string MeshRefinement::PerfCounter::m_names[MeshRefinement::PerfCounter::NbCounters] =
81 {
82 "INIT",
83 "CLEAR",
84 "ENDUPDATE",
85 "UPDATEMAP",
86 "UPDATEMAP2",
87 "CONSIST",
88 "PCONSIST",
89 "PCONSIST2",
90 "PGCONSIST",
91 "CONTRACT",
92 "COARSEN",
93 "REFINE",
94 "INTERP",
95 "PGHOST",
96 "COMPACT"
97} ;
98#endif
99
100// Mesh refinement methods
103: TraceAccessor(mesh->traceMng())
104, m_mesh(mesh)
105, m_face_family(&(mesh->trueFaceFamily()))
106, m_node_finder(mesh)
107, m_face_finder(mesh)
108, m_coarsen_by_parents(false)
109, m_max_level(-1)
110, m_nb_cell_target(0)
111, m_face_level_mismatch_limit(1)
112, m_max_node_uid(NULL_ITEM_UNIQUE_ID)
113, m_next_node_uid(NULL_ITEM_UNIQUE_ID)
114, m_max_cell_uid(NULL_ITEM_UNIQUE_ID)
115, m_next_cell_uid(NULL_ITEM_UNIQUE_ID)
116, m_max_face_uid(NULL_ITEM_UNIQUE_ID)
117, m_next_face_uid(NULL_ITEM_UNIQUE_ID)
118, m_max_nb_hChildren(0)
119, m_node_owner_memory(VariableBuildInfo(mesh,"NodeOwnerMemoryVar"))
120{
121 // \todo créer un builder
125 m_need_update = true ;
126
127 ENUMERATE_NODE(inode,m_mesh->allNodes()) m_node_owner_memory[inode] = inode->owner();
128
129#ifdef ACTIVATE_PERF_COUNTER
130 m_perf_counter.init() ;
131#endif
132}
133
134/*---------------------------------------------------------------------------*/
135/*---------------------------------------------------------------------------*/
136
139{
140 this->clear();
141 delete m_item_refinement;
143 delete m_call_back_mng;
144}
145
146/*---------------------------------------------------------------------------*/
147/*---------------------------------------------------------------------------*/
148
149void
151clear()
152{
153 CHECKPERF( m_perf_counter.start(PerfCounter::CLEAR) )
154 m_node_finder._clear();
155 m_face_finder._clear();
156 CHECKPERF( m_perf_counter.stop(PerfCounter::CLEAR) )
157}
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
160
161void
163init()
164{
165 // Recalcul le max uniqueId() des nodes/cells/faces.
166 CHECKPERF( m_perf_counter.start(PerfCounter::INIT) )
168 {
169 Int64 max_node_uid = 0;
171 {
172 const Node& node = *inode;
173 const Int64 uid = node.uniqueId();
174 if (uid>max_node_uid)
175 max_node_uid = uid;
176 }
177
178 if (pm->commSize() > 1)
179 m_max_node_uid = pm->reduce(Parallel::ReduceMax, max_node_uid);
180 else
181 m_max_node_uid = max_node_uid;
182 info() << "NODE_UID_INFO: MY_MAX_UID=" << max_node_uid << " GLOBAL=" << m_max_node_uid;
183 m_next_node_uid = m_max_node_uid + 1 + m_mesh->parallelMng()->commRank();
184 }
186
187 {
188 Int64 max_cell_uid = 0;
189 Integer max_nb_hChildren = 0;
191 {
192 const Cell& cell = *icell;
193 const Int64 uid = cell.uniqueId();
194 const Int32 nb_hChildren = itm->nbHChildrenByItemType(cell.type());
195 if (uid>max_cell_uid)
196 max_cell_uid = uid;
199
200 }
201 if (pm->commSize() > 1)
202 {
203 m_max_cell_uid = pm->reduce(Parallel::ReduceMax, max_cell_uid);
204 m_max_nb_hChildren = pm->reduce(Parallel::ReduceMax, max_nb_hChildren);
205 }
206 else
207 {
208 m_max_cell_uid = max_cell_uid;
209 m_max_nb_hChildren = max_nb_hChildren;
210 }
211 info() << "CELL_UID_INFO: MY_MAX_UID=" << max_cell_uid << " GLOBAL=" << m_max_cell_uid;
212 m_next_cell_uid = m_max_cell_uid + 1 + pm->commRank() * m_max_nb_hChildren;
213 }
214
215 {
216 Int64 max_face_uid = 0;
218 {
219 const Face& face = *iface;
220 const Int64 uid = face.uniqueId();
221 if (uid>max_face_uid)
222 max_face_uid = uid;
223 }
224
225 if (pm->commSize() > 1)
226 m_max_face_uid = pm->reduce(Parallel::ReduceMax, max_face_uid);
227 else
228 m_max_face_uid = max_face_uid;
229 info() << "FACE_UID_INFO: MY_MAX_UID=" << max_face_uid << " GLOBAL=" << m_max_face_uid;
230 m_next_face_uid = m_max_face_uid + 1 + pm->commRank();
231 }
232
234
235 CHECKPERF( m_perf_counter.stop(PerfCounter::INIT) )
236}
237
238
239void MeshRefinement::
240_updateMaxUid(ArrayView<ItemInternal*> cells)
241{
242 // Recalcul le max uniqueId() des nodes/cells/faces.
243 CHECKPERF( m_perf_counter.start(PerfCounter::INIT) )
246 {
247
248 Int64 max_node_uid = m_max_node_uid;
249 Int64 max_cell_uid = m_max_cell_uid;
250 Integer max_nb_hChildren = m_max_nb_hChildren;
251 Int64 max_face_uid = m_max_face_uid;
252
253 typedef std::set<Int64> set_type ;
254 typedef std::pair<set_type::iterator,bool> insert_return_type ;
255 set_type node_list ;
256 set_type face_list ;
257 for(Integer icell=0;icell<cells.size();++icell){
258 Cell cell = cells[icell];
259 for (UInt32 i = 0, nc = cell.nbHChildren(); i < nc; i++){
260 Cell child = cell.hChild(i);
261
262 //UPDATE MAX CELL UID
263 const Int64 cell_uid = child.uniqueId();
264 const Int32 nb_hChildren = itm->nbHChildrenByItemType(child.type());
265 if (cell_uid>max_cell_uid)
266 max_cell_uid = cell_uid;
269
270 //UPDATE MAX NODE UID
271 for( Node inode : child.nodes() ){
272 const Int64 uid = inode.uniqueId();
273 insert_return_type value = node_list.insert(uid) ;
274 if(value.second){
275 if (uid>max_node_uid)
276 max_node_uid = uid;
277 }
278 }
279
280
281 //UPDATE MAX FACE UID
282 for( Face iface : child.faces() ){
283 const Int64 uid = iface.uniqueId();
284 insert_return_type value = face_list.insert(uid) ;
285 if(value.second){
286 if (uid>max_face_uid)
287 max_face_uid = uid;
288 }
289 }
290 }
291 }
292
293
294 if (pm->commSize() > 1)
295 {
296 m_max_node_uid = pm->reduce(Parallel::ReduceMax, max_node_uid);
297 m_max_cell_uid = pm->reduce(Parallel::ReduceMax, max_cell_uid);
298 m_max_nb_hChildren = pm->reduce(Parallel::ReduceMax, max_nb_hChildren);
299 m_max_face_uid = pm->reduce(Parallel::ReduceMax, max_face_uid);
300 }
301 else
302 {
303 m_max_node_uid = max_node_uid;
304 m_max_cell_uid = max_cell_uid;
305 m_max_nb_hChildren = max_nb_hChildren;
306 m_max_face_uid = max_face_uid;
307 }
308 m_next_node_uid = m_max_node_uid + 1 + m_mesh->parallelMng()->commRank();
309 m_next_cell_uid = m_max_cell_uid + 1 + pm->commRank() * m_max_nb_hChildren;
310 m_next_face_uid = m_max_face_uid + 1 + pm->commRank();
311 }
312
313 CHECKPERF( m_perf_counter.stop(PerfCounter::INIT) )
314}
315
316
317void
318MeshRefinement::initMeshContainingBox()
319{
321 m_node_finder.setBox(&m_mesh_containing_box) ;
322 m_face_finder.setBox(&m_mesh_containing_box) ;
323}
324
325
326void
327MeshRefinement::update()
328{
329 init() ;
330 initMeshContainingBox() ;
331 m_item_refinement->initHMin() ;
332 m_node_finder.init() ;
333 //m_node_finder.check() ;
334 m_face_finder.initFaceCenter() ;
335 m_face_finder.init() ;
336 //m_face_finder.check() ;
338 m_need_update = false ;
339}
340/*---------------------------------------------------------------------------*/
341/*---------------------------------------------------------------------------*/
342
345{
347 for (Integer i = 0, is = lids.size(); i < is; i++) {
348 Item item = cells[lids[i]];
349 //ARCANE_ASSERT((item->type() ==IT_Hexaedron8),(""));
351 }
352}
353
354/*---------------------------------------------------------------------------*/
355/*---------------------------------------------------------------------------*/
356
357void MeshRefinement::
358flagCellToCoarsen(Int32ConstArrayView lids)
359{
361 for (Integer i = 0, is = lids.size(); i < is; i++) {
362 Item item = cells[lids[i]];
363 //ARCANE_ASSERT((item->type() ==IT_Hexaedron8),(""));
365 }
366}
367/*---------------------------------------------------------------------------*/
368/*---------------------------------------------------------------------------*/
369
370bool
373{
374 CHECKPERF( m_perf_counter.start(PerfCounter::INIT) )
375
377
378 // la règle de niveau-un est la seule condition implementée
380 {
381 warning() << "Warning, level one rule is the only condition accepted for AMR!";
382 }
383 else
384 _maintain_level_one = m_face_level_mismatch_limit;
385
386 // Nous ne pouvons pas encore transformer un maillage de non-niveau-un en un maillage de niveau-un
388 ARCANE_ASSERT((_checkLevelOne(true)), ("checkLevelOne failed"));
389 }
390
391 // Nettoyage des flags de raffinement d'une étape précédente
392 this->_cleanRefinementFlags();
393 CHECKPERF( m_perf_counter.stop(PerfCounter::INIT) )
394
395 // La consistence parallèle doit venir en premier, ou le déraffinement
396 // le long des interfaces entre processeurs pourrait de temps en temps être
397 // faussement empéché
398 if (m_mesh->parallelMng()->isParallel())
400
401 CHECKPERF( m_perf_counter.start(PerfCounter::CONSIST) )
402 // Repete jusqu'au matching du changement de flags sur chaque processeur
403 Integer iter = 0 ;
404 do
405 {
406 // Repete jusqu'au matching des flags coarsen/refine localement
407 bool satisfied = false;
408 do
409 {
410 const bool coarsening_satisfied = this->_makeCoarseningCompatible(maintain_level_one);
411 const bool refinement_satisfied = this->_makeRefinementCompatible(maintain_level_one);
413#ifdef ARCANE_DEBUG
415 max_satisfied = m_mesh->parallelMng()->reduce(Parallel::ReduceMax,max_satisfied);
416 min_satisfied = m_mesh->parallelMng()->reduce(Parallel::ReduceMin,min_satisfied);
417 ARCANE_ASSERT ( (satisfied == max_satisfied), ("parallel max_satisfied failed"));
418 ARCANE_ASSERT ( (satisfied == min_satisfied), ("parallel min_satisfied failed"));
419#endif
420 } while (!satisfied);
421 ++iter ;
422 } while (m_mesh->parallelMng()->isParallel() && !this->_makeFlagParallelConsistent() && iter<10 );
423 if(iter==AMRMAXCONSISTENCYITER) fatal()<<" MAX CONSISTENCY ITER REACHED";
424 CHECKPERF( m_perf_counter.stop(PerfCounter::CONSIST) )
425
426 // D'abord déraffine les items flaggés.
427 CHECKPERF( m_perf_counter.start(PerfCounter::COARSEN) )
428 const bool coarsening_changed_mesh = this->_coarsenItems();
429 CHECKPERF( m_perf_counter.stop(PerfCounter::COARSEN) )
430
431 // Maintenant, raffine les items flaggés. Ceci prendra
432 // plus de mémoire, et peut être plus de ce qui est libre.
434 const bool refining_changed_mesh = this->_refineItems(cells_to_refine);
435
436 // Finalement, préparation du nouveau maillage pour utilisation
438 bool do_compact = m_mesh->properties()->getBool("compact");
439 m_mesh->properties()->setBool("compact",true) ; // Forcing compaction prevents from bugs when using AMR
440
441 // Raffinement
442 CHECKPERF( m_perf_counter.start(PerfCounter::ENDUPDATE) )
444 m_mesh->properties()->setBool("compact",do_compact) ;
445 CHECKPERF( m_perf_counter.stop(PerfCounter::ENDUPDATE) )
446
447 // deraffinement
448 //bool remove_ghost_children = false;
450 {
451 //remove_ghost_children=true;
452
453 CHECKPERF( m_perf_counter.start(PerfCounter::CONTRACT) )
454 this->_contract();
455 CHECKPERF( m_perf_counter.stop(PerfCounter::CONTRACT) )
456
457 CHECKPERF( m_perf_counter.start(PerfCounter::ENDUPDATE) )
458 m_mesh->properties()->setBool("compact",true) ; // Forcing compaction prevents from bugs when using AMR (leads to problems whith dof)
460 m_mesh->properties()->setBool("compact",do_compact) ;
461 CHECKPERF( m_perf_counter.stop(PerfCounter::ENDUPDATE) )
462
463 }
464
465 // callback pour transporter les variables sur le nouveau maillage
466 CHECKPERF( m_perf_counter.start(PerfCounter::INTERP) )
467 this->_interpolateData(cells_to_refine);
468 CHECKPERF( m_perf_counter.stop(PerfCounter::INTERP) )
469 //
470
472 this->_makeFlagParallelConsistent2();
473
474 if (m_mesh->parallelMng()->isParallel())
475 {
476 CHECKPERF( m_perf_counter.start(PerfCounter::PGHOST) )
477 m_mesh->modifier()->setDynamic(true);
482 false);
483 _update(ghost_cell_to_refine) ;
484 CHECKPERF( m_perf_counter.stop(PerfCounter::PGHOST) )
485 _checkOwner("refineAndCoarsenItems after ghost update");
486 }
487
488 /*
489 if(do_compact)
490 {
491 CHECKPERF( m_perf_counter.start(PerfCounter::COMPACT) )
492 m_mesh->properties()->setBool("compact",true) ;
493 DynamicMesh* mesh = dynamic_cast<DynamicMesh*> (m_mesh);
494 if(mesh)
495 mesh->compact() ;
496 CHECKPERF( m_perf_counter.stop(PerfCounter::COMPACT) )
497 }*/
498
499#ifdef ACTIVATE_PERF_COUNTER
500 info()<<"MESH REFINEMENT PERF INFO" ;
501 m_perf_counter.printInfo(info().file()) ;
502 info()<<"NODE FINDER PERF INFO" ;
503 m_node_finder.getPerfCounter().printInfo(info().file()) ;
504 info()<<"FACE FINDER PERF INFO" ;
505 m_face_finder.getPerfCounter().printInfo(info().file()) ;
506 info()<<"PARALLEL AMR CONSISTENCY PERF INFO" ;
507 m_parallel_amr_consistency->getPerfCounter().printInfo(info().file()) ;
508#endif
509 return true;
510 }
511 // Si il n'y avait aucun changement dans le maillage
512 return false;
513}
514
515/*---------------------------------------------------------------------------*/
516/*---------------------------------------------------------------------------*/
517
518bool
521{
522
524
525 // la rêgle de niveau-un est la seule condition implementée
526 if (!maintain_level_one){
527 warning() << "Warning, level one rule is the only condition accepted for AMR!";
528 }
529 else
530 _maintain_level_one = m_face_level_mismatch_limit;
531
532 // Nous ne pouvons pas encore transformer un maillage de non-niveau-un en un maillage de niveau-un
534 ARCANE_ASSERT((_checkLevelOne(true)), ("check_level_one failed"));
535 }
536
537 // Nettoyage des flags de raffinement de l'étape précédente
538 this->_cleanRefinementFlags();
539
540 // La consistence parallêle doit venir en premier, ou le déraffinement
541 // le long des interfaces entre processeurs pourrait de temps en temps être
542 // faussement empéché
543 if (m_mesh->parallelMng()->isParallel())
545
546 // Repete jusqu'au matching du changement de flags sur chaque processeur
547 do
548 {
549 // Repete jusqu'au matching des flags localement.
550 bool satisfied = false;
551 do
552 {
553 const bool coarsening_satisfied = this->_makeCoarseningCompatible(maintain_level_one);
555#ifdef ARCANE_DEBUG
557 max_satisfied = m_mesh->parallelMng()->reduce(Parallel::ReduceMax,max_satisfied);
558 min_satisfied = m_mesh->parallelMng()->reduce(Parallel::ReduceMin,min_satisfied);
559 ARCANE_ASSERT ( (satisfied == max_satisfied), ("parallel max_satisfied failed"));
560 ARCANE_ASSERT ( (satisfied == min_satisfied), ("parallel min_satisfied failed"));
561#endif
562 } while (!satisfied);
563 } while (m_mesh->parallelMng()->isParallel() && !this->_makeFlagParallelConsistent());
564
565 // Déraffine les items flaggés.
566 const bool mesh_changed = this->_coarsenItems();
567
568 //if (_maintain_level_one)
569 //ARCANE_ASSERT( (checkLevelOne(true)),("checkLevelOne failed"));
570 //ARCANE_ASSERT( (this->makeCoarseningCompatible(maintain_level_one)), ("make_coarsening_comptaible failed"));
571
572 // Finalement, préparation du nouveau maillage pour utilisation
573 if (mesh_changed)
574 {
575 this->_contract();
576 _checkOwner("coarsenItems");
577 //
578 //m_mesh->modifier()->setDynamic(true);
579 //m_mesh->modifier()->updateGhostLayerFromParent(false);
580 }
581
582 return mesh_changed;
583}
584
585/*---------------------------------------------------------------------------*/
586/*---------------------------------------------------------------------------*/
587
590{
591 // Nettoyage des flags de raffinement de l'étape précédente
592 this->_cleanRefinementFlags();
593
595 //UniqueArray<Int64> d_to_coarse_uid;
596
598 Cell cell = *icell;
600 // On ne peut pas dé-raffiner des mailles de niveau 0.
601 if (cell.level() == 0) {
602 ARCANE_FATAL("Cannot coarse level-0 cell");
603 }
604 Cell parent = cell.hParent();
605
606 // TODO AH : Pour faire le dé-raffinement de plusieurs niveau en une fois,
607 // le flag II_Inactive doit être retiré (pour la méthode FaceFamily::removeCellFromFace()).
608 if (update_parent_flag) {
612 }
613
614 // Pour une maille de niveau n-1, si une de ses mailles filles doit être dé-raffinée,
615 // alors toutes ses mailles filles doivent être dé-raffinées.
616 for (Integer i = 0; i < parent.nbHChildren(); ++i) {
617 Cell child = parent.hChild(i);
618 if (!(child.mutableItemBase().flags() & ItemFlags::II_Coarsen)) {
619 ARCANE_FATAL("Parent cannot have children with coarse flag and children without coarse flag -- Parent uid: {0} -- Child uid: {1}", parent.uniqueId(), child.uniqueId());
620 }
621 }
622
623 // Pour l'instant, il est impossible de dé-raffiner de plusieurs niveaux en une fois.
624 // TODO AH : La méthode FaceReorienter::checkAndChangeOrientationAMR() va vérifier une
625 // face sensée être supprimée, voir pourquoi.
627 ARCANE_FATAL("Cannot coarse parent and child in same time");
628 }
629 if (cell.nbHChildren() != 0) {
630 ARCANE_FATAL("For now, cannot coarse cell with children");
631 // for (Integer i = 0; i < cell.nbHChildren(); ++i) {
632 // Cell child = cell.hChild(i);
633 // if (!(child.mutableItemBase().flags() & ItemFlags::II_Coarsen)) {
634 // ARCANE_FATAL("Cannot coarse cell with non-coarsen children -- Parent uid: {0} -- Child uid: {1}", cell.uniqueId(), child.uniqueId());
635 // }
636 // }
637 }
638 to_coarse.add(cell.localId());
639 //d_to_coarse_uid.add(cell.uniqueId());
640 }
641 }
642
643 if (m_mesh->parallelMng()->isParallel()) {
645
647 Cell cell = *icell;
649 for (Face face : cell.faces()) {
650 Cell other_cell = face.oppositeCell(cell);
651 // debug() << "Check face uid : " << face.uniqueId();
652 // Si la face est au bord, elle sera supprimée.
653 if (other_cell.null()) { // && !has_ghost_layer) {
654 continue;
655 //needed_cell.add(face.uniqueId());
656 }
657 if (other_cell.level() != cell.level()) {
658 //warning() << "Bad connectivity";
659 continue;
660 }
661 // Si les deux mailles vont être supprimées, la face sera supprimée.
662 if (other_cell.mutableItemBase().flags() & ItemFlags::II_Coarsen) {
663 continue;
664 }
665 // Si la maille à côté est raffinée, on aura plus d'un niveau de décalage.
666 if (other_cell.nbHChildren() != 0) { // && !(other_cell.mutableItemBase().flags() & ItemFlags::II_Coarsen)) { // Impossible de dé-raffiner plusieurs niveaux.
667 ARCANE_FATAL("Once level diff between two cells needed -- Cell uid: {0} -- Opposite cell uid: {1}", cell.uniqueId(), other_cell.uniqueId());
668 }
669 // Si la maille d'à côté n'est pas à nous, elle prend la propriété de la maille d'à côté.
670 if (other_cell.owner() != cell.owner()) {
671 // debug() << "Face uid : " << face.uniqueId()
672 // << " -- old owner: " << face.owner()
673 // << " -- new owner: " << other_cell.owner();
674 face.mutableItemBase().setOwner(other_cell.owner(), cell.owner());
675 // debug() << "Set owner face uid: " << face.uniqueId() << " -- New owner: " << other_cell.owner();
676 }
677 }
678 for (Node node : cell.nodes()) {
679 // debug() << "Check node uid : " << node.uniqueId();
680
681 // Noeud sera supprimé ?
682 {
683 bool will_deleted = true;
684 for (Cell cell2 : node.cells()) {
685 if (!(cell2.mutableItemBase().flags() & ItemFlags::II_Coarsen)) {
686 will_deleted = false;
687 break;
688 }
689 }
690 if (will_deleted) {
691 continue;
692 }
693 }
694
695 // Noeud devra changer de proprio ?
696 {
697 Integer node_owner = node.owner();
698 Integer new_owner = -1;
699 bool need_new_owner = true;
700 for (Cell cell2 : node.cells()) {
701 if (!(cell2.mutableItemBase().flags() & ItemFlags::II_Coarsen)) {
702 if (cell2.owner() == node_owner) {
703 need_new_owner = false;
704 break;
705 }
706 new_owner = cell2.owner();
707 }
708 }
709 if (!need_new_owner) {
710 continue;
711 }
712 // debug() << "Node uid : " << node.uniqueId()
713 // << " -- old owner: " << node.owner()
714 // << " -- new owner: " << new_owner;
715 node.mutableItemBase().setOwner(new_owner, cell.owner());
716 // debug() << "Set owner node uid: " << node.uniqueId() << " -- New owner: " << new_owner;
717 }
718 }
719 }
720 }
721
722 if (!has_ghost_layer) {
723 // TODO
724 ARCANE_NOT_YET_IMPLEMENTED("Support des maillages sans mailles fantômes à faire");
725 }
726 }
727
728 //debug() << "Removed cells: " << d_to_coarse_uid;
729
737 m_mesh->modifier()->setDynamic(true);
738
741
743
744 return m_mesh->parallelMng()->reduce(Parallel::ReduceMax, (!to_coarse.empty()));
745}
746
747/*---------------------------------------------------------------------------*/
748/*---------------------------------------------------------------------------*/
749
750bool
753{
754
756
757 // la règle de niveau-un est la seule condition implementé
759 {
760 warning() << "Warning, level one rule is the only condition accepted for AMR!";
761 }
762 else
763 _maintain_level_one = m_face_level_mismatch_limit;
764
766 ARCANE_ASSERT((_checkLevelOne(true)), ("check_level_one failed"));
767 }
768 // Nettoyage des flags de raffinement de l'étape précédente
769 this->_cleanRefinementFlags();
770
771 // La consistence parallêle doit venir en premier, ou le déraffinement
772 // le long des interfaces entre processeurs pourrait de temps en temps être
773 // faussement empêché
774 if (m_mesh->parallelMng()->isParallel())
776
777 // Repete jusqu'au matching du changement de flags sur chaque processeur
778 do
779 {
780 // Repete jusqu'au matching des flags localement.
781 bool satisfied = false;
782 do
783 {
784 const bool refinement_satisfied = this->_makeRefinementCompatible(maintain_level_one);
786#ifdef ARCANE_DEBUG
788 max_satisfied = m_mesh->parallelMng()->reduce(Parallel::ReduceMax,max_satisfied);
789 min_satisfied = m_mesh->parallelMng()->reduce(Parallel::ReduceMin,min_satisfied);
790 ARCANE_ASSERT ( (satisfied == max_satisfied), ("parallel max_satisfied failed"));
791 ARCANE_ASSERT ( (satisfied == min_satisfied), ("parallel min_satisfied failed"));
792#endif
793 } while (!satisfied);
794 } while (m_mesh->parallelMng()->isParallel() && !this->_makeFlagParallelConsistent());
795
796 // Maintenant, raffine les items flaggés. Ceci prendra
797 // plus de mémoire, et peut être plus de ce qui est libre.
799 const bool mesh_changed = this->_refineItems(cells_to_refine);
800
801 // Finalement, préparation du nouveau maillage pour utilisation
802 if (mesh_changed){
803 // mise a jour
804 bool do_compact = m_mesh->properties()->getBool("compact");
805 m_mesh->properties()->setBool("compact",true) ; // Forcing compaction prevents from bugs when using AMR
807 m_mesh->properties()->setBool("compact",do_compact) ;
808
809 // callback pour transporter les variables sur le nouveau maillage
810 this->_interpolateData(cells_to_refine);
811
812 // mise a jour des ghosts
813 m_mesh->modifier()->setDynamic(true);
817 _update(ghost_cell_to_refine) ;
818 }
819
820 //if (_maintain_level_one)
821 //ARCANE_ASSERT( (checkLevelOne(true)), ("check_level_one failed"));
822 //ARCANE_ASSERT( (this->makeRefinementCompatible(maintain_level_one)), ("make_refinment_compatible failed"));
823
824 return mesh_changed;
825}
826
827/*---------------------------------------------------------------------------*/
828/*---------------------------------------------------------------------------*/
829
831uniformlyRefine(Integer n)
832{
833 // Raffine n fois
834 // FIXME - ceci ne doit pas marcher si n>1 et le maillage
835 // est déjà attaché au système d'équations à résoudre
836 for (Integer rstep = 0; rstep < n; rstep++){
837 // Nettoyage des flags de raffinement
838 this->_cleanRefinementFlags();
839
840 // itérer seulement sur les mailles actives
841 // Flag tous les items actifs pour raffinement
843 Cell cell = *icell;
844 _setRefineFlags(cell);
845 }
846 // Raffine tous les items que nous avons flaggés.
848 this->_refineItems(cells_to_refine);
849 warning() << "ATTENTION: No Data Projection with this method!";
850 }
851
852 bool do_compact = m_mesh->properties()->getBool("compact");
853 m_mesh->properties()->setBool("compact",true) ;// Forcing compaction prevents from bugs when using AMR
855 m_mesh->properties()->setBool("compact",do_compact) ;
856}
857
858/*---------------------------------------------------------------------------*/
859/*---------------------------------------------------------------------------*/
860
861void
863uniformlyCoarsen(Integer n)
864{
865 // Déraffine n fois
866 for (Integer rstep = 0; rstep < n; rstep++){
867 // Nettoyage des flags de raffinement
868 this->_cleanRefinementFlags();
869
870 // itérer seulement sur les mailles actives
871 // Flag tous les items actifs pour déraffinement
873 Cell cell = *icell;
874 _setCoarseFlags(cell);
875 if (cell.nbHParent() != 0){
877 }
878 }
879 // Déraffine tous les items que nous venons de flagger.
880 this->_coarsenItems();
881 warning() << "ATTENTION: No Data Restriction with this method!";
882 }
883
884 // Finalement, préparation du nouveau maillage pour utilisation
885 bool do_compact = m_mesh->properties()->getBool("compact");
886 m_mesh->properties()->setBool("compact",true) ;
888 m_mesh->properties()->setBool("compact",do_compact) ;
889}
890
891/*---------------------------------------------------------------------------*/
892/*---------------------------------------------------------------------------*/
893
894Int64
896findOrAddNodeUid(const Real3& p, const Real& tol)
897{
898 //debug() << "addNode()";
899
900 // Return the node if it already exists
901 Int64 uid = m_node_finder.find(p, tol);
902 if (uid != NULL_ITEM_ID)
903 {
904 // debug() << "addNode() done";
905 return uid;
906 }
907 // Add the node to the map.
908 Int64 new_uid = m_next_node_uid;
909 m_node_finder.insert(p, new_uid,tol);
910 m_next_node_uid += m_mesh->parallelMng()->commSize() + 1;
911 // Return the uid of the new node
912 // debug() << "addNode() done";
913 return new_uid;
914}
915/*---------------------------------------------------------------------------*/
916/*---------------------------------------------------------------------------*/
917Int64
919findOrAddFaceUid(const Real3& p, const Real& tol, bool& is_added)
920{
921 //debug() << "findOrAddFaceUid()";
922
923 // Return the face if it already exists
924 Int64 uid = m_face_finder.find(p, tol);
925 if (uid != NULL_ITEM_ID)
926 {
927 // debug() << "findOrAddFaceUid() done";
928 is_added = false;
929 return uid;
930 }
931 // Add the face to the map.
932 is_added = true;
933 Int64 new_uid = m_next_face_uid;
934 m_face_finder.insert(p, new_uid,tol);
935 m_next_face_uid += m_mesh->parallelMng()->commSize() + 1;
936 // Return the uid of the new face
937 // debug() << "findOrAddFaceUid() done";
938 return new_uid;
939}
940
941/*---------------------------------------------------------------------------*/
942/*---------------------------------------------------------------------------*/
943
946{
947 Int64 new_uid = m_next_cell_uid;
948 Int64 comm_size = m_mesh->parallelMng()->commSize();
949 m_next_cell_uid += comm_size * m_max_nb_hChildren;
950 return new_uid;
951}
952
953/*---------------------------------------------------------------------------*/
954/*---------------------------------------------------------------------------*/
955/* PRIVATE METHODS */
956/*---------------------------------------------------------------------------*/
957/*---------------------------------------------------------------------------*/
958
959void
962{
963 //jmg this->init(); // \todo pas necessaire de l'appeler a chaque m-a-j
964 //m_node_finder.init();
965 m_node_finder.check() ;
966 //m_face_finder.init();
967 m_face_finder.check() ;
968 debug() << "[MeshRefinement::updateLocalityMap] done";
969}
970/*---------------------------------------------------------------------------*/
971/*---------------------------------------------------------------------------*/
972
973void
974MeshRefinement::
975_updateLocalityMap2()
976{
977 //this->init(); // \todo pas necessaire de l'appeler a chaque m-a-j
978 //this->m_node_finder.init2();
979 //m_node_finder.check2() ;
980 //m_face_finder.init2();
981 //m_face_finder.check2();
982 //debug() << "[MeshRefinement::updateLocalityMap2] done";
983}
984/*---------------------------------------------------------------------------*/
985/*---------------------------------------------------------------------------*/
986
989{
990 bool failure = false;
991
992 Integer sid = m_mesh->parallelMng()->commRank();
993 // itérer seulement sur les mailles actives
995 {
996 Cell cell = *icell;
997 for( Face face : cell.faces() ) {
998 if (face.nbCell()!=2)
999 continue;
1000 Cell back_cell = face.backCell();
1001 Cell front_cell = face.frontCell();
1002
1003 // On choisit l'autre cellule du cote de la face
1005 if (neighbor.null() || !neighbor.isActive() || !(neighbor.owner()==sid))
1006 continue;
1007 //debug() << "#### " << ineighbor->uniqueId() << " " << ineighbor->level() << " " << cell.level();
1008 if ((neighbor.level() + 1 < cell.level())){
1009 failure = true;
1010 break;
1011 }
1012 }
1013 }
1014
1015 // Si un processeur échoue, on échoue globalement
1016 failure = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, failure);
1017
1018 if (failure){
1019 // Nous n'avons pas passé le test level-one, donc arcane_assert
1020 // en fonction du booléen d'entré.
1022 throw FatalErrorException(A_FUNCINFO,"checkLevelOne failed");
1023 return false;
1024 }
1025 return true;
1026}
1027
1028/*---------------------------------------------------------------------------*/
1029/*---------------------------------------------------------------------------*/
1030
1033{
1034 bool found_flag = false;
1035
1036 // recherche pour les flags locaux
1037 // itérer seulement sur les mailles actives
1039 const Cell cell = *icell;
1040 const Integer f = cell.itemBase().flags();
1042 {
1043 found_flag = true;
1044 break;
1045 }
1046 }
1047 // Si nous trouvions un flag sur n'importe quel processeur, il compte
1048 found_flag = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, found_flag);
1049 if (found_flag){
1050 //nous n'avons pas passé le test "items are unflagged",
1051 //ainsi arcane_assert la non valeur de arcane_assert_pass
1053 throw FatalErrorException(A_FUNCINFO,"checkUnflagged failed");
1054 return false;
1055 }
1056 return true;
1057}
1058
1059/*---------------------------------------------------------------------------*/
1060/*---------------------------------------------------------------------------*/
1061
1064{
1065 if (!m_mesh->parallelMng()->isParallel())
1066 return true;
1067
1068 CHECKPERF( m_perf_counter.start(PerfCounter::PCONSIST) )
1069 debug() << "makeFlagsParallelConsistent() begin";
1070 bool parallel_consistent = true;
1073 ghost_cells.reserve(m_mesh->allCells().size()-m_mesh->ownCells().size()) ;
1075 Cell cell = *icell;
1076 if(cell.isOwn()) {
1077 Integer f = cell.itemBase().flags(); // TODO getAMRFlags()
1079 }
1080 else
1081 ghost_cells.add(cell);
1082 }
1083 flag_cells_consistent.synchronize();
1084 //ENUMERATE_CELL(icell,m_mesh->allCells())
1085 for(Integer icell=0, nb_cell=ghost_cells.size();icell<nb_cell;++icell) {
1087 Integer f = iitem.itemBase().flags();
1088
1089 //if(iitem->owner() != sid)
1090 {
1091 // il est possible que les flags des ghosts soient (temporairement) plus
1092 // conservatifs que nos propres flags , comme quand un raffinement d'une
1093 // des mailles du processeur distant est dicté par un raffinement d'une de nos mailles
1094 const Integer g = flag_cells_consistent[Cell(iitem)];
1096 {
1098 iitem.mutableItemBase().setFlags(f);
1099 parallel_consistent = false;
1100 }
1101 else if ((g & ItemFlags::II_Coarsen) && !(f & ItemFlags::II_Coarsen))
1102 {
1104 iitem.mutableItemBase().setFlags(f);
1105 parallel_consistent = false;
1106 }
1108 {
1110 iitem.mutableItemBase().setFlags(f);
1111 parallel_consistent = false;
1112 }
1114 {
1116 iitem.mutableItemBase().setFlags(f);
1117 parallel_consistent = false;
1118 }
1119 /*
1120 else if ((g & ItemFlags::II_CoarsenInactive) && !(f & ItemFlags::II_CoarsenInactive)){
1121 f |= ItemFlags::II_CoarsenInactive;
1122 //f |= ItemFlags::II_Inactive;
1123 iitem->setFlags(f);
1124 parallel_consistent = false;
1125 }
1126 else if ((g & ItemFlags::II_DoNothing) && !(f & ItemFlags::II_DoNothing)){
1127 f |= ItemFlags::II_DoNothing;
1128 //f |= ItemFlags::II_Inactive;
1129 iitem->setFlags(f);
1130 parallel_consistent = false;
1131 }
1132
1133 else if ((g & ItemFlags::II_Inactive) && !(f & ItemFlags::II_Inactive)){
1134 f |= ItemFlags::II_Inactive;
1135 //f |= ItemFlags::II_Inactive;
1136 iitem->setFlags(f);
1137 parallel_consistent = false;
1138 }*/
1139 }
1140 }
1141 // Si nous ne sommes pas consistent sur chaque processeur alors
1142 // nous ne le sommes pas globalement
1144 debug() << "makeFlagsParallelConsistent() end -- parallel_consistent : " << parallel_consistent;
1145
1146 CHECKPERF( m_perf_counter.stop(PerfCounter::PCONSIST) )
1147 return parallel_consistent;
1148}
1149/*---------------------------------------------------------------------------*/
1150/*---------------------------------------------------------------------------*/
1151bool
1152MeshRefinement::
1153_makeFlagParallelConsistent2()
1154{
1155 if (!m_mesh->parallelMng()->isParallel())
1156 return true;
1157
1158 CHECKPERF( m_perf_counter.start(PerfCounter::PCONSIST2) )
1159 debug() << "makeFlagsParallelConsistent2() begin";
1160 bool parallel_consistent = true;
1163 ghost_cells.reserve(m_mesh->allCells().size()-m_mesh->ownCells().size()) ;
1165 {
1166 Cell cell = *icell;
1167 if (cell.isOwn()) {
1168 Integer f = cell.itemBase().flags(); // TODO getAMRFlags()
1170 }
1171 else
1172 ghost_cells.add(cell);
1173 }
1174 flag_cells_consistent.synchronize();
1175 //ENUMERATE_CELL(icell,m_mesh->allCells())
1176 for(Integer icell=0, nb_cell=ghost_cells.size();icell<nb_cell;++icell) {
1177 //const Cell& cell = *icell;
1178 //ItemInternal * iitem = cell.internal();
1179 //Integer f = iitem->flags();
1180 Item iitem = ghost_cells[icell];
1181 Integer f = iitem.itemBase().flags();
1182
1183 //if(iitem->owner() != sid)
1184 {
1185 Integer g = flag_cells_consistent[Cell(iitem)];
1187 {
1189 iitem.mutableItemBase().setFlags(f);
1190 parallel_consistent = false;
1191 }
1193 {
1195 iitem.mutableItemBase().setFlags(f);
1196 parallel_consistent = false;
1197 }
1198 else if ((g & ItemFlags::II_Inactive) && !(f & ItemFlags::II_Inactive))
1199 {
1201 iitem.mutableItemBase().setFlags(f);
1202 parallel_consistent = false;
1203 }
1204 /*else if ((f & ItemFlags::II_JustRefined) && !(g & ItemFlags::II_JustRefined)){
1205 f &= ~ItemFlags::II_JustRefined;
1206 iitem->setFlags(f);
1207 parallel_consistent = false;
1208 }*/
1209 }
1210 }
1211 // Si nous ne sommes pas consistent sur chaque processeur alors
1212 // nous ne le sommes pas globalement
1213 parallel_consistent = m_mesh->parallelMng()->reduce(Parallel::ReduceMin, parallel_consistent);
1214 debug() << "makeFlagsParallelConsistent2() end";
1215
1216 CHECKPERF( m_perf_counter.stop(PerfCounter::PCONSIST2) )
1217 return parallel_consistent;
1218}
1219/*---------------------------------------------------------------------------*/
1220/*---------------------------------------------------------------------------*/
1221
1222bool
1225{
1226
1227 debug() << "makeCoarseningCompatible() begin";
1228
1230
1231 // la règle de niveau-un est la seule condition implementée
1232 if (!maintain_level_one){
1233 warning() << "Warning, level one rule is the only condition accepted for AMR!";
1234 }
1235 else
1236 _maintain_level_one = m_face_level_mismatch_limit;
1237
1238 // à moins que nous rencontrions une situation spécifique, la règle niveau-un
1239 // sera satisfaite aprês avoir exécuté cette boucle juste une fois
1240 bool level_one_satisfied = true;
1241
1242 // à moins que nous rencontrions une situation spéccifique, nous serons compatible
1243 // avec tous flags de raffinement choisis
1244 bool compatible_with_refinement = true;
1245
1246 // Trouver le niveau maximum dans le maillage
1247 Integer max_level = 0;
1248
1249 // d'abord nous regardons tous les items actifs de niveau 0. Puisque ca n'a pas de sens de
1250 // les déraffiner nous devons donc supprimer leur flags de déraffinement si
1251 // ils sont déjà positionnés.
1252 // itérer seulement sur les mailles actives
1254 const Cell cell = *icell;
1255 max_level = std::max(max_level, cell.level());
1256
1257 Integer f = cell.itemBase().flags();
1258 if ((cell.level() == 0) && (f & ItemFlags::II_Coarsen)) {
1259 f &= ~ItemFlags::II_Coarsen;
1261 cell.mutableItemBase().setFlags(f);
1262 }
1263 }
1264 // Si il n'y a pas d'items à raffiner sur ce processeur alors
1265 // il n'y a pas de travail à faire pour nous
1266 if (max_level == 0){
1267 debug() << "makeCoarseningCompatible() done";
1268
1269 // par contre il reste à vérifier avec les autres processeurs
1271
1273 }
1274
1275 // Boucle sur tous les items actifs. Si un item est marqué
1276 // pour déraffinement on check ses voisins. Si un de ses voisins
1277 // est marqué pour raffinement et est de même niveau alors il y a un
1278 // conflit. Par convention raffinement gagne, alors on démarque l'item pour
1279 // déraffinement. Le niveau-un serait violé dans ce cas-ci ainsi nous devons réexécuter
1280 // la boucle.
1281 const Integer sid = m_mesh->parallelMng()->commRank();
1283 {
1284
1286
1287 do
1288 {
1289 level_one_satisfied = true;
1290 // itérer seulement sur les mailles actives
1292 Cell cell = *icell;
1293 //ItemInternal* iitem = cell.internal();
1294 bool my_flag_changed = false;
1295 Integer f = cell.itemBase().flags();
1296 if (f & ItemFlags::II_Coarsen){ // Si l'item est actif et le flag de déraffinement est placé
1297 const Int32 my_level = cell.level();
1298 for( Face face : cell.faces() ) {
1299 if (face.nbCell()!=2)
1300 continue;
1301 Cell back_cell = face.backCell();
1302 Cell front_cell = face.frontCell();
1303
1304 // On choisit l'autre cellule du cote de la face
1306 //const ItemInternal* ineighbor = neighbor.internal();
1307 //if (ineighbor->owner() == sub_domain_id) // J'ai un voisin ici
1308
1309 {
1310 if (neighbor.isActive()) // et est actif
1311 {
1312 if ((neighbor.level() == my_level) &&
1313 (neighbor.itemBase().flags() & ItemFlags::II_Refine)){ // le voisin est à mon niveau et veut être raffiné
1314 f &= ~ItemFlags::II_Coarsen;
1316 cell.mutableItemBase().setFlags(f);
1317 my_flag_changed = true;
1318 break;
1319 }
1320 }
1321 else{
1322 // J'ai un voisin et n'est pas actif. Cela signifie qu'il a des enfants.
1323 // tandis qu'il peut être possible de me déraffiner si tous les enfants
1324 // de cet item veulent être déraffinés, il est impossible de savoir à ce stade.
1325 // On l'oublie pour le moment. Ceci peut être réalisé dans deux étapes.
1326 f &= ~ItemFlags::II_Coarsen;
1328 cell.mutableItemBase().setFlags(f);
1329 my_flag_changed = true;
1330 break;
1331 }
1332 }
1333 }
1334 }
1335
1336 //si le flag de la cellule courante a changé, nous n'avons pas
1337 //satisfait la rêgle du niveau un.
1338 if (my_flag_changed)
1339 level_one_satisfied = false;
1340
1341 //En plus, s'il a des voisins non-locaux, et
1342 //nous ne sommes pas en séquentiel, alors nous devons par la suite
1343 // retourner compatible_with_refinement= false, parce que
1344 //notre changement doit être propager aux processeurs voisins
1346 for( Face face : cell.faces() ){
1347 if (face.nbCell()!=2)
1348 continue;
1349 Cell back_cell = face.backCell();
1350 Cell front_cell = face.frontCell();
1351
1352 // On choisit l'autre cellule du cote de la face
1354 //ItemInternal* ineighbor = neighbor.internal();
1355 if (neighbor.owner() != sid){ // J'ai un voisin ici
1357 break;
1358 }
1359 // TODO FIXME - pour les maillages non niveau-1 nous devons
1360 // tester tous les descendants
1361 if (neighbor.hasHChildren())
1362 for (Integer c=0; c != neighbor.nbHChildren(); ++c)
1363 if (neighbor.hChild(c).owner() != sid){
1365 break;
1366 }
1367 }
1368
1369 }
1370 }
1371 while (!level_one_satisfied);
1372
1373 } // end if (_maintain_level_one)
1374
1375 //après, nous regardons tous les items ancêtres.
1376 //s'il y a un item parent avec tous ses enfants
1377 //voulant être déraffiné alors l'item est un candidat
1378 //pour le déraffinement. Si tous les enfants ne
1379 //veulent pas être déraffiné alors tous ont besoin d'avoir leur
1380 // flag de déraffinement dégagés.
1381 for (int level=(max_level); level >= 0; level--){
1382 // itérer sur les mailles niveau par niveau
1384 const Cell cell = *icell;
1385 //ItemInternal* iitem = cell.internal();
1386 if(cell.isAncestor()){
1387 // à ce moment là l'item n'a pas été éliminé
1388 // en tant que candidat pour le déraffinement
1389 bool is_a_candidate = true;
1390 bool found_remote_child = false;
1391
1392 for (Integer c=0; c<cell.nbHChildren(); c++){
1393 Cell child = cell.hChild(c);
1394 if (child.owner() != sid)
1395 found_remote_child = true;
1396 else if (!(child.itemBase().flags() & ItemFlags::II_Coarsen) || !child.isActive() )
1397 is_a_candidate = false;
1398 }
1399
1402 for (Integer c=0; c<cell.nbHChildren(); c++){
1403 Cell child = cell.hChild(c);
1404 if (child.owner() != sid)
1405 continue;
1406 if (child.itemBase().flags() & ItemFlags::II_Coarsen){
1407 level_one_satisfied = false;
1408 Int32 f = child.itemBase().flags();
1409 f &= ~ItemFlags::II_Coarsen;
1411 child.mutableItemBase().setFlags(f);
1412 }
1413 }
1414 }
1415 }
1416 }
1417 }
1419
1420 // Si tous les enfants d'un parent sont marqués pour déraffinement
1421 // Alors marque le parent à ce qu'il puisse tuer ses enfants.
1423 const Cell cell = *icell;
1424 //ItemInternal* iitem = cell.internal();
1425 if(cell.isAncestor()){
1426 // Supposons que tous les enfants sont locaux et marqués pour
1427 // déraffinement et donc cherche pour une contradiction
1429 bool found_remote_child = false;
1430
1431 for (Integer c=0; c<cell.nbHChildren(); c++){
1432 Cell child = cell.hChild(c);
1433 if (child.owner() != sid)
1434 found_remote_child = true;
1435 else if (!(child.itemBase().flags() & ItemFlags::II_Coarsen))
1437 }
1438 Integer f = cell.itemBase().flags();
1439 f &= ~ItemFlags::II_CoarsenInactive;
1441 {
1443 cell.mutableItemBase().setFlags(f);
1444 }
1445 else if (!found_remote_child)
1446 {
1448 cell.mutableItemBase().setFlags(f);
1449 }
1450 }
1451 }
1452
1453 debug() << "makeCoarseningCompatible() done";
1454
1455 // Si nous sommes pas compatible sur un processeur, nous ne le sommes pas globalement
1457
1459}
1460
1461/*---------------------------------------------------------------------------*/
1462/*---------------------------------------------------------------------------*/
1463
1464bool
1467{
1468
1469 debug() << "makeRefinementCompatible() begin";
1470
1472
1473 // la règle de niveau-un est la seule condition implementée
1474 if (!maintain_level_one){
1475 warning() << "Warning, level one rule is the only condition accepted now for AMR!";
1476 }
1477 else
1478 _maintain_level_one = m_face_level_mismatch_limit;
1479
1480 // à moins que nous rencontrions une situation spécifique, la règle niveau-un
1481 // sera satisfaite après avoir exécuté cette boucle juste une fois
1482 bool level_one_satisfied = true;
1483
1484 // à moins que nous rencontrions une situation spécifique, nous serons compatible
1485 // avec tous flags de déraffinement choisis
1486 bool compatible_with_coarsening = true;
1487
1488 // cette boucle impose la règle niveau-1. Nous devrions seulement
1489 // l'exécuter si l'utilisateur veut en effet que la niveau-1 soit satisfaite !
1490 Integer sid = m_mesh->parallelMng()->commRank();
1492 do {
1493 level_one_satisfied = true;
1494 // itérer seulement sur les mailles actives
1496 const Cell cell = *icell;
1497 //ItemInternal* iitem = cell.internal();
1498 if (cell.itemBase().flags() & ItemFlags::II_Refine){ // Si l'item est actif et le flag de
1499 // raffinement est placé
1500 const Int32 my_level = cell.level();
1501 bool refinable = true;
1502 //check if refinable
1503 for( Face face : cell.faces() ){
1504 if (face.nbCell()!=2)
1505 continue;
1506 Cell back_cell = face.backCell();
1507 Cell front_cell = face.frontCell();
1508
1509 // On choisit l'autre cellule du cote de la face
1511 //ItemInternal* ineighbor = neighbor.internal();
1512 //if (ineighbor->isActive() && ineighbor->owner() == sid)// J'ai un voisin ici et est actif
1513 if (neighbor.isActive() ){// J'ai un voisin ici et est actif
1514 // Cas 2: Le voisin est inférieur de un niveau que le mien.
1515 // Le voisin doit être raffiné pour satisfaire
1516 // la règle de niveau-1, indépendamment de s'il
1517 // a été à l'origine marqué pour raffinement. S'il
1518 // n'était pas flaggé déjà nous devons répéter
1519 // ce processus.
1520 Integer f = neighbor.itemBase().flags();
1521 if ( ( (neighbor.level()+1) == my_level) &&
1522 ( f & ItemFlags::II_UserMark1) ){
1523 refinable = false;
1524 Integer my_f = cell.itemBase().flags();
1525 my_f &= ~ItemFlags::II_Refine;
1527 break;
1528 }
1529 }
1530 }
1531 if(refinable)
1532 for( Face face : cell.faces() ){
1533 if (face.nbCell()!=2)
1534 continue;
1535 Cell back_cell = face.backCell();
1536 Cell front_cell = face.frontCell();
1537
1538 // On choisit l'autre cellule du cote de la face
1540 //ItemInternal* ineighbor = neighbor.internal();
1541 if (neighbor.isActive() && neighbor.owner() == sid){ // J'ai un voisin ici et est actif
1542
1543 // Cas 1: Le voisin est au même niveau que moi.
1544 // 1a: Le voisin sera raffiné -> NO PROBLEM
1545 // 1b: Le voisin ne va pas être raffiné -> NO PROBLEM
1546 // 1c: Le voisin veut être déjà raffiné -> PROBLEM
1547 if (neighbor.level() == my_level){
1548 Integer f = neighbor.itemBase().flags();
1549 if (f & ItemFlags::II_Coarsen) {
1550 f &= ~ItemFlags::II_Coarsen;
1552 neighbor.mutableItemBase().setFlags(f);
1553 if (neighbor.nbHParent() != 0){
1554 neighbor.hParent().mutableItemBase().addFlags(ItemFlags::II_Inactive);
1555 }
1557 level_one_satisfied = false;
1558 }
1559 }
1560
1561 // Cas 2: Le voisin est inférieur de un niveau que le mien.
1562 // Le voisin doit être raffiné pour satisfaire
1563 // la rêgle de niveau-1, indépendamment de s'il
1564 // a été à l'origine marqué pour raffinement. S'il
1565 // n'était pas flaggé déjà nous devons répéter
1566 // ce processus.
1567
1568 else if ((neighbor.level()+1) == my_level) {
1569 Integer f = neighbor.itemBase().flags();
1570 if (!(f & ItemFlags::II_Refine)) {
1571 f &= ~ItemFlags::II_Coarsen;
1573 neighbor.mutableItemBase().setFlags(f);
1574 if (neighbor.nbHParent() != 0){
1575 neighbor.hParent().mutableItemBase().addFlags(ItemFlags::II_Inactive);
1576 }
1578 level_one_satisfied = false;
1579 }
1580 }
1581#ifdef ARCANE_DEBUG
1582 // Contrôle. Nous ne devrions jamais entrer dans un
1583 // cas ou notre voisin est distancé de plus d'un niveau.
1584
1585 else if ((neighbor.level()+1) < my_level)
1586 {
1587 fatal() << "a neighbor is more than one level away";
1588 }
1589
1590 // On note que la seule autre possibilité est que
1591 // le voisin ait déjà été raffiné, dans ce cas il n'est pas
1592 //actif et nous ne devrions jamais tomber ici.
1593
1594 else
1595 {
1596 fatal() << "serious problem: we should never get here";
1597 }
1598#endif
1599 }
1600 }
1601 }
1602 }
1603 }
1604 while (!level_one_satisfied);
1605 } // end if (_maintain_level_one)
1606
1607 // Si nous sommes pas compatible sur un processeur, nous ne le sommes pas globalement
1609
1610 debug() << "makeRefinementCompatible() done";
1611
1613}
1614
1615/*---------------------------------------------------------------------------*/
1616/*---------------------------------------------------------------------------*/
1617
1618bool
1621{
1622 debug() << "[MeshRefinement::_coarsenItems] begin"<<m_mesh->allNodes().size();
1623 // Flag indiquant si cet appel change réellement le maillage
1624 bool mesh_changed = false;
1625
1626 // itérer sur toutes les mailles
1627 // Int32UniqueArray cell_to_detach;
1629 Cell cell = *icell;
1630 Cell iitem = cell;
1631 // items actifs flaggés prour déraffinement ne seront
1632 // pas supprimés jusqu'à contraction via MeshRefinement::contract()
1633
1634 if (cell.itemBase().flags() & ItemFlags::II_Coarsen){
1635 // Houups? aucun item de niveau-0 ne doit être a la fois actif
1636 // et flaggé pour déraffinement.
1637 ARCANE_ASSERT ( (cell.level() != 0), ("no level-0 element should be active and flagged for coarsening"));
1638
1639 // TODO Supprimer cet item de toute liste de voisinage
1640 // pointant vers lui.
1641 // FIXME à l'IFP, on utilise par défaut la macro REMOVE_UID_ON_DETACH suprimant le UID de CELL
1642 // dans la map des cell_uid donc on ne peut utiliser detachCell par défaut. En attendant
1643 // on utilise la méthode MeshRefinement::contract() après mise à jour des variables
1644 // cell_to_detach.add(iitem->localId());
1645
1646 //cells_to_remove.add(cell);
1647 // TODO optimisation des uids non utilisé.
1648 // m_unused_items.push_back (uid);
1649
1650 // Ne pas détruire l'item jusqu'à MeshRefinement::contract()
1651 // m_mesh->modifier()->removeCells(iitem->localId());
1652
1653 // Le maillage a certainement changé
1654 mesh_changed = true;
1655 }
1656 else if (cell.itemBase().flags() & ItemFlags::II_CoarsenInactive)
1657 {
1658 switch (cell.type())
1659 {
1660 case IT_Quad4:
1662 break;
1663 case IT_Tetraedron4:
1665 break;
1666 case IT_Pyramid5:
1668 break;
1669 case IT_Pentaedron6:
1671 break;
1672 case IT_Hexaedron8:
1674 break;
1675 case IT_HemiHexa7:
1677 break;
1678 case IT_HemiHexa6:
1680 break;
1681 case IT_HemiHexa5:
1683 break;
1684 case IT_AntiWedgeLeft6:
1686 break;
1687 case IT_AntiWedgeRight6:
1689 break;
1690 case IT_DiTetra5:
1692 break;
1693 default:
1694 ARCANE_FATAL("Not supported refinement Item Type type={0}",iitem.type());
1695 }
1696 ARCANE_ASSERT(cell.isActive(), ("cell_active failed"));
1697
1698 // le maillage a certainement changé
1699 mesh_changed = true;
1700 }
1701 }
1702 // TODO
1703 // m_mesh->modifier->detachCells(cell_to_detach);
1704
1705 // Si le maillage a changé sur un processeur, alors il a changé globalement
1706 mesh_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, mesh_changed);
1707 // Et peut être nous avons besoin de mettre à jour les entités refletant le changement
1708 //if (mesh_changed)
1709 // \todo compacte et update max_uids en parallel
1710
1711 // si une maille est deraffinee ailleurs, les noeuds attaches a cette maille
1712 // doivent etre mis a jour. Cela est traite dans endUpdate()
1713
1714 debug() << "[MeshRefinement::_coarsenItems()] done "<<m_mesh->allNodes().size();
1715
1716 return mesh_changed;
1717}
1718
1719/*---------------------------------------------------------------------------*/
1720/*---------------------------------------------------------------------------*/
1721
1722bool
1725{
1726 // Mise à jour de m_node_finder, m_face_finder permettra au maillage
1727 // d'etre consistent globalement (uids consistency).
1728 debug() << "[MeshRefinement::_refineItems]"<<m_mesh->allNodes().size();
1729#ifdef ARCANE_DEBUG
1730 m_node_finder.check() ;
1731 m_face_finder.check() ;
1732#endif
1733 CHECKPERF( m_perf_counter.start(PerfCounter::REFINE) )
1734 m_face_finder.clearNewUids() ;
1735 // Iterer sur les items, compter les items
1736 // flaggés pour le raffinement.
1737 //Integer nb_cell_flagged = 0;
1740 Cell cell = *icell;
1741 if (cell.itemBase().flags() & ItemFlags::II_Refine) {
1742 cell_to_refine_uids.add(cell.uniqueId());
1743 cell_to_refine_internals.add(cell);
1744 }
1745 }
1746 debug() << "[MeshRefinement::_refineItems] " << cell_to_refine_uids.size() << " flagged cells for refinement";
1747
1748 // Construire un vecteur local des items marqués
1749 // pour raffinement.
1750 /*
1751 local_copy_of_cells.reserve(nb_cell_flagged);
1752
1753 ENUMERATE_CELL(icell,m_mesh->ownCells()){
1754 Cell cell = *icell;
1755 ItemInternal* iitem = cell.internal();
1756 if(iitem->flags() & ItemFlags::II_Refine)
1757 local_copy_of_cells.add(iitem);
1758 }
1759 */
1760 // Maintenant, itere sur les copies locales et raffine chaque item.
1761 const Int32 i_size = cell_to_refine_internals.size();
1762 for (Integer e = 0; e != i_size; ++e) {
1764 //debug()<<"\t[MeshRefinement::_refineItems] focus on cell "<<iitem->uniqueId();
1765 switch (iitem.type())
1766 {
1767 case IT_Quad4:
1768 m_item_refinement->refineOneCell<IT_Quad4>(iitem,*this);
1769 break;
1770 case IT_Tetraedron4:
1771 m_item_refinement->refineOneCell<IT_Tetraedron4>(iitem,*this);
1772 break;
1773 case IT_Pyramid5:
1774 m_item_refinement->refineOneCell<IT_Pyramid5>(iitem,*this);
1775 break;
1776 case IT_Pentaedron6:
1777 m_item_refinement->refineOneCell<IT_Pentaedron6>(iitem,*this);
1778 break;
1779 case IT_Hexaedron8:
1780 m_item_refinement->refineOneCell<IT_Hexaedron8>(iitem,*this);
1781 break;
1782 case IT_HemiHexa7:
1783 m_item_refinement->refineOneCell<IT_HemiHexa7>(iitem,*this);
1784 break;
1785 case IT_HemiHexa6:
1786 m_item_refinement->refineOneCell<IT_HemiHexa6>(iitem,*this);
1787 break;
1788 case IT_HemiHexa5:
1789 m_item_refinement->refineOneCell<IT_HemiHexa5>(iitem,*this);
1790 break;
1791 case IT_AntiWedgeLeft6:
1792 m_item_refinement->refineOneCell<IT_AntiWedgeLeft6>(iitem,*this);
1793 break;
1794 case IT_AntiWedgeRight6:
1795 m_item_refinement->refineOneCell<IT_AntiWedgeRight6>(iitem,*this);
1796 break;
1797 case IT_DiTetra5:
1798 m_item_refinement->refineOneCell<IT_DiTetra5>(iitem,*this);
1799 break;
1800 default:
1801 ARCANE_FATAL("Not supported refinement Item Type type={0}",iitem.type());
1802 }
1803 }
1804
1805 // Le maillage change si des items sont raffinés
1806 bool mesh_changed = !(i_size == 0);
1807
1808 // Si le maillage change sur un processeur, il change globalement
1809 mesh_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, mesh_changed);
1810
1811 // Et nous avons besoin de mettre à jour le nombre des ids
1812 if (mesh_changed){
1813 for (Integer e = 0; e != i_size; ++e){
1815 populateBackFrontCellsFromParentFaces(i_hParent_cell);
1816 }
1817 }
1818 CHECKPERF( m_perf_counter.stop(PerfCounter::REFINE) )
1820 {
1821 CHECKPERF( m_perf_counter.start(PerfCounter::PGCONSIST) )
1822#ifdef ARCANE_DEBUG
1823 m_node_finder.check2() ;
1824 m_face_finder.check2() ;
1825#endif
1826
1827 // Nodes and faces parallel consistency
1828 m_parallel_amr_consistency->makeNewItemsConsistent(m_node_finder, m_face_finder);
1829 CHECKPERF( m_perf_counter.stop(PerfCounter::PGCONSIST) )
1830 }
1831
1832 debug() << "[MeshRefinement::_refineItems] done"<<m_mesh->allNodes().size();
1833
1834 return mesh_changed;
1835}
1836
1837/*---------------------------------------------------------------------------*/
1838/*---------------------------------------------------------------------------*/
1839
1842{
1843 //Nettoyage des flags de raffinement d'une étape précédente
1845 Cell cell = *icell;
1846 auto mutable_cell = cell.mutableItemBase();
1847 Integer f = mutable_cell.flags();
1848 if (cell.isActive()){
1850 mutable_cell.setFlags(f);
1851 }
1852 else{
1854 mutable_cell.setFlags(f);
1855 }
1856 // Ceci pourrait être laissé de la derniè étape
1858 f &= ~ItemFlags::II_JustRefined;
1860 mutable_cell.setFlags(f);
1861 }
1863 f &= ~ItemFlags::II_JustCoarsened;
1865 mutable_cell.setFlags(f);
1866 }
1867 if (f & ItemFlags::II_JustAdded){
1868 f &= ~ItemFlags::II_JustAdded;
1870 mutable_cell.setFlags(f);
1871 }
1873 f &= ~ItemFlags::II_CoarsenInactive;
1875 mutable_cell.setFlags(f);
1876 }
1877 }
1878}
1879
1880/*---------------------------------------------------------------------------*/
1881/*---------------------------------------------------------------------------*/
1882
1884_contract()
1885{
1886 DynamicMesh* mesh = m_mesh;
1887 ItemInternalMap& cells_map = mesh->cellsMap();
1888
1889 // Flag indicating if this call actually changes the mesh
1890 bool mesh_changed = false;
1891
1892 if (arcaneIsDebug()){
1893 cells_map.eachItem([&](impl::ItemBase item) {
1894 if (item.isOwn())
1895 // une maille est soit active, subactive ou ancestor
1896 ARCANE_ASSERT((item.isActive() || item.isSubactive() || item.isAncestor()), (" "));
1897 });
1898 }
1899
1900 //
1901 std::set < Int32 > cells_to_remove_set;
1903
1904 cells_map.eachItem([&](impl::ItemBase iitem) {
1905 if (!iitem.isOwn())
1906 return;
1907
1908 // suppression des subactives
1909 if (iitem.isSubactive()) {
1910 // aucune maille de niveau 0 ne doit être subactive.
1911 ARCANE_ASSERT((iitem.nbHParent() != 0), (""));
1912 cells_to_remove_set.insert(iitem.localId());
1913 // informe le client du changement de maillage
1914 mesh_changed = true;
1915 }
1916 else{
1917 // Compression des mailles actives
1918 if (iitem.isActive()) {
1919 bool active_parent = false;
1920 for (Integer c = 0; c < iitem.nbHChildren(); c++) {
1921 impl::ItemBase ichild = iitem.hChildBase(c);
1922 if (!ichild.isSuppressed()) {
1923 //debug() << "[\tMeshRefinement::contract]PARENT UID=" << iitem->uniqueId() << " " << iitem->owner() << " "
1924 // << iitem->level();
1925 cells_to_remove_set.insert(ichild.localId());
1926 //debug() << "[\tMeshRefinement::contract]CHILD UID=" << ichild->uniqueId() << " " << ichild->owner();
1927 active_parent = true;
1928 }
1929 }
1930 if (active_parent){
1931 parent_cells.add(iitem._itemInternal());
1932 ARCANE_ASSERT((iitem.flags() & ItemFlags::II_JustCoarsened), ("Incoherent JustCoarsened flag"));
1933 }
1934 // informe le client du changement de maillage
1935 mesh_changed = true;
1936 }
1937 else{
1938 ARCANE_ASSERT((iitem.isAncestor()), (""));
1939 }
1940 }
1941 });
1942 //
1944 std::copy(std::begin(cells_to_remove_set), std::end(cells_to_remove_set),std::begin(cell_lids));
1945
1946 if (m_mesh->parallelMng()->isParallel()){
1947 this->_makeFlagParallelConsistent2();
1948 this->_removeGhostChildren();
1949 this->_updateItemOwner(cell_lids);
1951 }
1952 if (cell_lids.size() > 0){
1953 this->_upscaleData(parent_cells);
1954 _invalidate(parent_cells);
1955 //_updateItemOwner(cells_local_id);
1957 const Integer ps = parent_cells.size();
1958 for (Integer i = 0; i < ps; i++)
1960 }
1961 else
1962 mesh_changed = false;
1963
1964 return mesh_changed;
1965}
1966
1967/*---------------------------------------------------------------------------*/
1968/*---------------------------------------------------------------------------*/
1969
1970void MeshRefinement::
1971registerCallBack(IAMRTransportFunctor* f)
1972{
1973 m_call_back_mng->registerCallBack(f);
1974}
1975
1976/*---------------------------------------------------------------------------*/
1977/*---------------------------------------------------------------------------*/
1978
1979void MeshRefinement::
1980unRegisterCallBack(IAMRTransportFunctor* f)
1981{
1982 m_call_back_mng->unregisterCallBack(f);
1983}
1984
1985/*---------------------------------------------------------------------------*/
1986/*---------------------------------------------------------------------------*/
1987
1990{
1991 const Int32 nb_cells = cells_to_refine.size();
1995
1997 for (Integer i = 0; i < nb_cells; i++) {
1998 cells_to_refine_internals[i] = ItemCompatibility::_itemInternal(internals[lids[i]]);
1999 }
2000 m_call_back_mng->callCallBacks(cells_to_refine_internals, Prolongation);
2002}
2003
2004void MeshRefinement::
2006{
2007 CHECKPERF( m_perf_counter.start(PerfCounter::UPDATEMAP) )
2008 const Int32 nb_cells = cells_to_refine_uids.size();
2013 for (Integer i = 0; i < nb_cells; i++) {
2014 cells_to_refine[i] = ItemCompatibility::_itemInternal(internals[lids[i]]);
2015 }
2016 m_node_finder.updateData(cells_to_refine);
2017 m_face_finder.updateData(cells_to_refine);
2018 _updateMaxUid(cells_to_refine);
2019 m_item_refinement->updateChildHMin(cells_to_refine) ;
2020 //m_face_finder.updateFaceCenter(cells_to_refine);
2021 CHECKPERF( m_perf_counter.stop(PerfCounter::UPDATEMAP) )
2022}
2023
2024void MeshRefinement::
2025_update(ArrayView<ItemInternal*> cells_to_refine)
2026{
2027 CHECKPERF( m_perf_counter.start(PerfCounter::UPDATEMAP) )
2028 m_node_finder.updateData(cells_to_refine) ;
2029 m_face_finder.updateData(cells_to_refine) ;
2030 _updateMaxUid(cells_to_refine) ;
2031 m_item_refinement->updateChildHMin(cells_to_refine) ;
2032 //m_face_finder.updateFaceCenter(cells_to_refine);
2033 CHECKPERF( m_perf_counter.stop(PerfCounter::UPDATEMAP) )
2034}
2035
2036void MeshRefinement::
2037_invalidate(ArrayView<ItemInternal*> coarsen_cells)
2038{
2039 CHECKPERF( m_perf_counter.start(PerfCounter::CLEAR) )
2040 m_node_finder.clearData(coarsen_cells) ;
2041 m_face_finder.clearData(coarsen_cells) ;
2042 CHECKPERF( m_perf_counter.stop(PerfCounter::CLEAR) )
2043}
2044
2045/*---------------------------------------------------------------------------*/
2046/*---------------------------------------------------------------------------*/
2047
2050{
2051 m_call_back_mng->callCallBacks(parent_cells,Restriction);
2052}
2053
2054/*---------------------------------------------------------------------------*/
2055/*---------------------------------------------------------------------------*/
2056
2057void MeshRefinement::
2058_updateItemOwner(Int32ArrayView cell_to_remove_lids)
2059{
2062
2065
2066 const Integer sid = m_mesh->parallelMng()->commRank();
2067
2068 bool node_owner_changed = false;
2069 bool face_owner_changed = false;
2070
2071 std::map<Int32, bool> marker;
2072
2073 for (Integer i = 0, is = cell_to_remove_lids.size(); i < is; i++){
2075 for (Node node : item.nodes()){
2076
2077 if (marker.find(node.localId()) != marker.end())
2078 continue;
2079 else
2080 marker[node.localId()] = true;
2081
2082 //debug() << "NODE " << FullItemPrinter(node);
2083 //const Int32 owner = node->owner();
2084 bool is_ok = false;
2085 Integer count = 0;
2086 const Integer node_cs = node.cells().size();
2087 for ( Cell cell : node.cells() ){
2088 if (cell_to_remove_lids.contains(cell.localId())){
2089 count++;
2090 if (count == node_cs)
2091 is_ok = true;
2092 continue;
2093 }
2094 // SDC : this condition contributes to desynchronize node owners...
2095// if (cell->owner() == owner)
2096// {
2097// is_ok = true;
2098// break;
2099// }
2100 }
2101 if (!is_ok){
2102 Cell cell;
2103 for ( Cell cell2 : node.cells() ){
2104 if (cell_to_remove_lids.contains(cell2.localId()))
2105 continue;
2106 if (cell.null() || cell2.uniqueId() < cell.uniqueId())
2107 cell = cell2;
2108 }
2109 if (cell.null())
2110 ARCANE_FATAL("Inconsistent null cell owner reference");
2111 const Int32 new_owner = cell.owner();
2112 nodes_owner[node] = new_owner;
2113 node.mutableItemBase().setOwner(new_owner, sid);
2114 //debug() << " NODE CHANGED OWNER " << node->uniqueId();
2115 node_owner_changed = true;
2116 }
2117 }
2118 for ( Face face : item.faces() ){
2119 if (face.nbCell() != 2)
2120 continue;
2121 const Int32 owner = face.owner();
2122 bool is_ok = false;
2123 for (Cell cell : face.cells() ){
2124 if ((item.uniqueId() == cell.uniqueId()) || !(item.level() == cell.level()))
2125 continue;
2126 if (cell.owner() == owner){
2127 is_ok = true;
2128 break;
2129 }
2130 }
2131 if (!is_ok){
2132 for (Cell cell2 : face.cells()){
2133 if (item.uniqueId() == cell2.uniqueId())
2134 continue;
2135 faces_owner[face] = cell2.owner();
2136 face.mutableItemBase().setOwner(cell2.owner(), sid);
2137 //debug() << " FACE CHANGED OWNER " << FullItemPrinter(face);
2138 face_owner_changed = true;
2139 }
2140 }
2141 }
2142 }
2143
2144 node_owner_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, node_owner_changed);
2145 if (node_owner_changed){
2146 // nodes_owner.synchronize(); // SDC Surtout pas la synchro est KO à ce moment là (fantômes non raffinés/déraffinés)
2149 }
2150 face_owner_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, face_owner_changed);
2151 if (face_owner_changed){
2152 faces_owner.synchronize();
2155 }
2156}
2157
2158/*---------------------------------------------------------------------------*/
2159/*---------------------------------------------------------------------------*/
2160
2161void MeshRefinement::
2162_updateItemOwner2()
2163{
2164 // il faut que tout sub-item est une cellule voisine de même propriétaire
2166
2167 NodeGroup own_nodes = m_mesh->ownNodes();
2168 bool owner_changed = false;
2169 ENUMERATE_NODE(inode,own_nodes){
2170 Node node = (*inode);
2171 Int32 owner = node.owner();
2172 bool is_ok = false;
2173 for( Cell cell : node.cells() ){
2174 if (cell.owner()==owner){
2175 is_ok = true;
2176 break;
2177 }
2178 }
2179 if (!is_ok){
2180 Cell cell;
2181 for( Cell cell2 : node.cells() ){
2182 if (cell.null() || cell2.uniqueId() < cell.uniqueId())
2183 cell = cell2;
2184 }
2185 ARCANE_ASSERT((!cell.null()),("Inconsistent null cell owner reference"));
2186 nodes_owner[node] = cell.owner();
2187 owner_changed =true;
2188 }
2189 }
2190 owner_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMin, owner_changed);
2191 if (owner_changed){
2192 nodes_owner.synchronize();
2195 }
2196
2197 // il faut que tout sub-item est une cellule voisine de même propriétaire
2199
2200 FaceGroup own_faces = m_mesh->ownFaces();
2201 owner_changed = false;
2202 ENUMERATE_FACE(iface,own_faces){
2203 Face face = (*iface);
2204 Int32 owner = face.owner();
2205 bool is_ok = false;
2206 for( Cell cell : face.cells() ){
2207 if (cell.owner()==owner){
2208 is_ok = true;
2209 break;
2210 }
2211 }
2212 if (!is_ok){
2213 if(face.nbCell() ==2)
2214 fatal() << "Face" << ItemPrinter(face) << " has a different owner with respect to Back/Front Cells";
2215
2216 faces_owner[face] = face.boundaryCell().owner();
2217 owner_changed=true;
2218 }
2219 }
2220 owner_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMin, owner_changed);
2221 if (owner_changed){
2222 faces_owner.synchronize();
2225 }
2226}
2227/*---------------------------------------------------------------------------*/
2228/*---------------------------------------------------------------------------*/
2229
2230bool MeshRefinement::
2231_removeGhostChildren()
2232{
2233 const Integer sid = m_mesh->parallelMng()->commRank();
2234 DynamicMesh* mesh = m_mesh;
2235 ItemInternalMap& cells_map = mesh->cellsMap();
2236
2237 // Suppression des mailles
2238 Int32UniqueArray cells_to_remove ;
2239 cells_to_remove.reserve(1000);
2240 UniqueArray<ItemInternal*> parent_cells;
2241 parent_cells.reserve(1000);
2242
2243 cells_map.eachItem([&](impl::ItemBase cell) {
2244 if (cell.owner() == sid)
2245 return;
2246
2247 if (cell.flags() & ItemFlags::II_JustCoarsened) {
2248 for (Integer c = 0, cs = cell.nbHChildren(); c < cs; c++) {
2249 cells_to_remove.add(cell.hChildBase(c).localId());
2250 }
2251 parent_cells.add(cell._itemInternal());
2252 }
2253 });
2254
2255 _invalidate(parent_cells) ;
2256
2257 // Avant suppression, mettre a jour les owner de Node/Face isoles
2258 _updateItemOwner(cells_to_remove);
2259 //info() << "Number of cells to remove: " << cells_to_remove.size();
2260 m_mesh->modifier()->removeCells(cells_to_remove,false);
2261 for (Integer i = 0, ps = parent_cells.size(); i < ps; i++)
2263
2264 return cells_to_remove.size() > 0 ;
2265}
2266
2267/*---------------------------------------------------------------------------*/
2268/*---------------------------------------------------------------------------*/
2269
2270void MeshRefinement::
2271populateBackFrontCellsFromParentFaces(Cell parent_cell)
2272{
2273 switch (parent_cell.type())
2274 {
2275 case IT_Quad4:
2276 _populateBackFrontCellsFromParentFaces<IT_Quad4>(parent_cell);
2277 break;
2278 case IT_Tetraedron4:
2279 _populateBackFrontCellsFromParentFaces<IT_Tetraedron4>(parent_cell);
2280 break;
2281 case IT_Pyramid5:
2282 _populateBackFrontCellsFromParentFaces<IT_Pyramid5>(parent_cell);
2283 break;
2284 case IT_Pentaedron6:
2285 _populateBackFrontCellsFromParentFaces<IT_Pentaedron6>(parent_cell);
2286 break;
2287 case IT_Hexaedron8:
2288 _populateBackFrontCellsFromParentFaces<IT_Hexaedron8>(parent_cell);
2289 break;
2290 case IT_HemiHexa7:
2291 _populateBackFrontCellsFromParentFaces<IT_HemiHexa7>(parent_cell);
2292 break;
2293 case IT_HemiHexa6:
2294 _populateBackFrontCellsFromParentFaces<IT_HemiHexa6>(parent_cell);
2295 break;
2296 case IT_HemiHexa5:
2297 _populateBackFrontCellsFromParentFaces<IT_HemiHexa5>(parent_cell);
2298 break;
2299 case IT_AntiWedgeLeft6:
2300 _populateBackFrontCellsFromParentFaces<IT_AntiWedgeLeft6>(parent_cell);
2301 break;
2302 case IT_AntiWedgeRight6:
2303 _populateBackFrontCellsFromParentFaces<IT_AntiWedgeRight6>(parent_cell);
2304 break;
2305 case IT_DiTetra5:
2306 _populateBackFrontCellsFromParentFaces<IT_DiTetra5>(parent_cell);
2307 break;
2308 default:
2309 ARCANE_FATAL("Not supported refinement Item Type type={0}",parent_cell.type());
2310 }
2311}
2312/*---------------------------------------------------------------------------*/
2313/*---------------------------------------------------------------------------*/
2314
2315template <int typeID> void MeshRefinement::
2317{
2318 Integer nb_children = parent_cell.nbHChildren();
2320 for (Integer c = 0; c < nb_children; c++){
2321 Cell child = parent_cell.hChild(c);
2322 Integer nb_child_faces = child.nbFace();
2323 for (Integer fc = 0; fc < nb_child_faces; fc++){
2324 if (rp.face_mapping_topo(c, fc) == 0)
2325 continue;
2326 const Integer f = rp.face_mapping(c, fc);
2327 Face face = parent_cell.face(f);
2328 Integer nb_cell_face = face.nbCell();
2329 if (nb_cell_face == 1)
2330 continue;
2331 Face subface = child.face(fc);
2332 Integer nb_cell_subface = subface.nbCell();
2333 if (nb_cell_subface == 1){
2334 m_face_family->addBackFrontCellsFromParentFace(subface, face);
2335 }
2336 else{
2337 if (face.backCell().isOwn() != face.frontCell().isOwn()){
2338 m_face_family->replaceBackFrontCellsFromParentFace(child, subface, parent_cell, face);
2339 }
2340 else{
2341 if (!face.backCell().isOwn() && !face.frontCell().isOwn()){
2342 m_face_family->replaceBackFrontCellsFromParentFace(child, subface, parent_cell, face);
2343 }
2344 }
2345 }
2346 ARCANE_ASSERT((subface.backCell() != parent_cell && subface.frontCell() != parent_cell),
2347 ("back front cells error"));
2348 }
2349 }
2350}
2351
2352/*---------------------------------------------------------------------------*/
2353/*---------------------------------------------------------------------------*/
2354
2357{
2358 ARCANE_ASSERT((parent_cell.isActive()), (""));
2359 Integer nb_faces = parent_cell.nbFace();
2360 for (Integer f = 0; f < nb_faces; f++){
2361 Face face = parent_cell.face(f);
2362 Integer nb_cell_face = face.nbCell();
2363 if (nb_cell_face == 1)
2364 continue;
2365 Cell neighbor_cell = (face.cell(0) == parent_cell) ? face.cell(1) : face.cell(0);
2366 if (neighbor_cell.isActive())
2367 continue;
2368 switch (neighbor_cell.type()){
2369 case IT_Quad4:
2371 break;
2372 case IT_Tetraedron4:
2374 break;
2375 case IT_Pyramid5:
2377 break;
2378 case IT_Pentaedron6:
2380 break;
2381 case IT_Hexaedron8:
2383 break;
2384 case IT_HemiHexa7:
2386 break;
2387 case IT_HemiHexa6:
2389 break;
2390 case IT_HemiHexa5:
2392 break;
2393 case IT_AntiWedgeLeft6:
2395 break;
2396 case IT_AntiWedgeRight6:
2398 break;
2399 case IT_DiTetra5:
2401 break;
2402 default:
2403 ARCANE_FATAL("Not supported refinement Item Type type={0}",neighbor_cell.type());
2404 }
2405 }
2406}
2407
2408/*---------------------------------------------------------------------------*/
2409/*---------------------------------------------------------------------------*/
2410
2411template <int typeID> void MeshRefinement::
2412_populateBackFrontCellsFromChildrenFaces(Face face, Cell parent_cell,
2414{
2416 for(Integer f=0;f<neighbor_cell.nbFace();f++){
2417 if (neighbor_cell.face(f) == face){
2418 Integer nb_children = neighbor_cell.nbHChildren();
2419 for (Integer c = 0; c < nb_children; c++){
2420 Cell child = neighbor_cell.hChild(c);
2421 Integer nb_child_faces = child.nbFace();
2422 for (Integer fc = 0; fc < nb_child_faces; fc++){
2423 if (f == rp.face_mapping(c, fc) && (rp.face_mapping_topo(c, fc))){
2424 Face subface = child.face(fc);
2425 if (subface.itemBase().flags() & ItemFlags::II_HasBackCell){
2426 m_face_family->addFrontCellToFace(subface, parent_cell);
2427 }
2428 else if (subface.itemBase().flags() & ItemFlags::II_HasFrontCell){
2429 m_face_family->addBackCellToFace(subface, parent_cell);
2430 }
2431 ARCANE_ASSERT((subface.backCell() != subface.frontCell()), ("back front cells error"));
2432 }
2433 }
2434 }
2435 break;
2436 }
2437 }
2438}
2439
2440/*---------------------------------------------------------------------------*/
2441/*---------------------------------------------------------------------------*/
2442
2443void MeshRefinement::
2444_checkOwner(const String& msg)
2445{
2446 // This method has been introduced to patch node owner desynchronization occuring in IFPEN applications
2447 info() << "----CheckOwner in " << msg;
2448 VariableNodeInt32 syncvariable(VariableBuildInfo(m_mesh,"SyncVarNodeOwnerContract"));
2449 syncvariable.fill(-1);
2450 bool has_owner_changed = false;
2451 ENUMERATE_NODE(inode,m_mesh->ownNodes()) syncvariable[inode] = inode->owner();
2452 VariableNodeInt32 syncvariable_copy(VariableBuildInfo(m_mesh,"SyncVarNodeOwnerContractCopy"));
2453 syncvariable_copy.copy(syncvariable);
2454 syncvariable.synchronize();
2455 ItemVector desync_nodes(m_mesh->nodeFamily());
2456 ENUMERATE_NODE(inode,m_mesh->allNodes())
2457 {
2458 if (syncvariable[inode] == -1) {
2459 debug(Trace::Highest) << "----- Inconsistent owner (ghost everywhere) for node with uid : "
2460 << inode->uniqueId().asInt64();
2461 desync_nodes.addItem(*inode);
2462 has_owner_changed = true;
2463 }
2464 if (inode->isOwn() && (syncvariable_copy[inode] != syncvariable[inode])) {
2465 debug(Trace::Highest) << "----- Inconsistent owner (own everywhere) for node with uid : "
2466 << inode->uniqueId().asInt64();
2467 desync_nodes.addItem(*inode);
2468 has_owner_changed = true;
2469 }
2470 }
2471 // Find a new owner different from the historical one stored in node_owner_memory
2472 // Indeed the desync occured while changing from this historical owner to avoid an isolated item
2473 // Going back to this owner would make this problem of isolated owner appear again
2474 // 1-Get the owners of all desync nodes on every process
2475 // 1.1 Synchronize desync_nodes : if a node is desynchronized in a domain, all the domains must do the correction
2476 Int64UniqueArray desync_node_uids(desync_nodes.size());
2477 ENUMERATE_NODE(inode, desync_nodes) {
2478 desync_node_uids[inode.index()] = inode->uniqueId().asInt64();
2479 }
2480 Int64UniqueArray desync_node_uids_gather;
2481 m_mesh->parallelMng()->allGatherVariable(desync_node_uids.view(),desync_node_uids_gather);
2482 Int32UniqueArray desync_node_lids_gather(desync_node_uids_gather.size());
2483 m_mesh->nodeFamily()->itemsUniqueIdToLocalId(desync_node_lids_gather,desync_node_uids_gather,false);
2484 for (auto lid : desync_node_lids_gather) {
2485 if (lid == NULL_ITEM_LOCAL_ID)
2486 continue;
2487 if (std::find(desync_nodes.viewAsArray().begin(), desync_nodes.viewAsArray().end(),lid) == desync_nodes.viewAsArray().end()){
2488 desync_nodes.add(lid);
2489 }
2490 }
2491 // 1.2 Exchange the owners of the desynchronized nodes
2492 // each process fill an array [node1_uid, node1_owner,...nodei_uid, nodei_owner,...]
2493 Int64UniqueArray desync_node_owners(2*desync_nodes.size());
2494 ENUMERATE_NODE(inode, desync_nodes) {
2495 desync_node_owners[2*inode.index() ] = inode->uniqueId().asInt64();
2496 desync_node_owners[2*inode.index()+1] = inode->owner();
2497 }
2498 // 1.2 gather this array on every process
2499 Int64UniqueArray desync_node_owners_gather;
2500 m_mesh->parallelMng()->allGatherVariable(desync_node_owners.view(),desync_node_owners_gather);
2501 // 1.3 store the information in a map <uid, Array[owner] >
2502 std::map<Int64,Int32SharedArray> uid_owners_map;
2503 for (Integer node_index = 0; node_index+1 < desync_node_owners_gather.size();) {
2504 uid_owners_map[desync_node_owners_gather[node_index]].add((Int32)desync_node_owners_gather[node_index+1]);
2505 desync_node_uids_gather.add(desync_node_owners_gather[node_index]);
2506 node_index+=2;
2507 }
2508 // 2 choose the unique owner of the desynchronized nodes :
2509 // Choose the minimum owner (same choice on each proc) different from the historical owner
2510 Integer new_owner = m_mesh->parallelMng()->commSize()+1;
2511 ENUMERATE_NODE(inode, desync_nodes) {
2512 for (auto owner : uid_owners_map[inode->uniqueId().asInt64()]) {
2513 if (owner < new_owner && owner != m_node_owner_memory[inode]) new_owner = owner;
2514 }
2515 debug(Trace::Highest) << "------ Change owner for node " << inode->uniqueId() << " from " << inode->owner() << " to " << new_owner;
2516 inode->mutableItemBase().setOwner(new_owner, m_mesh->parallelMng()->commRank());
2517 new_owner = m_mesh->parallelMng()->commSize()+1;
2518 }
2519 // Update family if owners have changed
2520 bool p_has_owner_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, has_owner_changed);
2521 if (p_has_owner_changed) {
2525 }
2526 // update node memory owner
2527 ENUMERATE_NODE(inode,m_mesh->allNodes()) m_node_owner_memory[inode] = inode->owner();
2528}
2529
2530/*---------------------------------------------------------------------------*/
2531/*---------------------------------------------------------------------------*/
2532
2534getMesh() const
2535{
2536 return m_mesh;
2537}
2538
2539/*---------------------------------------------------------------------------*/
2540/*---------------------------------------------------------------------------*/
2541
2543getMesh()
2544{
2545 return m_mesh;
2546}
2547
2548/*---------------------------------------------------------------------------*/
2549/*---------------------------------------------------------------------------*/
2550
2551} // End namespace Arcane::mesh
2552
2553/*---------------------------------------------------------------------------*/
2554/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_FACE(name, group)
Enumérateur générique d'un groupe de faces.
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
Déclarations des types utilisés dans Arcane.
Tableau d'items de types quelconques.
Vue sur les informations des mailles.
Maille d'un maillage.
Definition Item.h:1178
FaceConnectedListViewType faces() const
Liste des faces de la maille.
Definition Item.h:1258
Int32 nbHChildren() const
Nombre d'enfants pour l'AMR.
Definition Item.h:1293
bool isAncestor() const
Definition Item.h:1315
Face face(Int32 i) const
i-ème face de la maille
Definition Item.h:1255
Int32 nbFace() const
Nombre de faces de la maille.
Definition Item.h:1252
Cell hChild(Int32 i) const
i-ème enfant AMR
Definition Item.h:1296
bool isActive() const
Definition Item.h:1306
Int32 level() const
Definition Item.h:1328
Cell hParent() const
Definition Item.h:1287
Int32 nbHParent() const
Nombre de parent pour l'AMR.
Definition Item.h:1290
Face d'une maille.
Definition Item.h:932
Cell frontCell() const
Maille devant la face (maille nulle si aucune)
Definition Item.h:1604
Cell cell(Int32 i) const
i-ème maille de la face
Definition Item.h:1617
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
Definition Item.h:1006
Cell backCell() const
Maille derrière la face (maille nulle si aucune)
Definition Item.h:1598
Interface d'un fonctor avec argument.
virtual Integer nbGhostLayer() const =0
Nombre de couches fantômes.
Interface d'une famille d'entités.
virtual void computeSynchronizeInfos()=0
Construit les structures nécessaires à la synchronisation.
virtual void notifyItemsOwnerChanged()=0
Notifie que les entités propres au sous-domaine de la famille ont été modifiées.
virtual void itemsUniqueIdToLocalId(Int32ArrayView local_ids, Int64ConstArrayView unique_ids, bool do_fatal=true) const =0
Converti un tableau de numéros uniques en numéros locaux.
virtual VariableItemInt32 & itemsNewOwner()=0
Variable contenant le numéro du nouveau sous-domaine propriétaire de l'entité.
virtual void endUpdate()=0
Notifie la fin de modification de la liste des entités.
virtual void setDynamic(bool v)=0
Positionne la propriété indiquant si le maillage peut évoluer.
virtual void removeCells(Int32ConstArrayView cells_local_id)=0
Supprime des mailles.
virtual void endUpdate()=0
Notifie l'instance de la fin de la modification du maillage.
virtual void updateGhostLayerFromParent(Array< Int64 > &ghost_cell_to_refine, Array< Int64 > &ghost_cell_to_coarsen, bool remove_old_ghost)=0
AMR.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual void allGatherVariable(ConstArrayView< char > send_buf, Array< char > &recv_buf)=0
Effectue un regroupement sur tous les processeurs.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual bool isParallel() const =0
Retourne true si l'exécution est parallèle.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
virtual void barrier()=0
Effectue une barière.
Classe de base pour les entités du maillage.
bool isActive() const
Int32 flags() const
Flags de l'entité
bool isSubactive() const
bool isOwn() const
Vrai si l'entité appartient au sous-domaine.
bool isAncestor() const
Flags pour les caractéristiques des entités.
Definition ItemFlags.h:31
@ II_Inactive
L'entité est inactive //COARSEN_INACTIVE,.
Definition ItemFlags.h:66
@ II_Refine
L'entité est marquée pour raffinement.
Definition ItemFlags.h:63
@ II_JustAdded
L'entité vient d'être ajoutée.
Definition ItemFlags.h:54
@ II_HasBackCell
L'entité a une maille derrière.
Definition ItemFlags.h:45
@ II_JustRefined
L'entité vient d'être raffinée.
Definition ItemFlags.h:64
@ II_CoarsenInactive
L'entité est inactive et a des enfants tagués pour déraffinement.
Definition ItemFlags.h:67
@ II_HasFrontCell
L'entité a une maille devant.
Definition ItemFlags.h:44
@ II_DoNothing
L'entité est bloquée.
Definition ItemFlags.h:62
@ II_Coarsen
L'entité est marquée pour déraffinement.
Definition ItemFlags.h:61
@ II_JustCoarsened
L'entité vient d'être déraffiné
Definition ItemFlags.h:65
@ II_UserMark1
Marque utilisateur old_value 1<<24.
Definition ItemFlags.h:69
Integer size() const
Nombre d'éléments du groupe.
Definition ItemGroup.h:88
Vue sur une liste pour obtenir des informations sur les entités.
Gestionnaire des types d'entités de maillage.
Definition ItemTypeMng.h:66
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Definition Item.h:771
Classe de base d'un élément de maillage.
Definition Item.h:83
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
Definition Item.h:365
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:210
bool isOwn() const
true si l'entité est appartient au sous-domaine
Definition Item.h:244
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
Definition Item.h:229
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:216
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:354
Int16 type() const
Type de l'entité
Definition Item.h:232
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
void setFlags(Int32 f)
Positionne les flags de l'entité
void addFlags(Int32 added_flags)
Ajoute les flags \added_flags à ceux de l'entité
void removeFlags(Int32 removed_flags)
Supprime les flags \added_flags de ceux de l'entité
Noeud d'un maillage.
Definition Dom.h:204
bool getBool(const String &name) const
Valeur de la propriété de nom name.
void setBool(const String &name, bool value)
Positionne une propriété de type bool de nom name et de valeur value.
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
Paramètres nécessaires à la construction d'une variable.
Implémentation d'un maillage.
Definition DynamicMesh.h:97
IItemFamily * nodeFamily() override
Retourne la famille des noeuds.
IItemFamily * cellFamily() override
Retourne la famille des mailles.
FaceGroup allFaces() override
Groupe de toutes les faces.
CellGroup allActiveCells() override
AMR.
IParallelMng * parallelMng() override
Gestionnaire de parallèlisme.
NodeGroup ownNodes() override
Groupe de tous les noeuds propres au domaine.
IMeshModifier * modifier() override
Interface de modification associée.
ItemTypeMng * itemTypeMng() const override
Gestionnaire de types d'entités associé
CellGroup allCells() override
Groupe de toutes les mailles.
IGhostLayerMng * ghostLayerMng() const override
Gestionnare de couche fantômes associé
FaceGroup ownFaces() override
Groupe de toutes les faces propres au domaine.
IItemFamily * faceFamily() override
Retourne la famille des faces.
Properties * properties() override
Propriétés associées à ce maillage.
CellGroup ownCells() override
Groupe de toutes les mailles propres au domaine.
CellGroup ownActiveCells() override
Groupe de toutes les mailles actives et propres au domaine.
NodeGroup allNodes() override
Groupe de tous les noeuds.
CellGroup ownLevelCells(const Integer &level) override
Groupe de toutes les mailles propres de niveau level.
void addFrontCellToFace(Face face, Cell new_cell)
Ajoute une maille devant la face.
void addBackCellToFace(Face face, Cell new_cell)
Ajoute une maille derrière la face.
Tableau associatif de ItemInternal.
void refineOneCell(Cell item, MeshRefinement &mesh_refinement)
void coarsenOneCell(Cell item, const ItemRefinementPatternT< typeID > &rp)
Implémentation des algorithmes d'adaptation par raffinement de maillages non-structuré.
bool _checkUnflagged(bool arcane_assert_yes=false)
MeshRefinement(DynamicMesh *mesh)
void populateBackFrontCellsFromChildrenFaces(Cell parent_cell)
bool coarsenItemsV2(bool update_parent_flag)
Méthode permettant de retirer les mailles marquées avec le flag "II_Coarsen".
bool refineAndCoarsenItems(const bool maintain_level_one=true)
bool refineItems(const bool maintain_level_one=true)
const IMesh * getMesh() const
Référence constante au maillage.
void uniformlyCoarsen(Integer n=1)
Int64 findOrAddFaceUid(const Real3 &face_center, const Real &tol, bool &is_added)
MapCoordToUid::Box m_mesh_containing_box
ParallelAMRConsistency * m_parallel_amr_consistency
bool _makeCoarseningCompatible(const bool)
bool _makeRefinementCompatible(const bool)
void _upscaleData(Array< ItemInternal * > &parent_cells)
restriction des données sur les mailles parents
ItemRefinement * m_item_refinement
Int64 findOrAddNodeUid(const Real3 &p, const Real &tol)
bool _checkLevelOne(bool arcane_assert_yes=false)
void uniformlyRefine(Integer n=1)
bool coarsenItems(const bool maintain_level_one=true)
void _populateBackFrontCellsFromParentFaces(Cell parent_cell)
void _interpolateData(const Int64Array &cells_to_refine)
interpolation des données sur les mailles enfants
virtual void flagCellToRefine(Int32ConstArrayView cells_lids)
Passage de l'erreur commise par maille au flag de raffinement.
bool _refineItems(Int64Array &cells_to_refine)
void makeNewItemsConsistent(NodeMapCoordToUid &node_finder, FaceMapCoordToUid &face_finder)
Détermine les faces à envoyer aux voisins.
Vue modifiable d'un tableau d'un type T.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
Vue constante d'un tableau de type T.
Exception lorsqu'une erreur fatale est survenue.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage warning() const
Flot pour un message d'avertissement.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
Vecteur 1D de données avec sémantique par valeur (style STL).
ItemGroupT< Face > FaceGroup
Groupe de faces.
Definition ItemTypes.h:178
ItemGroupT< Node > NodeGroup
Groupe de noeuds.
Definition ItemTypes.h:167
MeshVariableScalarRefT< Node, Int32 > VariableNodeInt32
Grandeur au noeud de type entier 32 bits.
ItemVariableScalarRefT< Int32 > VariableItemInt32
Grandeur de type entier 32 bits.
Integer arcaneCheckArraySize(unsigned long long size)
Vérifie que size peut être converti dans un 'Integer' pour servir de taille à un tableau....
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:513
bool arcaneIsDebug()
Vrai si la macro ARCANE_DEBUG est définie.
Definition Misc.cc:163
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:515
Int32 Integer
Type représentant un entier.