14#include "arcane/utils/CheckedConvert.h"
15#include "arcane/utils/PlatformUtils.h"
16#include "arcane/utils/Real2.h"
17#include "arcane/utils/MD5HashAlgorithm.h"
20#include "arcane/core/MeshKind.h"
21#include "arcane/core/Directory.h"
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"
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"
44#include "arcane/cartesianmesh/ICartesianMesh.h"
45#include "arcane/cartesianmesh/AMRZonePosition.h"
46#include "arcane/cartesianmesh/CellDirectionMng.h"
47#include "arcane/cartesianmesh/FaceDirectionMng.h"
48#include "arcane/cartesianmesh/NodeDirectionMng.h"
49#include "arcane/cartesianmesh/CartesianConnectivity.h"
50#include "arcane/cartesianmesh/CartesianMeshAMRMng.h"
51#include "arcane/cartesianmesh/CartesianMeshRenumberingInfo.h"
52#include "arcane/cartesianmesh/ICartesianMeshPatch.h"
53#include "arcane/cartesianmesh/CartesianMeshUtils.h"
54#include "arcane/cartesianmesh/CartesianMeshCoarsening2.h"
55#include "arcane/cartesianmesh/CartesianMeshPatchListView.h"
56#include "arcane/cartesianmesh/SimpleHTMLMeshAMRPatchExporter.h"
58#include "arcane/tests/ArcaneTestGlobal.h"
59#include "arcane/tests/AMRCartesianMeshTester_axl.h"
60#include "arcane/tests/CartesianMeshTestUtils.h"
68using namespace Arcane;
75class AMRCartesianMeshTesterModule
76:
public ArcaneAMRCartesianMeshTesterObject
81 ~AMRCartesianMeshTesterModule();
89 void buildInit()
override;
90 void compute()
override;
103 Int32 m_nb_expected_patch = 0;
104 bool m_merge_patches =
true;
112 void _mergePatches();
113 void _reduceNbGhostLayers();
115 void _computeCenters();
116 void _processPatches();
117 void _writePostProcessing();
118 void _checkUniqueIds();
120 void _testDirections();
121 void _checkDirections();
133AMRCartesianMeshTesterModule::
135: ArcaneAMRCartesianMeshTesterObject(mbi)
141, m_cartesian_mesh(nullptr)
148AMRCartesianMeshTesterModule::
149~AMRCartesianMeshTesterModule()
158void AMRCartesianMeshTesterModule::
161 String time_loop_name(
"AMRCartesianMeshTestLoop");
167 List<TimeLoopEntryPointInfo> clist;
168 clist.add(TimeLoopEntryPointInfo(
"AMRCartesianMeshTester.buildInit"));
173 List<TimeLoopEntryPointInfo> clist;
174 clist.add(TimeLoopEntryPointInfo(
"AMRCartesianMeshTester.init"));
179 List<TimeLoopEntryPointInfo> clist;
180 clist.add(TimeLoopEntryPointInfo(
"AMRCartesianMeshTester.compute"));
186 clist.add(
"AMRCartesianMeshTester");
189 clist.add(
"ArcanePostProcessing");
190 clist.add(
"ArcaneCheckpoint");
191 clist.add(
"ArcaneLoadBalance");
201void AMRCartesianMeshTesterModule::
204 if (subDomain()->isContinue())
207 m_global_deltat.assign(1.0);
209 IItemFamily* cell_family = defaultMesh()->cellFamily();
220 IItemFamily* face_family = defaultMesh()->faceFamily();
235void AMRCartesianMeshTesterModule::
238 info() <<
"AMR Init";
240 IMesh* mesh = defaultMesh();
242 IItemFamily* cell_family = mesh->
cellFamily();
250 IItemFamily* face_family = defaultMesh()->faceFamily();
265 m_utils =
makeRef(
new CartesianMeshTestUtils(m_cartesian_mesh,acceleratorMng()));
267 m_merge_patches = options()->mergePatches();
269 if (!subDomain()->isContinue()) {
272 if (m_merge_patches) {
275 _reduceNbGhostLayers();
281 const bool do_coarse_at_init = options()->coarseAtInit();
283 const Integer dimension = defaultMesh()->dimension();
285 m_nb_expected_patch = 1 + options()->refinement2d().size();
286 else if (dimension==3)
287 m_nb_expected_patch = 1 + options()->refinement3d().size();
290 if (do_coarse_at_init)
291 ++m_nb_expected_patch;
293 if (subDomain()->isContinue())
294 m_cartesian_mesh->recreateFromDump();
296 m_cartesian_mesh->computeDirections();
297 CartesianMeshRenumberingInfo renumbering_info;
300 if (options()->coarseAtInit())
302 m_cartesian_mesh->renumberItemsUniqueId(renumbering_info);
306 info() <<
"MaxUid for mesh=" << MeshUtils::getMaxItemUniqueIdCollective(m_cartesian_mesh->mesh());
314 for(
Integer idir=0, nb_dir=dimension; idir<nb_dir; ++idir){
315 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(idir));
319 DirCell cc(cdm.cell(*icell));
320 Cell next = cc.next();
321 Cell prev = cc.previous();
326 m_density[icell] += 5.0;
331 DirCell cc(cdm[icell]);
333 info() <<
"CELL: cell=" << ItemPrinter(*icell)
334 <<
" next=" << ItemPrinter(cc.next())
335 <<
" previous=" << ItemPrinter(cc.previous());
338 m_density[icell] += 5.0;
341 info() <<
"NB_BOUNDARY1=" << nb_boundary1 <<
" NB_BOUNDARY2=" << nb_boundary2;
343 bool is_amr = m_nb_expected_patch!=1;
344 if (options()->verbosityLevel()==0)
345 m_utils->setNbPrint(5);
346 m_utils->testAll(is_amr);
347 _writePostProcessing();
356void AMRCartesianMeshTesterModule::
359 IMesh* mesh = m_cartesian_mesh->mesh();
360 bool print_hash =
true;
361 bool with_ghost = options()->hashWithGhost();
362 MD5HashAlgorithm hash_algo;
363 MeshUtils::checkUniqueIdsHashCollective(mesh->
nodeFamily(), &hash_algo, options()->nodesUidHash(),
364 print_hash, with_ghost);
365 MeshUtils::checkUniqueIdsHashCollective(mesh->
faceFamily(), &hash_algo, options()->facesUidHash(),
366 print_hash, with_ghost);
367 MeshUtils::checkUniqueIdsHashCollective(mesh->
cellFamily(), &hash_algo, options()->cellsUidHash(),
368 print_hash, with_ghost);
374void AMRCartesianMeshTesterModule::
377 const Int32 dimension = defaultMesh()->dimension();
378 const Int32 nb_patch = m_cartesian_mesh->nbPatch();
380 IParallelMng* pm = parallelMng();
384 SimpleHTMLMeshAMRPatchExporter amr_exporter;
385 Directory directory = subDomain()->exportDirectory();
388 for (
Integer i = 0; i < nb_patch; ++i) {
389 ICartesianMeshPatch* p = m_cartesian_mesh->patch(i);
393 if (dimension == 2 && options()->dumpSvg()) {
394 String filename = String::format(
"Patch{0}-{1}-{2}.svg", i, comm_rank, comm_size);
395 String full_filename = directory.
file(filename);
396 std::ofstream ofile(full_filename.
localstr());
397 SimpleSVGMeshExporter exporter(ofile);
398 exporter.write(patch_cells);
399 amr_exporter.addPatch(m_cartesian_mesh->amrPatch(i));
402 if (dimension == 2 && options()->dumpSvg()) {
403 String amr_filename = String::format(
"MeshPatch{0}-{1}.html", comm_rank, comm_size);
404 String amr_full_filename = directory.
file(amr_filename);
405 std::ofstream amr_ofile(amr_full_filename.
localstr());
406 amr_exporter.write(amr_ofile);
413void AMRCartesianMeshTesterModule::
416 const bool do_check =
true;
417 const bool is_verbose = options()->verbosityLevel()>=1;
419 const Int32 dimension = defaultMesh()->dimension();
421 bool without_coarse_zone =
true;
423 without_coarse_zone = options()->coarseZone2d().empty();
424 else if (dimension == 3)
425 without_coarse_zone = options()->coarseZone3d().empty();
434 Integer nb_expected_patch = m_nb_expected_patch;
436 Integer nb_patch = m_cartesian_mesh->nbPatch();
437 if (without_coarse_zone && nb_expected_patch != nb_patch && !m_merge_patches)
438 ARCANE_FATAL(
"Bad number of patchs expected={0} value={1}",nb_expected_patch,nb_patch);
440 IParallelMng* pm = parallelMng();
443 UniqueArray<Int32> nb_cells_expected(options()->expectedNumberOfCellsInPatchs);
444 if (nb_cells_expected.size()!=nb_patch)
445 ARCANE_FATAL(
"Bad size ({0}, expected={1}) for option '{2}'",
446 nb_cells_expected.size(),nb_patch,options()->expectedNumberOfCellsInPatchs.name());
449 bool has_expected_ghost_cells = options()->expectedNumberOfGhostCellsInPatchs.isPresent();
451 has_expected_ghost_cells =
false;
453 UniqueArray<Int32> nb_ghost_cells_expected(options()->expectedNumberOfGhostCellsInPatchs);
454 if (has_expected_ghost_cells && (nb_ghost_cells_expected.size()!=nb_patch))
455 ARCANE_FATAL(
"Bad size ({0}, expected={1}) for option '{2}'",
456 nb_ghost_cells_expected.size(), nb_patch, options()->expectedNumberOfGhostCellsInPatchs.name());
459 for(
Integer i=0; i<nb_patch; ++i ){
460 ICartesianMeshPatch* p = m_cartesian_mesh->patch(i);
462 info() <<
"Patch cell_group=" << patch_cells.name() <<
" nb_cell=" << patch_cells.size();
464 m_cell_patch_variables.add(cellv);
467 (*cellv)[icell] = 2.0;
470 CellGroup patch_own_cell = patch_cells.own();
471 UniqueArray<Int64> own_cells_uid;
475 info() <<
"Patch i=" << i <<
" cell=" << ItemPrinter(*icell);
476 own_cells_uid.
add(cell.uniqueId());
480 UniqueArray<Int64> global_cells_uid;
482 std::sort(global_cells_uid.
begin(),global_cells_uid.
end());
484 info() <<
"GlobalUids Patch=" << i <<
" NB=" << nb_global_uid
485 <<
" expected=" << nb_cells_expected[i];
487 if (do_check && nb_cells_expected[i]!=nb_global_uid)
488 ARCANE_FATAL(
"Bad number of cells for patch I={0} N={1} expected={2}",
489 i,nb_global_uid,nb_cells_expected[i]);
491 for(
Integer c=0; c<nb_global_uid; ++c )
492 info() <<
"GlobalUid Patch=" << i <<
" I=" << c <<
" cell_uid=" << global_cells_uid[c];
495 if (has_expected_ghost_cells){
496 Int32 local_nb_ghost_cell = patch_cells.size() - patch_own_cell.
size();
498 pinfo() <<
"NbGhostCells my_rank=" << comm_rank <<
" local=" << local_nb_ghost_cell <<
" total=" << total;
499 if (total!=nb_ghost_cells_expected[i])
500 ARCANE_FATAL(
"Bad number of ghost cells for patch I={0} N={1} expected={2}",
501 i,total,nb_ghost_cells_expected[i]);
509void AMRCartesianMeshTesterModule::
512 IMesh* mesh = defaultMesh();
520 for( NodeLocalId inode : cell.
nodes() )
521 center += nodes_coord[inode];
523 m_cell_center[icell] = center;
533 for( NodeLocalId inode : face.
nodes() )
534 center += nodes_coord[inode];
536 m_face_center[iface] = center;
544void AMRCartesianMeshTesterModule::
547 CartesianMeshAMRMng amr_mng(m_cartesian_mesh);
548 amr_mng.setOverlapLayerSizeTopLevel(options()->overlapLayerSizeTopLevel());
551 if (options()->coarseAtInit()){
553 m_cartesian_mesh->computeDirections();
555 info() <<
"Doint initial coarsening";
566 amr_mng.createSubLevel();
568 CartesianMeshPatchListView patches = m_cartesian_mesh->patches();
569 Int32 nb_patch = patches.size();
572 info() <<
"NB_PATCH=" << nb_patch;
573 for( CartesianPatch p : patches){
574 info() <<
"Patch i=" << index <<
" nb_cell=" << p.
cells().
size();
582 Int32 dim = defaultMesh()->dimension();
584 for (
const auto& x : options()->refinement2d()) {
585 amr_mng.refineZone({ x->position(), x->length() });
586 m_cartesian_mesh->computeDirections();
590 for (
const auto& x : options()->refinement3d()) {
591 amr_mng.refineZone({ x->position(), x->length() });
592 m_cartesian_mesh->computeDirections();
600void AMRCartesianMeshTesterModule::
603 Int32 dim = defaultMesh()->dimension();
604 CartesianMeshAMRMng amr_mng(m_cartesian_mesh);
608 for (
auto& x : options()->coarseZone2d()) {
613 amr_mng.coarseZone({ { x->position() }, { x->length() } });
614 m_cartesian_mesh->computeDirections();
619 for (
auto& x : options()->coarseZone3d()) {
624 amr_mng.coarseZone({ { x->position() }, { x->length() } });
625 m_cartesian_mesh->computeDirections();
633void AMRCartesianMeshTesterModule::
636 CartesianMeshAMRMng amr_mng(m_cartesian_mesh);
637 amr_mng.mergePatches();
639 m_cartesian_mesh->computeDirections();
645void AMRCartesianMeshTesterModule::
646_reduceNbGhostLayers()
648 for (
auto& x : options()->reduceNbGhostLayers()) {
649 Integer final_nb_ghost_layer{ m_cartesian_mesh->reduceNbGhostLayers(x->level(), x->nbGhostLayers()) };
651 if (parallelMng()->commSize() != 1 && final_nb_ghost_layer != x->nbGhostLayers()) {
661void AMRCartesianMeshTesterModule::
689 for(
Int32 j=0; j<nb_children; ++j ) {
690 Real sub_density = 0.0;
693 for(
Integer k=0; k<sub_cell_nb_node; ++k )
694 sub_density += m_node_density[sub_cell.
node(k)];
695 sub_density /= (
Real)sub_cell_nb_node;
696 m_density[sub_cell] =sub_density;
704void AMRCartesianMeshTesterModule::
717 for(
Integer idir=0; idir<nb_dir; ++idir){
718 m_old_density.copy(m_density);
721 info() <<
"Direction=" << idir <<
" cells=" << cdm.innerCells().name()
722 <<
" n=" << cdm.innerCells().size();
726 Cell next = cc.next();
727 Cell prev = cc.previous();
728 Real d = m_old_density[icell] + m_old_density[next] + m_old_density[prev];
729 m_density[icell] = d / 3.0;
737 Cell next = cc.next();
738 Cell prev = cc.previous();
739 Real d = m_old_density[icell];
742 d += m_old_density[next];
746 d += m_old_density[prev];
749 m_density[icell] = d / n;
759 for(
Integer i=0; i<nb_cell; ++i )
760 density += m_density[node.
cell(i)];
761 density /= (
Real)nb_cell;
762 m_node_density[inode] = density;
769void AMRCartesianMeshTesterModule::
779 Integer nb_dir = defaultMesh()->dimension();
780 for(
Integer idir=0; idir<nb_dir; ++idir){
781 CellDirectionMng cdm(m_cartesian_mesh->cellDirection(idir));
784 DirCell cc(cdm[icell]);
785 Cell next = cc.next();
786 Cell prev = cc.previous();
787 Real d = m_density[icell];
790 d += m_density[next];
794 d += m_density[prev];
797 m_density[icell] = d / n;
805void AMRCartesianMeshTesterModule::
806_writePostProcessing()
808 info() <<
"Post-process AMR";
809 IPostProcessorWriter* post_processor = options()->postProcessor();
810 Directory output_directory = Directory(subDomain()->exportDirectory(),
"amrtestpost1");
812 info() <<
"Creating output dir '" << output_directory.
path() <<
"' for export";
813 UniqueArray<Real> times;
814 times.
add(m_global_time());
816 post_processor->
setMesh(defaultMesh());
819 VariableList variables;
823 variables.add(v->variable());
826 groups.add(allCells());
827 for( CartesianPatch p : m_cartesian_mesh->patches() )
828 groups.add(p.
cells());
830 IVariableMng* vm = subDomain()->variableMng();
837void AMRCartesianMeshTesterModule::
840 Integer nb_patch = m_cartesian_mesh->nbPatch();
841 Integer nb_dir = m_cartesian_mesh->mesh()->dimension();
842 NodeDirectionMng node_dm2;
843 for(
Integer ipatch=0; ipatch<nb_patch; ++ipatch ){
844 ICartesianMeshPatch* p = m_cartesian_mesh->patch(ipatch);
845 for(
Integer idir=0; idir<nb_dir; ++idir ){
848 NodeGroup dm_all_nodes = node_dm.allNodes();
850 DirNode dir_node(node_dm[inode]);
851 DirNode dir_node2(node_dm2[inode]);
852 Node prev_node = dir_node.previous();
853 Node next_node = dir_node.next();
854 Node prev_node2 = dir_node2.previous();
855 Node next_node2 = dir_node2.next();
856 m_utils->checkSameId(prev_node, prev_node2);
857 m_utils->checkSameId(next_node, next_node2);
863void AMRCartesianMeshTesterModule::
866 m_cartesian_mesh->computeDirections();
867 IMesh* mesh = m_cartesian_mesh->mesh();
868 bool print_hash =
true;
870 auto check_hash = [&](
const IItemFamily* item_family,
const String& expected_hash, ArrayView<Int64> own_items_uid_around,
Integer nb_items_around) {
874 info() <<
"HASH_RESULT direction items of family=" << item_family->
name()
875 <<
" v= " << cell_hash <<
" expected= " << expected_hash;
878 if (cell_hash != expected_hash)
879 ARCANE_FATAL(
"Bad hash for uniqueId() for direction items of family '{0}' v='{1}' expected='{2}'",
880 item_family->
fullName(), cell_hash, expected_hash);
883 if (!options()->cellsDirectionHash().empty()) {
884 debug() <<
"Check cells direction hash";
885 UniqueArray<Int64> own_cells_uid_around_cells;
887 check_hash(mesh->
cellFamily(), options()->cellsDirectionHash(), own_cells_uid_around_cells, nb_items_around);
889 if (!options()->facesDirectionHash().empty()) {
890 debug() <<
"Check faces direction hash";
891 UniqueArray<Int64> own_cells_uid_around_faces;
893 check_hash(mesh->
faceFamily(), options()->facesDirectionHash(), own_cells_uid_around_faces, nb_items_around);
896 if (!options()->nodesDirectionHash().empty()) {
897 debug() <<
"Check nodes direction hash";
898 UniqueArray<Int64> own_nodes_uid_around_nodes;
900 check_hash(mesh->
nodeFamily(), options()->nodesDirectionHash(), own_nodes_uid_around_nodes, nb_items_around);
918 Integer size_of_once_case_around = nb_items_around + 1;
923 parallelMng()->allGatherVariable(own_items_uid_around, global_items_uid_around);
928 for (
Int64 i = 0; i < global_items_uid_around.
size(); i += size_of_once_case_around) {
929 Int64 uid = global_items_uid_around[i];
930 ARCANE_ASSERT((uid != -1), (
"Un uid dans le tableau est = -1"));
931 global_items_uid[index++] = &(global_items_uid_around[i]);
935 std::sort(global_items_uid.
begin(), global_items_uid.
end(),
940 final_all_items_uid.
resize(global_items_uid_around.
size());
943 Int64 previous_uid = -1;
945 for (
Int64* ptr_uid : global_items_uid) {
946 if (*ptr_uid == previous_uid) {
949 previous_uid = *ptr_uid;
950 for (
Integer iaround = 0; iaround < size_of_once_case_around; ++iaround) {
951 final_all_items_uid[index++] = ptr_uid[iaround];
979 if (pm->
commSize() != 1 &&
mesh->ghostLayerMng()->nbGhostLayer() == 0) {
983 Integer nb_patch = m_cartesian_mesh->nbPatch();
985 Integer nb_items =
mesh->cellFamily()->allItems().own().size();
988 constexpr Integer nb_items_per_dir = 2;
993 Integer size_of_once_case_around = nb_dir * nb_items_per_dir + 1;
995 own_cells_uid_around_cells.
resize(nb_items * size_of_once_case_around, -1);
999 own_cells_uid_around_cells[index] = icell->uniqueId();
1000 index += size_of_once_case_around;
1009 ARCANE_ASSERT((uid != -1), (
"Uid ne peut pas être égal à -1"));
1011 for (
Integer i = 0; i < own_cells_uid_around_cells.
size(); i += size_of_once_case_around) {
1012 if (own_cells_uid_around_cells[i] == uid) {
1013 Integer pos_final = i + 1 + (dir * nb_items_per_dir);
1014 Integer pos_pred = pos_final + ipred;
1015 Integer pos_succ = pos_final + isucc;
1019 if (own_cells_uid_around_cells[pos_pred] != -1 && own_cells_uid_around_cells[pos_pred] != uid_pred) {
1020 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);
1022 if (own_cells_uid_around_cells[pos_succ] != -1 && own_cells_uid_around_cells[pos_succ] != uid_succ) {
1023 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);
1025 own_cells_uid_around_cells[pos_pred] = uid_pred;
1026 own_cells_uid_around_cells[pos_succ] = uid_succ;
1032 own_cells_uid_around_cells[pos_pred] = std::max(own_cells_uid_around_cells[pos_pred], uid_pred);
1033 own_cells_uid_around_cells[pos_succ] = std::max(own_cells_uid_around_cells[pos_succ], uid_succ);
1040 for (
Integer idir = 0; idir < nb_dir; ++idir) {
1046 set_value(idir, icell->uniqueId(), prev.uniqueId(), next.uniqueId());
1050 for (
Integer ipatch = 0; ipatch < nb_patch; ++ipatch) {
1052 for (
Integer idir = 0; idir < nb_dir; ++idir) {
1058 set_value(idir, icell->uniqueId(), prev.uniqueId(), next.uniqueId());
1063 return size_of_once_case_around-1;
1081 if (pm->
commSize() != 1 &&
mesh->ghostLayerMng()->nbGhostLayer() == 0) {
1085 Integer nb_patch = m_cartesian_mesh->nbPatch();
1087 Integer nb_items =
mesh->faceFamily()->allItems().own().size();
1090 constexpr Integer nb_items_per_dir = 2;
1095 Integer size_of_once_case_around = nb_items_per_dir * nb_patch + 1;
1097 own_cells_uid_around_faces.
resize(nb_items * size_of_once_case_around, -1);
1101 own_cells_uid_around_faces[index] = iitem->uniqueId();
1102 index += size_of_once_case_around;
1110 ARCANE_ASSERT((uid != -1), (
"Uid ne peut pas être égal à -1"));
1112 for (
Integer i = 0; i < own_cells_uid_around_faces.
size(); i += size_of_once_case_around) {
1113 if (own_cells_uid_around_faces[i] == uid) {
1114 Integer pos_final = i + 1 + ipatch * nb_items_per_dir;
1115 Integer pos_pred = pos_final + ipred;
1116 Integer pos_succ = pos_final + isucc;
1117 if (own_cells_uid_around_faces[pos_pred] != -1 && own_cells_uid_around_faces[pos_pred] != uid_pred) {
1118 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);
1120 if (own_cells_uid_around_faces[pos_succ] != -1 && own_cells_uid_around_faces[pos_succ] != uid_succ) {
1121 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);
1123 own_cells_uid_around_faces[pos_pred] = uid_pred;
1124 own_cells_uid_around_faces[pos_succ] = uid_succ;
1141 for (
Integer ipatch = 0; ipatch < nb_patch; ++ipatch) {
1143 for (
Integer idir = 0; idir < nb_dir; ++idir) {
1149 set_value(ipatch, iface->uniqueId(), prev.uniqueId(), next.uniqueId());
1154 return size_of_once_case_around-1;
1177 if (pm->
commSize() != 1 &&
mesh->ghostLayerMng()->nbGhostLayer() == 0) {
1181 Integer nb_patch = m_cartesian_mesh->nbPatch();
1183 Integer nb_items =
mesh->nodeFamily()->allItems().own().size();
1186 constexpr Integer nb_items_per_dir = 2;
1191 Integer size_of_once_case_around = nb_dir * nb_items_per_dir * nb_patch + 1;
1193 own_nodes_uid_around_nodes.
resize(nb_items * size_of_once_case_around, -1);
1197 own_nodes_uid_around_nodes[index] = iitem->uniqueId();
1198 index += size_of_once_case_around;
1208 ARCANE_ASSERT((uid != -1), (
"Uid ne peut pas être égal à -1"));
1210 for (
Integer i = 0; i < own_nodes_uid_around_nodes.
size(); i += size_of_once_case_around) {
1211 if (own_nodes_uid_around_nodes[i] == uid) {
1212 Integer pos_final = i + 1 + ipatch * (nb_items_per_dir * nb_dir) + dir * nb_items_per_dir;
1213 Integer pos_pred = pos_final + ipred;
1214 Integer pos_succ = pos_final + isucc;
1215 if (own_nodes_uid_around_nodes[pos_pred] != -1 && own_nodes_uid_around_nodes[pos_pred] != uid_pred) {
1216 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);
1218 if (own_nodes_uid_around_nodes[pos_succ] != -1 && own_nodes_uid_around_nodes[pos_succ] != uid_succ) {
1219 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);
1221 own_nodes_uid_around_nodes[pos_pred] = uid_pred;
1222 own_nodes_uid_around_nodes[pos_succ] = uid_succ;
1239 for (
Integer ipatch = 0; ipatch < nb_patch; ++ipatch) {
1241 for (
Integer idir = 0; idir < nb_dir; ++idir) {
1247 set_value(idir, ipatch, inode->uniqueId(), prev.uniqueId(), next.uniqueId());
1252 return size_of_once_case_around-1;
1258void AMRCartesianMeshTesterModule::
1267 test_var[icell] = 1;
1269 test_var.synchronize();
1271 if (test_var[icell] != 1) {
1283void AMRCartesianMeshTesterModule::
1289 Real3 min_pos = position;
1290 Real3 max_pos = min_pos + length;
1292 if ((icell->level() == level) || (level == -1 && icell->nbHChildren() == 0)) {
1293 Real3 center = m_cell_center[icell];
1294 bool is_inside_x = center.
x > min_pos.
x && center.
x < max_pos.
x;
1295 bool is_inside_y = center.
y > min_pos.
y && center.
y < max_pos.
y;
1296 bool is_inside_z = (center.
z > min_pos.
z && center.
z < max_pos.
z) || !is_3d;
1297 if (is_inside_x && is_inside_y && is_inside_z) {
1298 cells_in_patch.
add(icell.itemLocalId());
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
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".
Integer size() const
Nombre d'éléments du vecteur.
Vue modifiable d'un tableau d'un type T.
iterator end()
Itérateur sur le premier élément après la fin du tableau.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
iterator begin()
Itérateur sur le premier élément du tableau.
Span< const T > constSpan() const
Vue constante sur ce tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
void setSortAfterRenumbering(bool v)
Indique si on retrie les entités après renumérotation.
void setParentPatch(CartesianPatch patch)
Numéro du patch parent pour la renumérotation.
void setRenumberPatchMethod(Int32 v)
Méthode pour renuméroter les patchs.
Infos sur les mailles d'une direction spécifique X,Y ou Z d'un maillage structuré.
CellGroup allCells() const
Groupe de toutes les mailles dans la direction.
DirCell cell(Cell c) const
Maille direction correspondant à la maille c.
Int32 nbHChildren() const
Nombre d'enfants pour l'AMR.
Cell hChild(Int32 i) const
i-ème enfant AMR
void clear()
Supprime tous les éléments de la collection.
Maille avant et après une maille suivant une direction.
Cell previous() const
Maille avant.
Cell next() const
Maille après.
Infos sur maille avant et après une face suivant une direction.
Cell nextCell() const
Maille après.
Cell previousCell() const
Maille avant.
Noeud avant et après un noeud suivant une direction.
Node next() const
Maille après.
Node previous() const
Maille avant.
String file(const String &file_name) const override
Retourne le chemin complet du fichier file_name dans le répertoire.
bool createDirectory() const override
Créé le répertoire.
String path() const override
Retourne le chemin du répertoire.
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.
Interface d'un patch AMR d'un maillage cartésien.
virtual CellGroup cells()=0
Groupe de mailles du patch.
virtual NodeDirectionMng & nodeDirection(eMeshDirection dir)=0
Liste des noeuds dans la direction dir.
virtual FaceDirectionMng & faceDirection(eMeshDirection dir)=0
Liste des faces dans la direction dir.
virtual CellDirectionMng & cellDirection(eMeshDirection dir)=0
Liste des mailles dans la direction dir.
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 IMesh * mesh() const =0
Maillage associé à ce maillage cartésien.
virtual ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Créé un groupe d'entités de nom name contenant les entités local_ids.
virtual String name() const =0
Nom de la famille.
virtual String fullName() const =0
Nom complet de la famille (avec celui du maillage)
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
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.
virtual void setVariables(VariableCollection variables)=0
Positionne la liste des variables à sortir.
virtual void setTimes(RealConstArrayView times)=0
Positionne la liste des temps.
virtual void setGroups(ItemGroupCollection groups)=0
Positionne la liste des groupes à sortir.
virtual void setBaseDirectoryName(const String &dirname)=0
Positionne le nom du répertoire de sortie des fichiers. Ce répertoire doit exister.
virtual void setMesh(IMesh *mesh)
Positionne le maillage.
Interface du gestionnaire d'un sous-domaine.
virtual ITimeLoopMng * timeLoopMng()=0
Retourne le gestionnaire de la boucle en temps.
virtual ITimeLoop * createTimeLoop(const String &name)=0
Crée une boucle en temps de nom name.
virtual void registerTimeLoop(ITimeLoop *time_loop)=0
Enregistrement et choix de la boucle en temps.
virtual void setRequiredModulesName(const StringCollection &)=0
Positionne la liste des des modules obligatoires.
virtual void setOptionalModulesName(const StringCollection &)=0
Positionne la liste des des modules facultatifs.
static const char * WBuild
appelé lors de la lecture du jeu de données
static const char * WComputeLoop
appelé pendant la boucle de calcul
virtual void setEntryPoints(const String &where, const TimeLoopEntryPointInfoCollection &)=0
Positionne la liste des noms des points d'entrée pour le point d'appel where.
static const char * WInit
appelé pendant l'initialisation, l'initialisation d'une reprise ou d'un nouveau cas
virtual void writePostProcessing(IPostProcessorWriter *writer)=0
Ecrit les variables pour un post-traitement.
Integer size() const
Nombre d'éléments du groupe.
Node node(Int32 i) const
i-ème noeud de l'entité
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Int32 nbNode() const
Nombre de noeuds de l'entité
Classe de base d'un élément de maillage.
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Calcule la fonction de hashage MD5 d'un tableau.
void computeHash64(Span< const Byte > input, ByteArray &output) override
Calcule la valeur du hash pour le tableau input.
Informations pour construire un module.
Infos sur les noeuds d'une direction spécifique X,Y ou Z d'un maillage structuré.
NodeGroup allNodes() const
Groupe de tous les noeuds dans la direction.
DirNode node(Node n) const
Noeud direction correspondant au noeud n.
Cell cell(Int32 i) const
i-ème maille du noeud
Int32 nbCell() const
Nombre de mailles connectées au noeud.
Classe gérant un vecteur de réel de dimension 3.
Référence à une instance.
Chaîne de caractères unicode.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Vecteur 1D de données avec sémantique par valeur (style STL).
Paramètres nécessaires à la construction d'une variable.
ItemGroupT< Cell > CellGroup
Groupe de mailles.
ItemGroupT< Node > NodeGroup
Groupe de noeuds.
MeshVariableScalarRefT< Cell, Real > VariableCellReal
Grandeur au centre des mailles de type réel.
MeshVariableScalarRefT< Cell, Real3 > VariableCellReal3
Grandeur au centre des mailles de type coordonnées.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
MeshVariableScalarRefT< Face, Real3 > VariableFaceReal3
Grandeur aux faces de type coordonnées.
MeshVariableScalarRefT< Node, Real > VariableNodeReal
Grandeur au noeud de type réel.
MeshVariableScalarRefT< Cell, Int32 > VariableCellInt32
Grandeur au centre des mailles de type entier 32 bits.
String toHexaString(ByteConstArrayView input)
Converti un tableau d'octet en sa représentation hexadécimale.
@ ReduceSum
Somme des valeurs.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
List< ItemGroup > ItemGroupList
Tableau de groupes d'éléments du maillage.
List< String > StringList
Tableau de chaînes de caractères unicode.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
double Real
Type représentant un réel.
Impl::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converti la vue en un tableau d'octets non modifiables.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
@ Cell
Le maillage est AMR par maille.
std::int32_t Int32
Type entier signé sur 32 bits.
Real y
deuxième composante du triplet
Real z
troisième composante du triplet
Real x
première composante du triplet