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;
208bool CartesianMeshGenerator::
213 m_mesh_dimension = m_build_info.m_mesh_dimension;
214 Int32 nb_sub_domain = m_mesh->parallelMng()->commSize();
217 if (m_build_info.m_nsdx == 0 || nb_sub_domain == 1)
218 m_build_info.m_nsdx = 1;
219 if (m_build_info.m_nsdy == 0 || nb_sub_domain == 1)
220 m_build_info.m_nsdy = 1;
221 if (m_build_info.m_nsdz == 0 || nb_sub_domain == 1)
222 m_build_info.m_nsdz = 1;
225 m_l.x = m_l.y = m_l.z = 0.;
226 for (
int i = 0; i < m_build_info.m_bloc_lx.size(); i += 1)
227 m_l.x += m_build_info.m_bloc_lx.at(i);
228 for (
int i = 0; i < m_build_info.m_bloc_ly.size(); i += 1)
229 m_l.y += m_build_info.m_bloc_ly.at(i);
230 if (m_mesh_dimension == 3)
231 for (
int i = 0; i < m_build_info.m_bloc_lz.size(); i += 1)
232 m_l.z += m_build_info.m_bloc_lz.at(i);
235 m_bloc_ox.add(m_build_info.m_origine.x);
236 m_bloc_oy.add(m_build_info.m_origine.y);
237 if (m_mesh_dimension == 3)
238 m_bloc_oz.add(m_build_info.m_origine.z);
239 for (
int i = 0; i < m_build_info.m_bloc_lx.size(); i += 1)
240 m_bloc_ox.add(m_bloc_ox.at(i) + m_build_info.m_bloc_lx.at(i));
241 for (
int i = 0; i < m_build_info.m_bloc_ly.size(); i += 1)
242 m_bloc_oy.add(m_bloc_oy.at(i) + m_build_info.m_bloc_ly.at(i));
243 if (m_mesh_dimension == 3)
244 for (
int i = 0; i < m_build_info.m_bloc_lz.size(); i += 1)
245 m_bloc_oz.add(m_bloc_oz.at(i) + m_build_info.m_bloc_lz.at(i));
248 m_nx = m_ny = m_nz = 0;
250 for (
int i = 0; i < m_build_info.m_bloc_nx.size(); ++i)
251 m_nx += m_build_info.m_bloc_nx.at(i);
252 for (
int i = 0; i < m_build_info.m_bloc_ny.size(); ++i)
253 m_ny += m_build_info.m_bloc_ny.at(i);
255 if (m_mesh_dimension == 3)
256 for (
int i = 0; i < m_build_info.m_bloc_nz.size(); i += 1)
257 m_nz += m_build_info.m_bloc_nz.at(i);
262 info() <<
" mesh_name=" << m_mesh->name();
263 info() <<
" dimension=" << m_mesh_dimension;
264 info() <<
" origin:" << m_build_info.m_origine;
265 info() <<
" length x =" << m_l.x <<
"," << m_build_info.m_bloc_lx;
266 info() <<
" length y=" << m_l.y <<
"," << m_build_info.m_bloc_ly;
267 if (m_build_info.m_mesh_dimension == 3)
268 info() <<
" length z=" << m_l.z <<
"," << m_build_info.m_bloc_lz;
269 info() <<
"cells number:" << m_nx <<
"x" << m_ny <<
"x" << m_nz;
270 info() <<
"progression x:" << m_build_info.m_bloc_px;
271 info() <<
"progression y:" << m_build_info.m_bloc_py;
272 if (m_mesh_dimension == 3)
273 info() <<
"progression z:" << m_build_info.m_bloc_pz;
274 info() <<
" nb_sub_domain:" << nb_sub_domain;
275 info() <<
" decomposing the subdomains:" << m_build_info.m_nsdx <<
"x"
276 << m_build_info.m_nsdy <<
"x" << m_build_info.m_nsdz;
279 if (m_build_info.m_nsdx * m_build_info.m_nsdy * m_build_info.m_nsdz != nb_sub_domain)
280 ARCANE_FATAL(
"Specified partition {0}x{1}x{2} has to be equal to number of parts ({3})",
281 m_build_info.m_nsdx,m_build_info.m_nsdy,m_build_info.m_nsdz,nb_sub_domain);
291inline Integer CartesianMeshGenerator::
292sdXOffset(
Int32 this_sub_domain_id)
294 return this_sub_domain_id % m_build_info.m_nsdx;
297inline Integer CartesianMeshGenerator::
298sdYOffset(Int32 this_sub_domain_id)
300 return (this_sub_domain_id / m_build_info.m_nsdx) % m_build_info.m_nsdy;
303inline Integer CartesianMeshGenerator::
304sdZOffset(Int32 this_sub_domain_id)
306 return (this_sub_domain_id / (m_build_info.m_nsdx * m_build_info.m_nsdy)) % m_build_info.m_nsdz;
309inline Integer CartesianMeshGenerator::
312 return sdXOffset(m_my_mesh_part);
315inline Integer CartesianMeshGenerator::
318 return sdYOffset(m_my_mesh_part);
321inline Integer CartesianMeshGenerator::
324 return sdZOffset(m_my_mesh_part);
332inline Int32 ownNbCell(Int64 n, Integer nsd,
int sd_offset)
338 return CheckedConvert::toInt32(q);
340 if (sd_offset < (nsd - r))
341 return CheckedConvert::toInt32(q);
342 return CheckedConvert::toInt32(q + 1);
345inline Int32 CartesianMeshGenerator::
348 return ownNbCell(m_nx, m_build_info.m_nsdx, sdXOffset());
350inline Int32 CartesianMeshGenerator::
353 return ownNbCell(m_nx, m_build_info.m_nsdx, sdXOffset(isd));
355inline Int32 CartesianMeshGenerator::
358 return ownNbCell(m_ny, m_build_info.m_nsdy, sdYOffset());
360inline Int32 CartesianMeshGenerator::
363 return ownNbCell(m_ny, m_build_info.m_nsdy, sdYOffset(isd));
365inline Int32 CartesianMeshGenerator::
368 return ownNbCell(m_nz, m_build_info.m_nsdz, sdZOffset());
370inline Int32 CartesianMeshGenerator::
373 return ownNbCell(m_nz, m_build_info.m_nsdz, sdZOffset(isd));
381 const RealArray& bloc_p,
382 const Int32Array& bloc_n,
383 const RealArray& bloc_l,
387 Real p = bloc_p.at(iBloc);
388 Real n = (Real)bloc_n.at(iBloc);
389 Real l = bloc_l.at(iBloc);
391 return all_l / (Real)all_n;
392 return (p - 1.0) / (math::pow(p, n) - 1.0) * l;
398 const RealArray& bloc_p,
399 const Int32Array& bloc_n,
400 const RealArray& bloc_l,
404 ARCANE_UNUSED(all_l);
405 ARCANE_UNUSED(all_n);
407 Real p = bloc_p.at(iBloc);
408 Real n = (Real)bloc_n.at(iBloc);
409 Real l = bloc_l.at(iBloc);
412 return l * (math::pow(p, k) - 1.0) / (math::pow(p, (Real)n) - 1.0);
415inline Real CartesianMeshGenerator::
416nxDelta(Real k,
int iBloc)
418 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);
420inline Real CartesianMeshGenerator::
423 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);
426inline Real CartesianMeshGenerator::
427nyDelta(Real k,
int iBloc)
429 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);
431inline Real CartesianMeshGenerator::
434 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);
437inline Real CartesianMeshGenerator::
438nzDelta(Real k,
int iBloc)
440 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);
443inline Real CartesianMeshGenerator::
446 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);
454void CartesianMeshGenerator::
455xScan(
const Int64 all_nb_cell_x,
456 IntegerArray& sd_x_ibl,
457 IntegerArray& sd_x_obl,
458 Int64Array& sd_x_nbl,
459 Int64Array& sd_x_node_offset,
460 Int64Array& sd_x_cell_offset)
465 sd_x_node_offset.add(0);
466 sd_x_cell_offset.add(0);
473 for (Int64 x = 0; x < all_nb_cell_x; ++x) {
475 if (x == (nbl + m_build_info.m_bloc_nx.at(ibl))) {
476 nbl += m_build_info.m_bloc_nx.at(ibl);
477 info(4) <<
"\t␛[2;33m[CartesianMeshGenerator::xScan] Scan hit x bloc boundary: @ node " << nbl <<
"␛[0m";
484 if (x == (nsd + ownXNbCell(isd))) {
485 nsd += ownXNbCell(isd);
486 info(4) <<
"\t␛[2;33m[CartesianMeshGenerator::xScan] Scan hit x sub domain boundary: @ node " << nsd <<
"␛[0m";
491 sd_x_node_offset.add(nsd);
492 sd_x_cell_offset.add(nsd);
494 info(4) <<
"\t␛[2;33m[CartesianMeshGenerator::xScan] Saving state: "
495 <<
", node_offset=" << sd_x_node_offset.at(isd)
496 <<
", cell_offset=" << sd_x_cell_offset.at(isd)
497 <<
", ibl=" << sd_x_ibl.at(isd)
498 <<
", nbl=" << sd_x_nbl.at(isd) <<
"␛[0m";
510void CartesianMeshGenerator::
511yScan(
const Integer all_nb_cell_y,
512 IntegerArray& sd_y_ibl,
513 IntegerArray& sd_y_obl,
514 Int64Array& sd_y_nbl,
515 Int64Array& sd_y_node_offset,
516 Int64Array& sd_y_cell_offset,
523 sd_y_node_offset.add(0);
524 sd_y_cell_offset.add(0);
530 for (Int64 y = 0; y < all_nb_cell_y; ++y) {
531 if (y == (nbl + m_build_info.m_bloc_ny.at(ibl))) {
532 nbl += m_build_info.m_bloc_ny.at(ibl);
533 info(4) <<
"\t␛[2;33m[CartesianMeshGenerator::generateMesh] Scan hit y bloc boundary: @ node " << nbl <<
"␛[0m";
537 if (y == (nsd + ownYNbCell(isd))) {
538 nsd += ownYNbCell(isd);
539 info(4) <<
"\t␛[2;33m[CartesianMeshGenerator::generateMesh] Scan hit y sub domain boundary: @ node " << nsd <<
"␛[0m";
542 sd_y_nbl.add(nbl * all_nb_node_x);
543 sd_y_node_offset.add(nsd * all_nb_node_x);
544 sd_y_cell_offset.add(nsd * all_nb_cell_x);
545 isd += m_build_info.m_nsdx;
556void CartesianMeshGenerator::
557zScan(
const Int64 all_nb_cell_z,
558 IntegerArray& sd_z_ibl,
559 IntegerArray& sd_z_obl,
560 Int64Array& sd_z_nbl,
561 Int64Array& sd_z_node_offset,
562 Int64Array& sd_z_cell_offset,
563 Int64 all_nb_node_xy,
564 Int64 all_nb_cell_xy)
566 if (m_mesh_dimension != 3)
571 sd_z_node_offset.add(0);
572 sd_z_cell_offset.add(0);
578 for (Int64 z = 0; z < all_nb_cell_z; ++z) {
579 if (z == (nbl + m_build_info.m_bloc_nz.at(ibl))) {
580 nbl += m_build_info.m_bloc_nz.at(ibl);
584 if (z == (nsd + ownZNbCell(isd))) {
585 nsd += ownZNbCell(isd);
588 sd_z_nbl.add(nbl * all_nb_node_xy);
589 sd_z_node_offset.add(nsd * all_nb_node_xy);
590 sd_z_cell_offset.add(nsd * all_nb_cell_xy);
591 isd += m_build_info.m_nsdx * m_build_info.m_nsdy;
601bool CartesianMeshGenerator::
604 Trace::Setter mci(traceMng(),
"CartesianMeshGenerator");
605 IPrimaryMesh* mesh = m_mesh;
607 m_generation_info = ICartesianMeshGenerationInfo::getReference(mesh,
true);
609 CartesianMeshAllocateBuildInfo cartesian_mesh_build_info(mesh);
611 info() <<
" decomposing the subdomains:" << m_build_info.m_nsdx <<
"x"
612 << m_build_info.m_nsdy <<
"x" << m_build_info.m_nsdz;
613 info() <<
"sub domain offset @ " << sdXOffset() <<
"x" << sdYOffset() <<
"x" << sdZOffset();
622 m_generation_info->setGlobalNbCells(all_nb_cell_x,all_nb_cell_y,all_nb_cell_z);
623 m_generation_info->setSubDomainOffsets(sdXOffset(),sdYOffset(),sdZOffset());
624 m_generation_info->setNbSubDomains(m_build_info.m_nsdx,m_build_info.m_nsdy,m_build_info.m_nsdz);
626 m_generation_info->setGlobalOrigin(m_build_info.m_origine);
627 m_generation_info->setGlobalLength(m_l);
629 Int64 all_nb_cell_xy = ((Int64)all_nb_cell_x) * ((Int64)all_nb_cell_y);
630 Int64 all_nb_cell_xyz = ((Int64)all_nb_cell_xy) * ((Int64)all_nb_cell_z);
631 info() <<
" all cells: " << all_nb_cell_x <<
"x" << all_nb_cell_y <<
"y"
632 << all_nb_cell_z <<
"=" << all_nb_cell_xyz;
635 Int32 own_nb_cell_x = ownXNbCell();
636 Int32 own_nb_cell_y = ownYNbCell();
637 Int32 own_nb_cell_z = ownZNbCell();
638 m_generation_info->setOwnNbCells(own_nb_cell_x,own_nb_cell_y,own_nb_cell_z);
639 Integer own_nb_cell_xy = CheckedConvert::multiply(own_nb_cell_x, own_nb_cell_y);
640 Integer own_nb_cell_xyz = CheckedConvert::multiply(own_nb_cell_xy, own_nb_cell_z);
641 info() <<
" own cells: " << own_nb_cell_x <<
"x" << own_nb_cell_y <<
"y"
642 << own_nb_cell_z <<
"=" << own_nb_cell_xyz;
645 Integer all_nb_node_x = all_nb_cell_x + 1;
646 Integer all_nb_node_y = all_nb_cell_y + 1;
647 Int64 all_nb_node_xy = ((Int64)all_nb_node_x) * ((Int64)all_nb_node_y);
650 Integer own_nb_node_x = own_nb_cell_x + 1;
651 Integer own_nb_node_y = own_nb_cell_y + 1;
652 Integer own_nb_node_z = (m_mesh_dimension == 3) ? own_nb_cell_z + 1 : own_nb_cell_z;
653 Integer own_nb_node_xy = CheckedConvert::multiply(own_nb_node_x, own_nb_node_y);
654 Integer own_nb_node_xyz = CheckedConvert::multiply(own_nb_node_xy, own_nb_node_z);
655 info() <<
" own nodes: "
656 << own_nb_node_x <<
"x"
657 << own_nb_node_y <<
"y"
658 << own_nb_node_z <<
"=" << own_nb_node_xyz;
661 UniqueArray<Int64> nodes_unique_id(CheckedConvert::toInteger(own_nb_node_xyz));
662 HashTableMapT<Int64, NodeInfo> nodes_infos(CheckedConvert::toInteger(own_nb_node_xyz),
true);
681 sd_x_ibl, sd_x_obl, sd_x_nbl,
682 sd_x_node_offset, sd_x_cell_offset);
686 sd_y_ibl, sd_y_obl, sd_y_nbl,
687 sd_y_node_offset, sd_y_cell_offset,
688 all_nb_node_x, all_nb_cell_x);
692 sd_z_ibl, sd_z_obl, sd_z_nbl,
693 sd_z_node_offset, sd_z_cell_offset,
694 all_nb_node_xy, all_nb_cell_xy);
697 Int64x3 first_own_cell_offset;
699 Int64 cell_offset_x = sd_x_cell_offset[sdXOffset()];
700 Int64 cell_offset_y = sd_y_cell_offset[sdYOffset()] / all_nb_cell_x;
701 Int64 cell_offset_z = 0;
702 if (m_mesh_dimension == 3) {
703 cell_offset_z = sd_z_cell_offset[sdZOffset()] / all_nb_cell_xy;
705 first_own_cell_offset = Int64x3(cell_offset_x,cell_offset_y,cell_offset_z);
706 info() <<
"OwnCellOffset info X=" << cell_offset_x <<
" Y=" << cell_offset_y <<
" Z=" << cell_offset_z;
707 m_generation_info->setOwnCellOffsets(cell_offset_x,cell_offset_y,cell_offset_z);
710 info() <<
" sd_x_ibl=" << sd_x_ibl;
711 info() <<
" sd_x_obl=" << sd_x_obl;
712 info() <<
" sd_x_nbl=" << sd_x_nbl;
714 info() <<
" sd_y_ibl=" << sd_y_ibl;
715 info() <<
" sd_y_obl=" << sd_y_obl;
716 info() <<
" sd_y_nbl=" << sd_y_nbl;
718 info() <<
" sd_z_ibl=" << sd_z_ibl;
719 info() <<
" sd_z_obl=" << sd_z_obl;
720 info() <<
" sd_z_nbl=" << sd_z_nbl;
723 info() <<
" sd_x_node_offset=" << sd_x_node_offset;
724 info() <<
" sd_y_node_offset=" << sd_y_node_offset;
725 info() <<
" sd_z_node_offset=" << sd_z_node_offset;
728 info() <<
" sd_x_cell_offset=" << sd_x_cell_offset;
729 info() <<
" sd_y_cell_offset=" << sd_y_cell_offset;
730 info() <<
" sd_z_cell_offset=" << sd_z_cell_offset;
734 Int64 node_unique_id_offset = 0;
735 info() <<
" sdXOffset=" << sdXOffset()
736 <<
" sdYOffset=" << sdYOffset()
737 <<
" sdZOffset=" << sdZOffset();
739 node_unique_id_offset += sd_x_node_offset.at(sdXOffset());
740 info() <<
" node_unique_id_offset=" << node_unique_id_offset;
742 node_unique_id_offset += (sd_y_node_offset.at(sdYOffset()));
743 info() <<
" node_unique_id_offset=" << node_unique_id_offset;
744 if (m_mesh_dimension == 3) {
746 node_unique_id_offset += (sd_z_node_offset.at(sdZOffset()));
747 info() <<
" node_unique_id_offset=" << node_unique_id_offset;
753 if (m_mesh_dimension == 3) {
754 z_ibl = sd_z_ibl.at(sdZOffset());
755 z_obl = sd_z_obl.at(sdZOffset());
756 z_nbl = sd_z_nbl.at(sdZOffset());
758 for (Int64 z = 0; z < own_nb_node_z; ++z) {
759 if (m_mesh_dimension == 3) {
762 if (((z + 1) != own_nb_node_z) &&
763 ((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))) {
764 info() <<
" Creation hit z bloc boundarz: @ node " << z;
765 z_nbl += m_build_info.m_bloc_nz.at(z_ibl) * all_nb_node_xy;
772 if (m_mesh_dimension == 3)
773 nz = nzDelta(z_obl, z_ibl);
774 Integer y_ibl = sd_y_ibl.at(sdYOffset());
775 Integer y_obl = sd_y_obl.at(sdYOffset());
776 Int64 y_nbl = sd_y_nbl.at(sdYOffset());
777 for (Int64 y = 0; y < own_nb_node_y; ++y) {
780 if (((y + 1) != own_nb_node_y) &&
781 ((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))) {
782 info() <<
" Creation hit y bloc boundary: @ node " << y;
783 y_nbl += m_build_info.m_bloc_ny.at(y_ibl) * all_nb_node_x;
788 Real ny = nyDelta(y_obl, y_ibl);
790 Integer x_ibl = sd_x_ibl.at(sdXOffset());
792 Integer x_obl = sd_x_obl.at(sdXOffset());
794 Int64 x_nbl = sd_x_nbl.at(sdXOffset());
795 for (Int64 x = 0; x < own_nb_node_x; ++x) {
796 Int64 node_unique_id = node_unique_id_offset + x + y * all_nb_node_x + z * all_nb_node_xy;
797 nodes_unique_id[node_local_id] = node_unique_id;
798 Int32 owner = m_my_mesh_part;
801 if (((sdXOffset() + 1) != m_build_info.m_nsdx) && ((x + 1) == own_nb_node_x))
803 if (((sdYOffset() + 1) != m_build_info.m_nsdy) && ((y + 1) == own_nb_node_y))
804 owner += m_build_info.m_nsdx;
805 if (((sdZOffset() + 1) != m_build_info.m_nsdz) && ((z + 1) == own_nb_node_z))
806 owner += m_build_info.m_nsdx * m_build_info.m_nsdy;
809 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)))) {
810 info() <<
" Creation hit x bloc boundary: @ node " << x;
811 x_nbl += m_build_info.m_bloc_nx.at(x_ibl);
816 Real nx = nxDelta(x_obl, x_ibl);
820 nodes_infos.nocheckAdd(node_unique_id, NodeInfo(owner, Real3(nx, ny, nz)));
834 Int64 cell_unique_id_offset = 0;
836 cell_unique_id_offset += sd_x_cell_offset.at(sdXOffset());
837 info() <<
"cell_unique_id_offset=" << cell_unique_id_offset;
839 cell_unique_id_offset += sd_y_cell_offset.at(sdYOffset());
840 info() <<
"cell_unique_id_offset=" << cell_unique_id_offset;
841 if (m_mesh_dimension == 3) {
843 cell_unique_id_offset += sd_z_cell_offset.at(sdZOffset());
844 info() <<
"cell_unique_id_offset=" << cell_unique_id_offset;
846 info() <<
"cell_unique_id_offset=" << cell_unique_id_offset;
847 m_generation_info->setFirstOwnCellUniqueId(cell_unique_id_offset);
849 const Int32 face_numbering_version = m_build_info.m_face_numbering_version;
850 info() <<
"FaceNumberingVersion = " << face_numbering_version;
851 const Int32 edge_numbering_version = m_build_info.m_edge_numbering_version;
852 info() <<
"EdgeNumberingVersion = " << edge_numbering_version;
855 info() <<
"Set Specific info for cartesian mesh";
856 if (m_mesh_dimension==3)
857 cartesian_mesh_build_info.setInfos3D({all_nb_cell_x,all_nb_cell_y,all_nb_cell_z},
858 {own_nb_cell_x,own_nb_cell_y,own_nb_cell_z},
859 {first_own_cell_offset.x,first_own_cell_offset.y,first_own_cell_offset.z},
861 else if (m_mesh_dimension==2){
862 cartesian_mesh_build_info.setInfos2D({all_nb_cell_x,all_nb_cell_y},
863 {own_nb_cell_x,own_nb_cell_y},
864 {first_own_cell_offset.x,first_own_cell_offset.y},
868 ARCANE_FATAL(
"Invalid dimensionn '{0}' (valid values are 2 or 3)",m_mesh_dimension);
870 if (face_numbering_version>=0)
871 cartesian_mesh_build_info._internal()->setFaceBuilderVersion(face_numbering_version);
872 if (edge_numbering_version>=0)
873 cartesian_mesh_build_info._internal()->setEdgeBuilderVersion(edge_numbering_version);
876 cartesian_mesh_build_info.allocateMesh();
880 info() <<
"Fills the variable containing the coordinates of the nodes";
882 IItemFamily* family = mesh->nodeFamily();
883 family->itemsUniqueIdToLocalId(nodes_local_id, nodes_unique_id);
884 NodeInfoListView nodes_internal(family);
885 for (Integer i = 0; i < node_local_id; ++i) {
886 Node node = nodes_internal[nodes_local_id[i]];
887 Int64 unique_id = nodes_unique_id[i];
888 nodes_coord_var[node] = nodes_infos.lookupValue(unique_id).m_coord;
893 nodes_coord_var.synchronize();
898 SodStandardGroupsBuilder groups_builder(traceMng());
899 Real3 origin = m_build_info.m_origine;
900 Real3 length(m_l.x,m_l.y,m_l.z);
901 Real3 max_pos = origin + length;
906 bool do_zg_and_zd = m_build_info.m_is_generate_sod_groups;
907 Real middle_x = (origin.x + max_pos.x) / 2.0;
908 Real middle_height = (origin.y + max_pos.y) / 2.0;
909 groups_builder.generateGroups(mesh, origin, origin + length, middle_x, middle_height, do_zg_and_zd);
923class Cartesian2DMeshGenerator
935 ARCANE_UNUSED(build_info);
936 info() <<
"Cartesian2DMeshGenerator: fillMeshBuildInfo()";
937 m_build_info.m_nsdx =
options()->nbPartX();
938 m_build_info.m_nsdy =
options()->nbPartY();
940 m_build_info.m_mesh_dimension = 2;
942 m_build_info.m_origine.x = origin.
x;
943 m_build_info.m_origine.y = origin.
y;
944 m_build_info.m_is_generate_sod_groups =
options()->generateSodGroups();
945 m_build_info.m_face_numbering_version =
options()->faceNumberingVersion();
947 for(
auto& o :
options()->x() ){
948 m_build_info.m_bloc_lx.add(o->length);
949 m_build_info.m_bloc_nx.add(o->n);
950 m_build_info.m_bloc_px.add(o->progression);
953 for(
auto& o :
options()->y() ){
954 m_build_info.m_bloc_ly.add(o->length);
955 m_build_info.m_bloc_ny.add(o->n);
956 m_build_info.m_bloc_py.add(o->progression);
962 info() <<
"Cartesian2DMeshGenerator: allocateMeshItems()";
965 auto [ x, y ] = _computePartition(pm,m_build_info.m_nsdx,m_build_info.m_nsdy);
966 m_build_info.m_nsdx = x;
967 m_build_info.m_nsdy = y;
968 g.setBuildInfo(m_build_info);
976 static std::tuple<Integer,Integer>
984 if (nb_x!=0 && nb_y!=0)
988 if (nb_x==0 && nb_y==0){
989 double s = math::sqrt((
double)(nb_part));
991 if ((s_int*s_int) != nb_part)
992 ARCANE_FATAL(
"Invalid number of part '{0}' for automatic partitioning: sqrt({1}) is not an integer",
994 return {s_int,s_int};
998 if ( (nb_part % nb_y) != 0 )
999 ARCANE_FATAL(
"Invalid number of Y part '{0}' for automatic partitioning: can not divide '{1}' by '{2}'",
1001 nb_x = nb_part / nb_y;
1004 if ( (nb_part % nb_x) != 0 )
1005 ARCANE_FATAL(
"Invalid number of X part '{0}' for automatic partitioning: can not divide '{1}' by '{2}'",
1007 nb_y = nb_part / nb_x;
1013ARCANE_REGISTER_SERVICE_CARTESIAN2DMESHGENERATOR(Cartesian2D,Cartesian2DMeshGenerator);
1020class Cartesian3DMeshGenerator
1029 ARCANE_UNUSED(build_info);
1030 info() <<
"Cartesian3DMeshGenerator: fillMeshBuildInfo()";
1031 m_build_info.m_nsdx =
options()->nbPartX();
1032 m_build_info.m_nsdy =
options()->nbPartY();
1033 m_build_info.m_nsdz =
options()->nbPartZ();
1035 m_build_info.m_mesh_dimension = 3;
1037 m_build_info.m_origine.x = origin.
x;
1038 m_build_info.m_origine.y = origin.
y;
1039 m_build_info.m_origine.z = origin.
z;
1040 m_build_info.m_is_generate_sod_groups =
options()->generateSodGroups();
1041 m_build_info.m_face_numbering_version =
options()->faceNumberingVersion();
1042 m_build_info.m_edge_numbering_version =
options()->edgeNumberingVersion();
1044 for(
auto& o :
options()->x() ){
1045 m_build_info.m_bloc_lx.add(o->length);
1046 m_build_info.m_bloc_nx.add(o->n);
1047 m_build_info.m_bloc_px.add(o->progression);
1050 for(
auto& o :
options()->y() ){
1051 m_build_info.m_bloc_ly.add(o->length);
1052 m_build_info.m_bloc_ny.add(o->n);
1053 m_build_info.m_bloc_py.add(o->progression);
1056 for(
auto& o :
options()->z() ){
1057 m_build_info.m_bloc_lz.add(o->length);
1058 m_build_info.m_bloc_nz.add(o->n);
1059 m_build_info.m_bloc_pz.add(o->progression);
1065 info() <<
"Cartesian3DMeshGenerator: allocateMeshItems()";
1067 g.setBuildInfo(m_build_info);
1074ARCANE_REGISTER_SERVICE_CARTESIAN3DMESHGENERATOR(Cartesian3D,Cartesian3DMeshGenerator);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions utilitaires sur le maillage.
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
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.
Int32 m_face_numbering_version
Version de l'algorithme de numérotation des faces.
Int32 m_edge_numbering_version
Version de l'algorithme de numérotation des arêtes.
virtual const MeshPartInfo & meshPartInfo() const =0
Informations sur les parties du maillage.
Paramètres nécessaires à la construction d'un maillage.
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.
Classe d'accès aux traces.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
Positionne une classe de message.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Int32 Integer
Type représentant un entier.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
double Real
Type représentant un réel.
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
std::int32_t Int32
Type entier signé sur 32 bits.
Real y
deuxième composante du couple
Real x
première composante du couple
Real y
deuxième composante du triplet
Real z
troisième composante du triplet
Real x
première composante du triplet