Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
AMRCartesianMeshTesterModule.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/* AMRCartesianMeshTesterModule.cc (C) 2000-2024 */
9/* */
10/* Module de test du gestionnaire de maillages cartésiens AMR. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/CheckedConvert.h"
15#include "arcane/utils/PlatformUtils.h"
16#include "arcane/utils/Real2.h"
17#include "arcane/utils/MD5HashAlgorithm.h"
18
20#include "arcane/core/MeshKind.h"
21#include "arcane/core/Directory.h"
22
23#include "arcane/core/ITimeLoopMng.h"
24#include "arcane/core/ITimeLoopService.h"
25#include "arcane/core/ITimeLoop.h"
26#include "arcane/core/TimeLoopEntryPointInfo.h"
27#include "arcane/core/IMesh.h"
28#include "arcane/core/IItemFamily.h"
29#include "arcane/core/ItemPrinter.h"
30#include "arcane/core/IParallelMng.h"
31
32#include "arcane/core/IMesh.h"
33#include "arcane/core/IItemFamily.h"
34#include "arcane/core/IMeshModifier.h"
35#include "arcane/core/IMeshUtilities.h"
36#include "arcane/core/ServiceBuilder.h"
38#include "arcane/core/MeshStats.h"
39#include "arcane/core/IPostProcessorWriter.h"
40#include "arcane/core/IVariableMng.h"
41#include "arcane/core/SimpleSVGMeshExporter.h"
42
43#include "arcane/cartesianmesh/ICartesianMesh.h"
44#include "arcane/cartesianmesh/CellDirectionMng.h"
45#include "arcane/cartesianmesh/FaceDirectionMng.h"
46#include "arcane/cartesianmesh/NodeDirectionMng.h"
47#include "arcane/cartesianmesh/CartesianConnectivity.h"
48#include "arcane/cartesianmesh/CartesianMeshRenumberingInfo.h"
49#include "arcane/cartesianmesh/ICartesianMeshPatch.h"
50#include "arcane/cartesianmesh/CartesianMeshUtils.h"
51#include "arcane/cartesianmesh/CartesianMeshCoarsening2.h"
52#include "arcane/cartesianmesh/CartesianMeshPatchListView.h"
53
54#include "arcane/tests/ArcaneTestGlobal.h"
55#include "arcane/tests/AMRCartesianMeshTester_axl.h"
56#include "arcane/tests/CartesianMeshTestUtils.h"
57
58/*---------------------------------------------------------------------------*/
59/*---------------------------------------------------------------------------*/
60
61namespace ArcaneTest
62{
63
64using namespace Arcane;
65
66/*---------------------------------------------------------------------------*/
67/*---------------------------------------------------------------------------*/
72: public ArcaneAMRCartesianMeshTesterObject
73{
74 public:
75
78
79 public:
80
81 static void staticInitialize(ISubDomain* sd);
82
83 public:
84
85 void buildInit() override;
86 void compute() override;
87 void init() override;
88
89 private:
90
91 VariableCellReal m_density;
92 VariableCellReal m_old_density;
93 VariableCellReal3 m_cell_center;
94 VariableFaceReal3 m_face_center;
95 VariableNodeReal m_node_density;
96 ICartesianMesh* m_cartesian_mesh;
98 UniqueArray<VariableCellReal*> m_cell_patch_variables;
99 Int32 m_nb_expected_patch = 0;
100
101 private:
102
103 void _compute1();
104 void _compute2();
105 void _initAMR();
106 void _coarseZone();
107 void _reduceNbGhostLayers();
108 void _computeSubCellDensity(Cell cell);
109 void _computeCenters();
110 void _processPatches();
111 void _writePostProcessing();
112 void _checkUniqueIds();
113 void _testDirections();
114 void _cellsInPatch(Real3 position, Real3 length, bool is_3d, Int32 level, UniqueArray<Int32>& cells_in_patch);
115};
116
117/*---------------------------------------------------------------------------*/
118/*---------------------------------------------------------------------------*/
119
120AMRCartesianMeshTesterModule::
121AMRCartesianMeshTesterModule(const ModuleBuildInfo& mbi)
122: ArcaneAMRCartesianMeshTesterObject(mbi)
123, m_density(VariableBuildInfo(this,"Density"))
124, m_old_density(VariableBuildInfo(this,"OldDensity"))
125, m_cell_center(VariableBuildInfo(this,"CellCenter"))
126, m_face_center(VariableBuildInfo(this,"FaceCenter"))
127, m_node_density(VariableBuildInfo(this,"NodeDensity"))
128, m_cartesian_mesh(nullptr)
129{
130}
131
132/*---------------------------------------------------------------------------*/
133/*---------------------------------------------------------------------------*/
134
135AMRCartesianMeshTesterModule::
136~AMRCartesianMeshTesterModule()
137{
138 for (VariableCellReal* v : m_cell_patch_variables)
139 delete v;
140}
141
142/*---------------------------------------------------------------------------*/
143/*---------------------------------------------------------------------------*/
144
145void AMRCartesianMeshTesterModule::
146staticInitialize(ISubDomain* sd)
147{
148 String time_loop_name("AMRCartesianMeshTestLoop");
149
150 ITimeLoopMng* tlm = sd->timeLoopMng();
151 ITimeLoop* time_loop = tlm->createTimeLoop(time_loop_name);
152
153 {
155 clist.add(TimeLoopEntryPointInfo("AMRCartesianMeshTester.buildInit"));
156 time_loop->setEntryPoints(ITimeLoop::WBuild,clist);
157 }
158
159 {
161 clist.add(TimeLoopEntryPointInfo("AMRCartesianMeshTester.init"));
162 time_loop->setEntryPoints(ITimeLoop::WInit,clist);
163 }
164
165 {
167 clist.add(TimeLoopEntryPointInfo("AMRCartesianMeshTester.compute"));
168 time_loop->setEntryPoints(ITimeLoop::WComputeLoop,clist);
169 }
170
171 {
173 clist.add("AMRCartesianMeshTester");
174 time_loop->setRequiredModulesName(clist);
175 clist.clear();
176 clist.add("ArcanePostProcessing");
177 clist.add("ArcaneCheckpoint");
178 clist.add("ArcaneLoadBalance");
179 time_loop->setOptionalModulesName(clist);
180 }
181
182 tlm->registerTimeLoop(time_loop);
183}
184
185/*---------------------------------------------------------------------------*/
186/*---------------------------------------------------------------------------*/
187
188void AMRCartesianMeshTesterModule::
189buildInit()
190{
191 if (subDomain()->isContinue())
192 return;
193
194 m_global_deltat.assign(1.0);
195
196 IItemFamily* cell_family = defaultMesh()->cellFamily();
197 cell_family->createGroup("CELL0");
198 cell_family->createGroup("CELL1");
199 cell_family->createGroup("CELL2");
200 cell_family->createGroup("AMRPatchCells0");
201 cell_family->createGroup("AMRPatchCells1");
202 cell_family->createGroup("AMRPatchCells2");
203 cell_family->createGroup("AMRPatchCells3");
204 cell_family->createGroup("AMRPatchCells4");
205 cell_family->createGroup("AMRPatchCells5");
206
207 IItemFamily* face_family = defaultMesh()->faceFamily();
208 face_family->createGroup("FACE0");
209 face_family->createGroup("FACE1");
210 face_family->createGroup("FACE2");
211 face_family->createGroup("FACE3");
212 face_family->createGroup("FACE4");
213 face_family->createGroup("FACE5");
214
215 face_family->createGroup("AllFacesDirection0");
216 face_family->createGroup("AllFacesDirection1");
217}
218
219/*---------------------------------------------------------------------------*/
220/*---------------------------------------------------------------------------*/
221
222void AMRCartesianMeshTesterModule::
223init()
224{
225 info() << "AMR Init";
226
227 IMesh* mesh = defaultMesh();
228
230 Int32UniqueArray ids(1);
231 ids[0] = 0;
232 cell_family->createGroup("CELL0",ids,true);
233 ids[0] = 1;
234 cell_family->createGroup("CELL1",ids,true);
235 ids[0] = 2;
236 cell_family->createGroup("CELL2",ids,true);
237 IItemFamily* face_family = defaultMesh()->faceFamily();
238 ids[0] = 0;
239 face_family->createGroup("FACE0",ids,true);
240 ids[0] = 1;
241 face_family->createGroup("FACE1",ids,true);
242 ids[0] = 2;
243 face_family->createGroup("FACE2",ids,true);
244 ids[0] = 3;
245 face_family->createGroup("FACE3",ids,true);
246 ids[0] = 4;
247 face_family->createGroup("FACE4",ids,true);
248 ids[0] = 5;
249 face_family->createGroup("FACE5",ids,true);
250
251 m_cartesian_mesh = ICartesianMesh::getReference(mesh);
252 m_utils = makeRef(new CartesianMeshTestUtils(m_cartesian_mesh,acceleratorMng()));
253
254 if (!subDomain()->isContinue()) {
255 _initAMR();
256 _coarseZone();
257 _reduceNbGhostLayers();
258 }
259
260 _computeCenters();
261
262
263 const bool do_coarse_at_init = options()->coarseAtInit();
264
265 const Integer dimension = defaultMesh()->dimension();
266 if (dimension==2)
267 m_nb_expected_patch = 1 + options()->refinement2d().size();
268 else if (dimension==3)
269 m_nb_expected_patch = 1 + options()->refinement3d().size();
270
271 // Si on dé-raffine à l'init, on aura un patch de plus
273 ++m_nb_expected_patch;
274
275 if (subDomain()->isContinue())
276 m_cartesian_mesh->recreateFromDump();
277 else{
278 m_cartesian_mesh->computeDirections();
280 renumbering_info.setRenumberPatchMethod(options()->renumberPatchMethod());
281 renumbering_info.setSortAfterRenumbering(true);
282 if (options()->coarseAtInit())
283 renumbering_info.setParentPatch(m_cartesian_mesh->amrPatch(1));
284 m_cartesian_mesh->renumberItemsUniqueId(renumbering_info);
285 _checkUniqueIds();
286 _processPatches();
287 info() << "MaxUid for mesh=" << MeshUtils::getMaxItemUniqueIdCollective(m_cartesian_mesh->mesh());
288 }
289
290 // Initialise la densité.
291 // On met une densité de 1.0 à l'intérieur
292 // et on ajoute une densité de 5.0 pour chaque direction dans les
293 // mailles de bord.
294 m_density.fill(1.0);
295 for( Integer idir=0, nb_dir=dimension; idir<nb_dir; ++idir){
296 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(idir));
299 ENUMERATE_CELL(icell,cdm.innerCells()){
300 DirCell cc(cdm.cell(*icell));
301 Cell next = cc.next();
302 Cell prev = cc.previous();
303 if (next.null() || prev.null()){
304 // Maille au bord. J'ajoute de la densité.
305 // Ne devrait pas arriver car on est sur les innerCells()
306 ++nb_boundary1;
307 m_density[icell] += 5.0;
308 }
309 }
310 // Parcours les mailles frontières pour la direction
311 ENUMERATE_CELL(icell,cdm.outerCells()){
313 if (icell.index()<5)
314 info() << "CELL: cell=" << ItemPrinter(*icell)
315 << " next=" << ItemPrinter(cc.next())
316 << " previous=" << ItemPrinter(cc.previous());
317 // Maille au bord. J'ajoute de la densité.
318 ++nb_boundary2;
319 m_density[icell] += 5.0;
320 }
321
322 info() << "NB_BOUNDARY1=" << nb_boundary1 << " NB_BOUNDARY2=" << nb_boundary2;
323 }
324 bool is_amr = m_nb_expected_patch!=1;
325 if (options()->verbosityLevel()==0)
326 m_utils->setNbPrint(5);
327 m_utils->testAll(is_amr);
328 _writePostProcessing();
329 _testDirections();
330}
331
332/*---------------------------------------------------------------------------*/
333/*---------------------------------------------------------------------------*/
334
335void AMRCartesianMeshTesterModule::
336_checkUniqueIds()
337{
338 IMesh* mesh = m_cartesian_mesh->mesh();
339 bool print_hash = true;
340 bool with_ghost = options()->hashWithGhost();
342 MeshUtils::checkUniqueIdsHashCollective(mesh->nodeFamily(), &hash_algo, options()->nodesUidHash(),
344 MeshUtils::checkUniqueIdsHashCollective(mesh->faceFamily(), &hash_algo, options()->facesUidHash(),
346 MeshUtils::checkUniqueIdsHashCollective(mesh->cellFamily(), &hash_algo, options()->cellsUidHash(),
348}
349
350/*---------------------------------------------------------------------------*/
351/*---------------------------------------------------------------------------*/
352
353void AMRCartesianMeshTesterModule::
354_processPatches()
355{
356 const bool do_check = true;
357 const bool is_verbose = options()->verbosityLevel()>=1;
358
359 const Int32 dimension = defaultMesh()->dimension();
360
361 bool without_coarse_zone = true;
362 if (dimension == 2)
363 without_coarse_zone = options()->coarseZone2d().empty();
364 else if (dimension == 3)
365 without_coarse_zone = options()->coarseZone3d().empty();
366
367 // Vérifie qu'il y a autant de patchs que d'options raffinement dans
368 // le jeu de données (en comptant le patch 0 qui est le maillage cartésien).
369 // Cela permet de vérifier que les appels successifs
370 // à computeDirections() n'ajoutent pas de patchs.
371 // Cette vérification ne s'applique que s'il n'y a pas de zone de dé-raffinement.
372 // En effet, dé-raffiner un patch complet le supprime de la liste des patchs.
373 Integer nb_expected_patch = m_nb_expected_patch;
374
375 Integer nb_patch = m_cartesian_mesh->nbPatch();
377 ARCANE_FATAL("Bad number of patchs expected={0} value={1}",nb_expected_patch,nb_patch);
378
379 IParallelMng* pm = parallelMng();
380 Int32 comm_rank = pm->commRank();
381 Int32 comm_size = pm->commSize();
382
384 if (nb_cells_expected.size()!=nb_patch)
385 ARCANE_FATAL("Bad size ({0}, expected={1}) for option '{2}'",
387
388 // Nombre de mailles fantômes attendu. Utilisé uniquement en parallèle
389 bool has_expected_ghost_cells = options()->expectedNumberOfGhostCellsInPatchs.isPresent();
390 if (!pm->isParallel())
392
395 ARCANE_FATAL("Bad size ({0}, expected={1}) for option '{2}'",
397 // Affiche les informations sur les patchs
398 for( Integer i=0; i<nb_patch; ++i ){
399 ICartesianMeshPatch* p = m_cartesian_mesh->patch(i);
400 CellGroup patch_cells(p->cells());
401 info() << "Patch cell_group=" << patch_cells.name() << " nb_cell=" << patch_cells.size();
402 VariableCellReal* cellv = new VariableCellReal(VariableBuildInfo(defaultMesh(),String("CellPatch")+i));
403 m_cell_patch_variables.add(cellv);
404 cellv->fill(0.0);
406 (*cellv)[icell] = 2.0;
407 }
408
412 Cell cell{*icell};
413 if (is_verbose)
414 info() << "Patch i=" << i << " cell=" << ItemPrinter(*icell);
415 own_cells_uid.add(cell.uniqueId());
416 }
417 // Affiche la liste globales des uniqueId() des mailles.
418 {
421 std::sort(global_cells_uid.begin(),global_cells_uid.end());
423 info() << "GlobalUids Patch=" << i << " NB=" << nb_global_uid
424 << " expected=" << nb_cells_expected[i];
425 // Vérifie que le nombre de mailles par patch est le bon.
427 ARCANE_FATAL("Bad number of cells for patch I={0} N={1} expected={2}",
429 if (is_verbose)
430 for( Integer c=0; c<nb_global_uid; ++c )
431 info() << "GlobalUid Patch=" << i << " I=" << c << " cell_uid=" << global_cells_uid[c];
432 }
433 // Teste le nombre de mailles fantômes
435 Int32 local_nb_ghost_cell = patch_cells.size() - patch_own_cell.size();
436 Int32 total = pm->reduce(Parallel::ReduceSum,local_nb_ghost_cell);
437 pinfo() << "NbGhostCells my_rank=" << comm_rank << " local=" << local_nb_ghost_cell << " total=" << total;
438 if (total!=nb_ghost_cells_expected[i])
439 ARCANE_FATAL("Bad number of ghost cells for patch I={0} N={1} expected={2}",
440 i,total,nb_ghost_cells_expected[i]);
441 }
442
443 // Exporte le patch au format SVG
444 if (dimension==2 && options()->dumpSvg()){
445 String filename = String::format("Patch{0}-{1}-{2}.svg",i,comm_rank,comm_size);
446 Directory directory = subDomain()->exportDirectory();
447 String full_filename = directory.file(filename);
448 std::ofstream ofile(full_filename.localstr());
450 exporter.write(patch_cells);
451 }
452 }
453}
454
455/*---------------------------------------------------------------------------*/
456/*---------------------------------------------------------------------------*/
457
458void AMRCartesianMeshTesterModule::
459_computeCenters()
460{
461 IMesh* mesh = defaultMesh();
462
463 // Calcule le centre des mailles
464 {
466 ENUMERATE_CELL(icell,allCells()){
467 Cell cell = *icell;
468 Real3 center;
469 for( NodeLocalId inode : cell.nodes() )
470 center += nodes_coord[inode];
471 center /= cell.nbNode();
472 m_cell_center[icell] = center;
473 }
474 }
475
476 // Calcule le centre des faces
477 {
479 ENUMERATE_FACE(iface,allFaces()){
480 Face face = *iface;
481 Real3 center;
482 for( NodeLocalId inode : face.nodes() )
483 center += nodes_coord[inode];
484 center /= face.nbNode();
485 m_face_center[iface] = center;
486 }
487 }
488}
489
490/*---------------------------------------------------------------------------*/
491/*---------------------------------------------------------------------------*/
492
493void AMRCartesianMeshTesterModule::
494_initAMR()
495{
496 // Regarde si on dé-raffine le maillage initial
497 if (options()->coarseAtInit()){
498 // Il faut que les directions aient été calculées avant d'appeler le dé-raffinement
499 m_cartesian_mesh->computeDirections();
500
501 info() << "Doint initial coarsening";
502
503 if (m_cartesian_mesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
504 debug() << "Coarse with specific coarser (for cartesian mesh only)";
506 coarser->coarse();
507 }
508 else {
510 coarser->createCoarseCells();
511 }
512
513 CartesianMeshPatchListView patches = m_cartesian_mesh->patches();
514 Int32 nb_patch = patches.size();
515 {
516 Int32 index = 0;
517 info() << "NB_PATCH=" << nb_patch;
518 for( CartesianPatch p : patches){
519 info() << "Patch i=" << index << " nb_cell=" << p.cells().size();
520 ++index;
521 }
522 }
523 }
524 // Parcours les mailles actives et ajoute dans la liste des mailles
525 // à raffiner celles qui sont contenues dans le boîte englobante
526 // spécifiée dans le jeu de données.
527 Int32 dim = defaultMesh()->dimension();
528 if (dim==2){
529 for( auto& x : options()->refinement2d() ){
530 m_cartesian_mesh->refinePatch2D(x->position(),x->length());
531 m_cartesian_mesh->computeDirections();
532 }
533 }
534 if (dim==3){
535 for( auto& x : options()->refinement3d() ){
536 m_cartesian_mesh->refinePatch3D(x->position(),x->length());
537 m_cartesian_mesh->computeDirections();
538 }
539 }
540}
541
542/*---------------------------------------------------------------------------*/
543/*---------------------------------------------------------------------------*/
544
545void AMRCartesianMeshTesterModule::
546_coarseZone()
547{
548 Int32 dim = defaultMesh()->dimension();
549
550 if (dim == 2) {
551 //UniqueArray<Int32> cells_in_patchs;
552 for (auto& x : options()->coarseZone2d()) {
553 // _cellsInPatch(Real3(x->position()), Real3(x->length()), false, x->level(), cells_in_patchs);
554 // defaultMesh()->modifier()->flagCellToCoarsen(cells_in_patchs);
555 // defaultMesh()->modifier()->coarsenItemsV2(true);
556 // cells_in_patchs.clear();
557 m_cartesian_mesh->coarseZone2D(x->position(), x->length());
558 m_cartesian_mesh->computeDirections();
559 }
560 }
561 if (dim == 3) {
562 // UniqueArray<Int32> cells_in_patchs;
563 for (auto& x : options()->coarseZone3d()) {
564 // _cellsInPatch(x->position(), x->length(), true, x->level(), cells_in_patchs);
565 // defaultMesh()->modifier()->flagCellToCoarsen(cells_in_patchs);
566 // defaultMesh()->modifier()->coarsenItemsV2(true);
567 // cells_in_patchs.clear();
568 m_cartesian_mesh->coarseZone3D(x->position(), x->length());
569 m_cartesian_mesh->computeDirections();
570 }
571 }
572}
573
574/*---------------------------------------------------------------------------*/
575/*---------------------------------------------------------------------------*/
576
577void AMRCartesianMeshTesterModule::
578_reduceNbGhostLayers()
579{
580 for (auto& x : options()->reduceNbGhostLayers()) {
581 Integer final_nb_ghost_layer{ m_cartesian_mesh->reduceNbGhostLayers(x->level(), x->nbGhostLayers()) };
582
583 if (parallelMng()->commSize() != 1 && final_nb_ghost_layer != x->nbGhostLayers()) {
584 ARCANE_FATAL("Bad nb ghost layers");
585 }
586 //info() << "Final nb ghost layer : " << final_nb_ghost_layer;
587 }
588}
589
590/*---------------------------------------------------------------------------*/
591/*---------------------------------------------------------------------------*/
592
593void AMRCartesianMeshTesterModule::
594compute()
595{
596 _compute1();
597}
598
599/*---------------------------------------------------------------------------*/
600/*---------------------------------------------------------------------------*/
606{
607 Int32 nb_children = cell.nbHChildren();
608 if (nb_children==0)
609 return;
610 // Pour les mailles AMR, la densité est la moyenne des noeuds qui la compose.
611 for( Int32 j=0; j<nb_children; ++j ) {
612 Real sub_density = 0.0;
613 Cell sub_cell = cell.hChild(j);
614 Integer sub_cell_nb_node = sub_cell.nbNode();
615 for( Integer k=0; k<sub_cell_nb_node; ++k )
616 sub_density += m_node_density[sub_cell.node(k)];
618 m_density[sub_cell] =sub_density;
620 }
621}
622
623/*---------------------------------------------------------------------------*/
624/*---------------------------------------------------------------------------*/
625
626void AMRCartesianMeshTesterModule::
627_compute1()
628{
629 // Pour test, on parcours les N directions
630 // et pour chaque maille, on modifie sa densité
631 // par la formule new_density = (density+density_next+density_prev) / 3.0.
632
633 // Effectue l'operation en deux fois. Une premiere sur les
634 // mailles internes, et une deuxieme sur les mailles externes.
635 // Du coup, il faut passer par une variable intermediaire (m_old_density)
636 // mais on evite un test dans la boucle principale
637 IMesh* mesh = defaultMesh();
638 Integer nb_dir = mesh->dimension();
639 for( Integer idir=0; idir<nb_dir; ++idir){
640 m_old_density.copy(m_density);
641 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(idir));
642 // Travail sur les mailles internes
643 info() << "Direction=" << idir << " cells=" << cdm.innerCells().name()
644 << " n=" << cdm.innerCells().size();
645 ENUMERATE_CELL(icell,cdm.innerCells()){
646 Cell cell = *icell;
647 DirCell cc(cdm.cell(cell));
648 Cell next = cc.next();
649 Cell prev = cc.previous();
650 Real d = m_old_density[icell] + m_old_density[next] + m_old_density[prev];
651 m_density[icell] = d / 3.0;
653 }
654 // Travail sur les mailles externes
655 // Test si la maille avant ou apres est nulle.
656 ENUMERATE_CELL(icell,cdm.outerCells()){
657 Cell cell = *icell;
659 Cell next = cc.next();
660 Cell prev = cc.previous();
661 Real d = m_old_density[icell];
662 Integer n = 1;
663 if (!next.null()){
664 d += m_old_density[next];
665 ++n;
666 }
667 if (!prev.null()){
668 d += m_old_density[prev];
669 ++n;
670 }
671 m_density[icell] = d / n;
673 }
674 }
675 // Modifie la densité aux noeuds.
676 // Elle sera égale à la moyenne des densités des mailles entourant ce noeud
678 Node node = *inode;
679 Integer nb_cell = node.nbCell();
680 Real density = 0.0;
681 for( Integer i=0; i<nb_cell; ++i )
682 density += m_density[node.cell(i)];
683 density /= (Real)nb_cell;
684 m_node_density[inode] = density;
685 }
686}
687
688/*---------------------------------------------------------------------------*/
689/*---------------------------------------------------------------------------*/
690
691void AMRCartesianMeshTesterModule::
692_compute2()
693{
694 // Pour test, on parcours les N directions
695 // et pour chaque maille, on modifie sa densité
696 // par la formule new_density = (density+density_next+density_prev) / 3.0.
697
698 // A noter que cette methode ne donne pas le meme comportement que
699 // _compute1() car les mailles de bord et internes sont mises à jour
700 // dans un ordre différent.
701 Integer nb_dir = defaultMesh()->dimension();
702 for( Integer idir=0; idir<nb_dir; ++idir){
703 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(idir));
704 // Travail sur toutes les mailles
705 ENUMERATE_CELL(icell,cdm.allCells()){
707 Cell next = cc.next();
708 Cell prev = cc.previous();
709 Real d = m_density[icell];
710 Integer n = 1;
711 if (!next.null()){
712 d += m_density[next];
713 ++n;
714 }
715 if (!prev.null()){
716 d += m_density[prev];
717 ++n;
718 }
719 m_density[icell] = d / n;
720 }
721 }
722}
723
724/*---------------------------------------------------------------------------*/
725/*---------------------------------------------------------------------------*/
726
727void AMRCartesianMeshTesterModule::
728_writePostProcessing()
729{
730 info() << "Post-process AMR";
731 IPostProcessorWriter* post_processor = options()->postProcessor();
732 Directory output_directory = Directory(subDomain()->exportDirectory(),"amrtestpost1");
733 output_directory.createDirectory();
734 info() << "Creating output dir '" << output_directory.path() << "' for export";
735 UniqueArray<Real> times;
736 times.add(m_global_time());
737 post_processor->setTimes(times);
738 post_processor->setMesh(defaultMesh());
739 post_processor->setBaseDirectoryName(output_directory.path());
740
741 VariableList variables;
742 //variables.add(m_density.variable());
743 //variables.add(m_node_density.variable());
744 for( VariableCellReal* v : m_cell_patch_variables )
745 variables.add(v->variable());
746 post_processor->setVariables(variables);
747 ItemGroupList groups;
748 groups.add(allCells());
749 for( CartesianPatch p : m_cartesian_mesh->patches() )
750 groups.add(p.cells());
751 post_processor->setGroups(groups);
752 IVariableMng* vm = subDomain()->variableMng();
753 vm->writePostProcessing(post_processor);
754}
755
756/*---------------------------------------------------------------------------*/
757/*---------------------------------------------------------------------------*/
758
759void AMRCartesianMeshTesterModule::
760_testDirections()
761{
762 Integer nb_patch = m_cartesian_mesh->nbPatch();
763 Integer nb_dir = m_cartesian_mesh->mesh()->dimension();
765 for( Integer ipatch=0; ipatch<nb_patch; ++ipatch ){
766 ICartesianMeshPatch* p = m_cartesian_mesh->patch(ipatch);
767 for( Integer idir=0; idir<nb_dir; ++idir ){
768 NodeDirectionMng node_dm(p->nodeDirection(idir));
769 node_dm2 = p->nodeDirection(idir);
770 NodeGroup dm_all_nodes = node_dm.allNodes();
774 Node prev_node = dir_node.previous();
775 Node next_node = dir_node.next();
776 Node prev_node2 = dir_node2.previous();
777 Node next_node2 = dir_node2.next();
778 m_utils->checkSameId(prev_node,prev_node2);
779 m_utils->checkSameId(next_node,next_node2);
780 }
781 }
782 }
783}
784
785/*---------------------------------------------------------------------------*/
786/*---------------------------------------------------------------------------*/
787
788void AMRCartesianMeshTesterModule::
789_cellsInPatch(Real3 position, Real3 length, bool is_3d, Int32 level, UniqueArray<Int32>& cells_in_patch)
790{
791 // Parcours les mailles actives et ajoute dans la liste des mailles
792 // à raffiner celles qui sont contenues dans le boîte englobante
793 // spécifiée dans le jeu de données.
794 Real3 min_pos = position;
795 Real3 max_pos = min_pos + length;
796 ENUMERATE_ (Cell, icell, mesh()->allCells()) {
797 if ((icell->level() == level) || (level == -1 && icell->nbHChildren() == 0)) {
798 Real3 center = m_cell_center[icell];
799 bool is_inside_x = center.x > min_pos.x && center.x < max_pos.x;
800 bool is_inside_y = center.y > min_pos.y && center.y < max_pos.y;
801 bool is_inside_z = (center.z > min_pos.z && center.z < max_pos.z) || !is_3d;
803 cells_in_patch.add(icell.itemLocalId());
804 }
805 }
806 }
807}
808
809/*---------------------------------------------------------------------------*/
810/*---------------------------------------------------------------------------*/
811
812ARCANE_REGISTER_MODULE_AMRCARTESIANMESHTESTER(AMRCartesianMeshTesterModule);
813
814/*---------------------------------------------------------------------------*/
815/*---------------------------------------------------------------------------*/
816
817} // End namespace ArcaneTest
818
819/*---------------------------------------------------------------------------*/
820/*---------------------------------------------------------------------------*/
#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.
Fonctions utilitaires sur le maillage.
Ce fichier contient les différentes fabriques de services et macro pour enregistrer les services.
Module de test pour les infos sur les maillages cartésiens.
void _computeSubCellDensity(Cell cell)
Calcule la densité d'une maille AMR.
Patch AMR d'un maillage cartésien.
Infos sur les mailles d'une direction spécifique X,Y ou Z d'un maillage structuré.
Maille d'un maillage.
Definition Item.h:1178
Int32 nbHChildren() const
Nombre d'enfants pour l'AMR.
Definition Item.h:1293
Cell hChild(Int32 i) const
i-ème enfant AMR
Definition Item.h:1296
Maille avant et après une maille suivant une direction.
Noeud avant et après un noeud suivant une direction.
Classe gérant un répertoire.
Definition Directory.h:33
virtual String file(const String &file_name) const
Retourne le chemin complet du fichier file_name dans le répertoire.
Definition Directory.cc:138
Face d'une maille.
Definition Item.h:932
Interface d'un patch AMR d'un maillage cartésien.
Interface d'un maillage cartésien.
static ICartesianMesh * getReference(const MeshHandleOrMesh &mesh, bool create=true)
Récupère ou créé la référence associée à mesh.
virtual CellDirectionMng cellDirection(eMeshDirection dir)=0
Liste des mailles dans la direction dir.
virtual void recreateFromDump()=0
Recalcule les informations de cartésiennes après une reprise.
virtual void renumberItemsUniqueId(const CartesianMeshRenumberingInfo &v)=0
Renumérote les uniqueId() des entités.
virtual IMesh * mesh() const =0
Maillage associé à ce maillage cartésien.
virtual ICartesianMeshPatch * patch(Int32 index) const =0
Retourne le index-ième patch du maillage.
virtual void refinePatch2D(Real2 position, Real2 length)=0
Raffine en 2D un bloc du maillage cartésien.
virtual void refinePatch3D(Real3 position, Real3 length)=0
Raffine en 3D un bloc du maillage cartésien.
virtual CartesianMeshPatchListView patches() const =0
Vue sur la liste des patchs.
virtual CartesianPatch amrPatch(Int32 index) const =0
Retourne le index-ième patch du maillage.
virtual void coarseZone3D(Real3 position, Real3 length)=0
Dé-raffine en 3D un bloc du maillage cartésien.
virtual void coarseZone2D(Real2 position, Real2 length)=0
Dé-raffine en 2D un bloc du maillage cartésien.
virtual void computeDirections()=0
Calcule les infos pour les accès par direction.
virtual Int32 nbPatch() const =0
Nombre de patchs du maillage.
virtual Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers)=0
Méthode permettant de supprimer une ou plusieurs couches de mailles fantômes sur un niveau de raffine...
Interface d'une famille d'entités.
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual Integer dimension()=0
Dimension du maillage (1D, 2D ou 3D).
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
virtual NodeGroup allNodes()=0
Groupe de tous les noeuds.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
virtual VariableNodeReal3 & nodesCoordinates()=0
Coordonnées des noeuds.
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.
Interface d'un écrivain pour les informations de post-traitement.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
Interface du gestionnaire de la boucle en temps.
Interface d'une boucle en temps.
Definition ITimeLoop.h:41
static const char * WBuild
appelé lors de la lecture du jeu de données
Definition ITimeLoop.h:50
static const char * WComputeLoop
appelé pendant la boucle de calcul
Definition ITimeLoop.h:48
static const char * WInit
appelé pendant l'initialisation, l'initialisation d'une reprise ou d'un nouveau cas
Definition ITimeLoop.h:52
Interface du gestionnaire de variables.
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:35
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:765
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Definition Item.h:207
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Calcule la fonction de hashage MD5 d'un tableau.
Informations pour construire un module.
Infos sur les noeuds d'une direction spécifique X,Y ou Z d'un maillage structuré.
Noeud d'un maillage.
Definition Dom.h:204
Cell cell(Int32 i) const
i-ème maille du noeud
Definition Item.h:1568
Int32 nbCell() const
Nombre de mailles connectées au noeud.
Definition Item.h:643
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
Exportation d'un maillage au format SVG.
Infos d'un point d'entrée d'une boucle en temps.
Paramètres nécessaires à la construction d'une variable.
Collection de variables.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Chaîne de caractères unicode.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:227
Vecteur 1D de données avec sémantique par valeur (style STL).
MeshVariableScalarRefT< Cell, Real > VariableCellReal
Grandeur au centre des mailles de type réel.
ARCANE_CARTESIANMESH_EXPORT Ref< CartesianMeshCoarsening2 > createCartesianMeshCoarsening2(ICartesianMesh *cm)
Créé une instance pour gérer le déraffinement du maillage (V2).
ARCANE_CARTESIANMESH_EXPORT Ref< ICartesianMeshAMRPatchMng > cartesianMeshAMRPatchMng(ICartesianMesh *cm)
Créé une instance pour gérer le déraffinement du maillage (V3?).
void add(ArrayView< T > lhs, ConstArrayView< T > copy_array)
Ajoute le tableau copy_array dans l'instance.
Definition MathUtils.h:885
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
Real y
deuxième composante du triplet
Definition Real3.h:36
Real z
troisième composante du triplet
Definition Real3.h:37
Real x
première composante du triplet
Definition Real3.h:35