14#include "arcane/std/HoneyCombMeshGenerator.h"
16#include "arcane/utils/Real2.h"
18#include "arcane/core/IMeshBuilder.h"
19#include "arcane/core/IPrimaryMesh.h"
20#include "arcane/core/IItemFamily.h"
21#include "arcane/core/IParallelMng.h"
22#include "arcane/core/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)
275class HoneyComb2DMeshGeneratorService
292 info() <<
"HoneyComb2DMeshGenerator: allocateMeshItems()";
297 ARCANE_FATAL(
"Invalid valid value '{0}' for pitch (should be > 0.0)", pitch);
299 ARCANE_FATAL(
"Invalid valid value '{0}' for 'nb-layer' (should be > 0)", nb_layer);
300 g.generateMesh(
options()->origin(), pitch, nb_layer);
309ARCANE_REGISTER_SERVICE_HONEYCOMB2DMESHGENERATOR(HoneyComb2D, HoneyComb2DMeshGeneratorService);
323 : m_first_center(first_center)
331 Real2 m_first_center;
340HoneyComb3DMeshGenerator::
350void HoneyComb3DMeshGenerator::
361 ARCANE_FATAL(
"Bad number of heights '{0}' (minimum=2)", nb_height);
362 for (
Integer i = 0; i < (nb_height - 1); ++i)
363 if (m_heights[i] > m_heights[i + 1])
364 ARCANE_FATAL(
"Heights are not increasing ({0} < {1})", m_heights[i], m_heights[i + 1]);
372void HoneyComb3DMeshGenerator::
377 if (pm->commRank() == 0)
388void HoneyComb3DMeshGenerator::
391 SimpleSequentialMeshBuilder simple_mesh_builder(m_mesh);
393 const Real pitch = m_pitch;
394 const Integer nb_ring = m_nb_ring;
395 const Integer nb_height = m_heights.size();
397 ARCANE_FATAL(
"Bad number of heights '{0}' (minimum=2)", nb_height);
398 info() <<
"Build Hexagonal 3D Cells nb_layer=" << nb_ring <<
" nb_height=" << nb_height;
400 UniqueArray<Real3> cell_nodes_coords(12);
401 UniqueArray<CellLineInfo> cells_line_info;
405 Real2 u1(0.5 * pitch *
math::sqrt(3.0), -0.5 * pitch);
406 Real2 u2(0.5 * pitch *
math::sqrt(3.0), 0.5 * pitch);
407 Real2 u3(pitch * 0.0, pitch * 1.0);
409 for (
Integer zz = 0; zz < (nb_height - 1); ++zz) {
411 for (
Integer i = (-nb_ring + 1); i < 1; ++i) {
412 Real x0 = u3[0] * i - u1[0] * (nb_ring - 1);
413 Real y0 = u3[1] * i - u1[1] * (nb_ring - 1);
416 Integer nb_cell_in_line = 2 * nb_ring - 1 + i;
417 cells_line_info.add(
CellLineInfo(pos, m_heights[zz], m_heights[zz + 1], nb_cell_in_line));
421 for (
Integer i = 1; i < nb_ring; ++i) {
422 Real x0{ u2[0] * i - u1[0] * (nb_ring - 1) };
423 Real y0{ u2[1] * i - u1[1] * (nb_ring - 1) };
426 Integer nb_cell_in_line = 2 * nb_ring - 1 - i;
427 cells_line_info.add(
CellLineInfo(pos, m_heights[zz], m_heights[zz + 1], nb_cell_in_line));
432 Real2 xy = cli.m_first_center;
433 for (
Integer j = 0, n = cli.m_nb_cell; j < n; ++j) {
434 _buildCellNodesCoordinates(m_pitch, xy.x, xy.y, cli.m_bottom, cell_nodes_coords.subView(0, 6));
435 _buildCellNodesCoordinates(m_pitch, xy.x, xy.y, cli.m_top, cell_nodes_coords.subView(6, 6));
436 simple_mesh_builder.addCell(IT_Octaedron12, cell_nodes_coords);
441 m_mesh->setDimension(3);
442 m_mesh->allocateCells(simple_mesh_builder.nbCell(), simple_mesh_builder.cellsInfos(),
true);
444 simple_mesh_builder.setNodesCoordinates();
453class HoneyComb3DMeshGeneratorService
470 info() <<
"HoneyComb2DMeshGenerator: allocateMeshItems()";
477 ARCANE_FATAL(
"Invalid valid value '{0}' for pitch (should be > 0.0)", pitch);
479 ARCANE_FATAL(
"Invalid valid value '{0}' for 'nb-layer' (should be > 0)", nb_layer);
481 ARCANE_FATAL(
"Invalid valid value '{0}' for 'nb-height' (should be >= 2)", nb_height);
482 g.generateMesh(
options()->origin(), pitch, nb_layer, heights);
491ARCANE_REGISTER_SERVICE_HONEYCOMB3DMESHGENERATOR(HoneyComb3D, HoneyComb3DMeshGeneratorService);
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Integer size() const
Number of elements in the vector.
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.
Modifiable view of an array of type T.
void add(ConstReferenceType val)
Adds element val to the end of the array.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
void fillMeshBuildInfo(MeshBuildInfo &build_info) override
Fills build_info with the necessary information to create the mesh.
void allocateMeshItems(IPrimaryMesh *pm) override
Allocates the mesh entities managed by this service.
void allocateMeshItems(IPrimaryMesh *pm) override
Allocates the mesh entities managed by this service.
void fillMeshBuildInfo(MeshBuildInfo &build_info) override
Fills build_info with the necessary information to create the mesh.
Info about a line of hexagons.
virtual IParallelMng * parallelMng()=0
Parallelism manager.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual void allocateCells(Integer nb_cell, Int64ConstArrayView cells_infos, bool one_alloc=true)=0
Allocation of a mesh.
virtual void setDimension(Integer dim)=0
Positions the mesh dimension (1D, 2D, or 3D).
Parameters necessary for building a mesh.
MeshBuildInfo & addNeedPartitioning(bool v)
Indicates whether the generator needs to call a partitioner.
Class managing a 2-dimensional real vector.
Class managing a 3-dimensional real vector.
Structure containing the information to create a service.
UniqueArray< Real3 > m_nodes_coordinates
uid->coord correspondence for nodes
Int32 addNode(Real3 coord)
Adds or retrieves the uniqueId() of the node with coordinates coord.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
__host__ __device__ double sqrt(double v)
Square root of v.
constexpr __host__ __device__ bool isNearlyEqualWithEpsilon(const _Type &a, const _Type &b, const _Type &epsilon)
Tests if two values are approximately equal. For integer types, this function is equivalent to IsEqua...
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
double Real
Type representing a real number.
std::int32_t Int32
Signed integer type of 32 bits.
Real y
second component of the triplet
Real z
third component of the triplet
Real x
first component of the triplet