Arcane  v3.15.0.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#include "arcane/core/ItemVector.h"
38
39#include "arcane/mesh/DynamicMesh.h"
40#include "arcane/mesh/ItemRefinement.h"
41#include "arcane/mesh/MeshRefinement.h"
42#include "arcane/mesh/ParallelAMRConsistency.h"
43#include "arcane/mesh/FaceReorienter.h"
44#include "arcane/mesh/NodeFamily.h"
45#include "arcane/mesh/EdgeFamily.h"
46
47#include "arcane/core/materials/IMeshMaterialMng.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("Max one level diff between two cells is allowed -- Uid of Cell to be coarseing: {0} -- Uid of Opposite cell with children: {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
742 if (!update_parent_flag) {
743 // Si les matériaux sont actifs, il faut forcer un recalcul des matériaux car les groupes
744 // de mailles ont été modifiés et donc la liste des constituants aussi
746 if (mm)
747 mm->forceRecompute();
748 }
749
751
752 return m_mesh->parallelMng()->reduce(Parallel::ReduceMax, (!to_coarse.empty()));
753}
754
755/*---------------------------------------------------------------------------*/
756/*---------------------------------------------------------------------------*/
757
758bool
761{
762
764
765 // la règle de niveau-un est la seule condition implementé
767 {
768 warning() << "Warning, level one rule is the only condition accepted for AMR!";
769 }
770 else
771 _maintain_level_one = m_face_level_mismatch_limit;
772
774 ARCANE_ASSERT((_checkLevelOne(true)), ("check_level_one failed"));
775 }
776 // Nettoyage des flags de raffinement de l'étape précédente
777 this->_cleanRefinementFlags();
778
779 // La consistence parallêle doit venir en premier, ou le déraffinement
780 // le long des interfaces entre processeurs pourrait de temps en temps être
781 // faussement empêché
782 if (m_mesh->parallelMng()->isParallel())
784
785 // Repete jusqu'au matching du changement de flags sur chaque processeur
786 do
787 {
788 // Repete jusqu'au matching des flags localement.
789 bool satisfied = false;
790 do
791 {
792 const bool refinement_satisfied = this->_makeRefinementCompatible(maintain_level_one);
794#ifdef ARCANE_DEBUG
796 max_satisfied = m_mesh->parallelMng()->reduce(Parallel::ReduceMax,max_satisfied);
797 min_satisfied = m_mesh->parallelMng()->reduce(Parallel::ReduceMin,min_satisfied);
798 ARCANE_ASSERT ( (satisfied == max_satisfied), ("parallel max_satisfied failed"));
799 ARCANE_ASSERT ( (satisfied == min_satisfied), ("parallel min_satisfied failed"));
800#endif
801 } while (!satisfied);
802 } while (m_mesh->parallelMng()->isParallel() && !this->_makeFlagParallelConsistent());
803
804 // Maintenant, raffine les items flaggés. Ceci prendra
805 // plus de mémoire, et peut être plus de ce qui est libre.
807 const bool mesh_changed = this->_refineItems(cells_to_refine);
808
809 // Finalement, préparation du nouveau maillage pour utilisation
810 if (mesh_changed){
811 // mise a jour
812 bool do_compact = m_mesh->properties()->getBool("compact");
813 m_mesh->properties()->setBool("compact",true) ; // Forcing compaction prevents from bugs when using AMR
815 m_mesh->properties()->setBool("compact",do_compact) ;
816
817 // callback pour transporter les variables sur le nouveau maillage
818 this->_interpolateData(cells_to_refine);
819
820 // mise a jour des ghosts
821 m_mesh->modifier()->setDynamic(true);
825 _update(ghost_cell_to_refine) ;
826 }
827
828 //if (_maintain_level_one)
829 //ARCANE_ASSERT( (checkLevelOne(true)), ("check_level_one failed"));
830 //ARCANE_ASSERT( (this->makeRefinementCompatible(maintain_level_one)), ("make_refinment_compatible failed"));
831
832 return mesh_changed;
833}
834
835/*---------------------------------------------------------------------------*/
836/*---------------------------------------------------------------------------*/
837
839uniformlyRefine(Integer n)
840{
841 // Raffine n fois
842 // FIXME - ceci ne doit pas marcher si n>1 et le maillage
843 // est déjà attaché au système d'équations à résoudre
844 for (Integer rstep = 0; rstep < n; rstep++){
845 // Nettoyage des flags de raffinement
846 this->_cleanRefinementFlags();
847
848 // itérer seulement sur les mailles actives
849 // Flag tous les items actifs pour raffinement
851 Cell cell = *icell;
852 _setRefineFlags(cell);
853 }
854 // Raffine tous les items que nous avons flaggés.
856 this->_refineItems(cells_to_refine);
857 warning() << "ATTENTION: No Data Projection with this method!";
858 }
859
860 bool do_compact = m_mesh->properties()->getBool("compact");
861 m_mesh->properties()->setBool("compact",true) ;// Forcing compaction prevents from bugs when using AMR
863 m_mesh->properties()->setBool("compact",do_compact) ;
864}
865
866/*---------------------------------------------------------------------------*/
867/*---------------------------------------------------------------------------*/
868
869void
871uniformlyCoarsen(Integer n)
872{
873 // Déraffine n fois
874 for (Integer rstep = 0; rstep < n; rstep++){
875 // Nettoyage des flags de raffinement
876 this->_cleanRefinementFlags();
877
878 // itérer seulement sur les mailles actives
879 // Flag tous les items actifs pour déraffinement
881 Cell cell = *icell;
882 _setCoarseFlags(cell);
883 if (cell.nbHParent() != 0){
885 }
886 }
887 // Déraffine tous les items que nous venons de flagger.
888 this->_coarsenItems();
889 warning() << "ATTENTION: No Data Restriction with this method!";
890 }
891
892 // Finalement, préparation du nouveau maillage pour utilisation
893 bool do_compact = m_mesh->properties()->getBool("compact");
894 m_mesh->properties()->setBool("compact",true) ;
896 m_mesh->properties()->setBool("compact",do_compact) ;
897}
898
899/*---------------------------------------------------------------------------*/
900/*---------------------------------------------------------------------------*/
901
902Int64
904findOrAddNodeUid(const Real3& p, const Real& tol)
905{
906 //debug() << "addNode()";
907
908 // Return the node if it already exists
909 Int64 uid = m_node_finder.find(p, tol);
910 if (uid != NULL_ITEM_ID)
911 {
912 // debug() << "addNode() done";
913 return uid;
914 }
915 // Add the node to the map.
916 Int64 new_uid = m_next_node_uid;
917 m_node_finder.insert(p, new_uid,tol);
918 m_next_node_uid += m_mesh->parallelMng()->commSize() + 1;
919 // Return the uid of the new node
920 // debug() << "addNode() done";
921 return new_uid;
922}
923/*---------------------------------------------------------------------------*/
924/*---------------------------------------------------------------------------*/
925Int64
927findOrAddFaceUid(const Real3& p, const Real& tol, bool& is_added)
928{
929 //debug() << "findOrAddFaceUid()";
930
931 // Return the face if it already exists
932 Int64 uid = m_face_finder.find(p, tol);
933 if (uid != NULL_ITEM_ID)
934 {
935 // debug() << "findOrAddFaceUid() done";
936 is_added = false;
937 return uid;
938 }
939 // Add the face to the map.
940 is_added = true;
941 Int64 new_uid = m_next_face_uid;
942 m_face_finder.insert(p, new_uid,tol);
943 m_next_face_uid += m_mesh->parallelMng()->commSize() + 1;
944 // Return the uid of the new face
945 // debug() << "findOrAddFaceUid() done";
946 return new_uid;
947}
948
949/*---------------------------------------------------------------------------*/
950/*---------------------------------------------------------------------------*/
951
954{
955 Int64 new_uid = m_next_cell_uid;
956 Int64 comm_size = m_mesh->parallelMng()->commSize();
957 m_next_cell_uid += comm_size * m_max_nb_hChildren;
958 return new_uid;
959}
960
961/*---------------------------------------------------------------------------*/
962/*---------------------------------------------------------------------------*/
963/* PRIVATE METHODS */
964/*---------------------------------------------------------------------------*/
965/*---------------------------------------------------------------------------*/
966
967void
970{
971 //jmg this->init(); // \todo pas necessaire de l'appeler a chaque m-a-j
972 //m_node_finder.init();
973 m_node_finder.check() ;
974 //m_face_finder.init();
975 m_face_finder.check() ;
976 debug() << "[MeshRefinement::updateLocalityMap] done";
977}
978/*---------------------------------------------------------------------------*/
979/*---------------------------------------------------------------------------*/
980
981void
982MeshRefinement::
983_updateLocalityMap2()
984{
985 //this->init(); // \todo pas necessaire de l'appeler a chaque m-a-j
986 //this->m_node_finder.init2();
987 //m_node_finder.check2() ;
988 //m_face_finder.init2();
989 //m_face_finder.check2();
990 //debug() << "[MeshRefinement::updateLocalityMap2] done";
991}
992/*---------------------------------------------------------------------------*/
993/*---------------------------------------------------------------------------*/
994
997{
998 bool failure = false;
999
1000 Integer sid = m_mesh->parallelMng()->commRank();
1001 // itérer seulement sur les mailles actives
1003 {
1004 Cell cell = *icell;
1005 for( Face face : cell.faces() ) {
1006 if (face.nbCell()!=2)
1007 continue;
1008 Cell back_cell = face.backCell();
1009 Cell front_cell = face.frontCell();
1010
1011 // On choisit l'autre cellule du cote de la face
1013 if (neighbor.null() || !neighbor.isActive() || !(neighbor.owner()==sid))
1014 continue;
1015 //debug() << "#### " << ineighbor->uniqueId() << " " << ineighbor->level() << " " << cell.level();
1016 if ((neighbor.level() + 1 < cell.level())){
1017 failure = true;
1018 break;
1019 }
1020 }
1021 }
1022
1023 // Si un processeur échoue, on échoue globalement
1024 failure = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, failure);
1025
1026 if (failure){
1027 // Nous n'avons pas passé le test level-one, donc arcane_assert
1028 // en fonction du booléen d'entré.
1030 throw FatalErrorException(A_FUNCINFO,"checkLevelOne failed");
1031 return false;
1032 }
1033 return true;
1034}
1035
1036/*---------------------------------------------------------------------------*/
1037/*---------------------------------------------------------------------------*/
1038
1041{
1042 bool found_flag = false;
1043
1044 // recherche pour les flags locaux
1045 // itérer seulement sur les mailles actives
1047 const Cell cell = *icell;
1048 const Integer f = cell.itemBase().flags();
1050 {
1051 found_flag = true;
1052 break;
1053 }
1054 }
1055 // Si nous trouvions un flag sur n'importe quel processeur, il compte
1056 found_flag = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, found_flag);
1057 if (found_flag){
1058 //nous n'avons pas passé le test "items are unflagged",
1059 //ainsi arcane_assert la non valeur de arcane_assert_pass
1061 throw FatalErrorException(A_FUNCINFO,"checkUnflagged failed");
1062 return false;
1063 }
1064 return true;
1065}
1066
1067/*---------------------------------------------------------------------------*/
1068/*---------------------------------------------------------------------------*/
1069
1072{
1073 if (!m_mesh->parallelMng()->isParallel())
1074 return true;
1075
1076 CHECKPERF( m_perf_counter.start(PerfCounter::PCONSIST) )
1077 debug() << "makeFlagsParallelConsistent() begin";
1078 bool parallel_consistent = true;
1081 ghost_cells.reserve(m_mesh->allCells().size()-m_mesh->ownCells().size()) ;
1083 Cell cell = *icell;
1084 if(cell.isOwn()) {
1085 Integer f = cell.itemBase().flags(); // TODO getAMRFlags()
1087 }
1088 else
1089 ghost_cells.add(cell);
1090 }
1091 flag_cells_consistent.synchronize();
1092 //ENUMERATE_CELL(icell,m_mesh->allCells())
1093 for(Integer icell=0, nb_cell=ghost_cells.size();icell<nb_cell;++icell) {
1095 Integer f = iitem.itemBase().flags();
1096
1097 //if(iitem->owner() != sid)
1098 {
1099 // il est possible que les flags des ghosts soient (temporairement) plus
1100 // conservatifs que nos propres flags , comme quand un raffinement d'une
1101 // des mailles du processeur distant est dicté par un raffinement d'une de nos mailles
1102 const Integer g = flag_cells_consistent[Cell(iitem)];
1104 {
1106 iitem.mutableItemBase().setFlags(f);
1107 parallel_consistent = false;
1108 }
1109 else if ((g & ItemFlags::II_Coarsen) && !(f & ItemFlags::II_Coarsen))
1110 {
1112 iitem.mutableItemBase().setFlags(f);
1113 parallel_consistent = false;
1114 }
1116 {
1118 iitem.mutableItemBase().setFlags(f);
1119 parallel_consistent = false;
1120 }
1122 {
1124 iitem.mutableItemBase().setFlags(f);
1125 parallel_consistent = false;
1126 }
1127 /*
1128 else if ((g & ItemFlags::II_CoarsenInactive) && !(f & ItemFlags::II_CoarsenInactive)){
1129 f |= ItemFlags::II_CoarsenInactive;
1130 //f |= ItemFlags::II_Inactive;
1131 iitem->setFlags(f);
1132 parallel_consistent = false;
1133 }
1134 else if ((g & ItemFlags::II_DoNothing) && !(f & ItemFlags::II_DoNothing)){
1135 f |= ItemFlags::II_DoNothing;
1136 //f |= ItemFlags::II_Inactive;
1137 iitem->setFlags(f);
1138 parallel_consistent = false;
1139 }
1140
1141 else if ((g & ItemFlags::II_Inactive) && !(f & ItemFlags::II_Inactive)){
1142 f |= ItemFlags::II_Inactive;
1143 //f |= ItemFlags::II_Inactive;
1144 iitem->setFlags(f);
1145 parallel_consistent = false;
1146 }*/
1147 }
1148 }
1149 // Si nous ne sommes pas consistent sur chaque processeur alors
1150 // nous ne le sommes pas globalement
1152 debug() << "makeFlagsParallelConsistent() end -- parallel_consistent : " << parallel_consistent;
1153
1154 CHECKPERF( m_perf_counter.stop(PerfCounter::PCONSIST) )
1155 return parallel_consistent;
1156}
1157/*---------------------------------------------------------------------------*/
1158/*---------------------------------------------------------------------------*/
1159bool
1160MeshRefinement::
1161_makeFlagParallelConsistent2()
1162{
1163 if (!m_mesh->parallelMng()->isParallel())
1164 return true;
1165
1166 CHECKPERF( m_perf_counter.start(PerfCounter::PCONSIST2) )
1167 debug() << "makeFlagsParallelConsistent2() begin";
1168 bool parallel_consistent = true;
1171 ghost_cells.reserve(m_mesh->allCells().size()-m_mesh->ownCells().size()) ;
1173 {
1174 Cell cell = *icell;
1175 if (cell.isOwn()) {
1176 Integer f = cell.itemBase().flags(); // TODO getAMRFlags()
1178 }
1179 else
1180 ghost_cells.add(cell);
1181 }
1182 flag_cells_consistent.synchronize();
1183 //ENUMERATE_CELL(icell,m_mesh->allCells())
1184 for(Integer icell=0, nb_cell=ghost_cells.size();icell<nb_cell;++icell) {
1185 //const Cell& cell = *icell;
1186 //ItemInternal * iitem = cell.internal();
1187 //Integer f = iitem->flags();
1188 Item iitem = ghost_cells[icell];
1189 Integer f = iitem.itemBase().flags();
1190
1191 //if(iitem->owner() != sid)
1192 {
1193 Integer g = flag_cells_consistent[Cell(iitem)];
1195 {
1197 iitem.mutableItemBase().setFlags(f);
1198 parallel_consistent = false;
1199 }
1201 {
1203 iitem.mutableItemBase().setFlags(f);
1204 parallel_consistent = false;
1205 }
1206 else if ((g & ItemFlags::II_Inactive) && !(f & ItemFlags::II_Inactive))
1207 {
1209 iitem.mutableItemBase().setFlags(f);
1210 parallel_consistent = false;
1211 }
1212 /*else if ((f & ItemFlags::II_JustRefined) && !(g & ItemFlags::II_JustRefined)){
1213 f &= ~ItemFlags::II_JustRefined;
1214 iitem->setFlags(f);
1215 parallel_consistent = false;
1216 }*/
1217 }
1218 }
1219 // Si nous ne sommes pas consistent sur chaque processeur alors
1220 // nous ne le sommes pas globalement
1221 parallel_consistent = m_mesh->parallelMng()->reduce(Parallel::ReduceMin, parallel_consistent);
1222 debug() << "makeFlagsParallelConsistent2() end";
1223
1224 CHECKPERF( m_perf_counter.stop(PerfCounter::PCONSIST2) )
1225 return parallel_consistent;
1226}
1227/*---------------------------------------------------------------------------*/
1228/*---------------------------------------------------------------------------*/
1229
1230bool
1233{
1234
1235 debug() << "makeCoarseningCompatible() begin";
1236
1238
1239 // la règle de niveau-un est la seule condition implementée
1240 if (!maintain_level_one){
1241 warning() << "Warning, level one rule is the only condition accepted for AMR!";
1242 }
1243 else
1244 _maintain_level_one = m_face_level_mismatch_limit;
1245
1246 // à moins que nous rencontrions une situation spécifique, la règle niveau-un
1247 // sera satisfaite aprês avoir exécuté cette boucle juste une fois
1248 bool level_one_satisfied = true;
1249
1250 // à moins que nous rencontrions une situation spéccifique, nous serons compatible
1251 // avec tous flags de raffinement choisis
1252 bool compatible_with_refinement = true;
1253
1254 // Trouver le niveau maximum dans le maillage
1255 Integer max_level = 0;
1256
1257 // d'abord nous regardons tous les items actifs de niveau 0. Puisque ca n'a pas de sens de
1258 // les déraffiner nous devons donc supprimer leur flags de déraffinement si
1259 // ils sont déjà positionnés.
1260 // itérer seulement sur les mailles actives
1262 const Cell cell = *icell;
1263 max_level = std::max(max_level, cell.level());
1264
1265 Integer f = cell.itemBase().flags();
1266 if ((cell.level() == 0) && (f & ItemFlags::II_Coarsen)) {
1267 f &= ~ItemFlags::II_Coarsen;
1269 cell.mutableItemBase().setFlags(f);
1270 }
1271 }
1272 // Si il n'y a pas d'items à raffiner sur ce processeur alors
1273 // il n'y a pas de travail à faire pour nous
1274 if (max_level == 0){
1275 debug() << "makeCoarseningCompatible() done";
1276
1277 // par contre il reste à vérifier avec les autres processeurs
1279
1281 }
1282
1283 // Boucle sur tous les items actifs. Si un item est marqué
1284 // pour déraffinement on check ses voisins. Si un de ses voisins
1285 // est marqué pour raffinement et est de même niveau alors il y a un
1286 // conflit. Par convention raffinement gagne, alors on démarque l'item pour
1287 // déraffinement. Le niveau-un serait violé dans ce cas-ci ainsi nous devons réexécuter
1288 // la boucle.
1289 const Integer sid = m_mesh->parallelMng()->commRank();
1291 {
1292
1294
1295 do
1296 {
1297 level_one_satisfied = true;
1298 // itérer seulement sur les mailles actives
1300 Cell cell = *icell;
1301 //ItemInternal* iitem = cell.internal();
1302 bool my_flag_changed = false;
1303 Integer f = cell.itemBase().flags();
1304 if (f & ItemFlags::II_Coarsen){ // Si l'item est actif et le flag de déraffinement est placé
1305 const Int32 my_level = cell.level();
1306 for( Face face : cell.faces() ) {
1307 if (face.nbCell()!=2)
1308 continue;
1309 Cell back_cell = face.backCell();
1310 Cell front_cell = face.frontCell();
1311
1312 // On choisit l'autre cellule du cote de la face
1314 //const ItemInternal* ineighbor = neighbor.internal();
1315 //if (ineighbor->owner() == sub_domain_id) // J'ai un voisin ici
1316
1317 {
1318 if (neighbor.isActive()) // et est actif
1319 {
1320 if ((neighbor.level() == my_level) &&
1321 (neighbor.itemBase().flags() & ItemFlags::II_Refine)){ // le voisin est à mon niveau et veut être raffiné
1322 f &= ~ItemFlags::II_Coarsen;
1324 cell.mutableItemBase().setFlags(f);
1325 my_flag_changed = true;
1326 break;
1327 }
1328 }
1329 else{
1330 // J'ai un voisin et n'est pas actif. Cela signifie qu'il a des enfants.
1331 // tandis qu'il peut être possible de me déraffiner si tous les enfants
1332 // de cet item veulent être déraffinés, il est impossible de savoir à ce stade.
1333 // On l'oublie pour le moment. Ceci peut être réalisé dans deux étapes.
1334 f &= ~ItemFlags::II_Coarsen;
1336 cell.mutableItemBase().setFlags(f);
1337 my_flag_changed = true;
1338 break;
1339 }
1340 }
1341 }
1342 }
1343
1344 //si le flag de la cellule courante a changé, nous n'avons pas
1345 //satisfait la rêgle du niveau un.
1346 if (my_flag_changed)
1347 level_one_satisfied = false;
1348
1349 //En plus, s'il a des voisins non-locaux, et
1350 //nous ne sommes pas en séquentiel, alors nous devons par la suite
1351 // retourner compatible_with_refinement= false, parce que
1352 //notre changement doit être propager aux processeurs voisins
1354 for( Face face : cell.faces() ){
1355 if (face.nbCell()!=2)
1356 continue;
1357 Cell back_cell = face.backCell();
1358 Cell front_cell = face.frontCell();
1359
1360 // On choisit l'autre cellule du cote de la face
1362 //ItemInternal* ineighbor = neighbor.internal();
1363 if (neighbor.owner() != sid){ // J'ai un voisin ici
1365 break;
1366 }
1367 // TODO FIXME - pour les maillages non niveau-1 nous devons
1368 // tester tous les descendants
1369 if (neighbor.hasHChildren())
1370 for (Integer c=0; c != neighbor.nbHChildren(); ++c)
1371 if (neighbor.hChild(c).owner() != sid){
1373 break;
1374 }
1375 }
1376
1377 }
1378 }
1379 while (!level_one_satisfied);
1380
1381 } // end if (_maintain_level_one)
1382
1383 //après, nous regardons tous les items ancêtres.
1384 //s'il y a un item parent avec tous ses enfants
1385 //voulant être déraffiné alors l'item est un candidat
1386 //pour le déraffinement. Si tous les enfants ne
1387 //veulent pas être déraffiné alors tous ont besoin d'avoir leur
1388 // flag de déraffinement dégagés.
1389 for (int level=(max_level); level >= 0; level--){
1390 // itérer sur les mailles niveau par niveau
1392 const Cell cell = *icell;
1393 //ItemInternal* iitem = cell.internal();
1394 if(cell.isAncestor()){
1395 // à ce moment là l'item n'a pas été éliminé
1396 // en tant que candidat pour le déraffinement
1397 bool is_a_candidate = true;
1398 bool found_remote_child = false;
1399
1400 for (Integer c=0; c<cell.nbHChildren(); c++){
1401 Cell child = cell.hChild(c);
1402 if (child.owner() != sid)
1403 found_remote_child = true;
1404 else if (!(child.itemBase().flags() & ItemFlags::II_Coarsen) || !child.isActive() )
1405 is_a_candidate = false;
1406 }
1407
1410 for (Integer c=0; c<cell.nbHChildren(); c++){
1411 Cell child = cell.hChild(c);
1412 if (child.owner() != sid)
1413 continue;
1414 if (child.itemBase().flags() & ItemFlags::II_Coarsen){
1415 level_one_satisfied = false;
1416 Int32 f = child.itemBase().flags();
1417 f &= ~ItemFlags::II_Coarsen;
1419 child.mutableItemBase().setFlags(f);
1420 }
1421 }
1422 }
1423 }
1424 }
1425 }
1427
1428 // Si tous les enfants d'un parent sont marqués pour déraffinement
1429 // Alors marque le parent à ce qu'il puisse tuer ses enfants.
1431 const Cell cell = *icell;
1432 //ItemInternal* iitem = cell.internal();
1433 if(cell.isAncestor()){
1434 // Supposons que tous les enfants sont locaux et marqués pour
1435 // déraffinement et donc cherche pour une contradiction
1437 bool found_remote_child = false;
1438
1439 for (Integer c=0; c<cell.nbHChildren(); c++){
1440 Cell child = cell.hChild(c);
1441 if (child.owner() != sid)
1442 found_remote_child = true;
1443 else if (!(child.itemBase().flags() & ItemFlags::II_Coarsen))
1445 }
1446 Integer f = cell.itemBase().flags();
1447 f &= ~ItemFlags::II_CoarsenInactive;
1449 {
1451 cell.mutableItemBase().setFlags(f);
1452 }
1453 else if (!found_remote_child)
1454 {
1456 cell.mutableItemBase().setFlags(f);
1457 }
1458 }
1459 }
1460
1461 debug() << "makeCoarseningCompatible() done";
1462
1463 // Si nous sommes pas compatible sur un processeur, nous ne le sommes pas globalement
1465
1467}
1468
1469/*---------------------------------------------------------------------------*/
1470/*---------------------------------------------------------------------------*/
1471
1472bool
1475{
1476
1477 debug() << "makeRefinementCompatible() begin";
1478
1480
1481 // la règle de niveau-un est la seule condition implementée
1482 if (!maintain_level_one){
1483 warning() << "Warning, level one rule is the only condition accepted now for AMR!";
1484 }
1485 else
1486 _maintain_level_one = m_face_level_mismatch_limit;
1487
1488 // à moins que nous rencontrions une situation spécifique, la règle niveau-un
1489 // sera satisfaite après avoir exécuté cette boucle juste une fois
1490 bool level_one_satisfied = true;
1491
1492 // à moins que nous rencontrions une situation spécifique, nous serons compatible
1493 // avec tous flags de déraffinement choisis
1494 bool compatible_with_coarsening = true;
1495
1496 // cette boucle impose la règle niveau-1. Nous devrions seulement
1497 // l'exécuter si l'utilisateur veut en effet que la niveau-1 soit satisfaite !
1498 Integer sid = m_mesh->parallelMng()->commRank();
1500 do {
1501 level_one_satisfied = true;
1502 // itérer seulement sur les mailles actives
1504 const Cell cell = *icell;
1505 //ItemInternal* iitem = cell.internal();
1506 if (cell.itemBase().flags() & ItemFlags::II_Refine){ // Si l'item est actif et le flag de
1507 // raffinement est placé
1508 const Int32 my_level = cell.level();
1509 bool refinable = true;
1510 //check if refinable
1511 for( Face face : cell.faces() ){
1512 if (face.nbCell()!=2)
1513 continue;
1514 Cell back_cell = face.backCell();
1515 Cell front_cell = face.frontCell();
1516
1517 // On choisit l'autre cellule du cote de la face
1519 //ItemInternal* ineighbor = neighbor.internal();
1520 //if (ineighbor->isActive() && ineighbor->owner() == sid)// J'ai un voisin ici et est actif
1521 if (neighbor.isActive() ){// J'ai un voisin ici et est actif
1522 // Cas 2: Le voisin est inférieur de un niveau que le mien.
1523 // Le voisin doit être raffiné pour satisfaire
1524 // la règle de niveau-1, indépendamment de s'il
1525 // a été à l'origine marqué pour raffinement. S'il
1526 // n'était pas flaggé déjà nous devons répéter
1527 // ce processus.
1528 Integer f = neighbor.itemBase().flags();
1529 if ( ( (neighbor.level()+1) == my_level) &&
1530 ( f & ItemFlags::II_UserMark1) ){
1531 refinable = false;
1532 Integer my_f = cell.itemBase().flags();
1533 my_f &= ~ItemFlags::II_Refine;
1535 break;
1536 }
1537 }
1538 }
1539 if(refinable)
1540 for( Face face : cell.faces() ){
1541 if (face.nbCell()!=2)
1542 continue;
1543 Cell back_cell = face.backCell();
1544 Cell front_cell = face.frontCell();
1545
1546 // On choisit l'autre cellule du cote de la face
1548 //ItemInternal* ineighbor = neighbor.internal();
1549 if (neighbor.isActive() && neighbor.owner() == sid){ // J'ai un voisin ici et est actif
1550
1551 // Cas 1: Le voisin est au même niveau que moi.
1552 // 1a: Le voisin sera raffiné -> NO PROBLEM
1553 // 1b: Le voisin ne va pas être raffiné -> NO PROBLEM
1554 // 1c: Le voisin veut être déjà raffiné -> PROBLEM
1555 if (neighbor.level() == my_level){
1556 Integer f = neighbor.itemBase().flags();
1557 if (f & ItemFlags::II_Coarsen) {
1558 f &= ~ItemFlags::II_Coarsen;
1560 neighbor.mutableItemBase().setFlags(f);
1561 if (neighbor.nbHParent() != 0){
1562 neighbor.hParent().mutableItemBase().addFlags(ItemFlags::II_Inactive);
1563 }
1565 level_one_satisfied = false;
1566 }
1567 }
1568
1569 // Cas 2: Le voisin est inférieur de un niveau que le mien.
1570 // Le voisin doit être raffiné pour satisfaire
1571 // la rêgle de niveau-1, indépendamment de s'il
1572 // a été à l'origine marqué pour raffinement. S'il
1573 // n'était pas flaggé déjà nous devons répéter
1574 // ce processus.
1575
1576 else if ((neighbor.level()+1) == my_level) {
1577 Integer f = neighbor.itemBase().flags();
1578 if (!(f & ItemFlags::II_Refine)) {
1579 f &= ~ItemFlags::II_Coarsen;
1581 neighbor.mutableItemBase().setFlags(f);
1582 if (neighbor.nbHParent() != 0){
1583 neighbor.hParent().mutableItemBase().addFlags(ItemFlags::II_Inactive);
1584 }
1586 level_one_satisfied = false;
1587 }
1588 }
1589#ifdef ARCANE_DEBUG
1590 // Contrôle. Nous ne devrions jamais entrer dans un
1591 // cas ou notre voisin est distancé de plus d'un niveau.
1592
1593 else if ((neighbor.level()+1) < my_level)
1594 {
1595 fatal() << "a neighbor is more than one level away";
1596 }
1597
1598 // On note que la seule autre possibilité est que
1599 // le voisin ait déjà été raffiné, dans ce cas il n'est pas
1600 //actif et nous ne devrions jamais tomber ici.
1601
1602 else
1603 {
1604 fatal() << "serious problem: we should never get here";
1605 }
1606#endif
1607 }
1608 }
1609 }
1610 }
1611 }
1612 while (!level_one_satisfied);
1613 } // end if (_maintain_level_one)
1614
1615 // Si nous sommes pas compatible sur un processeur, nous ne le sommes pas globalement
1617
1618 debug() << "makeRefinementCompatible() done";
1619
1621}
1622
1623/*---------------------------------------------------------------------------*/
1624/*---------------------------------------------------------------------------*/
1625
1626bool
1629{
1630 debug() << "[MeshRefinement::_coarsenItems] begin"<<m_mesh->allNodes().size();
1631 // Flag indiquant si cet appel change réellement le maillage
1632 bool mesh_changed = false;
1633
1634 // itérer sur toutes les mailles
1635 // Int32UniqueArray cell_to_detach;
1637 Cell cell = *icell;
1638 Cell iitem = cell;
1639 // items actifs flaggés prour déraffinement ne seront
1640 // pas supprimés jusqu'à contraction via MeshRefinement::contract()
1641
1642 if (cell.itemBase().flags() & ItemFlags::II_Coarsen){
1643 // Houups? aucun item de niveau-0 ne doit être a la fois actif
1644 // et flaggé pour déraffinement.
1645 ARCANE_ASSERT ( (cell.level() != 0), ("no level-0 element should be active and flagged for coarsening"));
1646
1647 // TODO Supprimer cet item de toute liste de voisinage
1648 // pointant vers lui.
1649 // FIXME à l'IFP, on utilise par défaut la macro REMOVE_UID_ON_DETACH suprimant le UID de CELL
1650 // dans la map des cell_uid donc on ne peut utiliser detachCell par défaut. En attendant
1651 // on utilise la méthode MeshRefinement::contract() après mise à jour des variables
1652 // cell_to_detach.add(iitem->localId());
1653
1654 //cells_to_remove.add(cell);
1655 // TODO optimisation des uids non utilisé.
1656 // m_unused_items.push_back (uid);
1657
1658 // Ne pas détruire l'item jusqu'à MeshRefinement::contract()
1659 // m_mesh->modifier()->removeCells(iitem->localId());
1660
1661 // Le maillage a certainement changé
1662 mesh_changed = true;
1663 }
1664 else if (cell.itemBase().flags() & ItemFlags::II_CoarsenInactive)
1665 {
1666 switch (cell.type())
1667 {
1668 case IT_Quad4:
1670 break;
1671 case IT_Tetraedron4:
1673 break;
1674 case IT_Pyramid5:
1676 break;
1677 case IT_Pentaedron6:
1679 break;
1680 case IT_Hexaedron8:
1682 break;
1683 case IT_HemiHexa7:
1685 break;
1686 case IT_HemiHexa6:
1688 break;
1689 case IT_HemiHexa5:
1691 break;
1692 case IT_AntiWedgeLeft6:
1694 break;
1695 case IT_AntiWedgeRight6:
1697 break;
1698 case IT_DiTetra5:
1700 break;
1701 default:
1702 ARCANE_FATAL("Not supported refinement Item Type type={0}",iitem.type());
1703 }
1704 ARCANE_ASSERT(cell.isActive(), ("cell_active failed"));
1705
1706 // le maillage a certainement changé
1707 mesh_changed = true;
1708 }
1709 }
1710 // TODO
1711 // m_mesh->modifier->detachCells(cell_to_detach);
1712
1713 // Si le maillage a changé sur un processeur, alors il a changé globalement
1714 mesh_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, mesh_changed);
1715 // Et peut être nous avons besoin de mettre à jour les entités refletant le changement
1716 //if (mesh_changed)
1717 // \todo compacte et update max_uids en parallel
1718
1719 // si une maille est deraffinee ailleurs, les noeuds attaches a cette maille
1720 // doivent etre mis a jour. Cela est traite dans endUpdate()
1721
1722 debug() << "[MeshRefinement::_coarsenItems()] done "<<m_mesh->allNodes().size();
1723
1724 return mesh_changed;
1725}
1726
1727/*---------------------------------------------------------------------------*/
1728/*---------------------------------------------------------------------------*/
1729
1730bool
1733{
1734 // Mise à jour de m_node_finder, m_face_finder permettra au maillage
1735 // d'etre consistent globalement (uids consistency).
1736 debug() << "[MeshRefinement::_refineItems]"<<m_mesh->allNodes().size();
1737#ifdef ARCANE_DEBUG
1738 m_node_finder.check() ;
1739 m_face_finder.check() ;
1740#endif
1741 CHECKPERF( m_perf_counter.start(PerfCounter::REFINE) )
1742 m_face_finder.clearNewUids() ;
1743 // Iterer sur les items, compter les items
1744 // flaggés pour le raffinement.
1745 //Integer nb_cell_flagged = 0;
1748 Cell cell = *icell;
1749 if (cell.itemBase().flags() & ItemFlags::II_Refine) {
1750 cell_to_refine_uids.add(cell.uniqueId());
1751 cell_to_refine_internals.add(cell);
1752 }
1753 }
1754 debug() << "[MeshRefinement::_refineItems] " << cell_to_refine_uids.size() << " flagged cells for refinement";
1755
1756 // Construire un vecteur local des items marqués
1757 // pour raffinement.
1758 /*
1759 local_copy_of_cells.reserve(nb_cell_flagged);
1760
1761 ENUMERATE_CELL(icell,m_mesh->ownCells()){
1762 Cell cell = *icell;
1763 ItemInternal* iitem = cell.internal();
1764 if(iitem->flags() & ItemFlags::II_Refine)
1765 local_copy_of_cells.add(iitem);
1766 }
1767 */
1768 // Maintenant, itere sur les copies locales et raffine chaque item.
1769 const Int32 i_size = cell_to_refine_internals.size();
1770 for (Integer e = 0; e != i_size; ++e) {
1772 //debug()<<"\t[MeshRefinement::_refineItems] focus on cell "<<iitem->uniqueId();
1773 switch (iitem.type())
1774 {
1775 case IT_Quad4:
1776 m_item_refinement->refineOneCell<IT_Quad4>(iitem,*this);
1777 break;
1778 case IT_Tetraedron4:
1779 m_item_refinement->refineOneCell<IT_Tetraedron4>(iitem,*this);
1780 break;
1781 case IT_Pyramid5:
1782 m_item_refinement->refineOneCell<IT_Pyramid5>(iitem,*this);
1783 break;
1784 case IT_Pentaedron6:
1785 m_item_refinement->refineOneCell<IT_Pentaedron6>(iitem,*this);
1786 break;
1787 case IT_Hexaedron8:
1788 m_item_refinement->refineOneCell<IT_Hexaedron8>(iitem,*this);
1789 break;
1790 case IT_HemiHexa7:
1791 m_item_refinement->refineOneCell<IT_HemiHexa7>(iitem,*this);
1792 break;
1793 case IT_HemiHexa6:
1794 m_item_refinement->refineOneCell<IT_HemiHexa6>(iitem,*this);
1795 break;
1796 case IT_HemiHexa5:
1797 m_item_refinement->refineOneCell<IT_HemiHexa5>(iitem,*this);
1798 break;
1799 case IT_AntiWedgeLeft6:
1800 m_item_refinement->refineOneCell<IT_AntiWedgeLeft6>(iitem,*this);
1801 break;
1802 case IT_AntiWedgeRight6:
1803 m_item_refinement->refineOneCell<IT_AntiWedgeRight6>(iitem,*this);
1804 break;
1805 case IT_DiTetra5:
1806 m_item_refinement->refineOneCell<IT_DiTetra5>(iitem,*this);
1807 break;
1808 default:
1809 ARCANE_FATAL("Not supported refinement Item Type type={0}",iitem.type());
1810 }
1811 }
1812
1813 // Le maillage change si des items sont raffinés
1814 bool mesh_changed = !(i_size == 0);
1815
1816 // Si le maillage change sur un processeur, il change globalement
1817 mesh_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, mesh_changed);
1818
1819 // Et nous avons besoin de mettre à jour le nombre des ids
1820 if (mesh_changed){
1821 for (Integer e = 0; e != i_size; ++e){
1823 populateBackFrontCellsFromParentFaces(i_hParent_cell);
1824 }
1825 }
1826 CHECKPERF( m_perf_counter.stop(PerfCounter::REFINE) )
1828 {
1829 CHECKPERF( m_perf_counter.start(PerfCounter::PGCONSIST) )
1830#ifdef ARCANE_DEBUG
1831 m_node_finder.check2() ;
1832 m_face_finder.check2() ;
1833#endif
1834
1835 // Nodes and faces parallel consistency
1836 m_parallel_amr_consistency->makeNewItemsConsistent(m_node_finder, m_face_finder);
1837 CHECKPERF( m_perf_counter.stop(PerfCounter::PGCONSIST) )
1838 }
1839
1840 debug() << "[MeshRefinement::_refineItems] done"<<m_mesh->allNodes().size();
1841
1842 return mesh_changed;
1843}
1844
1845/*---------------------------------------------------------------------------*/
1846/*---------------------------------------------------------------------------*/
1847
1850{
1851 //Nettoyage des flags de raffinement d'une étape précédente
1853 Cell cell = *icell;
1854 auto mutable_cell = cell.mutableItemBase();
1855 Integer f = mutable_cell.flags();
1856 if (cell.isActive()){
1858 mutable_cell.setFlags(f);
1859 }
1860 else{
1862 mutable_cell.setFlags(f);
1863 }
1864 // Ceci pourrait être laissé de la derniè étape
1866 f &= ~ItemFlags::II_JustRefined;
1868 mutable_cell.setFlags(f);
1869 }
1871 f &= ~ItemFlags::II_JustCoarsened;
1873 mutable_cell.setFlags(f);
1874 }
1875 if (f & ItemFlags::II_JustAdded){
1876 f &= ~ItemFlags::II_JustAdded;
1878 mutable_cell.setFlags(f);
1879 }
1881 f &= ~ItemFlags::II_CoarsenInactive;
1883 mutable_cell.setFlags(f);
1884 }
1885 }
1886}
1887
1888/*---------------------------------------------------------------------------*/
1889/*---------------------------------------------------------------------------*/
1890
1892_contract()
1893{
1894 DynamicMesh* mesh = m_mesh;
1895 ItemInternalMap& cells_map = mesh->cellsMap();
1896
1897 // Flag indicating if this call actually changes the mesh
1898 bool mesh_changed = false;
1899
1900 if (arcaneIsDebug()){
1901 cells_map.eachItem([&](impl::ItemBase item) {
1902 if (item.isOwn())
1903 // une maille est soit active, subactive ou ancestor
1904 ARCANE_ASSERT((item.isActive() || item.isSubactive() || item.isAncestor()), (" "));
1905 });
1906 }
1907
1908 //
1909 std::set < Int32 > cells_to_remove_set;
1911
1912 cells_map.eachItem([&](impl::ItemBase iitem) {
1913 if (!iitem.isOwn())
1914 return;
1915
1916 // suppression des subactives
1917 if (iitem.isSubactive()) {
1918 // aucune maille de niveau 0 ne doit être subactive.
1919 ARCANE_ASSERT((iitem.nbHParent() != 0), (""));
1920 cells_to_remove_set.insert(iitem.localId());
1921 // informe le client du changement de maillage
1922 mesh_changed = true;
1923 }
1924 else{
1925 // Compression des mailles actives
1926 if (iitem.isActive()) {
1927 bool active_parent = false;
1928 for (Integer c = 0; c < iitem.nbHChildren(); c++) {
1929 impl::ItemBase ichild = iitem.hChildBase(c);
1930 if (!ichild.isSuppressed()) {
1931 //debug() << "[\tMeshRefinement::contract]PARENT UID=" << iitem->uniqueId() << " " << iitem->owner() << " "
1932 // << iitem->level();
1933 cells_to_remove_set.insert(ichild.localId());
1934 //debug() << "[\tMeshRefinement::contract]CHILD UID=" << ichild->uniqueId() << " " << ichild->owner();
1935 active_parent = true;
1936 }
1937 }
1938 if (active_parent){
1939 parent_cells.add(iitem._itemInternal());
1940 ARCANE_ASSERT((iitem.flags() & ItemFlags::II_JustCoarsened), ("Incoherent JustCoarsened flag"));
1941 }
1942 // informe le client du changement de maillage
1943 mesh_changed = true;
1944 }
1945 else{
1946 ARCANE_ASSERT((iitem.isAncestor()), (""));
1947 }
1948 }
1949 });
1950 //
1952 std::copy(std::begin(cells_to_remove_set), std::end(cells_to_remove_set),std::begin(cell_lids));
1953
1954 if (m_mesh->parallelMng()->isParallel()){
1955 this->_makeFlagParallelConsistent2();
1956 this->_removeGhostChildren();
1957 this->_updateItemOwner(cell_lids);
1959 }
1960 if (cell_lids.size() > 0){
1961 this->_upscaleData(parent_cells);
1962 _invalidate(parent_cells);
1963 //_updateItemOwner(cells_local_id);
1965 const Integer ps = parent_cells.size();
1966 for (Integer i = 0; i < ps; i++)
1968 }
1969 else
1970 mesh_changed = false;
1971
1972 return mesh_changed;
1973}
1974
1975/*---------------------------------------------------------------------------*/
1976/*---------------------------------------------------------------------------*/
1977
1978void MeshRefinement::
1979registerCallBack(IAMRTransportFunctor* f)
1980{
1981 m_call_back_mng->registerCallBack(f);
1982}
1983
1984/*---------------------------------------------------------------------------*/
1985/*---------------------------------------------------------------------------*/
1986
1987void MeshRefinement::
1988unRegisterCallBack(IAMRTransportFunctor* f)
1989{
1990 m_call_back_mng->unregisterCallBack(f);
1991}
1992
1993/*---------------------------------------------------------------------------*/
1994/*---------------------------------------------------------------------------*/
1995
1998{
1999 const Int32 nb_cells = cells_to_refine.size();
2003
2005 for (Integer i = 0; i < nb_cells; i++) {
2006 cells_to_refine_internals[i] = ItemCompatibility::_itemInternal(internals[lids[i]]);
2007 }
2008 m_call_back_mng->callCallBacks(cells_to_refine_internals, Prolongation);
2010}
2011
2012void MeshRefinement::
2014{
2015 CHECKPERF( m_perf_counter.start(PerfCounter::UPDATEMAP) )
2016 const Int32 nb_cells = cells_to_refine_uids.size();
2021 for (Integer i = 0; i < nb_cells; i++) {
2022 cells_to_refine[i] = ItemCompatibility::_itemInternal(internals[lids[i]]);
2023 }
2024 m_node_finder.updateData(cells_to_refine);
2025 m_face_finder.updateData(cells_to_refine);
2026 _updateMaxUid(cells_to_refine);
2027 m_item_refinement->updateChildHMin(cells_to_refine) ;
2028 //m_face_finder.updateFaceCenter(cells_to_refine);
2029 CHECKPERF( m_perf_counter.stop(PerfCounter::UPDATEMAP) )
2030}
2031
2032void MeshRefinement::
2033_update(ArrayView<ItemInternal*> cells_to_refine)
2034{
2035 CHECKPERF( m_perf_counter.start(PerfCounter::UPDATEMAP) )
2036 m_node_finder.updateData(cells_to_refine) ;
2037 m_face_finder.updateData(cells_to_refine) ;
2038 _updateMaxUid(cells_to_refine) ;
2039 m_item_refinement->updateChildHMin(cells_to_refine) ;
2040 //m_face_finder.updateFaceCenter(cells_to_refine);
2041 CHECKPERF( m_perf_counter.stop(PerfCounter::UPDATEMAP) )
2042}
2043
2044void MeshRefinement::
2045_invalidate(ArrayView<ItemInternal*> coarsen_cells)
2046{
2047 CHECKPERF( m_perf_counter.start(PerfCounter::CLEAR) )
2048 m_node_finder.clearData(coarsen_cells) ;
2049 m_face_finder.clearData(coarsen_cells) ;
2050 CHECKPERF( m_perf_counter.stop(PerfCounter::CLEAR) )
2051}
2052
2053/*---------------------------------------------------------------------------*/
2054/*---------------------------------------------------------------------------*/
2055
2058{
2059 m_call_back_mng->callCallBacks(parent_cells,Restriction);
2060}
2061
2062/*---------------------------------------------------------------------------*/
2063/*---------------------------------------------------------------------------*/
2064
2065void MeshRefinement::
2066_updateItemOwner(Int32ArrayView cell_to_remove_lids)
2067{
2070
2073
2074 const Integer sid = m_mesh->parallelMng()->commRank();
2075
2076 bool node_owner_changed = false;
2077 bool face_owner_changed = false;
2078
2079 std::map<Int32, bool> marker;
2080
2081 for (Integer i = 0, is = cell_to_remove_lids.size(); i < is; i++){
2083 for (Node node : item.nodes()){
2084
2085 if (marker.find(node.localId()) != marker.end())
2086 continue;
2087 else
2088 marker[node.localId()] = true;
2089
2090 //debug() << "NODE " << FullItemPrinter(node);
2091 //const Int32 owner = node->owner();
2092 bool is_ok = false;
2093 Integer count = 0;
2094 const Integer node_cs = node.cells().size();
2095 for ( Cell cell : node.cells() ){
2096 if (cell_to_remove_lids.contains(cell.localId())){
2097 count++;
2098 if (count == node_cs)
2099 is_ok = true;
2100 continue;
2101 }
2102 // SDC : this condition contributes to desynchronize node owners...
2103// if (cell->owner() == owner)
2104// {
2105// is_ok = true;
2106// break;
2107// }
2108 }
2109 if (!is_ok){
2110 Cell cell;
2111 for ( Cell cell2 : node.cells() ){
2112 if (cell_to_remove_lids.contains(cell2.localId()))
2113 continue;
2114 if (cell.null() || cell2.uniqueId() < cell.uniqueId())
2115 cell = cell2;
2116 }
2117 if (cell.null())
2118 ARCANE_FATAL("Inconsistent null cell owner reference");
2119 const Int32 new_owner = cell.owner();
2120 nodes_owner[node] = new_owner;
2121 node.mutableItemBase().setOwner(new_owner, sid);
2122 //debug() << " NODE CHANGED OWNER " << node->uniqueId();
2123 node_owner_changed = true;
2124 }
2125 }
2126 for ( Face face : item.faces() ){
2127 if (face.nbCell() != 2)
2128 continue;
2129 const Int32 owner = face.owner();
2130 bool is_ok = false;
2131 for (Cell cell : face.cells() ){
2132 if ((item.uniqueId() == cell.uniqueId()) || !(item.level() == cell.level()))
2133 continue;
2134 if (cell.owner() == owner){
2135 is_ok = true;
2136 break;
2137 }
2138 }
2139 if (!is_ok){
2140 for (Cell cell2 : face.cells()){
2141 if (item.uniqueId() == cell2.uniqueId())
2142 continue;
2143 faces_owner[face] = cell2.owner();
2144 face.mutableItemBase().setOwner(cell2.owner(), sid);
2145 //debug() << " FACE CHANGED OWNER " << FullItemPrinter(face);
2146 face_owner_changed = true;
2147 }
2148 }
2149 }
2150 }
2151
2152 node_owner_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, node_owner_changed);
2153 if (node_owner_changed){
2154 // nodes_owner.synchronize(); // SDC Surtout pas la synchro est KO à ce moment là (fantômes non raffinés/déraffinés)
2157 }
2158 face_owner_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, face_owner_changed);
2159 if (face_owner_changed){
2160 faces_owner.synchronize();
2163 }
2164}
2165
2166/*---------------------------------------------------------------------------*/
2167/*---------------------------------------------------------------------------*/
2168
2169void MeshRefinement::
2170_updateItemOwner2()
2171{
2172 // il faut que tout sub-item est une cellule voisine de même propriétaire
2174
2175 NodeGroup own_nodes = m_mesh->ownNodes();
2176 bool owner_changed = false;
2177 ENUMERATE_NODE(inode,own_nodes){
2178 Node node = (*inode);
2179 Int32 owner = node.owner();
2180 bool is_ok = false;
2181 for( Cell cell : node.cells() ){
2182 if (cell.owner()==owner){
2183 is_ok = true;
2184 break;
2185 }
2186 }
2187 if (!is_ok){
2188 Cell cell;
2189 for( Cell cell2 : node.cells() ){
2190 if (cell.null() || cell2.uniqueId() < cell.uniqueId())
2191 cell = cell2;
2192 }
2193 ARCANE_ASSERT((!cell.null()),("Inconsistent null cell owner reference"));
2194 nodes_owner[node] = cell.owner();
2195 owner_changed =true;
2196 }
2197 }
2198 owner_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMin, owner_changed);
2199 if (owner_changed){
2200 nodes_owner.synchronize();
2203 }
2204
2205 // il faut que tout sub-item est une cellule voisine de même propriétaire
2207
2208 FaceGroup own_faces = m_mesh->ownFaces();
2209 owner_changed = false;
2210 ENUMERATE_FACE(iface,own_faces){
2211 Face face = (*iface);
2212 Int32 owner = face.owner();
2213 bool is_ok = false;
2214 for( Cell cell : face.cells() ){
2215 if (cell.owner()==owner){
2216 is_ok = true;
2217 break;
2218 }
2219 }
2220 if (!is_ok){
2221 if(face.nbCell() ==2)
2222 fatal() << "Face" << ItemPrinter(face) << " has a different owner with respect to Back/Front Cells";
2223
2224 faces_owner[face] = face.boundaryCell().owner();
2225 owner_changed=true;
2226 }
2227 }
2228 owner_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMin, owner_changed);
2229 if (owner_changed){
2230 faces_owner.synchronize();
2233 }
2234}
2235/*---------------------------------------------------------------------------*/
2236/*---------------------------------------------------------------------------*/
2237
2238bool MeshRefinement::
2239_removeGhostChildren()
2240{
2241 const Integer sid = m_mesh->parallelMng()->commRank();
2242 DynamicMesh* mesh = m_mesh;
2243 ItemInternalMap& cells_map = mesh->cellsMap();
2244
2245 // Suppression des mailles
2246 Int32UniqueArray cells_to_remove ;
2247 cells_to_remove.reserve(1000);
2248 UniqueArray<ItemInternal*> parent_cells;
2249 parent_cells.reserve(1000);
2250
2251 cells_map.eachItem([&](impl::ItemBase cell) {
2252 if (cell.owner() == sid)
2253 return;
2254
2255 if (cell.flags() & ItemFlags::II_JustCoarsened) {
2256 for (Integer c = 0, cs = cell.nbHChildren(); c < cs; c++) {
2257 cells_to_remove.add(cell.hChildBase(c).localId());
2258 }
2259 parent_cells.add(cell._itemInternal());
2260 }
2261 });
2262
2263 _invalidate(parent_cells) ;
2264
2265 // Avant suppression, mettre a jour les owner de Node/Face isoles
2266 _updateItemOwner(cells_to_remove);
2267 //info() << "Number of cells to remove: " << cells_to_remove.size();
2268 m_mesh->modifier()->removeCells(cells_to_remove,false);
2269 for (Integer i = 0, ps = parent_cells.size(); i < ps; i++)
2271
2272 return cells_to_remove.size() > 0 ;
2273}
2274
2275/*---------------------------------------------------------------------------*/
2276/*---------------------------------------------------------------------------*/
2277
2278void MeshRefinement::
2279populateBackFrontCellsFromParentFaces(Cell parent_cell)
2280{
2281 switch (parent_cell.type())
2282 {
2283 case IT_Quad4:
2284 _populateBackFrontCellsFromParentFaces<IT_Quad4>(parent_cell);
2285 break;
2286 case IT_Tetraedron4:
2287 _populateBackFrontCellsFromParentFaces<IT_Tetraedron4>(parent_cell);
2288 break;
2289 case IT_Pyramid5:
2290 _populateBackFrontCellsFromParentFaces<IT_Pyramid5>(parent_cell);
2291 break;
2292 case IT_Pentaedron6:
2293 _populateBackFrontCellsFromParentFaces<IT_Pentaedron6>(parent_cell);
2294 break;
2295 case IT_Hexaedron8:
2296 _populateBackFrontCellsFromParentFaces<IT_Hexaedron8>(parent_cell);
2297 break;
2298 case IT_HemiHexa7:
2299 _populateBackFrontCellsFromParentFaces<IT_HemiHexa7>(parent_cell);
2300 break;
2301 case IT_HemiHexa6:
2302 _populateBackFrontCellsFromParentFaces<IT_HemiHexa6>(parent_cell);
2303 break;
2304 case IT_HemiHexa5:
2305 _populateBackFrontCellsFromParentFaces<IT_HemiHexa5>(parent_cell);
2306 break;
2307 case IT_AntiWedgeLeft6:
2308 _populateBackFrontCellsFromParentFaces<IT_AntiWedgeLeft6>(parent_cell);
2309 break;
2310 case IT_AntiWedgeRight6:
2311 _populateBackFrontCellsFromParentFaces<IT_AntiWedgeRight6>(parent_cell);
2312 break;
2313 case IT_DiTetra5:
2314 _populateBackFrontCellsFromParentFaces<IT_DiTetra5>(parent_cell);
2315 break;
2316 default:
2317 ARCANE_FATAL("Not supported refinement Item Type type={0}",parent_cell.type());
2318 }
2319}
2320/*---------------------------------------------------------------------------*/
2321/*---------------------------------------------------------------------------*/
2322
2323template <int typeID> void MeshRefinement::
2325{
2326 Integer nb_children = parent_cell.nbHChildren();
2328 for (Integer c = 0; c < nb_children; c++){
2329 Cell child = parent_cell.hChild(c);
2330 Integer nb_child_faces = child.nbFace();
2331 for (Integer fc = 0; fc < nb_child_faces; fc++){
2332 if (rp.face_mapping_topo(c, fc) == 0)
2333 continue;
2334 const Integer f = rp.face_mapping(c, fc);
2335 Face face = parent_cell.face(f);
2336 Integer nb_cell_face = face.nbCell();
2337 if (nb_cell_face == 1)
2338 continue;
2339 Face subface = child.face(fc);
2340 Integer nb_cell_subface = subface.nbCell();
2341 if (nb_cell_subface == 1){
2342 m_face_family->addBackFrontCellsFromParentFace(subface, face);
2343 }
2344 else{
2345 if (face.backCell().isOwn() != face.frontCell().isOwn()){
2346 m_face_family->replaceBackFrontCellsFromParentFace(child, subface, parent_cell, face);
2347 }
2348 else{
2349 if (!face.backCell().isOwn() && !face.frontCell().isOwn()){
2350 m_face_family->replaceBackFrontCellsFromParentFace(child, subface, parent_cell, face);
2351 }
2352 }
2353 }
2354 ARCANE_ASSERT((subface.backCell() != parent_cell && subface.frontCell() != parent_cell),
2355 ("back front cells error"));
2356 }
2357 }
2358}
2359
2360/*---------------------------------------------------------------------------*/
2361/*---------------------------------------------------------------------------*/
2362
2365{
2366 ARCANE_ASSERT((parent_cell.isActive()), (""));
2367 Integer nb_faces = parent_cell.nbFace();
2368 for (Integer f = 0; f < nb_faces; f++){
2369 Face face = parent_cell.face(f);
2370 Integer nb_cell_face = face.nbCell();
2371 if (nb_cell_face == 1)
2372 continue;
2373 Cell neighbor_cell = (face.cell(0) == parent_cell) ? face.cell(1) : face.cell(0);
2374 if (neighbor_cell.isActive())
2375 continue;
2376 switch (neighbor_cell.type()){
2377 case IT_Quad4:
2379 break;
2380 case IT_Tetraedron4:
2382 break;
2383 case IT_Pyramid5:
2385 break;
2386 case IT_Pentaedron6:
2388 break;
2389 case IT_Hexaedron8:
2391 break;
2392 case IT_HemiHexa7:
2394 break;
2395 case IT_HemiHexa6:
2397 break;
2398 case IT_HemiHexa5:
2400 break;
2401 case IT_AntiWedgeLeft6:
2403 break;
2404 case IT_AntiWedgeRight6:
2406 break;
2407 case IT_DiTetra5:
2409 break;
2410 default:
2411 ARCANE_FATAL("Not supported refinement Item Type type={0}",neighbor_cell.type());
2412 }
2413 }
2414}
2415
2416/*---------------------------------------------------------------------------*/
2417/*---------------------------------------------------------------------------*/
2418
2419template <int typeID> void MeshRefinement::
2420_populateBackFrontCellsFromChildrenFaces(Face face, Cell parent_cell,
2422{
2424 for(Integer f=0;f<neighbor_cell.nbFace();f++){
2425 if (neighbor_cell.face(f) == face){
2426 Integer nb_children = neighbor_cell.nbHChildren();
2427 for (Integer c = 0; c < nb_children; c++){
2428 Cell child = neighbor_cell.hChild(c);
2429 Integer nb_child_faces = child.nbFace();
2430 for (Integer fc = 0; fc < nb_child_faces; fc++){
2431 if (f == rp.face_mapping(c, fc) && (rp.face_mapping_topo(c, fc))){
2432 Face subface = child.face(fc);
2433 if (subface.itemBase().flags() & ItemFlags::II_HasBackCell){
2434 m_face_family->addFrontCellToFace(subface, parent_cell);
2435 }
2436 else if (subface.itemBase().flags() & ItemFlags::II_HasFrontCell){
2437 m_face_family->addBackCellToFace(subface, parent_cell);
2438 }
2439 ARCANE_ASSERT((subface.backCell() != subface.frontCell()), ("back front cells error"));
2440 }
2441 }
2442 }
2443 break;
2444 }
2445 }
2446}
2447
2448/*---------------------------------------------------------------------------*/
2449/*---------------------------------------------------------------------------*/
2450
2451void MeshRefinement::
2452_checkOwner(const String& msg)
2453{
2454 // This method has been introduced to patch node owner desynchronization occuring in IFPEN applications
2455 info() << "----CheckOwner in " << msg;
2456 VariableNodeInt32 syncvariable(VariableBuildInfo(m_mesh,"SyncVarNodeOwnerContract"));
2457 syncvariable.fill(-1);
2458 bool has_owner_changed = false;
2459 ENUMERATE_NODE(inode,m_mesh->ownNodes()) syncvariable[inode] = inode->owner();
2460 VariableNodeInt32 syncvariable_copy(VariableBuildInfo(m_mesh,"SyncVarNodeOwnerContractCopy"));
2461 syncvariable_copy.copy(syncvariable);
2462 syncvariable.synchronize();
2463 ItemVector desync_nodes(m_mesh->nodeFamily());
2464 ENUMERATE_NODE(inode,m_mesh->allNodes())
2465 {
2466 if (syncvariable[inode] == -1) {
2467 debug(Trace::Highest) << "----- Inconsistent owner (ghost everywhere) for node with uid : "
2468 << inode->uniqueId().asInt64();
2469 desync_nodes.addItem(*inode);
2470 has_owner_changed = true;
2471 }
2472 if (inode->isOwn() && (syncvariable_copy[inode] != syncvariable[inode])) {
2473 debug(Trace::Highest) << "----- Inconsistent owner (own everywhere) for node with uid : "
2474 << inode->uniqueId().asInt64();
2475 desync_nodes.addItem(*inode);
2476 has_owner_changed = true;
2477 }
2478 }
2479 // Find a new owner different from the historical one stored in node_owner_memory
2480 // Indeed the desync occured while changing from this historical owner to avoid an isolated item
2481 // Going back to this owner would make this problem of isolated owner appear again
2482 // 1-Get the owners of all desync nodes on every process
2483 // 1.1 Synchronize desync_nodes : if a node is desynchronized in a domain, all the domains must do the correction
2484 Int64UniqueArray desync_node_uids(desync_nodes.size());
2485 ENUMERATE_NODE(inode, desync_nodes) {
2486 desync_node_uids[inode.index()] = inode->uniqueId().asInt64();
2487 }
2488 Int64UniqueArray desync_node_uids_gather;
2489 m_mesh->parallelMng()->allGatherVariable(desync_node_uids.view(),desync_node_uids_gather);
2490 Int32UniqueArray desync_node_lids_gather(desync_node_uids_gather.size());
2491 m_mesh->nodeFamily()->itemsUniqueIdToLocalId(desync_node_lids_gather,desync_node_uids_gather,false);
2492 for (auto lid : desync_node_lids_gather) {
2493 if (lid == NULL_ITEM_LOCAL_ID)
2494 continue;
2495 if (std::find(desync_nodes.viewAsArray().begin(), desync_nodes.viewAsArray().end(),lid) == desync_nodes.viewAsArray().end()){
2496 desync_nodes.add(lid);
2497 }
2498 }
2499 // 1.2 Exchange the owners of the desynchronized nodes
2500 // each process fill an array [node1_uid, node1_owner,...nodei_uid, nodei_owner,...]
2501 Int64UniqueArray desync_node_owners(2*desync_nodes.size());
2502 ENUMERATE_NODE(inode, desync_nodes) {
2503 desync_node_owners[2*inode.index() ] = inode->uniqueId().asInt64();
2504 desync_node_owners[2*inode.index()+1] = inode->owner();
2505 }
2506 // 1.2 gather this array on every process
2507 Int64UniqueArray desync_node_owners_gather;
2508 m_mesh->parallelMng()->allGatherVariable(desync_node_owners.view(),desync_node_owners_gather);
2509 // 1.3 store the information in a map <uid, Array[owner] >
2510 std::map<Int64,Int32SharedArray> uid_owners_map;
2511 for (Integer node_index = 0; node_index+1 < desync_node_owners_gather.size();) {
2512 uid_owners_map[desync_node_owners_gather[node_index]].add((Int32)desync_node_owners_gather[node_index+1]);
2513 desync_node_uids_gather.add(desync_node_owners_gather[node_index]);
2514 node_index+=2;
2515 }
2516 // 2 choose the unique owner of the desynchronized nodes :
2517 // Choose the minimum owner (same choice on each proc) different from the historical owner
2518 Integer new_owner = m_mesh->parallelMng()->commSize()+1;
2519 ENUMERATE_NODE(inode, desync_nodes) {
2520 for (auto owner : uid_owners_map[inode->uniqueId().asInt64()]) {
2521 if (owner < new_owner && owner != m_node_owner_memory[inode]) new_owner = owner;
2522 }
2523 debug(Trace::Highest) << "------ Change owner for node " << inode->uniqueId() << " from " << inode->owner() << " to " << new_owner;
2524 inode->mutableItemBase().setOwner(new_owner, m_mesh->parallelMng()->commRank());
2525 new_owner = m_mesh->parallelMng()->commSize()+1;
2526 }
2527 // Update family if owners have changed
2528 bool p_has_owner_changed = m_mesh->parallelMng()->reduce(Parallel::ReduceMax, has_owner_changed);
2529 if (p_has_owner_changed) {
2533 }
2534 // update node memory owner
2535 ENUMERATE_NODE(inode,m_mesh->allNodes()) m_node_owner_memory[inode] = inode->owner();
2536}
2537
2538/*---------------------------------------------------------------------------*/
2539/*---------------------------------------------------------------------------*/
2540
2542getMesh() const
2543{
2544 return m_mesh;
2545}
2546
2547/*---------------------------------------------------------------------------*/
2548/*---------------------------------------------------------------------------*/
2549
2551getMesh()
2552{
2553 return m_mesh;
2554}
2555
2556/*---------------------------------------------------------------------------*/
2557/*---------------------------------------------------------------------------*/
2558
2559} // End namespace Arcane::mesh
2560
2561/*---------------------------------------------------------------------------*/
2562/*---------------------------------------------------------------------------*/
#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:149
Interface du gestionnaire des matériaux et des milieux d'un maillage.
static IMeshMaterialMng * getReference(const MeshHandleOrMesh &mesh_handle, bool create=true)
Récupère ou créé la référence associée à mesh.
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 Item.h:564
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:550
bool arcaneIsDebug()
Vrai si la macro ARCANE_DEBUG est définie.
Definition Misc.cc:80
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:552
Int32 Integer
Type représentant un entier.