14#include "arcane/std/HoneyCombMeshGenerator.h"
16#include "arcane/utils/Real2.h"
18#include "arcane/IMeshBuilder.h"
19#include "arcane/IPrimaryMesh.h"
20#include "arcane/IItemFamily.h"
21#include "arcane/IParallelMng.h"
22#include "arcane/MeshBuildInfo.h"
24#include "arcane/std/HoneyComb2DMeshGenerator_axl.h"
25#include "arcane/std/HoneyComb3DMeshGenerator_axl.h"
42class SimpleSequentialMeshBuilder
51 bool operator()(
const Real3& a,
const Real3& b)
const
64 Real m_epsilon = 1e-14;
69 explicit SimpleSequentialMeshBuilder(
IMesh* pm)
80 auto p = m_nodes_coord_map.find(coord);
81 if (p != m_nodes_coord_map.end())
85 m_nodes_coord_map.insert(std::make_pair(coord, v));
91 m_cells_infos.
add(type);
92 const Int32 v = m_nb_cell;
95 for (
Real3 coord : nodes_coords)
99 ConstArrayView<Int64> cellsInfos()
const {
return m_cells_infos; }
100 Int32 nbCell()
const {
return m_nb_cell; }
102 void setNodesCoordinates()
const
105 UniqueArray<Int64> unique_ids(nb_node);
106 for (
Integer i = 0; i < nb_node; ++i)
108 UniqueArray<Int32> local_ids(nb_node);
109 IItemFamily* node_family = m_mesh->nodeFamily();
110 node_family->itemsUniqueIdToLocalId(local_ids, unique_ids);
113 NodeInfoListView nodes(node_family);
115 for (
Integer i = 0; i < nb_node; ++i) {
116 Node node{ nodes[local_ids[i]] };
123 using CoordMap = std::map<Real3, Int32, Real3Compare>;
125 IMesh* m_mesh =
nullptr;
126 CoordMap m_nodes_coord_map;
128 UniqueArray<Int64> m_cells_infos;
144 Real p = 0.5 * pitch;
146 coords[0] = { x - q, y - p, z };
147 coords[1] = { x + q, y - p, z };
148 coords[2] = { x + 2 * q, y, z };
149 coords[3] = { x + q, y + p, z };
150 coords[4] = { x - q, y + p, z };
151 coords[5] = { x - 2 * q, y, z };
163 CellLineInfo(
Real2 first_center,
Int32 nb_cell)
164 : m_first_center(first_center)
170 Real2 m_first_center;
177HoneyComb2DMeshGenerator::
187void HoneyComb2DMeshGenerator::
203void HoneyComb2DMeshGenerator::
206 SimpleSequentialMeshBuilder simple_mesh_builder(m_mesh);
208 const Real pitch = m_pitch;
209 const Integer nb_ring = m_nb_ring;
211 info() <<
"Build Hexagonal 2D Cells nb_layer=" << nb_ring;
213 UniqueArray<Real3> cell_nodes_coords(6);
214 UniqueArray<CellLineInfo> cells_line_info;
218 Real2 u1(0.5 * pitch *
math::sqrt(3.0), -0.5 * pitch);
219 Real2 u2(0.5 * pitch *
math::sqrt(3.0), 0.5 * pitch);
220 Real2 u3(pitch * 0.0, pitch * 1.0);
223 for (
Integer i = (-nb_ring + 1); i < 1; ++i) {
224 Real x0 = u3[0] * i - u1[0] * (nb_ring - 1);
225 Real y0 = u3[1] * i - u1[1] * (nb_ring - 1);
228 Integer nb_cell_in_line = 2 * nb_ring - 1 + i;
229 cells_line_info.add(
CellLineInfo(pos, nb_cell_in_line));
233 for (
Integer i = 1; i < nb_ring; ++i) {
234 Real x0{ u2[0] * i - u1[0] * (nb_ring - 1) };
235 Real y0{ u2[1] * i - u1[1] * (nb_ring - 1) };
238 Integer nb_cell_in_line = 2 * nb_ring - 1 - i;
239 cells_line_info.add(
CellLineInfo(pos, nb_cell_in_line));
243 Real2 xy = cli.m_first_center;
244 for (
Integer j = 0, n = cli.m_nb_cell; j < n; ++j) {
245 _buildCellNodesCoordinates(m_pitch, xy.x, xy.y, 0.0, cell_nodes_coords);
246 simple_mesh_builder.addCell(IT_Hexagon6, cell_nodes_coords);
251 m_mesh->setDimension(2);
252 m_mesh->allocateCells(simple_mesh_builder.nbCell(), simple_mesh_builder.cellsInfos(),
true);
254 simple_mesh_builder.setNodesCoordinates();
260void HoneyComb2DMeshGenerator::
261generateMesh(Real2 origin,
Real pitch,
Integer nb_ring)
274class HoneyComb2DMeshGeneratorService
291 info() <<
"HoneyComb2DMeshGenerator: allocateMeshItems()";
296 ARCANE_FATAL(
"Invalid valid value '{0}' for pitch (should be > 0.0)", pitch);
298 ARCANE_FATAL(
"Invalid valid value '{0}' for 'nb-layer' (should be > 0)", nb_layer);
299 g.generateMesh(
options()->origin(), pitch, nb_layer);
308ARCANE_REGISTER_SERVICE_HONEYCOMB2DMESHGENERATOR(HoneyComb2D, HoneyComb2DMeshGeneratorService);
322 : m_first_center(first_center)
330 Real2 m_first_center;
339HoneyComb3DMeshGenerator::
349void HoneyComb3DMeshGenerator::
360 ARCANE_FATAL(
"Bad number of heights '{0}' (minimum=2)", nb_height);
361 for (
Integer i = 0; i < (nb_height - 1); ++i)
362 if (m_heights[i] > m_heights[i + 1])
363 ARCANE_FATAL(
"Heights are not increasing ({0} < {1})", m_heights[i], m_heights[i + 1]);
371void HoneyComb3DMeshGenerator::
376 if (pm->commRank() == 0)
387void HoneyComb3DMeshGenerator::
390 SimpleSequentialMeshBuilder simple_mesh_builder(m_mesh);
392 const Real pitch = m_pitch;
393 const Integer nb_ring = m_nb_ring;
394 const Integer nb_height = m_heights.size();
396 ARCANE_FATAL(
"Bad number of heights '{0}' (minimum=2)", nb_height);
397 info() <<
"Build Hexagonal 3D Cells nb_layer=" << nb_ring <<
" nb_height=" << nb_height;
399 UniqueArray<Real3> cell_nodes_coords(12);
400 UniqueArray<CellLineInfo> cells_line_info;
404 Real2 u1(0.5 * pitch *
math::sqrt(3.0), -0.5 * pitch);
405 Real2 u2(0.5 * pitch *
math::sqrt(3.0), 0.5 * pitch);
406 Real2 u3(pitch * 0.0, pitch * 1.0);
408 for (
Integer zz = 0; zz < (nb_height - 1); ++zz) {
410 for (
Integer i = (-nb_ring + 1); i < 1; ++i) {
411 Real x0 = u3[0] * i - u1[0] * (nb_ring - 1);
412 Real y0 = u3[1] * i - u1[1] * (nb_ring - 1);
415 Integer nb_cell_in_line = 2 * nb_ring - 1 + i;
416 cells_line_info.add(
CellLineInfo(pos, m_heights[zz], m_heights[zz + 1], nb_cell_in_line));
420 for (
Integer i = 1; i < nb_ring; ++i) {
421 Real x0{ u2[0] * i - u1[0] * (nb_ring - 1) };
422 Real y0{ u2[1] * i - u1[1] * (nb_ring - 1) };
425 Integer nb_cell_in_line = 2 * nb_ring - 1 - i;
426 cells_line_info.add(
CellLineInfo(pos, m_heights[zz], m_heights[zz + 1], nb_cell_in_line));
431 Real2 xy = cli.m_first_center;
432 for (
Integer j = 0, n = cli.m_nb_cell; j < n; ++j) {
433 _buildCellNodesCoordinates(m_pitch, xy.x, xy.y, cli.m_bottom, cell_nodes_coords.subView(0, 6));
434 _buildCellNodesCoordinates(m_pitch, xy.x, xy.y, cli.m_top, cell_nodes_coords.subView(6, 6));
435 simple_mesh_builder.addCell(IT_Octaedron12, cell_nodes_coords);
440 m_mesh->setDimension(3);
441 m_mesh->allocateCells(simple_mesh_builder.nbCell(), simple_mesh_builder.cellsInfos(),
true);
443 simple_mesh_builder.setNodesCoordinates();
451class HoneyComb3DMeshGeneratorService
468 info() <<
"HoneyComb2DMeshGenerator: allocateMeshItems()";
475 ARCANE_FATAL(
"Invalid valid value '{0}' for pitch (should be > 0.0)", pitch);
477 ARCANE_FATAL(
"Invalid valid value '{0}' for 'nb-layer' (should be > 0)", nb_layer);
479 ARCANE_FATAL(
"Invalid valid value '{0}' for 'nb-height' (should be >= 2)", nb_height);
480 g.generateMesh(
options()->origin(), pitch, nb_layer, heights);
489ARCANE_REGISTER_SERVICE_HONEYCOMB3DMESHGENERATOR(HoneyComb3D, HoneyComb3DMeshGeneratorService);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Integer size() const
Nombre d'éléments du vecteur.
CaseOptionsHoneyComb2DMeshGenerator * options() const
Options du jeu de données du service.
ArcaneHoneyComb2DMeshGeneratorObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
ArcaneHoneyComb3DMeshGeneratorObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
CaseOptionsHoneyComb3DMeshGenerator * options() const
Options du jeu de données du service.
Vue modifiable d'un tableau d'un type T.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
void fillMeshBuildInfo(MeshBuildInfo &build_info) override
Remplit build_info avec les informations nécessaires pour créer le maillage.
void allocateMeshItems(IPrimaryMesh *pm) override
Alloue les entités du maillage géré par ce service.
void allocateMeshItems(IPrimaryMesh *pm) override
Alloue les entités du maillage géré par ce service.
void fillMeshBuildInfo(MeshBuildInfo &build_info) override
Remplit build_info avec les informations nécessaires pour créer le maillage.
Infos sur une ligne d'hexagone.
virtual IParallelMng * parallelMng()=0
Gestionnaire de parallèlisme.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual void allocateCells(Integer nb_cell, Int64ConstArrayView cells_infos, bool one_alloc=true)=0
Allocation d'un maillage.
virtual void setDimension(Integer dim)=0
Positionne la dimension du maillage (1D, 2D ou 3D).
Paramètres nécessaires à la construction d'un maillage.
MeshBuildInfo & addNeedPartitioning(bool v)
Indique si le générateur nécessite d'appeler un partitionneur.
Classe gérant un vecteur réel 2-dimensionnel.
Classe gérant un vecteur réel de 3 dimensions.
Structure contenant les informations pour créer un service.
UniqueArray< Real3 > m_nodes_coordinates
Correspondante uid->coord pour les noeuds.
Int32 addNode(Real3 coord)
Ajoute ou récupère l'uniqueId() du noeud de coordonnées coord.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
constexpr __host__ __device__ bool isNearlyEqualWithEpsilon(const Type &a, const Type &b, const Type &epsilon)
Teste si deux valeurs sont approximativement égales. Pour les types entiers, cette fonction est équiv...
apfloat sqrt(apfloat v)
Racine carrée de v.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type représentant un entier.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
double Real
Type représentant un réel.
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