14#include "arcane/std/CartesianMeshGenerator.h"
16#include "arcane/utils/Array.h"
17#include "arcane/utils/HashTableMap.h"
18#include "arcane/utils/PlatformUtils.h"
19#include "arcane/utils/ITraceMng.h"
20#include "arcane/utils/Real3.h"
21#include "arcane/utils/ValueConvert.h"
22#include "arcane/utils/CheckedConvert.h"
23#include "arcane/utils/Vector3.h"
24#include "arcane/utils/Vector2.h"
26#include "arcane/core/IMeshReader.h"
27#include "arcane/core/ISubDomain.h"
28#include "arcane/core/ICaseDocument.h"
29#include "arcane/core/XmlNode.h"
30#include "arcane/core/XmlNodeList.h"
31#include "arcane/core/XmlNodeIterator.h"
32#include "arcane/core/Service.h"
33#include "arcane/core/IParallelMng.h"
34#include "arcane/core/Item.h"
35#include "arcane/core/ItemGroup.h"
36#include "arcane/core/IMesh.h"
37#include "arcane/core/IMeshSubMeshTransition.h"
38#include "arcane/core/IItemFamily.h"
39#include "arcane/core/MeshVariable.h"
41#include "arcane/core/ItemPrinter.h"
42#include "arcane/core/FactoryService.h"
43#include "arcane/core/AbstractService.h"
44#include "arcane/core/Properties.h"
45#include "arcane/core/MeshPartInfo.h"
46#include "arcane/core/IMeshBuilder.h"
47#include "arcane/core/IMeshUniqueIdMng.h"
48#include "arcane/core/IMeshInitialAllocator.h"
49#include "arcane/core/ICartesianMeshGenerationInfo.h"
50#include "arcane/core/CartesianMeshAllocateBuildInfo.h"
51#include "arcane/core/internal/CartesianMeshAllocateBuildInfoInternal.h"
53#include "arcane/std/Cartesian2DMeshGenerator_axl.h"
54#include "arcane/std/Cartesian3DMeshGenerator_axl.h"
56#include "arcane/std/internal/SodStandardGroupsBuilder.h"
67void CartesianMeshGeneratorBuildInfo::
68readOptionsFromXml(
XmlNode cartesian_node)
70 XmlNode origine_node = cartesian_node.child(
"origine");
71 XmlNode nsd_node = cartesian_node.child(
"nsd");
72 XmlNodeList lx_node_list = cartesian_node.children(
"lx");
73 XmlNodeList ly_node_list = cartesian_node.children(
"ly");
74 XmlNodeList lz_node_list = cartesian_node.children(
"lz");
77 if (origine_node.null())
79 if (lx_node_list.size() == 0)
81 if (ly_node_list.size() == 0)
84 String origine_value = origine_node.value();
86 bool is_bad_origin = builtInGetValue(m_origine, origine_value);
89 if (lz_node_list.size() == 0) {
94 is_bad_origin = builtInGetValue(xy, origine_value);
102 m_mesh_dimension = 3;
105 ARCANE_FATAL(
"Element '{0}' : can not convert value '{1}' to type Real3", origine_node.xpathFullName(), origine_value);
111 for (XmlNode& lx_node : lx_node_list) {
112 m_bloc_lx.add(lx_node.valueAsReal(
true));
113 m_bloc_nx.add(lx_node.attr(
"nx",
true).valueAsInteger(
true));
114 Real px = lx_node.attr(
"prx").valueAsReal(
true);
119 for (XmlNode& ly_node : ly_node_list) {
120 m_bloc_ly.add(ly_node.valueAsReal(
true));
121 m_bloc_ny.add(ly_node.attr(
"ny",
true).valueAsInteger(
true));
122 Real py = ly_node.attr(
"pry").valueAsReal(
true);
127 if (m_mesh_dimension == 3) {
128 for (XmlNode& lz_node : lz_node_list) {
129 m_bloc_lz.add(lz_node.valueAsReal(
true));
130 m_bloc_nz.add(lz_node.attr(
"nz",
true).valueAsInteger(
true));
131 Real pz = lz_node.attr(
"prz").valueAsReal(
true);
139 String nsd_value = nsd_node.value();
141 if (builtInGetValue(nsd, nsd_value))
142 ARCANE_FATAL(
"Can not convert string '{0}' to Int[]", nsd_value);
143 if (nsd.size() != m_mesh_dimension)
144 ARCANE_FATAL(
"Number of sub-domain '<nsd>={0}' has to be equal to mesh dimension '{1}'",
145 nsd.size(), m_mesh_dimension);
149 m_nsdz = (m_mesh_dimension == 3) ? nsd[2] : 0;
152 XmlNode version_node = cartesian_node.child(
"face-numbering-version");
153 if (!version_node.null()) {
154 Int32 v = version_node.valueAsInteger(
true);
160 XmlNode version_node = cartesian_node.child(
"edge-numbering-version");
161 if (!version_node.null()) {
162 Int32 v = version_node.valueAsInteger(
true);
175CartesianMeshGenerator::
179, m_my_mesh_part(
mesh->parallelMng()->commRank())
186bool CartesianMeshGenerator::
187readOptions(XmlNode cartesian_node)
189 m_build_info.readOptionsFromXml(cartesian_node);
190 return _readOptions();
196void CartesianMeshGenerator::
197setBuildInfo(
const CartesianMeshGeneratorBuildInfo& build_info)
199 m_build_info = build_info;
209bool CartesianMeshGenerator::
214 m_mesh_dimension = m_build_info.m_mesh_dimension;
215 Int32 nb_sub_domain = m_mesh->parallelMng()->commSize();
218 if (m_build_info.m_nsdx == 0 || nb_sub_domain == 1)
219 m_build_info.m_nsdx = 1;
220 if (m_build_info.m_nsdy == 0 || nb_sub_domain == 1)
221 m_build_info.m_nsdy = 1;
222 if (m_build_info.m_nsdz == 0 || nb_sub_domain == 1)
223 m_build_info.m_nsdz = 1;
226 m_l.x = m_l.y = m_l.z = 0.;
227 for (
int i = 0; i < m_build_info.m_bloc_lx.size(); i += 1)
228 m_l.x += m_build_info.m_bloc_lx.at(i);
229 for (
int i = 0; i < m_build_info.m_bloc_ly.size(); i += 1)
230 m_l.y += m_build_info.m_bloc_ly.at(i);
231 if (m_mesh_dimension == 3)
232 for (
int i = 0; i < m_build_info.m_bloc_lz.size(); i += 1)
233 m_l.z += m_build_info.m_bloc_lz.at(i);
236 m_bloc_ox.add(m_build_info.m_origine.x);
237 m_bloc_oy.add(m_build_info.m_origine.y);
238 if (m_mesh_dimension == 3)
239 m_bloc_oz.add(m_build_info.m_origine.z);
240 for (
int i = 0; i < m_build_info.m_bloc_lx.size(); i += 1)
241 m_bloc_ox.add(m_bloc_ox.at(i) + m_build_info.m_bloc_lx.at(i));
242 for (
int i = 0; i < m_build_info.m_bloc_ly.size(); i += 1)
243 m_bloc_oy.add(m_bloc_oy.at(i) + m_build_info.m_bloc_ly.at(i));
244 if (m_mesh_dimension == 3)
245 for (
int i = 0; i < m_build_info.m_bloc_lz.size(); i += 1)
246 m_bloc_oz.add(m_bloc_oz.at(i) + m_build_info.m_bloc_lz.at(i));
249 m_nx = m_ny = m_nz = 0;
251 for (
int i = 0; i < m_build_info.m_bloc_nx.size(); ++i)
252 m_nx += m_build_info.m_bloc_nx.at(i);
253 for (
int i = 0; i < m_build_info.m_bloc_ny.size(); ++i)
254 m_ny += m_build_info.m_bloc_ny.at(i);
256 if (m_mesh_dimension == 3)
257 for (
int i = 0; i < m_build_info.m_bloc_nz.size(); i += 1)
258 m_nz += m_build_info.m_bloc_nz.at(i);
263 info() <<
" mesh_name=" << m_mesh->name();
264 info() <<
" dimension=" << m_mesh_dimension;
265 info() <<
" origin:" << m_build_info.m_origine;
266 info() <<
" length x =" << m_l.x <<
"," << m_build_info.m_bloc_lx;
267 info() <<
" length y=" << m_l.y <<
"," << m_build_info.m_bloc_ly;
268 if (m_build_info.m_mesh_dimension == 3)
269 info() <<
" length z=" << m_l.z <<
"," << m_build_info.m_bloc_lz;
270 info() <<
"cells number:" << m_nx <<
"x" << m_ny <<
"x" << m_nz;
271 info() <<
"progression x:" << m_build_info.m_bloc_px;
272 info() <<
"progression y:" << m_build_info.m_bloc_py;
273 if (m_mesh_dimension == 3)
274 info() <<
"progression z:" << m_build_info.m_bloc_pz;
275 info() <<
" nb_sub_domain:" << nb_sub_domain;
276 info() <<
" decomposing the subdomains:" << m_build_info.m_nsdx <<
"x"
277 << m_build_info.m_nsdy <<
"x" << m_build_info.m_nsdz;
280 if (m_build_info.m_nsdx * m_build_info.m_nsdy * m_build_info.m_nsdz != nb_sub_domain)
281 ARCANE_FATAL(
"Specified partition {0}x{1}x{2} has to be equal to number of parts ({3})",
282 m_build_info.m_nsdx, m_build_info.m_nsdy, m_build_info.m_nsdz, nb_sub_domain);
292inline Integer CartesianMeshGenerator::
293sdXOffset(
Int32 this_sub_domain_id)
295 return this_sub_domain_id % m_build_info.m_nsdx;
298inline Integer CartesianMeshGenerator::
299sdYOffset(Int32 this_sub_domain_id)
301 return (this_sub_domain_id / m_build_info.m_nsdx) % m_build_info.m_nsdy;
304inline Integer CartesianMeshGenerator::
305sdZOffset(Int32 this_sub_domain_id)
307 return (this_sub_domain_id / (m_build_info.m_nsdx * m_build_info.m_nsdy)) % m_build_info.m_nsdz;
310inline Integer CartesianMeshGenerator::
313 return sdXOffset(m_my_mesh_part);
316inline Integer CartesianMeshGenerator::
319 return sdYOffset(m_my_mesh_part);
322inline Integer CartesianMeshGenerator::
325 return sdZOffset(m_my_mesh_part);
333inline Int32 ownNbCell(Int64 n, Integer nsd,
int sd_offset)
339 return CheckedConvert::toInt32(q);
341 if (sd_offset < (nsd - r))
342 return CheckedConvert::toInt32(q);
343 return CheckedConvert::toInt32(q + 1);
346inline Int32 CartesianMeshGenerator::
349 return ownNbCell(m_nx, m_build_info.m_nsdx, sdXOffset());
351inline Int32 CartesianMeshGenerator::
354 return ownNbCell(m_nx, m_build_info.m_nsdx, sdXOffset(isd));
356inline Int32 CartesianMeshGenerator::
359 return ownNbCell(m_ny, m_build_info.m_nsdy, sdYOffset());
361inline Int32 CartesianMeshGenerator::
364 return ownNbCell(m_ny, m_build_info.m_nsdy, sdYOffset(isd));
366inline Int32 CartesianMeshGenerator::
369 return ownNbCell(m_nz, m_build_info.m_nsdz, sdZOffset());
371inline Int32 CartesianMeshGenerator::
374 return ownNbCell(m_nz, m_build_info.m_nsdz, sdZOffset(isd));
382 const RealArray& bloc_p,
383 const Int32Array& bloc_n,
384 const RealArray& bloc_l,
388 Real p = bloc_p.at(iBloc);
389 Real n = (Real)bloc_n.at(iBloc);
390 Real l = bloc_l.at(iBloc);
392 return all_l / (Real)all_n;
393 return (p - 1.0) / (math::pow(p, n) - 1.0) * l;
399 const RealArray& bloc_p,
400 const Int32Array& bloc_n,
401 const RealArray& bloc_l,
405 ARCANE_UNUSED(all_l);
406 ARCANE_UNUSED(all_n);
408 Real p = bloc_p.at(iBloc);
409 Real n = (Real)bloc_n.at(iBloc);
410 Real l = bloc_l.at(iBloc);
413 return l * (math::pow(p, k) - 1.0) / (math::pow(p, (Real)n) - 1.0);
416inline Real CartesianMeshGenerator::
417nxDelta(Real k,
int iBloc)
419 return m_bloc_ox.at(iBloc) + kDelta(k, iBloc, m_build_info.m_bloc_px, m_build_info.m_bloc_nx, m_build_info.m_bloc_lx, m_l.x, m_nx);
421inline Real CartesianMeshGenerator::
424 return iDelta(iBloc, m_build_info.m_bloc_px, m_build_info.m_bloc_nx, m_build_info.m_bloc_lx, m_l.x, m_nx);
427inline Real CartesianMeshGenerator::
428nyDelta(Real k,
int iBloc)
430 return m_bloc_oy.at(iBloc) + kDelta(k, iBloc, m_build_info.m_bloc_py, m_build_info.m_bloc_ny, m_build_info.m_bloc_ly, m_l.y, m_ny);
432inline Real CartesianMeshGenerator::
435 return iDelta(iBloc, m_build_info.m_bloc_py, m_build_info.m_bloc_ny, m_build_info.m_bloc_ly, m_l.y, m_ny);
438inline Real CartesianMeshGenerator::
439nzDelta(Real k,
int iBloc)
441 return m_bloc_oz.at(iBloc) + kDelta(k, iBloc, m_build_info.m_bloc_pz, m_build_info.m_bloc_nz, m_build_info.m_bloc_lz, m_l.z, m_nz);
444inline Real CartesianMeshGenerator::
447 return iDelta(iBloc, m_build_info.m_bloc_pz, m_build_info.m_bloc_nz, m_build_info.m_bloc_lz, m_l.z, m_nz);
455void CartesianMeshGenerator::
456xScan(
const Int64 all_nb_cell_x,
457 IntegerArray& sd_x_ibl,
458 IntegerArray& sd_x_obl,
459 Int64Array& sd_x_nbl,
460 Int64Array& sd_x_node_offset,
461 Int64Array& sd_x_cell_offset)
466 sd_x_node_offset.add(0);
467 sd_x_cell_offset.add(0);
474 for (Int64 x = 0; x < all_nb_cell_x; ++x) {
476 if (x == (nbl + m_build_info.m_bloc_nx.at(ibl))) {
477 nbl += m_build_info.m_bloc_nx.at(ibl);
478 info(4) <<
"\t␛[2;33m[CartesianMeshGenerator::xScan] Scan hit x bloc boundary: @ node " << nbl <<
"␛[0m";
485 if (x == (nsd + ownXNbCell(isd))) {
486 nsd += ownXNbCell(isd);
487 info(4) <<
"\t␛[2;33m[CartesianMeshGenerator::xScan] Scan hit x sub domain boundary: @ node " << nsd <<
"␛[0m";
492 sd_x_node_offset.add(nsd);
493 sd_x_cell_offset.add(nsd);
495 info(4) <<
"\t␛[2;33m[CartesianMeshGenerator::xScan] Saving state: "
496 <<
", node_offset=" << sd_x_node_offset.at(isd)
497 <<
", cell_offset=" << sd_x_cell_offset.at(isd)
498 <<
", ibl=" << sd_x_ibl.at(isd)
499 <<
", nbl=" << sd_x_nbl.at(isd) <<
"␛[0m";
511void CartesianMeshGenerator::
512yScan(
const Integer all_nb_cell_y,
513 IntegerArray& sd_y_ibl,
514 IntegerArray& sd_y_obl,
515 Int64Array& sd_y_nbl,
516 Int64Array& sd_y_node_offset,
517 Int64Array& sd_y_cell_offset,
524 sd_y_node_offset.add(0);
525 sd_y_cell_offset.add(0);
531 for (Int64 y = 0; y < all_nb_cell_y; ++y) {
532 if (y == (nbl + m_build_info.m_bloc_ny.at(ibl))) {
533 nbl += m_build_info.m_bloc_ny.at(ibl);
534 info(4) <<
"\t␛[2;33m[CartesianMeshGenerator::generateMesh] Scan hit y bloc boundary: @ node " << nbl <<
"␛[0m";
538 if (y == (nsd + ownYNbCell(isd))) {
539 nsd += ownYNbCell(isd);
540 info(4) <<
"\t␛[2;33m[CartesianMeshGenerator::generateMesh] Scan hit y sub domain boundary: @ node " << nsd <<
"␛[0m";
543 sd_y_nbl.add(nbl * all_nb_node_x);
544 sd_y_node_offset.add(nsd * all_nb_node_x);
545 sd_y_cell_offset.add(nsd * all_nb_cell_x);
546 isd += m_build_info.m_nsdx;
557void CartesianMeshGenerator::
558zScan(
const Int64 all_nb_cell_z,
559 IntegerArray& sd_z_ibl,
560 IntegerArray& sd_z_obl,
561 Int64Array& sd_z_nbl,
562 Int64Array& sd_z_node_offset,
563 Int64Array& sd_z_cell_offset,
564 Int64 all_nb_node_xy,
565 Int64 all_nb_cell_xy)
567 if (m_mesh_dimension != 3)
572 sd_z_node_offset.add(0);
573 sd_z_cell_offset.add(0);
579 for (Int64 z = 0; z < all_nb_cell_z; ++z) {
580 if (z == (nbl + m_build_info.m_bloc_nz.at(ibl))) {
581 nbl += m_build_info.m_bloc_nz.at(ibl);
585 if (z == (nsd + ownZNbCell(isd))) {
586 nsd += ownZNbCell(isd);
589 sd_z_nbl.add(nbl * all_nb_node_xy);
590 sd_z_node_offset.add(nsd * all_nb_node_xy);
591 sd_z_cell_offset.add(nsd * all_nb_cell_xy);
592 isd += m_build_info.m_nsdx * m_build_info.m_nsdy;
602bool CartesianMeshGenerator::
605 Trace::Setter mci(traceMng(),
"CartesianMeshGenerator");
606 IPrimaryMesh* mesh = m_mesh;
608 m_generation_info = ICartesianMeshGenerationInfo::getReference(mesh,
true);
610 CartesianMeshAllocateBuildInfo cartesian_mesh_build_info(mesh);
612 info() <<
" decomposing the subdomains:" << m_build_info.m_nsdx <<
"x"
613 << m_build_info.m_nsdy <<
"x" << m_build_info.m_nsdz;
614 info() <<
"sub domain offset @ " << sdXOffset() <<
"x" << sdYOffset() <<
"x" << sdZOffset();
623 m_generation_info->setGlobalNbCells(all_nb_cell_x, all_nb_cell_y, all_nb_cell_z);
624 m_generation_info->setSubDomainOffsets(sdXOffset(), sdYOffset(), sdZOffset());
625 m_generation_info->setNbSubDomains(m_build_info.m_nsdx, m_build_info.m_nsdy, m_build_info.m_nsdz);
627 m_generation_info->setGlobalOrigin(m_build_info.m_origine);
628 m_generation_info->setGlobalLength(m_l);
630 Int64 all_nb_cell_xy = ((Int64)all_nb_cell_x) * ((Int64)all_nb_cell_y);
631 Int64 all_nb_cell_xyz = ((Int64)all_nb_cell_xy) * ((Int64)all_nb_cell_z);
632 info() <<
" all cells: " << all_nb_cell_x <<
"x" << all_nb_cell_y <<
"y"
633 << all_nb_cell_z <<
"=" << all_nb_cell_xyz;
636 Int32 own_nb_cell_x = ownXNbCell();
637 Int32 own_nb_cell_y = ownYNbCell();
638 Int32 own_nb_cell_z = ownZNbCell();
639 m_generation_info->setOwnNbCells(own_nb_cell_x, own_nb_cell_y, own_nb_cell_z);
640 Integer own_nb_cell_xy = CheckedConvert::multiply(own_nb_cell_x, own_nb_cell_y);
641 Integer own_nb_cell_xyz = CheckedConvert::multiply(own_nb_cell_xy, own_nb_cell_z);
642 info() <<
" own cells: " << own_nb_cell_x <<
"x" << own_nb_cell_y <<
"y"
643 << own_nb_cell_z <<
"=" << own_nb_cell_xyz;
646 Integer all_nb_node_x = all_nb_cell_x + 1;
647 Integer all_nb_node_y = all_nb_cell_y + 1;
648 Int64 all_nb_node_xy = ((Int64)all_nb_node_x) * ((Int64)all_nb_node_y);
651 Integer own_nb_node_x = own_nb_cell_x + 1;
652 Integer own_nb_node_y = own_nb_cell_y + 1;
653 Integer own_nb_node_z = (m_mesh_dimension == 3) ? own_nb_cell_z + 1 : own_nb_cell_z;
654 Integer own_nb_node_xy = CheckedConvert::multiply(own_nb_node_x, own_nb_node_y);
655 Integer own_nb_node_xyz = CheckedConvert::multiply(own_nb_node_xy, own_nb_node_z);
656 info() <<
" own nodes: "
657 << own_nb_node_x <<
"x"
658 << own_nb_node_y <<
"y"
659 << own_nb_node_z <<
"=" << own_nb_node_xyz;
662 UniqueArray<Int64> nodes_unique_id(CheckedConvert::toInteger(own_nb_node_xyz));
663 HashTableMapT<Int64, NodeInfo> nodes_infos(CheckedConvert::toInteger(own_nb_node_xyz),
true);
682 sd_x_ibl, sd_x_obl, sd_x_nbl,
683 sd_x_node_offset, sd_x_cell_offset);
687 sd_y_ibl, sd_y_obl, sd_y_nbl,
688 sd_y_node_offset, sd_y_cell_offset,
689 all_nb_node_x, all_nb_cell_x);
693 sd_z_ibl, sd_z_obl, sd_z_nbl,
694 sd_z_node_offset, sd_z_cell_offset,
695 all_nb_node_xy, all_nb_cell_xy);
698 Int64x3 first_own_cell_offset;
700 Int64 cell_offset_x = sd_x_cell_offset[sdXOffset()];
701 Int64 cell_offset_y = sd_y_cell_offset[sdYOffset()] / all_nb_cell_x;
702 Int64 cell_offset_z = 0;
703 if (m_mesh_dimension == 3) {
704 cell_offset_z = sd_z_cell_offset[sdZOffset()] / all_nb_cell_xy;
706 first_own_cell_offset = Int64x3(cell_offset_x, cell_offset_y, cell_offset_z);
707 info() <<
"OwnCellOffset info X=" << cell_offset_x <<
" Y=" << cell_offset_y <<
" Z=" << cell_offset_z;
708 m_generation_info->setOwnCellOffsets(cell_offset_x, cell_offset_y, cell_offset_z);
711 info() <<
" sd_x_ibl=" << sd_x_ibl;
712 info() <<
" sd_x_obl=" << sd_x_obl;
713 info() <<
" sd_x_nbl=" << sd_x_nbl;
715 info() <<
" sd_y_ibl=" << sd_y_ibl;
716 info() <<
" sd_y_obl=" << sd_y_obl;
717 info() <<
" sd_y_nbl=" << sd_y_nbl;
719 info() <<
" sd_z_ibl=" << sd_z_ibl;
720 info() <<
" sd_z_obl=" << sd_z_obl;
721 info() <<
" sd_z_nbl=" << sd_z_nbl;
724 info() <<
" sd_x_node_offset=" << sd_x_node_offset;
725 info() <<
" sd_y_node_offset=" << sd_y_node_offset;
726 info() <<
" sd_z_node_offset=" << sd_z_node_offset;
729 info() <<
" sd_x_cell_offset=" << sd_x_cell_offset;
730 info() <<
" sd_y_cell_offset=" << sd_y_cell_offset;
731 info() <<
" sd_z_cell_offset=" << sd_z_cell_offset;
735 Int64 node_unique_id_offset = 0;
736 info() <<
" sdXOffset=" << sdXOffset()
737 <<
" sdYOffset=" << sdYOffset()
738 <<
" sdZOffset=" << sdZOffset();
740 node_unique_id_offset += sd_x_node_offset.at(sdXOffset());
741 info() <<
" node_unique_id_offset=" << node_unique_id_offset;
743 node_unique_id_offset += (sd_y_node_offset.at(sdYOffset()));
744 info() <<
" node_unique_id_offset=" << node_unique_id_offset;
745 if (m_mesh_dimension == 3) {
747 node_unique_id_offset += (sd_z_node_offset.at(sdZOffset()));
748 info() <<
" node_unique_id_offset=" << node_unique_id_offset;
754 if (m_mesh_dimension == 3) {
755 z_ibl = sd_z_ibl.at(sdZOffset());
756 z_obl = sd_z_obl.at(sdZOffset());
757 z_nbl = sd_z_nbl.at(sdZOffset());
759 for (Int64 z = 0; z < own_nb_node_z; ++z) {
760 if (m_mesh_dimension == 3) {
763 if (((z + 1) != own_nb_node_z) &&
764 ((z * all_nb_node_xy + sd_z_node_offset.at(sdZOffset())) == (z_nbl + m_build_info.m_bloc_nz.at(z_ibl) * all_nb_node_xy))) {
765 info() <<
" Creation hit z bloc boundarz: @ node " << z;
766 z_nbl += m_build_info.m_bloc_nz.at(z_ibl) * all_nb_node_xy;
773 if (m_mesh_dimension == 3)
774 nz = nzDelta(z_obl, z_ibl);
775 Integer y_ibl = sd_y_ibl.at(sdYOffset());
776 Integer y_obl = sd_y_obl.at(sdYOffset());
777 Int64 y_nbl = sd_y_nbl.at(sdYOffset());
778 for (Int64 y = 0; y < own_nb_node_y; ++y) {
781 if (((y + 1) != own_nb_node_y) &&
782 ((y * all_nb_node_x + sd_y_node_offset.at(sdYOffset())) == (y_nbl + m_build_info.m_bloc_ny.at(y_ibl) * all_nb_node_x))) {
783 info() <<
" Creation hit y bloc boundary: @ node " << y;
784 y_nbl += m_build_info.m_bloc_ny.at(y_ibl) * all_nb_node_x;
789 Real ny = nyDelta(y_obl, y_ibl);
791 Integer x_ibl = sd_x_ibl.at(sdXOffset());
793 Integer x_obl = sd_x_obl.at(sdXOffset());
795 Int64 x_nbl = sd_x_nbl.at(sdXOffset());
796 for (Int64 x = 0; x < own_nb_node_x; ++x) {
797 Int64 node_unique_id = node_unique_id_offset + x + y * all_nb_node_x + z * all_nb_node_xy;
798 nodes_unique_id[node_local_id] = node_unique_id;
799 Int32 owner = m_my_mesh_part;
802 if (((sdXOffset() + 1) != m_build_info.m_nsdx) && ((x + 1) == own_nb_node_x))
804 if (((sdYOffset() + 1) != m_build_info.m_nsdy) && ((y + 1) == own_nb_node_y))
805 owner += m_build_info.m_nsdx;
806 if (((sdZOffset() + 1) != m_build_info.m_nsdz) && ((z + 1) == own_nb_node_z))
807 owner += m_build_info.m_nsdx * m_build_info.m_nsdy;
810 if (((x + 1) != own_nb_node_x) && ((x + sd_x_node_offset.at(sdXOffset())) == (x_nbl + m_build_info.m_bloc_nx.at(x_ibl)))) {
811 info() <<
" Creation hit x bloc boundary: @ node " << x;
812 x_nbl += m_build_info.m_bloc_nx.at(x_ibl);
817 Real nx = nxDelta(x_obl, x_ibl);
821 nodes_infos.nocheckAdd(node_unique_id, NodeInfo(owner, Real3(nx, ny, nz)));
835 Int64 cell_unique_id_offset = 0;
837 cell_unique_id_offset += sd_x_cell_offset.at(sdXOffset());
838 info() <<
"cell_unique_id_offset=" << cell_unique_id_offset;
840 cell_unique_id_offset += sd_y_cell_offset.at(sdYOffset());
841 info() <<
"cell_unique_id_offset=" << cell_unique_id_offset;
842 if (m_mesh_dimension == 3) {
844 cell_unique_id_offset += sd_z_cell_offset.at(sdZOffset());
845 info() <<
"cell_unique_id_offset=" << cell_unique_id_offset;
847 info() <<
"cell_unique_id_offset=" << cell_unique_id_offset;
848 m_generation_info->setFirstOwnCellUniqueId(cell_unique_id_offset);
850 const Int32 face_numbering_version = m_build_info.m_face_numbering_version;
851 info() <<
"FaceNumberingVersion = " << face_numbering_version;
852 const Int32 edge_numbering_version = m_build_info.m_edge_numbering_version;
853 info() <<
"EdgeNumberingVersion = " << edge_numbering_version;
856 info() <<
"Set Specific info for cartesian mesh";
857 if (m_mesh_dimension == 3)
858 cartesian_mesh_build_info.setInfos3D({ all_nb_cell_x, all_nb_cell_y, all_nb_cell_z },
859 { own_nb_cell_x, own_nb_cell_y, own_nb_cell_z },
860 { first_own_cell_offset.x, first_own_cell_offset.y, first_own_cell_offset.z },
862 else if (m_mesh_dimension == 2) {
863 cartesian_mesh_build_info.setInfos2D({ all_nb_cell_x, all_nb_cell_y },
864 { own_nb_cell_x, own_nb_cell_y },
865 { first_own_cell_offset.x, first_own_cell_offset.y },
869 ARCANE_FATAL(
"Invalid dimensionn '{0}' (valid values are 2 or 3)", m_mesh_dimension);
871 if (face_numbering_version >= 0)
872 cartesian_mesh_build_info._internal()->setFaceBuilderVersion(face_numbering_version);
873 if (edge_numbering_version >= 0)
874 cartesian_mesh_build_info._internal()->setEdgeBuilderVersion(edge_numbering_version);
877 cartesian_mesh_build_info.allocateMesh();
881 info() <<
"Fills the variable containing the coordinates of the nodes";
883 IItemFamily* family = mesh->nodeFamily();
884 family->itemsUniqueIdToLocalId(nodes_local_id, nodes_unique_id);
885 NodeInfoListView nodes_internal(family);
886 for (Integer i = 0; i < node_local_id; ++i) {
887 Node node = nodes_internal[nodes_local_id[i]];
888 Int64 unique_id = nodes_unique_id[i];
889 nodes_coord_var[node] = nodes_infos.lookupValue(unique_id).m_coord;
894 nodes_coord_var.synchronize();
899 SodStandardGroupsBuilder groups_builder(traceMng());
900 Real3 origin = m_build_info.m_origine;
901 Real3 length(m_l.x, m_l.y, m_l.z);
902 Real3 max_pos = origin + length;
907 bool do_zg_and_zd = m_build_info.m_is_generate_sod_groups;
908 Real middle_x = (origin.x + max_pos.x) / 2.0;
909 Real middle_height = (origin.y + max_pos.y) / 2.0;
910 groups_builder.generateGroups(mesh, origin, origin + length, middle_x, middle_height, do_zg_and_zd);
925class Cartesian2DMeshGenerator
938 ARCANE_UNUSED(build_info);
939 info() <<
"Cartesian2DMeshGenerator: fillMeshBuildInfo()";
940 m_build_info.m_nsdx =
options()->nbPartX();
941 m_build_info.m_nsdy =
options()->nbPartY();
943 m_build_info.m_mesh_dimension = 2;
945 m_build_info.m_origine.x = origin.
x;
946 m_build_info.m_origine.y = origin.
y;
947 m_build_info.m_is_generate_sod_groups =
options()->generateSodGroups();
948 m_build_info.m_face_numbering_version =
options()->faceNumberingVersion();
950 for (
auto& o :
options()->x()) {
951 m_build_info.m_bloc_lx.add(o->length);
952 m_build_info.m_bloc_nx.add(o->n);
953 m_build_info.m_bloc_px.add(o->progression);
956 for (
auto& o :
options()->y()) {
957 m_build_info.m_bloc_ly.add(o->length);
958 m_build_info.m_bloc_ny.add(o->n);
959 m_build_info.m_bloc_py.add(o->progression);
965 info() <<
"Cartesian2DMeshGenerator: allocateMeshItems()";
968 auto [x, y] = _computePartition(pm, m_build_info.m_nsdx, m_build_info.m_nsdy);
969 m_build_info.m_nsdx = x;
970 m_build_info.m_nsdy = y;
971 g.setBuildInfo(m_build_info);
979 static std::tuple<Integer, Integer>
987 if (nb_x != 0 && nb_y != 0)
988 return { nb_x, nb_y };
991 if (nb_x == 0 && nb_y == 0) {
992 double s = math::sqrt((
double)(nb_part));
994 if ((s_int * s_int) != nb_part)
995 ARCANE_FATAL(
"Invalid number of part '{0}' for automatic partitioning: sqrt({1}) is not an integer",
997 return { s_int, s_int };
1001 if ((nb_part % nb_y) != 0)
1002 ARCANE_FATAL(
"Invalid number of Y part '{0}' for automatic partitioning: can not divide '{1}' by '{2}'",
1003 nb_y, nb_part, nb_y);
1004 nb_x = nb_part / nb_y;
1007 if ((nb_part % nb_x) != 0)
1008 ARCANE_FATAL(
"Invalid number of X part '{0}' for automatic partitioning: can not divide '{1}' by '{2}'",
1009 nb_x, nb_part, nb_x);
1010 nb_y = nb_part / nb_x;
1012 return { nb_x, nb_y };
1016ARCANE_REGISTER_SERVICE_CARTESIAN2DMESHGENERATOR(Cartesian2D, Cartesian2DMeshGenerator);
1024class Cartesian3DMeshGenerator
1037 ARCANE_UNUSED(build_info);
1038 info() <<
"Cartesian3DMeshGenerator: fillMeshBuildInfo()";
1039 m_build_info.m_nsdx =
options()->nbPartX();
1040 m_build_info.m_nsdy =
options()->nbPartY();
1041 m_build_info.m_nsdz =
options()->nbPartZ();
1043 m_build_info.m_mesh_dimension = 3;
1045 m_build_info.m_origine.x = origin.
x;
1046 m_build_info.m_origine.y = origin.
y;
1047 m_build_info.m_origine.z = origin.
z;
1048 m_build_info.m_is_generate_sod_groups =
options()->generateSodGroups();
1049 m_build_info.m_face_numbering_version =
options()->faceNumberingVersion();
1050 m_build_info.m_edge_numbering_version =
options()->edgeNumberingVersion();
1052 for (
auto& o :
options()->x()) {
1053 m_build_info.m_bloc_lx.add(o->length);
1054 m_build_info.m_bloc_nx.add(o->n);
1055 m_build_info.m_bloc_px.add(o->progression);
1058 for (
auto& o :
options()->y()) {
1059 m_build_info.m_bloc_ly.add(o->length);
1060 m_build_info.m_bloc_ny.add(o->n);
1061 m_build_info.m_bloc_py.add(o->progression);
1064 for (
auto& o :
options()->z()) {
1065 m_build_info.m_bloc_lz.add(o->length);
1066 m_build_info.m_bloc_nz.add(o->n);
1067 m_build_info.m_bloc_pz.add(o->progression);
1073 info() <<
"Cartesian3DMeshGenerator: allocateMeshItems()";
1075 g.setBuildInfo(m_build_info);
1085ARCANE_REGISTER_SERVICE_CARTESIAN3DMESHGENERATOR(Cartesian3D, Cartesian3DMeshGenerator);
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Utility functions for the mesh.
ArcaneCartesian2DMeshGeneratorObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
CaseOptionsCartesian2DMeshGenerator * options() const
Options du jeu de données du service.
ArcaneCartesian3DMeshGeneratorObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
CaseOptionsCartesian3DMeshGenerator * options() const
Options du jeu de données du service.
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.
Int32 m_face_numbering_version
Version of the face numbering algorithm.
Int32 m_edge_numbering_version
Version of the edge numbering algorithm.
virtual const MeshPartInfo & meshPartInfo() const =0
Mesh part information.
Parameters necessary for building a mesh.
Class managing a 2-dimensional real vector.
Class managing a 3-dimensional real vector.
Structure containing the information to create a service.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
Int32 Integer
Type representing an integer.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
double Real
Type representing a real number.
UniqueArray< Integer > IntegerUniqueArray
Dynamic 1D array of integers.
std::int32_t Int32
Signed integer type of 32 bits.
Real y
second component of the pair
Real x
first component of the pair
Real y
second component of the triplet
Real z
third component of the triplet
Real x
first component of the triplet