15#include "arcane/utils/ApplicationInfo.h"
16#include "arcane/utils/CommandLineArguments.h"
17#include "arcane/utils/List.h"
18#include "arcane/utils/MDDim.h"
20#include "arcane/core/IMeshSubdivider.h"
21#include "arcane/impl/ArcaneBasicMeshSubdividerService_axl.h"
23#include "arcane/core/ItemGroup.h"
24#include "arcane/core/ItemPrinter.h"
25#include "arcane/core/IItemFamily.h"
26#include "arcane/core/IGhostLayerMng.h"
28#include "arcane/core/IMeshModifier.h"
30#include "arcane/core/SimpleSVGMeshExporter.h"
33#include "arcane/core/ServiceBuilder.h"
34#include "arcane/core/Directory.h"
35#include "arcane/core/IVariableMng.h"
36#include "arcane/core/IParallelMng.h"
37#include "arcane/core/BasicService.h"
38#include "arcane/core/IPrimaryMesh.h"
39#include "arcane/core/Item.h"
41#include "arcane/core/PostProcessorWriterBase.h"
43#include "arcane/core/VariableBuildInfo.h"
44#include "arcane/core/IMeshUtilities.h"
45#include "arcane/core/ISubDomain.h"
46#include "arcane/cartesianmesh/ICartesianMesh.h"
47#include "arcane/core/Properties.h"
48#include "arcane/std/IMeshGenerator.h"
51#include <unordered_set>
63namespace MeshSubdivider
87 StorageRefine child_faces;
111 this->child_faces = child_faces;
114 Pattern(Pattern&& other) noexcept
121 , child_faces(other.child_faces)
124 Pattern(
const Pattern&) =
delete;
126 Pattern(Pattern& other) noexcept
133 , child_faces(other.child_faces)
135 Pattern& operator=(
const Pattern& other)
137 if (
this != &other) {
144 child_faces = other.child_faces;
149 Pattern& operator=(Pattern&& other)
noexcept
151 if (
this != &other) {
158 child_faces = other.child_faces;
162 Pattern& operator=(Pattern& other)
noexcept
164 if (
this != &other) {
171 child_faces = other.child_faces;
246 StorageRefine nodes({
253 StorageRefine faces({
267 StorageRefine cells({
273 StorageRefine child_faces({
280 return { IT_Quad4, IT_Line2, IT_Quad4, nodes, faces, cells, child_faces };
303 StorageRefine nodes({});
304 StorageRefine faces({
311 StorageRefine cells({ { 0, 3, 2 }, { 2, 1, 0 } });
312 StorageRefine child_faces({});
313 return { IT_Quad4, IT_Line2, IT_Triangle3, nodes, faces, cells, child_faces };
340 StorageRefine nodes({
345 StorageRefine faces({
356 StorageRefine cells({ { 3, 0, 5 },
360 StorageRefine child_faces(
364 return { IT_Triangle3, IT_Line2, IT_Triangle3, nodes, faces, cells, child_faces };
369 StorageRefine nodes({
375 StorageRefine faces({
378 StorageRefine cells({
383 StorageRefine child_faces({});
384 return { IT_Triangle3, IT_Line2, IT_Quad4, nodes, faces, cells, child_faces };
390 StorageRefine nodes = {
409 { 0, 1, 5, 4, 3, 2, 7, 6 }
411 StorageRefine faces = {
452 StorageRefine child_faces = {
460 StorageRefine cells = {
461 { 0, 8, 20, 9, 10, 21, 26, 22 },
462 { 10, 21, 26, 22, 4, 16, 25, 17 },
463 { 8, 1, 11, 20, 21, 12, 23, 26 },
464 { 21, 12, 23, 26, 16, 5, 18, 25 },
465 { 9, 20, 13, 3, 22, 26, 24, 15 },
466 { 22, 26, 24, 15, 17, 25, 19, 7 },
467 { 20, 11, 2, 13, 26, 23, 14, 24 },
468 { 26, 23, 14, 24, 25, 18, 6, 19 }
470 return { IT_Hexaedron8, IT_Quad4, IT_Hexaedron8, nodes, faces, cells, child_faces };
475 StorageRefine nodes = {
484 StorageRefine faces = {
510 StorageRefine child_faces = {
516 StorageRefine cells = {
526 return { IT_Tetraedron4, IT_Triangle3, IT_Tetraedron4, nodes, faces, cells, child_faces };
532 StorageRefine nodes = {};
533 StorageRefine faces = {
553 StorageRefine child_faces = {
561 StorageRefine cells = {
568 return { IT_Hexaedron8, IT_Triangle3, IT_Tetraedron4, nodes, faces, cells, child_faces };
573 StorageRefine nodes = {
586 StorageRefine faces = {
606 StorageRefine child_faces = {
616 StorageRefine cells = {
629 { 7, 10, 14, 13, 0, 4, 12, 6 },
630 { 8, 11, 5, 2, 13, 14, 12, 6 },
631 { 3, 9, 11, 8, 7, 10, 14, 13 },
632 { 9, 1, 5, 11, 10, 4, 12, 14 }
634 return { IT_Tetraedron4, IT_Quad4, IT_Hexaedron8, nodes, faces, cells, child_faces };
639 StorageRefine nodes({
646 { 0, 1, 2, 3, 4, 5, 6, 7 },
648 StorageRefine faces({
711 StorageRefine cells({
743 StorageRefine child_faces({
753 return { IT_Hexaedron8, IT_Triangle3, IT_Tetraedron4, nodes, faces, cells, child_faces };
761class ArcaneBasicMeshSubdividerService
806 void _refineOnce([[maybe_unused]]
IPrimaryMesh*
mesh, std::unordered_map<Arccore::Int16, MeshSubdivider::Pattern>& pattern_manager);
819 if (
mesh->dimension() == 2) {
822 else if (
mesh->dimension() == 3) {
829 std::unordered_map<Arccore::Int16, MeshSubdivider::Pattern> pattern_manager;
831 mesh->faceFamily()->destroyGroups();
833 pattern_manager[IT_Triangle3] = PatternBuilder::tritotri();
835 std::string prefix(
"subdivider_pattern2D_");
836 mesh->utilities()->writeToFile(prefix +
"tritotri.vtk",
"VtkLegacyMeshWriter");
838 mesh->faceFamily()->destroyGroups();
840 pattern_manager[IT_Triangle3] = PatternBuilder::tritoquad();
842 mesh->utilities()->writeToFile(prefix +
"tritoquad.vtk",
"VtkLegacyMeshWriter");
844 mesh->faceFamily()->destroyGroups();
846 pattern_manager[IT_Quad4] = PatternBuilder::quadtoquad();
848 mesh->utilities()->writeToFile(prefix +
"quadtoquad.vtk",
"VtkLegacyMeshWriter");
850 mesh->faceFamily()->destroyGroups();
852 pattern_manager[IT_Quad4] = PatternBuilder::quadtotri();
854 mesh->utilities()->writeToFile(prefix +
"quadtotri.vtk",
"VtkLegacyMeshWriter");
859 std::unordered_map<Arccore::Int16, MeshSubdivider::Pattern> pattern_manager;
860 std::string prefix(
"subdivider_pattern3D_");
861 mesh->faceFamily()->destroyGroups();
863 pattern_manager[IT_Tetraedron4] = PatternBuilder::tettotet();
865 mesh->utilities()->writeToFile(prefix +
"tettotet.vtk",
"VtkLegacyMeshWriter");
867 mesh->faceFamily()->destroyGroups();
869 pattern_manager[IT_Tetraedron4] = PatternBuilder::tettohex();
871 mesh->utilities()->writeToFile(prefix +
"tettohex.vtk",
"VtkLegacyMeshWriter");
873 mesh->faceFamily()->destroyGroups();
875 pattern_manager[IT_Hexaedron8] = PatternBuilder::hextohex();
877 mesh->utilities()->writeToFile(prefix +
"hextohex.vtk",
"VtkLegacyMeshWriter");
879 mesh->faceFamily()->destroyGroups();
881 pattern_manager[IT_Hexaedron8] = PatternBuilder::hextotet24();
883 mesh->utilities()->writeToFile(prefix +
"hextotet24.vtk",
"VtkLegacyMeshWriter");
885 mesh->faceFamily()->destroyGroups();
887 pattern_manager[IT_Hexaedron8] = PatternBuilder::hextotet();
889 mesh->utilities()->writeToFile(prefix +
"subdivider_hextotet.vtk",
"VtkLegacyMeshWriter");
938 info() <<
"#subdivide mesh";
941 const Cell& cell = *icell;
949 info() <<
"subdivide mesh with " <<
options()->nbSubdivision() <<
" nb_refine";
951 Int32 my_rank =
mesh->parallelMng()->commRank();
987 std::unordered_map<Int64, Real3> nodes_to_add_coords;
990 std::set<Int64> new_nodes;
991 std::set<Int64> new_faces;
993 std::unordered_map<Int64, Int32> node_uid_to_owner;
994 std::unordered_map<Int64, Int32> edge_uid_to_owner;
995 std::unordered_map<Int64, Int32> face_uid_to_owner;
996 std::unordered_map<Int64, Int32> child_cell_owner;
997 std::unordered_map<Int32, Int32> old_face_lid_to_owner;
1010 ARCANE_ASSERT((
mesh->nbEdge() == 0), (
"Wrong number of edge"));
1018 std::unordered_map<Int64, std::pair<Int64, Int64>> parents_to_childs_cell;
1019 std::unordered_map<Int64, std::pair<Int64, Int64>> parents_to_childs_faces;
1021 Int64 childs_count = 0;
1024 std::unordered_map<Int64, std::pair<Int64, Int64>> parents_to_childs_faces_groups;
1037 debug() <<
"Refining element";
1068 const Cell& cell = *icell;
1071 StorageRefine& node_pattern = p.
nodes;
1074 StorageRefine& child_faces = p.child_faces;
1081 debug() <<
"Noeuds initiaux";
1091 debug() <<
"Génération des uid noeuds";
1093 for (
Integer i = 0; i < node_pattern.
size(); i++) {
1096 for (
Integer j = 0; j < node_pattern[i].
size(); j++) {
1097 tmp.
add(node_in_cell[node_pattern[i][j]]);
1101 node_in_cell[index_27 + i] = uid;
1103 if (new_nodes.find(node_in_cell[i + index_27]) == new_nodes.end()) {
1106 for (
Integer j = 0; j < node_pattern[i].
size(); j++) {
1107 info() <<
"loop" << cell.
node(
static_cast<Integer>(node_pattern[i][j])) <<
" " << nodes_coords[cell.
node(
static_cast<Integer>(node_pattern[i][j]))];
1108 middle_coord += nodes_coords[cell.
node(
static_cast<Integer>(node_pattern[i][j]))];
1110 if (node_pattern[i].size() == 0) {
1113 middle_coord /= node_pattern[i].
size();
1114 if (middle_coord ==
Real3(0.0, 0.0, 0.0)) {
1115 ARCANE_FATAL(
"Bad coordinate for new node, the node '{0}' probably has a default coordinate (0.0,0.0,0.0).", uid);
1117 new_nodes.insert(node_in_cell[i + index_27]);
1119 nodes_to_add_coords[node_in_cell[i + index_27]] = middle_coord;
1121 nodes_to_add.
add(uid);
1135 debug() <<
"nodetoadd size " << nodes_to_add.
size() <<
" " << nodes_to_add_coords.size();
1136 debug() <<
"Node coord & nb node to add" << nodes_to_add_coords.size() <<
" " << nodes_to_add.
size();
1141 StorageRefine& face_refine = p.
faces;
1142 debug() <<
"face_refine.size() " << face_refine.
size();
1144 debug() <<
"Refine face";
1145 for (
Integer i = 0; i < face_refine.
size(); i++) {
1149 for (
Integer j = 0; j < face_refine[i].
size(); j++) {
1150 tmp.
add(node_in_cell[face_refine[i][j]]);
1155 face_in_cell.
add(uid);
1157 if (new_faces.find(uid) == new_faces.end()) {
1160 faces_to_add.
add(uid);
1162 for (
Integer j = 0; j < face_refine[i].
size(); j++) {
1164 faces_to_add.
add(node_in_cell[face_refine[i][j]]);
1167 faces_uids.
add(uid);
1169 new_faces.insert(uid);
1178 debug() <<
"Gestion face groupe";
1179 for (
Integer i = 0; i < child_faces.
size(); i++) {
1180 parents_to_childs_faces_groups[cell.
face(i).
uniqueId()] = std::pair<Int64, Int64>(face_external_uid.
size(), child_faces[i].
size());
1181 for (
Integer j = 0; j < child_faces[i].
size(); j++) {
1182 face_external_uid.
add(face_in_cell[child_faces[i][j]]);
1187 StorageRefine& cells_refine = p.
cells;
1189 debug() <<
"Génération des cellules enfants";
1191 for (
Integer i = 0; i < cells_refine.
size(); i++) {
1194 for (
Integer j = 0; j < cells_refine[i].
size(); j++) {
1195 tmp.
add(node_in_cell[cells_refine[i][j]]);
1201 cells_to_add.
add(cell_uid);
1202 for (
Integer j = 0; j < cells_refine[i].
size(); j++) {
1203 cells_to_add.
add(node_in_cell[cells_refine[i][j]]);
1205 child_cell_owner[cell_uid] = cell.
owner();
1207 child_cells.
add(cell_uid);
1212 parents_to_childs_cell[cell.
uniqueId()] = std::pair<Int64, Int64>(childs_count, cells_refine.
size());
1213 childs_count += cells_refine.
size();
1219 info() <<
"JustBeforeAdd " << nodes_to_add;
1220 mesh->modifier()->addNodes(nodes_to_add, nodes_lid.
view());
1224 debug() <<
"Faces_uids " << faces_uids <<
" faces_to_add " << faces_to_add.
size() <<
" faces_to_add/6 " << faces_to_add.
size() / 6;
1230 debug() <<
"Before addOneFace " << nb_face_to_add;
1233 mesh->modifier()->addFaces(nb_face_to_add, faces_to_add.
constView(), face_lid.
view());
1234 debug() <<
"addOneFace " << nb_face_to_add;
1235 mesh->faceFamily()->itemsUniqueIdToLocalId(face_lid, faces_uids,
true);
1236 debug() <<
"NB_FACE_ADDED AFTER " << face_lid.
size() <<
" " << new_faces.size();
1241 mesh->modifier()->detachCells(cells_to_detach);
1244 mesh->modifier()->addCells(nb_cell_to_add, cells_to_add.
constView(), cells_lid);
1245 info() <<
"After addCells";
1249 mesh->cellFamily()->itemsUniqueIdToLocalId(child_cells_lid, child_cells,
true);
1280 mesh->faceFamily()->itemsUniqueIdToLocalId(face_external_lid, face_external_uid);
1286 if (group.
isOwn() &&
mesh->parallelMng()->isParallel()) {
1287 info() <<
"#groups: OWN";
1291 info() <<
"#groups: ALLITEMS";
1294 info() <<
"#groups: Added ";
1298 Int64 step = parents_to_childs_faces_groups[iitem->uniqueId().asInt64()].first;
1299 Int64 n_childs = parents_to_childs_faces_groups[iitem->uniqueId().asInt64()].second;
1300 auto subview = face_external_lid.
subView(step,
static_cast<Integer>(n_childs));
1304 group.
addItems(to_add_to_group,
true);
1311 if (group.
isOwn() &&
mesh->parallelMng()->isParallel()) {
1312 info() <<
"#groups: OWN";
1316 info() <<
"#groups: ALLITEMS";
1320 info() <<
"#groups: Added ";
1324 Int64 step = parents_to_childs_cell[iitem->uniqueId().asInt64()].first;
1325 Int64 n_childs = parents_to_childs_cell[iitem->uniqueId().asInt64()].second;
1326 auto subview = child_cells_lid.
subView(step,
static_cast<Integer>(n_childs));
1329 info() <<
"#Added " << to_add_to_group.
size() <<
" to group " << group.
fullName();
1330 group.
addItems(to_add_to_group,
true);
1333 mesh->modifier()->removeDetachedCells(cells_to_detach.
constView());
1335 mesh->modifier()->endUpdate();
1338 debug() <<
"Debug faces " << faces_to_add;
1350 mesh->cellFamily()->notifyItemsOwnerChanged();
1353 ARCANE_ASSERT((nodes_lid.
size() == nodes_to_add.
size()), (
"End"));
1357 mesh->nodeFamily()->itemsUniqueIdToLocalId(to_add_to_nodes, nodes_to_add,
true);
1366 nodes_coords[node] = nodes_to_add_coords[node.
uniqueId().asInt64()];
1367 debug() <<
"InSBD" << node.
uniqueId().asInt64() <<
" " << nodes_to_add_coords[node.
uniqueId().asInt64()];
1374 mesh->updateGhostLayers(
true);
1382 node_uid_to_owner[node.
uniqueId().asInt64()] = cell.
owner();
1391 face_uid_to_owner[face.
uniqueId().asInt64()] = cell.
owner();
1400 mesh->updateGhostLayers(
true);
1411 debug() <<
"nbface " <<
mesh->nbFace() <<
" " << nb_face_to_add <<
" expected " << nb_face_init * 4 + 12 * nb_cell_init;
1421 mesh->nodeFamily()->notifyItemsOwnerChanged();
1428 mesh->faceFamily()->notifyItemsOwnerChanged();
1432 mesh->updateGhostLayers(
true);
1453 std::unordered_map<Int64, Real3> nodes_to_add_coords;
1457 Int64 max_offset = 0;
1466 info() <<
"#_refineWithArcaneFaces";
1468 const Cell& cell = *icell;
1469 info() <<
"cell[" << icell->localId() <<
"," << icell->uniqueId() <<
"] type="
1470 << icell->type() <<
", nb nodes=" << icell->nbNode();
1473 info() <<
"Face " << face.uniqueId() <<
" nodes ";
1474 for (
Node node : face.nodes()) {
1475 info() << node.uniqueId() <<
" ";
1480 ARCANE_ASSERT((!p.
cells.
empty()), (
"Pattern not init"));
1484 Int64 face_count = 0;
1486 std::map<Int64, Int32> node_uid_to_cell_local_id;
1490 const Cell& cell = *icell;
1493 info() <<
"Get Pattern";
1494 StorageRefine& node_pattern = p.
nodes;
1495 StorageRefine& cells = p.
cells;
1497 info() <<
"Get Nodes";
1502 info() <<
"Node pattern " << node_pattern.
size() <<
"nic " << node_in_cell;
1505 for (
Integer i = 0; i < node_pattern.
size(); i++) {
1506 info() <<
"test " << i;
1511 node_in_cell.
add(uid);
1516 for (
Integer j = 0; j < node_pattern[i].
size(); j++) {
1517 middle_coord += nodes_coords[cell.
node(
static_cast<Int32>(node_pattern[i][j]))];
1518 info() << node_pattern[i][j] << cell.
node(
static_cast<Int32>(node_pattern[i][j]));
1520 middle_coord /= node_pattern[i].
size();
1521 nodes_to_add_coords[uid] = middle_coord;
1522 info() <<
"NodeX " << uid <<
" " <<
" coord " << nodes_to_add_coords[uid] <<
" " << middle_coord;
1523 node_uid_to_cell_local_id[uid] = cell.
nbNode() + i;
1526 info() <<
"#node in cell " << node_in_cell;
1545 cells_infos.
add(max_offset);
1547 info() <<
"Cell " << i;
1549 info() <<
"test2bis " << node_in_cell[cells[i][j]] <<
" " << node_in_cell.
size() <<
" " << node_pattern.
size();
1550 cells_infos.
add(node_in_cell[cells[i][j]]);
1554 info() <<
"test2bisbis ";
1555 for (
Integer i = 0; i < node_in_cell.
size(); i++) {
1556 info() <<
"node_in_cell[ " << i <<
" ] " << node_in_cell[i];
1562 info() <<
"test3 " << nodes_uid.
size() <<
" " << nodes_lid.
size();
1566 modifier->
addNodes(nodes_uid, nodes_lid);
1567 info() <<
"After nodes";
1570 info() <<
"After faces";
1573 modifier->
addCells(cellcount, cells_infos, cells_lid);
1574 info() <<
"cellsize " << cells_infos.
size() <<
" " << cellcount;
1582 mesh->nodeFamily()->itemsUniqueIdToLocalId(to_add_to_nodes, nodes_uid,
true);
1584 info() <<
"#NODESHERE";
1587 coords_bis[node] = nodes_to_add_coords[node.
uniqueId()];
1589 info() << node.
uniqueId() <<
" " << nodes_coords[node];
1594 info() <<
"#coords" << coords_bis.asArray();
1595 info() <<
"#My mesh ";
1599 const Cell& cell = *icell;
1602 for (
Node node : face.nodes()) {
1603 stuff.
add(node.uniqueId());
1605 info() <<
"Faces " << face.uniqueId() <<
" node " << stuff;
1609 info() <<
"#Arcane face numbering:";
1612 const Face& face = *iface;
1614 std::cout <<
"{" << face.
nodes()[0].uniqueId().asInt64();
1617 std::cout <<
"," << face.
nodes()[i].uniqueId().asInt64();
1624 std::cout <<
"}," << std::endl;
1637 (*arcane_cell_uid)[icell] = icell->uniqueId().asInt64();
1640 (*arcane_face_uid)[iface] = iface->uniqueId().asInt64();
1644 (*arcane_node_uid)[inode] = inode->uniqueId().asInt64();
1645 info() << inode->uniqueId().asInt64();
1686 info() <<
"#ENDSUBDV ";
1691 mesh->utilities()->writeToFile(
"subdivider_one_quad_input.vtk",
"VtkLegacyMeshWriter");
1696 info() <<
"cell[" << icell->localId() <<
"," << icell->uniqueId() <<
"] type="
1697 << icell->type() <<
", nb nodes=" << icell->nbNode();
1698 lids[icell.index()] = icell->localId();
1706 for (
Integer i = 0; i < 4; i++)
1711 mesh->nodeFamily()->endUpdate();
1714 nodes_coords[new_nodes[nodes_lid[0]]] =
Arcane::Real3(0.0, 0.0, 0.0);
1715 nodes_coords[new_nodes[nodes_lid[1]]] =
Arcane::Real3(10.0, 0.0, 0.0);
1716 nodes_coords[new_nodes[nodes_lid[2]]] =
Arcane::Real3(10.0, 10.0, 0.0);
1717 nodes_coords[new_nodes[nodes_lid[3]]] =
Arcane::Real3(0.0, 10.0, 0.0);
1721 cells_infos[0] = IT_Quad4;
1722 cells_infos[1] = 44;
1723 cells_infos[2] = nodes_uid[0];
1724 cells_infos[3] = nodes_uid[1];
1725 cells_infos[4] = nodes_uid[2];
1726 cells_infos[5] = nodes_uid[3];
1729 modifier->
addCells(1, cells_infos, cells_lid);
1731 mesh->utilities()->writeToFile(
"subdivider_one_quad_ouput.vtk",
"VtkLegacyMeshWriter");
1737 mesh->utilities()->writeToFile(
"subdivider_one_hexa_input.vtk",
"VtkLegacyMeshWriter");
1741 info() <<
"cell[" << icell->localId() <<
"," << icell->uniqueId() <<
"] type="
1742 << icell->type() <<
", nb nodes=" << icell->nbNode();
1743 lids[icell.index()] = icell->localId();
1750 for (
Integer i = 0; i < 3; i++)
1755 mesh->nodeFamily()->endUpdate();
1758 nodes_coords[new_nodes[nodes_lid[0]]] =
Arcane::Real3(0.0, 0.0, 0.0);
1759 nodes_coords[new_nodes[nodes_lid[1]]] =
Arcane::Real3(10.0, 0.0, 0.0);
1760 nodes_coords[new_nodes[nodes_lid[2]]] =
Arcane::Real3(10.0, 10.0, 0.0);
1764 cells_infos[0] = IT_Triangle3;
1765 cells_infos[1] = 44;
1766 cells_infos[2] = nodes_uid[0];
1767 cells_infos[3] = nodes_uid[1];
1768 cells_infos[4] = nodes_uid[2];
1771 modifier->
addCells(1, cells_infos, cells_lid);
1773 mesh->utilities()->writeToFile(
"subdivider_one_tri.vtk",
"VtkLegacyMeshWriter");
1780 for (
Integer i = 0; i < node_pattern.
size(); i++) {
1783 tmp.
resize(node_pattern[i].size());
1784 for (
Integer j = 0; j < node_pattern[i].
size(); j++) {
1785 tmp.
add(node_in_cell[node_pattern[i][j]]);
1789 node_in_cell.
add(init_size + i);
1790 new_node_uid.
add(node_in_cell[init_size + i]);
1792 return new_node_uid;
1795ArcaneBasicMeshSubdividerService::
1803 mesh->utilities()->writeToFile(
"subdivider_one_hexa_input.vtk",
"VtkLegacyMeshWriter");
1807 info() <<
"cell[" << icell->localId() <<
"," << icell->uniqueId() <<
"] type="
1808 << icell->type() <<
", nb nodes=" << icell->nbNode();
1809 lids[icell.index()] = icell->localId();
1816 for (
Integer i = 0; i < 8; i++)
1821 mesh->nodeFamily()->endUpdate();
1824 nodes_coords[new_nodes[nodes_lid[0]]] =
Arcane::Real3(0.0, 0.0, 0.0);
1825 nodes_coords[new_nodes[nodes_lid[1]]] =
Arcane::Real3(10.0, 0.0, 0.0);
1826 nodes_coords[new_nodes[nodes_lid[2]]] =
Arcane::Real3(10.0, 10.0, 0.0);
1827 nodes_coords[new_nodes[nodes_lid[3]]] =
Arcane::Real3(0.0, 10.0, 0.0);
1828 nodes_coords[new_nodes[nodes_lid[4]]] =
Arcane::Real3(0.0, 0.0, 10.0);
1829 nodes_coords[new_nodes[nodes_lid[5]]] =
Arcane::Real3(10.0, 0.0, 10.0);
1830 nodes_coords[new_nodes[nodes_lid[6]]] =
Arcane::Real3(10.0, 10.0, 10.0);
1831 nodes_coords[new_nodes[nodes_lid[7]]] =
Arcane::Real3(0.0, 10.0, 10.0);
1835 cells_infos[0] = IT_Hexaedron8;
1836 cells_infos[1] = 44;
1837 cells_infos[2] = nodes_uid[0];
1838 cells_infos[3] = nodes_uid[1];
1839 cells_infos[4] = nodes_uid[2];
1840 cells_infos[5] = nodes_uid[3];
1841 cells_infos[6] = nodes_uid[4];
1842 cells_infos[7] = nodes_uid[5];
1843 cells_infos[8] = nodes_uid[6];
1844 cells_infos[9] = nodes_uid[7];
1847 modifier->
addCells(1, cells_infos, cells_lid);
1856 mesh->faceFamily()->itemsUniqueIdToLocalId(face_lid, face_uid,
true);
1857 mesh->faceFamily()->createGroup(
"GroupeTest", face_lid);
1858 mesh->utilities()->writeToFile(
"subdivider_one_hexa_ouput.vtk",
"VtkLegacyMeshWriter");
1864 mesh->utilities()->writeToFile(
"subdivider_one_tetra_input.vtk",
"VtkLegacyMeshWriter");
1870 info() <<
"cell[" << icell->localId() <<
"," << icell->uniqueId() <<
"] type="
1871 << icell->type() <<
", nb nodes=" << icell->nbNode();
1872 lids[icell.index()] = icell->localId();
1880 info() <<
"===================== THE MESH IS EMPTY";
1884 for (
Integer i = 0; i < 4; i++)
1889 mesh->nodeFamily()->endUpdate();
1890 info() <<
"===================== THE MESH IS EMPTY";
1894 nodes_coords[new_nodes[nodes_lid[0]]] =
Arcane::Real3(0.0, 0.0, 0.0);
1895 nodes_coords[new_nodes[nodes_lid[1]]] =
Arcane::Real3(10.0, 0.0, 0.0);
1896 nodes_coords[new_nodes[nodes_lid[2]]] =
Arcane::Real3(5.0, 5.0 / 3.0, 10.0);
1897 nodes_coords[new_nodes[nodes_lid[3]]] =
Arcane::Real3(5.0, 5.0, 0.0);
1902 cells_infos[0] = IT_Tetraedron4;
1903 cells_infos[1] = 44;
1904 cells_infos[2] = nodes_uid[0];
1905 cells_infos[3] = nodes_uid[1];
1906 cells_infos[4] = nodes_uid[2];
1907 cells_infos[5] = nodes_uid[3];
1910 modifier->
addCells(1, cells_infos, cells_lid);
1920 mesh->faceFamily()->itemsUniqueIdToLocalId(face_lid, face_uid,
true);
1921 mesh->faceFamily()->createGroup(
"GroupeTest", face_lid);
1923 info() <<
"===================== THE CELLS ARE ADDED";
1929 mesh->utilities()->writeToFile(
"3D_last_input_seq.vtk",
"VtkLegacyMeshWriter");
1930 info() <<
"#ORDRE FACES";
1933 const Cell& cell = *icell;
1936 for (
Node node : face.nodes()) {
1937 n.
add(node.uniqueId().asInt64());
1939 info() << face.uniqueId() <<
" nodes " << n;
1947 std::unordered_map<Arccore::Int16, MeshSubdivider::Pattern> pattern_manager;
1949 pattern_manager[IT_Quad4] = PatternBuilder::quadtoquad();
1950 pattern_manager[IT_Triangle3] = PatternBuilder::tritotri();
1951 pattern_manager[IT_Hexaedron8] = PatternBuilder::hextohex();
1952 pattern_manager[IT_Tetraedron4] = PatternBuilder::tettotet();
1954 if(
options()->differentElementTypeOutput()){
1955 pattern_manager[IT_Quad4] = PatternBuilder::quadtotri();
1956 pattern_manager[IT_Triangle3] = PatternBuilder::tritoquad();
1957 pattern_manager[IT_Hexaedron8] = PatternBuilder::hextotet24();
1958 pattern_manager[IT_Tetraedron4] = PatternBuilder::tettohex();
1959 info() <<
"The refinement patterns have changed for meshes of the following types: Quad4, Triangle3, Hexaedron8, Tetraedron4." ;
1960 info() <<
"The output element types will be:\nQuad4->Triangle3\nTriangle3->Quad4\nHexaedron8->Tetraedron4\nTetraedron4->Hexaedron8" ;
1965 debug() << i <<
"refine done";
1983ARCANE_REGISTER_SERVICE_ARCANEBASICMESHSUBDIVIDERSERVICE(ArcaneBasicMeshSubdivider,
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions utilitaires sur le maillage.
Int64 generateHashUniqueId(SmallSpan< const Int64 > nodes_unique_id)
Génère un identifiant unique à partir d'une liste d'identifiants de noeuds.
Integer size() const
Nombre d'éléments du vecteur.
bool empty() const
Capacité (nombre d'éléments alloués) du vecteur.
Generation de la classe de base du Service.
ArcaneArcaneBasicMeshSubdividerServiceObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
CaseOptionsArcaneBasicMeshSubdividerService * options() const
Options du jeu de données du service.
Service Arcane un maillage du jeu de données.
static UniqueArray< Int64 > _computeNodeUid(UniqueArray< Int64 > nodes_uid, const StorageRefine &node_pattern)
Calcule le unique id en fonction des noeuds de node_uid.
void _generatePattern2D(IPrimaryMesh *mesh)
Methode pour obtenir les fichier vtk pour les différent pattern disponibles en 2D.
void _generatePattern3D(IPrimaryMesh *mesh)
Methode pour obtenir les fichier vtk pour les différent pattern disponibles en 3D.
void subdivideMesh(IPrimaryMesh *mesh) override
Raffine le maillage un nombre nb-subdivision.
void _generateOneTri(IPrimaryMesh *mesh)
Génère un triangle.
void _generateOneQuad(IPrimaryMesh *mesh)
Génère un quadrilatère.
void _getArcaneOrder(IPrimaryMesh *mesh)
Methode pour avoir la manière dont sont crée les nouvelles faces pour un élément. Utile pour remplir ...
void _generatePattern(IPrimaryMesh *mesh)
Méthode pour générer les motifs sur un seul élément de base.
void _refineOnce(IPrimaryMesh *mesh, std::unordered_map< Arccore::Int16, MeshSubdivider::Pattern > &pattern_manager)
Raffine une fois le maillage avec les motifs présent dans le pattern_manager.
void _generateOneTetra(IPrimaryMesh *mesh)
Génère un tetraèdre.
void _faceOrderArcane(IPrimaryMesh *mesh)
Génère l'ordre des faces arcane pour tout les motifs.
void _refineWithArcaneFaces(IPrimaryMesh *mesh, MeshSubdivider::Pattern p)
Raffine en utilisant les faces d'arcane et le motif (Pattern) p.
void _generateOneHexa(IPrimaryMesh *mesh)
Génère un hexaèdre.
void clear()
Supprime les éléments du tableau.
iterator end()
Itérateur sur le premier élément après la fin du tableau.
ConstArrayView< T > constView() const
Vue constante sur ce tableau.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
ArrayView< T > subView(Int64 abegin, Integer asize)
Sous-vue à partir de l'élément abegin et contenant asize éléments.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void addRange(ConstReferenceType val, Int64 n)
Ajoute n élément de valeur val à la fin du tableau.
ArrayView< T > view() const
Vue mutable sur ce tableau.
iterator begin()
Itérateur sur le premier élément du tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
FaceConnectedListViewType faces() const
Liste des faces de la maille.
Face face(Int32 i) const
i-ème face de la maille
Integer count() const
Nombre d'éléments de la collection.
EnumeratorT< ItemGroup > Enumerator
Cell cell(Int32 i) const
i-ème maille de la face
CellConnectedListViewType cells() const
Liste des mailles de la face.
virtual void setBuilderVersion(Integer n)=0
Positionne la version du constructeur de mailles fantômes. Pour l'instant (version 3....
virtual Integer nbGhostLayer() const =0
Nombre de couches fantômes.
virtual Integer builderVersion() const =0
Version du constructeur de mailles fantômes.
virtual void setNbGhostLayer(Integer n)=0
Positionne le nombre de couches fantômes.
Interface d'une famille d'entités.
virtual ItemGroupCollection groups() const =0
Liste des groupes de cette famille.
virtual Integer nbItem() const =0
Nombre d'entités.
Interface de modification du maillage.
virtual void updateGhostLayers()=0
Mise à jour de la couche fantôme.
virtual void setDynamic(bool v)=0
Positionne la propriété indiquant si le maillage peut évoluer.
virtual void removeCells(Int32ConstArrayView cells_local_id)=0
Supprime des mailles.
virtual void addNodes(Int64ConstArrayView nodes_uid, Int32ArrayView nodes_lid=Int32ArrayView())=0
Ajoute des noeuds.
virtual void addCells(Integer nb_cell, Int64ConstArrayView cell_infos, Int32ArrayView cells_lid=Int32ArrayView())=0
Ajoute des mailles.
virtual void endUpdate()=0
Notifie l'instance de la fin de la modification du maillage.
SentinelType end() const
Itérateur sur après la dernière entité connectée.
const_iterator begin() const
Itérateur sur la première entité connectée.
Groupe d'entités de maillage.
bool isOwn() const
Retourne si le groupe contient uniquement des éléments propres au sous-domaine.
const String & fullName() const
Nom du groupe.
void addItems(Int32ConstArrayView items_local_id, bool check_if_present=true)
Ajoute des entités.
bool isAllItems() const
Indique si le groupe est celui de toutes les entités.
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é
NodeLocalIdView nodeIds() const
Liste des noeuds de l'entité
Classe de base d'un élément de maillage.
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
ItemTypeId itemTypeId() const
Type de l'entité
Int16 type() const
Type de l'entité
Classe Pattern qui permet de manipuler un motif (pattern en anglais) de raffinement.
StorageRefine faces
Matrice pour la génération des nouvelles faces.
StorageRefine cells
Matrice pour la génération des nouvelles cellules.
Int16 type
Type de l'élément a rafiner.
StorageRefine nodes
Matrice pour la génération des nouveaux noeuds.
Int16 face_type
Type de la face de l'élément a rafiner.
Int16 cell_type
Type des cellules enfants.
void setOwner(Integer suid, Int32 current_sub_domain)
Positionne le numéro du sous-domaine propriétaire de l'entité.
Vue sur les informations des noeuds.
Cell cell(Int32 i) const
i-ème maille du noeud
CellConnectedListViewType cells() const
Liste des mailles du noeud.
Classe qui permet de construire des patterns.
Integer arraySize() const
Si la variable est un tableau, retourne sa dimension, sinon retourne 0.
Classe gérant un vecteur de réel de dimension 3.
Structure contenant les informations pour créer un service.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
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.
MeshVariableScalarRefT< Cell, Int64 > VariableCellInt64
Grandeur au centre des mailles de type entier 64 bits.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
MeshVariableScalarRefT< Node, Int64 > VariableNodeInt64
Grandeur au noeud de type entier 64 bits.
MeshVariableScalarRefT< Face, Int64 > VariableFaceInt64
Grandeur aux faces de type entier 64 bits.
VariableRefScalarT< Integer > VariableScalarInteger
Variable scalaire de type entier.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
std::int16_t Int16
Type entier signé sur 16 bits.
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
std::int32_t Int32
Type entier signé sur 32 bits.