Arcane  v3.15.3.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-2025 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-2025 */
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#include "arcane/core/IGhostLayerMng.h"
43
44#include "arcane/cartesianmesh/ICartesianMesh.h"
45#include "arcane/cartesianmesh/CellDirectionMng.h"
46#include "arcane/cartesianmesh/FaceDirectionMng.h"
47#include "arcane/cartesianmesh/NodeDirectionMng.h"
48#include "arcane/cartesianmesh/CartesianConnectivity.h"
49#include "arcane/cartesianmesh/CartesianMeshRenumberingInfo.h"
50#include "arcane/cartesianmesh/ICartesianMeshPatch.h"
51#include "arcane/cartesianmesh/CartesianMeshUtils.h"
52#include "arcane/cartesianmesh/CartesianMeshCoarsening2.h"
53#include "arcane/cartesianmesh/CartesianMeshPatchListView.h"
54
55#include "arcane/tests/ArcaneTestGlobal.h"
56#include "arcane/tests/AMRCartesianMeshTester_axl.h"
57#include "arcane/tests/CartesianMeshTestUtils.h"
58
59/*---------------------------------------------------------------------------*/
60/*---------------------------------------------------------------------------*/
61
62namespace ArcaneTest
63{
64
65using namespace Arcane;
66
67/*---------------------------------------------------------------------------*/
68/*---------------------------------------------------------------------------*/
73: public ArcaneAMRCartesianMeshTesterObject
74{
75 public:
76
79
80 public:
81
82 static void staticInitialize(ISubDomain* sd);
83
84 public:
85
86 void buildInit() override;
87 void compute() override;
88 void init() override;
89
90 private:
91
92 VariableCellReal m_density;
93 VariableCellReal m_old_density;
94 VariableCellReal3 m_cell_center;
95 VariableFaceReal3 m_face_center;
96 VariableNodeReal m_node_density;
97 ICartesianMesh* m_cartesian_mesh;
99 UniqueArray<VariableCellReal*> m_cell_patch_variables;
100 Int32 m_nb_expected_patch = 0;
101
102 private:
103
104 void _compute1();
105 void _compute2();
106 void _initAMR();
107 void _coarseZone();
108 void _reduceNbGhostLayers();
109 void _computeSubCellDensity(Cell cell);
110 void _computeCenters();
111 void _processPatches();
112 void _writePostProcessing();
113 void _checkUniqueIds();
114 void _testDirections();
115 void _checkDirections();
120 void _checkSync();
121 void _cellsInPatch(Real3 position, Real3 length, bool is_3d, Int32 level, UniqueArray<Int32>& cells_in_patch);
122};
123
124/*---------------------------------------------------------------------------*/
125/*---------------------------------------------------------------------------*/
126
127AMRCartesianMeshTesterModule::
128AMRCartesianMeshTesterModule(const ModuleBuildInfo& mbi)
129: ArcaneAMRCartesianMeshTesterObject(mbi)
130, m_density(VariableBuildInfo(this,"Density"))
131, m_old_density(VariableBuildInfo(this,"OldDensity"))
132, m_cell_center(VariableBuildInfo(this,"CellCenter"))
133, m_face_center(VariableBuildInfo(this,"FaceCenter"))
134, m_node_density(VariableBuildInfo(this,"NodeDensity"))
135, m_cartesian_mesh(nullptr)
136{
137}
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
142AMRCartesianMeshTesterModule::
143~AMRCartesianMeshTesterModule()
144{
145 for (VariableCellReal* v : m_cell_patch_variables)
146 delete v;
147}
148
149/*---------------------------------------------------------------------------*/
150/*---------------------------------------------------------------------------*/
151
152void AMRCartesianMeshTesterModule::
153staticInitialize(ISubDomain* sd)
154{
155 String time_loop_name("AMRCartesianMeshTestLoop");
156
157 ITimeLoopMng* tlm = sd->timeLoopMng();
158 ITimeLoop* time_loop = tlm->createTimeLoop(time_loop_name);
159
160 {
162 clist.add(TimeLoopEntryPointInfo("AMRCartesianMeshTester.buildInit"));
163 time_loop->setEntryPoints(ITimeLoop::WBuild,clist);
164 }
165
166 {
168 clist.add(TimeLoopEntryPointInfo("AMRCartesianMeshTester.init"));
169 time_loop->setEntryPoints(ITimeLoop::WInit,clist);
170 }
171
172 {
174 clist.add(TimeLoopEntryPointInfo("AMRCartesianMeshTester.compute"));
175 time_loop->setEntryPoints(ITimeLoop::WComputeLoop,clist);
176 }
177
178 {
180 clist.add("AMRCartesianMeshTester");
181 time_loop->setRequiredModulesName(clist);
182 clist.clear();
183 clist.add("ArcanePostProcessing");
184 clist.add("ArcaneCheckpoint");
185 clist.add("ArcaneLoadBalance");
186 time_loop->setOptionalModulesName(clist);
187 }
188
189 tlm->registerTimeLoop(time_loop);
190}
191
192/*---------------------------------------------------------------------------*/
193/*---------------------------------------------------------------------------*/
194
195void AMRCartesianMeshTesterModule::
196buildInit()
197{
198 if (subDomain()->isContinue())
199 return;
200
201 m_global_deltat.assign(1.0);
202
203 IItemFamily* cell_family = defaultMesh()->cellFamily();
204 cell_family->createGroup("CELL0");
205 cell_family->createGroup("CELL1");
206 cell_family->createGroup("CELL2");
207 cell_family->createGroup("AMRPatchCells0");
208 cell_family->createGroup("AMRPatchCells1");
209 cell_family->createGroup("AMRPatchCells2");
210 cell_family->createGroup("AMRPatchCells3");
211 cell_family->createGroup("AMRPatchCells4");
212 cell_family->createGroup("AMRPatchCells5");
213
214 IItemFamily* face_family = defaultMesh()->faceFamily();
215 face_family->createGroup("FACE0");
216 face_family->createGroup("FACE1");
217 face_family->createGroup("FACE2");
218 face_family->createGroup("FACE3");
219 face_family->createGroup("FACE4");
220 face_family->createGroup("FACE5");
221
222 face_family->createGroup("AllFacesDirection0");
223 face_family->createGroup("AllFacesDirection1");
224}
225
226/*---------------------------------------------------------------------------*/
227/*---------------------------------------------------------------------------*/
228
229void AMRCartesianMeshTesterModule::
230init()
231{
232 info() << "AMR Init";
233
234 IMesh* mesh = defaultMesh();
235
237 Int32UniqueArray ids(1);
238 ids[0] = 0;
239 cell_family->createGroup("CELL0",ids,true);
240 ids[0] = 1;
241 cell_family->createGroup("CELL1",ids,true);
242 ids[0] = 2;
243 cell_family->createGroup("CELL2",ids,true);
244 IItemFamily* face_family = defaultMesh()->faceFamily();
245 ids[0] = 0;
246 face_family->createGroup("FACE0",ids,true);
247 ids[0] = 1;
248 face_family->createGroup("FACE1",ids,true);
249 ids[0] = 2;
250 face_family->createGroup("FACE2",ids,true);
251 ids[0] = 3;
252 face_family->createGroup("FACE3",ids,true);
253 ids[0] = 4;
254 face_family->createGroup("FACE4",ids,true);
255 ids[0] = 5;
256 face_family->createGroup("FACE5",ids,true);
257
258 m_cartesian_mesh = ICartesianMesh::getReference(mesh);
259 m_utils = makeRef(new CartesianMeshTestUtils(m_cartesian_mesh,acceleratorMng()));
260
261 if (!subDomain()->isContinue()) {
262 _initAMR();
263 _coarseZone();
264 _reduceNbGhostLayers();
265 }
266
267 _computeCenters();
268
269
270 const bool do_coarse_at_init = options()->coarseAtInit();
271
272 const Integer dimension = defaultMesh()->dimension();
273 if (dimension==2)
274 m_nb_expected_patch = 1 + options()->refinement2d().size();
275 else if (dimension==3)
276 m_nb_expected_patch = 1 + options()->refinement3d().size();
277
278 // Si on dé-raffine à l'init, on aura un patch de plus
280 ++m_nb_expected_patch;
281
282 if (subDomain()->isContinue())
283 m_cartesian_mesh->recreateFromDump();
284 else{
285 m_cartesian_mesh->computeDirections();
287 renumbering_info.setRenumberPatchMethod(options()->renumberPatchMethod());
288 renumbering_info.setSortAfterRenumbering(true);
289 if (options()->coarseAtInit())
290 renumbering_info.setParentPatch(m_cartesian_mesh->amrPatch(1));
291 m_cartesian_mesh->renumberItemsUniqueId(renumbering_info);
292 _checkUniqueIds();
293 _processPatches();
294 info() << "MaxUid for mesh=" << MeshUtils::getMaxItemUniqueIdCollective(m_cartesian_mesh->mesh());
295 }
296
297 // Initialise la densité.
298 // On met une densité de 1.0 à l'intérieur
299 // et on ajoute une densité de 5.0 pour chaque direction dans les
300 // mailles de bord.
301 m_density.fill(1.0);
302 for( Integer idir=0, nb_dir=dimension; idir<nb_dir; ++idir){
303 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(idir));
306 ENUMERATE_CELL(icell,cdm.innerCells()){
307 DirCell cc(cdm.cell(*icell));
308 Cell next = cc.next();
309 Cell prev = cc.previous();
310 if (next.null() || prev.null()){
311 // Maille au bord. J'ajoute de la densité.
312 // Ne devrait pas arriver car on est sur les innerCells()
313 ++nb_boundary1;
314 m_density[icell] += 5.0;
315 }
316 }
317 // Parcours les mailles frontières pour la direction
318 ENUMERATE_CELL(icell,cdm.outerCells()){
320 if (icell.index()<5)
321 info() << "CELL: cell=" << ItemPrinter(*icell)
322 << " next=" << ItemPrinter(cc.next())
323 << " previous=" << ItemPrinter(cc.previous());
324 // Maille au bord. J'ajoute de la densité.
325 ++nb_boundary2;
326 m_density[icell] += 5.0;
327 }
328
329 info() << "NB_BOUNDARY1=" << nb_boundary1 << " NB_BOUNDARY2=" << nb_boundary2;
330 }
331 bool is_amr = m_nb_expected_patch!=1;
332 if (options()->verbosityLevel()==0)
333 m_utils->setNbPrint(5);
334 m_utils->testAll(is_amr);
335 _writePostProcessing();
336 _testDirections();
337 _checkDirections();
338 _checkSync();
339}
340
341/*---------------------------------------------------------------------------*/
342/*---------------------------------------------------------------------------*/
343
344void AMRCartesianMeshTesterModule::
345_checkUniqueIds()
346{
347 IMesh* mesh = m_cartesian_mesh->mesh();
348 bool print_hash = true;
349 bool with_ghost = options()->hashWithGhost();
351 MeshUtils::checkUniqueIdsHashCollective(mesh->nodeFamily(), &hash_algo, options()->nodesUidHash(),
353 MeshUtils::checkUniqueIdsHashCollective(mesh->faceFamily(), &hash_algo, options()->facesUidHash(),
355 MeshUtils::checkUniqueIdsHashCollective(mesh->cellFamily(), &hash_algo, options()->cellsUidHash(),
357}
358
359/*---------------------------------------------------------------------------*/
360/*---------------------------------------------------------------------------*/
361
362void AMRCartesianMeshTesterModule::
363_processPatches()
364{
365 const bool do_check = true;
366 const bool is_verbose = options()->verbosityLevel()>=1;
367
368 const Int32 dimension = defaultMesh()->dimension();
369
370 bool without_coarse_zone = true;
371 if (dimension == 2)
372 without_coarse_zone = options()->coarseZone2d().empty();
373 else if (dimension == 3)
374 without_coarse_zone = options()->coarseZone3d().empty();
375
376 // Vérifie qu'il y a autant de patchs que d'options raffinement dans
377 // le jeu de données (en comptant le patch 0 qui est le maillage cartésien).
378 // Cela permet de vérifier que les appels successifs
379 // à computeDirections() n'ajoutent pas de patchs.
380 // Cette vérification ne s'applique que s'il n'y a pas de zone de dé-raffinement.
381 // En effet, dé-raffiner un patch complet le supprime de la liste des patchs.
382 Integer nb_expected_patch = m_nb_expected_patch;
383
384 Integer nb_patch = m_cartesian_mesh->nbPatch();
386 ARCANE_FATAL("Bad number of patchs expected={0} value={1}",nb_expected_patch,nb_patch);
387
388 IParallelMng* pm = parallelMng();
389 Int32 comm_rank = pm->commRank();
390 Int32 comm_size = pm->commSize();
391
393 if (nb_cells_expected.size()!=nb_patch)
394 ARCANE_FATAL("Bad size ({0}, expected={1}) for option '{2}'",
396
397 // Nombre de mailles fantômes attendu. Utilisé uniquement en parallèle
398 bool has_expected_ghost_cells = options()->expectedNumberOfGhostCellsInPatchs.isPresent();
399 if (!pm->isParallel())
401
404 ARCANE_FATAL("Bad size ({0}, expected={1}) for option '{2}'",
406 // Affiche les informations sur les patchs
407 for( Integer i=0; i<nb_patch; ++i ){
408 ICartesianMeshPatch* p = m_cartesian_mesh->patch(i);
409 CellGroup patch_cells(p->cells());
410 info() << "Patch cell_group=" << patch_cells.name() << " nb_cell=" << patch_cells.size();
411 VariableCellReal* cellv = new VariableCellReal(VariableBuildInfo(defaultMesh(),String("CellPatch")+i));
412 m_cell_patch_variables.add(cellv);
413 cellv->fill(0.0);
415 (*cellv)[icell] = 2.0;
416 }
417
421 Cell cell{*icell};
422 if (is_verbose)
423 info() << "Patch i=" << i << " cell=" << ItemPrinter(*icell);
424 own_cells_uid.add(cell.uniqueId());
425 }
426 // Affiche la liste globales des uniqueId() des mailles.
427 {
430 std::sort(global_cells_uid.begin(),global_cells_uid.end());
432 info() << "GlobalUids Patch=" << i << " NB=" << nb_global_uid
433 << " expected=" << nb_cells_expected[i];
434 // Vérifie que le nombre de mailles par patch est le bon.
436 ARCANE_FATAL("Bad number of cells for patch I={0} N={1} expected={2}",
438 if (is_verbose)
439 for( Integer c=0; c<nb_global_uid; ++c )
440 info() << "GlobalUid Patch=" << i << " I=" << c << " cell_uid=" << global_cells_uid[c];
441 }
442 // Teste le nombre de mailles fantômes
444 Int32 local_nb_ghost_cell = patch_cells.size() - patch_own_cell.size();
445 Int32 total = pm->reduce(Parallel::ReduceSum,local_nb_ghost_cell);
446 pinfo() << "NbGhostCells my_rank=" << comm_rank << " local=" << local_nb_ghost_cell << " total=" << total;
447 if (total!=nb_ghost_cells_expected[i])
448 ARCANE_FATAL("Bad number of ghost cells for patch I={0} N={1} expected={2}",
449 i,total,nb_ghost_cells_expected[i]);
450 }
451
452 // Exporte le patch au format SVG
453 if (dimension==2 && options()->dumpSvg()){
454 String filename = String::format("Patch{0}-{1}-{2}.svg",i,comm_rank,comm_size);
455 Directory directory = subDomain()->exportDirectory();
456 String full_filename = directory.file(filename);
457 std::ofstream ofile(full_filename.localstr());
459 exporter.write(patch_cells);
460 }
461 }
462}
463
464/*---------------------------------------------------------------------------*/
465/*---------------------------------------------------------------------------*/
466
467void AMRCartesianMeshTesterModule::
468_computeCenters()
469{
470 IMesh* mesh = defaultMesh();
471
472 // Calcule le centre des mailles
473 {
475 ENUMERATE_CELL(icell,allCells()){
476 Cell cell = *icell;
477 Real3 center;
478 for( NodeLocalId inode : cell.nodes() )
479 center += nodes_coord[inode];
480 center /= cell.nbNode();
481 m_cell_center[icell] = center;
482 }
483 }
484
485 // Calcule le centre des faces
486 {
488 ENUMERATE_FACE(iface,allFaces()){
489 Face face = *iface;
490 Real3 center;
491 for( NodeLocalId inode : face.nodes() )
492 center += nodes_coord[inode];
493 center /= face.nbNode();
494 m_face_center[iface] = center;
495 }
496 }
497}
498
499/*---------------------------------------------------------------------------*/
500/*---------------------------------------------------------------------------*/
501
502void AMRCartesianMeshTesterModule::
503_initAMR()
504{
505 // Regarde si on dé-raffine le maillage initial
506 if (options()->coarseAtInit()){
507 // Il faut que les directions aient été calculées avant d'appeler le dé-raffinement
508 m_cartesian_mesh->computeDirections();
509
510 info() << "Doint initial coarsening";
511
512 if (m_cartesian_mesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
513 debug() << "Coarse with specific coarser (for cartesian mesh only)";
515 coarser->coarse();
516 }
517 else {
519 coarser->createCoarseCells();
520 }
521
522 CartesianMeshPatchListView patches = m_cartesian_mesh->patches();
523 Int32 nb_patch = patches.size();
524 {
525 Int32 index = 0;
526 info() << "NB_PATCH=" << nb_patch;
527 for( CartesianPatch p : patches){
528 info() << "Patch i=" << index << " nb_cell=" << p.cells().size();
529 ++index;
530 }
531 }
532 }
533 // Parcours les mailles actives et ajoute dans la liste des mailles
534 // à raffiner celles qui sont contenues dans le boîte englobante
535 // spécifiée dans le jeu de données.
536 Int32 dim = defaultMesh()->dimension();
537 if (dim==2){
538 for( auto& x : options()->refinement2d() ){
539 m_cartesian_mesh->refinePatch2D(x->position(),x->length());
540 m_cartesian_mesh->computeDirections();
541 }
542 }
543 if (dim==3){
544 for( auto& x : options()->refinement3d() ){
545 m_cartesian_mesh->refinePatch3D(x->position(),x->length());
546 m_cartesian_mesh->computeDirections();
547 }
548 }
549}
550
551/*---------------------------------------------------------------------------*/
552/*---------------------------------------------------------------------------*/
553
554void AMRCartesianMeshTesterModule::
555_coarseZone()
556{
557 Int32 dim = defaultMesh()->dimension();
558
559 if (dim == 2) {
560 //UniqueArray<Int32> cells_in_patchs;
561 for (auto& x : options()->coarseZone2d()) {
562 // _cellsInPatch(Real3(x->position()), Real3(x->length()), false, x->level(), cells_in_patchs);
563 // defaultMesh()->modifier()->flagCellToCoarsen(cells_in_patchs);
564 // defaultMesh()->modifier()->coarsenItemsV2(true);
565 // cells_in_patchs.clear();
566 m_cartesian_mesh->coarseZone2D(x->position(), x->length());
567 m_cartesian_mesh->computeDirections();
568 }
569 }
570 if (dim == 3) {
571 // UniqueArray<Int32> cells_in_patchs;
572 for (auto& x : options()->coarseZone3d()) {
573 // _cellsInPatch(x->position(), x->length(), true, x->level(), cells_in_patchs);
574 // defaultMesh()->modifier()->flagCellToCoarsen(cells_in_patchs);
575 // defaultMesh()->modifier()->coarsenItemsV2(true);
576 // cells_in_patchs.clear();
577 m_cartesian_mesh->coarseZone3D(x->position(), x->length());
578 m_cartesian_mesh->computeDirections();
579 }
580 }
581}
582
583/*---------------------------------------------------------------------------*/
584/*---------------------------------------------------------------------------*/
585
586void AMRCartesianMeshTesterModule::
587_reduceNbGhostLayers()
588{
589 for (auto& x : options()->reduceNbGhostLayers()) {
590 Integer final_nb_ghost_layer{ m_cartesian_mesh->reduceNbGhostLayers(x->level(), x->nbGhostLayers()) };
591
592 if (parallelMng()->commSize() != 1 && final_nb_ghost_layer != x->nbGhostLayers()) {
593 ARCANE_FATAL("Bad nb ghost layers");
594 }
595 //info() << "Final nb ghost layer : " << final_nb_ghost_layer;
596 }
597}
598
599/*---------------------------------------------------------------------------*/
600/*---------------------------------------------------------------------------*/
601
602void AMRCartesianMeshTesterModule::
603compute()
604{
605 _compute1();
606}
607
608/*---------------------------------------------------------------------------*/
609/*---------------------------------------------------------------------------*/
615{
616 Int32 nb_children = cell.nbHChildren();
617 if (nb_children==0)
618 return;
619 // Pour les mailles AMR, la densité est la moyenne des noeuds qui la compose.
620 for( Int32 j=0; j<nb_children; ++j ) {
621 Real sub_density = 0.0;
622 Cell sub_cell = cell.hChild(j);
623 Integer sub_cell_nb_node = sub_cell.nbNode();
624 for( Integer k=0; k<sub_cell_nb_node; ++k )
625 sub_density += m_node_density[sub_cell.node(k)];
627 m_density[sub_cell] =sub_density;
629 }
630}
631
632/*---------------------------------------------------------------------------*/
633/*---------------------------------------------------------------------------*/
634
635void AMRCartesianMeshTesterModule::
636_compute1()
637{
638 // Pour test, on parcours les N directions
639 // et pour chaque maille, on modifie sa densité
640 // par la formule new_density = (density+density_next+density_prev) / 3.0.
641
642 // Effectue l'operation en deux fois. Une premiere sur les
643 // mailles internes, et une deuxieme sur les mailles externes.
644 // Du coup, il faut passer par une variable intermediaire (m_old_density)
645 // mais on evite un test dans la boucle principale
646 IMesh* mesh = defaultMesh();
647 Integer nb_dir = mesh->dimension();
648 for( Integer idir=0; idir<nb_dir; ++idir){
649 m_old_density.copy(m_density);
650 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(idir));
651 // Travail sur les mailles internes
652 info() << "Direction=" << idir << " cells=" << cdm.innerCells().name()
653 << " n=" << cdm.innerCells().size();
654 ENUMERATE_CELL(icell,cdm.innerCells()){
655 Cell cell = *icell;
656 DirCell cc(cdm.cell(cell));
657 Cell next = cc.next();
658 Cell prev = cc.previous();
659 Real d = m_old_density[icell] + m_old_density[next] + m_old_density[prev];
660 m_density[icell] = d / 3.0;
662 }
663 // Travail sur les mailles externes
664 // Test si la maille avant ou apres est nulle.
665 ENUMERATE_CELL(icell,cdm.outerCells()){
666 Cell cell = *icell;
668 Cell next = cc.next();
669 Cell prev = cc.previous();
670 Real d = m_old_density[icell];
671 Integer n = 1;
672 if (!next.null()){
673 d += m_old_density[next];
674 ++n;
675 }
676 if (!prev.null()){
677 d += m_old_density[prev];
678 ++n;
679 }
680 m_density[icell] = d / n;
682 }
683 }
684 // Modifie la densité aux noeuds.
685 // Elle sera égale à la moyenne des densités des mailles entourant ce noeud
687 Node node = *inode;
688 Integer nb_cell = node.nbCell();
689 Real density = 0.0;
690 for( Integer i=0; i<nb_cell; ++i )
691 density += m_density[node.cell(i)];
692 density /= (Real)nb_cell;
693 m_node_density[inode] = density;
694 }
695}
696
697/*---------------------------------------------------------------------------*/
698/*---------------------------------------------------------------------------*/
699
700void AMRCartesianMeshTesterModule::
701_compute2()
702{
703 // Pour test, on parcours les N directions
704 // et pour chaque maille, on modifie sa densité
705 // par la formule new_density = (density+density_next+density_prev) / 3.0.
706
707 // A noter que cette methode ne donne pas le meme comportement que
708 // _compute1() car les mailles de bord et internes sont mises à jour
709 // dans un ordre différent.
710 Integer nb_dir = defaultMesh()->dimension();
711 for( Integer idir=0; idir<nb_dir; ++idir){
712 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(idir));
713 // Travail sur toutes les mailles
714 ENUMERATE_CELL(icell,cdm.allCells()){
716 Cell next = cc.next();
717 Cell prev = cc.previous();
718 Real d = m_density[icell];
719 Integer n = 1;
720 if (!next.null()){
721 d += m_density[next];
722 ++n;
723 }
724 if (!prev.null()){
725 d += m_density[prev];
726 ++n;
727 }
728 m_density[icell] = d / n;
729 }
730 }
731}
732
733/*---------------------------------------------------------------------------*/
734/*---------------------------------------------------------------------------*/
735
736void AMRCartesianMeshTesterModule::
737_writePostProcessing()
738{
739 info() << "Post-process AMR";
740 IPostProcessorWriter* post_processor = options()->postProcessor();
741 Directory output_directory = Directory(subDomain()->exportDirectory(),"amrtestpost1");
742 output_directory.createDirectory();
743 info() << "Creating output dir '" << output_directory.path() << "' for export";
744 UniqueArray<Real> times;
745 times.add(m_global_time());
746 post_processor->setTimes(times);
747 post_processor->setMesh(defaultMesh());
748 post_processor->setBaseDirectoryName(output_directory.path());
749
750 VariableList variables;
751 //variables.add(m_density.variable());
752 //variables.add(m_node_density.variable());
753 for( VariableCellReal* v : m_cell_patch_variables )
754 variables.add(v->variable());
755 post_processor->setVariables(variables);
756 ItemGroupList groups;
757 groups.add(allCells());
758 for( CartesianPatch p : m_cartesian_mesh->patches() )
759 groups.add(p.cells());
760 post_processor->setGroups(groups);
761 IVariableMng* vm = subDomain()->variableMng();
762 vm->writePostProcessing(post_processor);
763}
764
765/*---------------------------------------------------------------------------*/
766/*---------------------------------------------------------------------------*/
767
768void AMRCartesianMeshTesterModule::
769_testDirections()
770{
771 Integer nb_patch = m_cartesian_mesh->nbPatch();
772 Integer nb_dir = m_cartesian_mesh->mesh()->dimension();
774 for( Integer ipatch=0; ipatch<nb_patch; ++ipatch ){
775 ICartesianMeshPatch* p = m_cartesian_mesh->patch(ipatch);
776 for( Integer idir=0; idir<nb_dir; ++idir ){
777 NodeDirectionMng node_dm(p->nodeDirection(idir));
778 node_dm2 = p->nodeDirection(idir);
779 NodeGroup dm_all_nodes = node_dm.allNodes();
783 Node prev_node = dir_node.previous();
784 Node next_node = dir_node.next();
785 Node prev_node2 = dir_node2.previous();
786 Node next_node2 = dir_node2.next();
787 m_utils->checkSameId(prev_node, prev_node2);
788 m_utils->checkSameId(next_node, next_node2);
789 }
790 }
791 }
792}
793
794void AMRCartesianMeshTesterModule::
795_checkDirections()
796{
797 m_cartesian_mesh->computeDirections();
798 IMesh* mesh = m_cartesian_mesh->mesh();
799 bool print_hash = true;
800
803
804 if (print_hash) {
805 info() << "HASH_RESULT direction items of family=" << item_family->name()
806 << " v= " << cell_hash << " expected= " << expected_hash;
807 }
808
809 if (!expected_hash.empty() && cell_hash != expected_hash)
810 ARCANE_FATAL("Bad hash for uniqueId() for direction items of family '{0}' v= {1} expected='{2}'",
811 item_family->fullName(), cell_hash, expected_hash);
812 };
813
814 {
815 debug() << "Check cells direction hash";
819 }
820 {
821 debug() << "Check faces direction hash";
825 }
826 {
827 debug() << "Check nodes direction hash";
831 }
832}
833
846{
847 // +1 car on a le uid dedans.
849
851 {
853 parallelMng()->allGatherVariable(own_items_uid_around, global_items_uid_around);
854
856 {
857 Int64 index = 0;
858 for (Int64 i = 0; i < global_items_uid_around.size(); i += size_of_once_case_around) {
859 Int64 uid = global_items_uid_around[i];
860 ARCANE_ASSERT((uid != -1), ("Un uid dans le tableau est = -1"));
862 }
863 }
864
865 std::sort(global_items_uid.begin(), global_items_uid.end(),
866 [](const Int64* a, const Int64* b) {
867 return *a < *b;
868 });
869
871
872 Int64 index = 0;
873 Int64 previous_uid = -1;
874
875 for (Int64* ptr_uid : global_items_uid) {
876 if (*ptr_uid == previous_uid) {
877 ARCANE_FATAL("Le uid {0} est dupliqué", *ptr_uid);
878 }
880 for (Integer iaround = 0; iaround < size_of_once_case_around; ++iaround) {
882 }
883 }
884 }
885
886 // info() << "final_all_items_uid : " << final_all_items_uid;
887
890 hash_algo.computeHash64(asBytes(final_all_items_uid.constSpan()), hash_result);
892}
893
905{
906 IParallelMng* pm = parallelMng();
907 IMesh* mesh = m_cartesian_mesh->mesh();
908
909 if (pm->commSize() != 1 && mesh->ghostLayerMng()->nbGhostLayer() == 0) {
910 ARCANE_FATAL("Pas compatible sans ghost");
911 }
912
913 Integer nb_patch = m_cartesian_mesh->nbPatch();
914 Integer nb_dir = mesh->dimension();
915 Integer nb_items = mesh->cellFamily()->allItems().own().size();
916
917 // On a que pred et succ.
918 constexpr Integer nb_items_per_dir = 2;
919 constexpr Integer ipred = 0;
920 constexpr Integer isucc = 1;
921
922 // +1 car on a le uid dedans.
924
926
927 Integer index = 0;
928 ENUMERATE_ (Cell, icell, mesh->cellFamily()->allItems().own()) {
929 own_cells_uid_around_cells[index] = icell->uniqueId();
931 }
932
933 auto set_value = [&](Integer dir, Int64 uid, Int64 uid_pred, Int64 uid_succ) -> void {
934 // debug() << " -- dir : " << dir
935 // << " -- uid : " << uid
936 // << " -- uid_pred : " << uid_pred
937 // << " -- uid_succ : " << uid_succ;
938
939 ARCANE_ASSERT((uid != -1), ("Uid ne peut pas être égal à -1"));
940
941 for (Integer i = 0; i < own_cells_uid_around_cells.size(); i += size_of_once_case_around) {
942 if (own_cells_uid_around_cells[i] == uid) {
943 Integer pos_final = i + 1 + (dir * nb_items_per_dir);
944 Integer pos_pred = pos_final + ipred;
945 Integer pos_succ = pos_final + isucc;
947 ARCANE_FATAL("Problème de cohérence entre les patchs (uid={0} -- old_uid_pred={1} -- new_uid_pred={2})", uid, own_cells_uid_around_cells[pos_pred], uid_pred);
948 }
950 ARCANE_FATAL("Problème de cohérence entre les patchs (uid={0} -- old_uid_succ={1} -- new_uid_succ={2})", uid, own_cells_uid_around_cells[pos_succ], uid_succ);
951 }
954 return;
955 }
956 }
957 };
958
959 for (Integer idir = 0; idir < nb_dir; ++idir) {
960 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(idir));
961 ENUMERATE_ (Cell, icell, cdm.allCells().own()) {
962 DirCell cc(cdm.cell(*icell));
963 Cell next = cc.next();
964 Cell prev = cc.previous();
965 set_value(idir, icell->uniqueId(), prev.uniqueId(), next.uniqueId());
966 }
967 }
968
969 for (Integer ipatch = 0; ipatch < nb_patch; ++ipatch) {
970 ICartesianMeshPatch* p = m_cartesian_mesh->patch(ipatch);
971 for (Integer idir = 0; idir < nb_dir; ++idir) {
972 CellDirectionMng cdm(p->cellDirection(idir));
973 ENUMERATE_ (Cell, icell, cdm.allCells().own()) {
974 DirCell cc(cdm.cell(*icell));
975 Cell next = cc.next();
976 Cell prev = cc.previous();
977 set_value(idir, icell->uniqueId(), prev.uniqueId(), next.uniqueId());
978 }
979 }
980 }
981
983}
984
996{
997 IParallelMng* pm = parallelMng();
998 IMesh* mesh = m_cartesian_mesh->mesh();
999
1000 if (pm->commSize() != 1 && mesh->ghostLayerMng()->nbGhostLayer() == 0) {
1001 ARCANE_FATAL("Pas compatible sans ghost");
1002 }
1003
1004 Integer nb_patch = m_cartesian_mesh->nbPatch();
1005 Integer nb_dir = mesh->dimension();
1006 Integer nb_items = mesh->faceFamily()->allItems().own().size();
1007
1008 // On a que pred et succ.
1009 constexpr Integer nb_items_per_dir = 2;
1010 constexpr Integer ipred = 0;
1011 constexpr Integer isucc = 1;
1012
1013 // +1 car on a le uid dedans.
1015
1017
1018 Integer index = 0;
1019 ENUMERATE_ (Item, iitem, mesh->faceFamily()->allItems().own()) {
1020 own_cells_uid_around_faces[index] = iitem->uniqueId();
1021 index += size_of_once_case_around;
1022 }
1023
1024 auto set_value = [&](Integer ipatch, Int64 uid, Int64 uid_pred, Int64 uid_succ) -> void {
1025 // debug() << " -- uid : " << uid
1026 // << " -- uid_pred : " << uid_pred
1027 // << " -- uid_succ : " << uid_succ;
1028
1029 ARCANE_ASSERT((uid != -1), ("Uid ne peut pas être égal à -1"));
1030
1031 for (Integer i = 0; i < own_cells_uid_around_faces.size(); i += size_of_once_case_around) {
1032 if (own_cells_uid_around_faces[i] == uid) {
1033 Integer pos_final = i + 1 + ipatch * nb_items_per_dir;
1034 Integer pos_pred = pos_final + ipred;
1035 Integer pos_succ = pos_final + isucc;
1037 ARCANE_FATAL("Problème de cohérence entre les patchs (uid={0} -- old_uid_pred={1} -- new_uid_pred={2})", uid, own_cells_uid_around_faces[pos_pred], uid_pred);
1038 }
1040 ARCANE_FATAL("Problème de cohérence entre les patchs (uid={0} -- old_uid_succ={1} -- new_uid_succ={2})", uid, own_cells_uid_around_faces[pos_succ], uid_succ);
1041 }
1044 return;
1045 }
1046 }
1047 };
1048
1049 // // TODO : Il faut pouvoir récupérer le patch correspondant.
1050 // for (Integer idir = 0; idir < nb_dir; ++idir) {
1051 // FaceDirectionMng fdm(m_cartesian_mesh->faceDirection(idir));
1052 // ENUMERATE_ (Face, iface, fdm.allFaces().own()) {
1053 // DirFace cc(fdm.face(*iface));
1054 // Cell next = cc.nextCell();
1055 // Cell prev = cc.previousCell();
1056 // set_value(iface->uniqueId(), prev.uniqueId(), next.uniqueId());
1057 // }
1058 // }
1059
1060 for (Integer ipatch = 0; ipatch < nb_patch; ++ipatch) {
1061 ICartesianMeshPatch* p = m_cartesian_mesh->patch(ipatch);
1062 for (Integer idir = 0; idir < nb_dir; ++idir) {
1063 FaceDirectionMng fdm(p->faceDirection(idir));
1064 ENUMERATE_ (Face, iface, fdm.allFaces().own()) {
1065 DirFace cc(fdm.face(*iface));
1066 Cell next = cc.nextCell();
1067 Cell prev = cc.previousCell();
1068 set_value(ipatch, iface->uniqueId(), prev.uniqueId(), next.uniqueId());
1069 }
1070 }
1071 }
1072
1073 return size_of_once_case_around-1;
1074}
1075
1092{
1093 IParallelMng* pm = parallelMng();
1094 IMesh* mesh = m_cartesian_mesh->mesh();
1095
1096 if (pm->commSize() != 1 && mesh->ghostLayerMng()->nbGhostLayer() == 0) {
1097 ARCANE_FATAL("Pas compatible sans ghost");
1098 }
1099
1100 Integer nb_patch = m_cartesian_mesh->nbPatch();
1101 Integer nb_dir = mesh->dimension();
1102 Integer nb_items = mesh->nodeFamily()->allItems().own().size();
1103
1104 // On a que pred et succ.
1105 constexpr Integer nb_items_per_dir = 2;
1106 constexpr Integer ipred = 0;
1107 constexpr Integer isucc = 1;
1108
1109 // +1 car on a le uid dedans.
1111
1113
1114 Integer index = 0;
1115 ENUMERATE_ (Item, iitem, mesh->nodeFamily()->allItems().own()) {
1116 own_nodes_uid_around_nodes[index] = iitem->uniqueId();
1117 index += size_of_once_case_around;
1118 }
1119
1120 auto set_value = [&](Integer dir, Integer ipatch, Int64 uid, Int64 uid_pred, Int64 uid_succ) {
1121 // debug() << " -- dir : " << dir
1122 // << " -- ipatch : " << ipatch
1123 // << " -- uid : " << uid
1124 // << " -- uid_pred : " << uid_pred
1125 // << " -- uid_succ : " << uid_succ;
1126
1127 ARCANE_ASSERT((uid != -1), ("Uid ne peut pas être égal à -1"));
1128
1129 for (Integer i = 0; i < own_nodes_uid_around_nodes.size(); i += size_of_once_case_around) {
1130 if (own_nodes_uid_around_nodes[i] == uid) {
1131 Integer pos_final = i + 1 + ipatch * (nb_items_per_dir * nb_dir) + dir * nb_items_per_dir;
1132 Integer pos_pred = pos_final + ipred;
1133 Integer pos_succ = pos_final + isucc;
1135 ARCANE_FATAL("Problème de cohérence entre les patchs (uid={0} -- old_uid_pred={1} -- new_uid_pred={2})", uid, own_nodes_uid_around_nodes[pos_pred], uid_pred);
1136 }
1138 ARCANE_FATAL("Problème de cohérence entre les patchs (uid={0} -- old_uid_succ={1} -- new_uid_succ={2})", uid, own_nodes_uid_around_nodes[pos_succ], uid_succ);
1139 }
1142 return;
1143 }
1144 }
1145 };
1146
1147 // // TODO : Il faut pouvoir récupérer le patch correspondant.
1148 // for (Integer idir = 0; idir < nb_dir; ++idir) {
1149 // NodeDirectionMng ndm(m_cartesian_mesh->nodeDirection(idir));
1150 // ENUMERATE_ (Node, inode, ndm.allNodes().own()) {
1151 // DirNode cc(ndm.node(*inode));
1152 // Node next = cc.next();
1153 // Node prev = cc.previous();
1154 // set_value(idir, 0, inode->uniqueId(), prev.uniqueId(), next.uniqueId());
1155 // }
1156 // }
1157
1158 for (Integer ipatch = 0; ipatch < nb_patch; ++ipatch) {
1159 ICartesianMeshPatch* p = m_cartesian_mesh->patch(ipatch);
1160 for (Integer idir = 0; idir < nb_dir; ++idir) {
1161 NodeDirectionMng ndm(p->nodeDirection(idir));
1162 ENUMERATE_ (Node, inode, ndm.allNodes().own()) {
1163 DirNode cc(ndm.node(*inode));
1164 Node next = cc.next();
1165 Node prev = cc.previous();
1166 set_value(idir, ipatch, inode->uniqueId(), prev.uniqueId(), next.uniqueId());
1167 }
1168 }
1169 }
1170
1171 return size_of_once_case_around-1;
1172}
1173
1174/*---------------------------------------------------------------------------*/
1175/*---------------------------------------------------------------------------*/
1176
1177void AMRCartesianMeshTesterModule::
1178_checkSync()
1179{
1180 IMesh* mesh = m_cartesian_mesh->mesh();
1181 Integer nb_error = 0;
1182
1183 VariableCellInt32 test_var(VariableBuildInfo(mesh, "ArcaneTestAMRCheckSync"));
1184 test_var.fill(0);
1185 ENUMERATE_ (Cell, icell, mesh->ownCells()) {
1186 test_var[icell] = 1;
1187 }
1188 test_var.synchronize();
1189 ENUMERATE_ (Cell, icell, mesh->allCells()) {
1190 if (test_var[icell] != 1) {
1191 nb_error++;
1192 }
1193 }
1194 if (nb_error > 0) {
1195 ARCANE_FATAL("Bad sync -- Nb error : {0}", nb_error);
1196 }
1197}
1198
1199/*---------------------------------------------------------------------------*/
1200/*---------------------------------------------------------------------------*/
1201
1202void AMRCartesianMeshTesterModule::
1203_cellsInPatch(Real3 position, Real3 length, bool is_3d, Int32 level, UniqueArray<Int32>& cells_in_patch)
1204{
1205 // Parcours les mailles actives et ajoute dans la liste des mailles
1206 // à raffiner celles qui sont contenues dans le boîte englobante
1207 // spécifiée dans le jeu de données.
1208 Real3 min_pos = position;
1209 Real3 max_pos = min_pos + length;
1210 ENUMERATE_ (Cell, icell, mesh()->allCells()) {
1211 if ((icell->level() == level) || (level == -1 && icell->nbHChildren() == 0)) {
1212 Real3 center = m_cell_center[icell];
1213 bool is_inside_x = center.x > min_pos.x && center.x < max_pos.x;
1214 bool is_inside_y = center.y > min_pos.y && center.y < max_pos.y;
1215 bool is_inside_z = (center.z > min_pos.z && center.z < max_pos.z) || !is_3d;
1217 cells_in_patch.add(icell.itemLocalId());
1218 }
1219 }
1220 }
1221}
1222
1223/*---------------------------------------------------------------------------*/
1224/*---------------------------------------------------------------------------*/
1225
1226ARCANE_REGISTER_MODULE_AMRCARTESIANMESHTESTER(AMRCartesianMeshTesterModule);
1227
1228/*---------------------------------------------------------------------------*/
1229/*---------------------------------------------------------------------------*/
1230
1231} // End namespace ArcaneTest
1232
1233/*---------------------------------------------------------------------------*/
1234/*---------------------------------------------------------------------------*/
#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.
Integer _cellsUidAroundFaces(UniqueArray< Int64 > &own_cells_uid_around_faces)
Méthode permettant de récupérer un tableau contenant les mailles autour des faces.
Integer _cellsUidAroundCells(UniqueArray< Int64 > &own_cells_uid_around_cells)
Méthode permettant de récupérer un tableau contenant les mailles autour des mailles.
Integer _nodesUidAroundNodes(UniqueArray< Int64 > &own_nodes_uid_around_nodes)
Méthode permettant de récupérer un tableau contenant les noeuds autour des noeuds.
void _computeSubCellDensity(Cell cell)
Calcule la densité d'une maille AMR.
String _checkDirectionUniqueIdsHashCollective(ArrayView< Int64 > own_items_uid_around, Integer nb_items_around)
Méthode permettant de calculer un hash à partir d'un tableau d'items "autour".
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:1191
Int32 nbHChildren() const
Nombre d'enfants pour l'AMR.
Definition Item.h:1307
Cell hChild(Int32 i) const
i-ème enfant AMR
Definition Item.h:1310
Maille avant et après une maille suivant une direction.
Infos sur maille avant et après une face 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
Infos sur les face d'une direction spécifique X,Y ou Z d'un maillage structuré.
DirFace face(Face f) const
Face direction correspondant à la face f.
FaceGroup allFaces() const
Groupe de toutes les faces dans la direction.
Face d'une maille.
Definition Item.h:944
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 CellGroup ownCells()=0
Groupe de toutes les mailles propres au domaine.
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 CellGroup allCells()=0
Groupe de toutes les mailles.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
virtual VariableNodeReal3 & nodesCoordinates()=0
Coordonnées des noeuds.
virtual IGhostLayerMng * ghostLayerMng() const =0
Gestionnare de couche fantômes associé
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:776
Classe de base d'un élément de maillage.
Definition Item.h:83
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Definition Item.h:216
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:149
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 Item.h:573
Cell cell(Int32 i) const
i-ème maille du noeud
Definition Item.h:1584
Int32 nbCell() const
Nombre de mailles connectées au noeud.
Definition Item.h:653
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?).
String toHexaString(ByteConstArrayView input)
Converti un tableau d'octet en sa représentation hexadécimale.
Definition Convert.cc:75
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