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::
176CartesianMeshGenerator(IPrimaryMesh* mesh)
177: TraceAccessor(mesh->traceMng())
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;
218 m_build_info.m_nsdx = 1;
220 m_build_info.m_nsdy = 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;
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::
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);
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);
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::
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();
895 if (m_build_info.m_is_generate_sod_groups){
896 SodStandardGroupsBuilder groups_builder(traceMng());
897 Real3 origin = m_build_info.m_origine;
898 Real3 length(m_l.x,m_l.y,m_l.z);
899 Real3 max_pos = origin + length;
904 Real middle_x = (origin.x + max_pos.x) / 2.0;
905 Real middle_height = (origin.y + max_pos.y) / 2.0;
906 groups_builder.generateGroups(mesh,origin,origin+length,middle_x,middle_height);
933 info() <<
"Cartesian2DMeshGenerator: fillMeshBuildInfo()";
934 m_build_info.m_nsdx = options()->nbPartX();
935 m_build_info.m_nsdy = options()->nbPartY();
937 m_build_info.m_mesh_dimension = 2;
938 Real2 origin = options()->origin;
939 m_build_info.m_origine.
x = origin.
x;
940 m_build_info.m_origine.y = origin.
y;
941 m_build_info.m_is_generate_sod_groups = options()->generateSodGroups();
942 m_build_info.m_face_numbering_version = options()->faceNumberingVersion();
944 for(
auto& o : options()->x() ){
945 m_build_info.m_bloc_lx.add(o->length);
946 m_build_info.m_bloc_nx.add(o->n);
947 m_build_info.m_bloc_px.add(o->progression);
950 for(
auto& o : options()->y() ){
951 m_build_info.m_bloc_ly.add(o->length);
952 m_build_info.m_bloc_ny.add(o->n);
953 m_build_info.m_bloc_py.add(o->progression);
959 info() <<
"Cartesian2DMeshGenerator: allocateMeshItems()";
962 auto [ x, y ] = _computePartition(pm,m_build_info.m_nsdx,m_build_info.m_nsdy);
963 m_build_info.m_nsdx = x;
964 m_build_info.m_nsdy = y;
965 g.setBuildInfo(m_build_info);
973 static std::tuple<Integer,Integer>
976 Int32
nb_part = pm->meshPartInfo().nbPart();
981 if (nb_x!=0 && nb_y!=0)
985 if (nb_x==0 && nb_y==0){
986 double s = math::sqrt((
double)(nb_part));
988 if ((s_int*s_int) != nb_part)
989 ARCANE_FATAL(
"Invalid number of part '{0}' for automatic partitioning: sqrt({1}) is not an integer",
991 return {s_int,s_int};
995 if ( (nb_part % nb_y) != 0 )
996 ARCANE_FATAL(
"Invalid number of Y part '{0}' for automatic partitioning: can not divide '{1}' by '{2}'",
998 nb_x = nb_part / nb_y;
1001 if ( (nb_part % nb_x) != 0 )
1002 ARCANE_FATAL(
"Invalid number of X part '{0}' for automatic partitioning: can not divide '{1}' by '{2}'",
1004 nb_y = nb_part / nb_x;
1010ARCANE_REGISTER_SERVICE_CARTESIAN2DMESHGENERATOR(Cartesian2D,Cartesian2DMeshGenerator);
1027 info() <<
"Cartesian3DMeshGenerator: fillMeshBuildInfo()";
1028 m_build_info.m_nsdx = options()->nbPartX();
1029 m_build_info.m_nsdy = options()->nbPartY();
1030 m_build_info.m_nsdz = options()->nbPartZ();
1032 m_build_info.m_mesh_dimension = 3;
1033 Real3 origin = options()->origin;
1034 m_build_info.m_origine.
x = origin.
x;
1035 m_build_info.m_origine.
y = origin.
y;
1036 m_build_info.m_origine.
z = origin.
z;
1041 for(
auto& o : options()->x() ){
1042 m_build_info.m_bloc_lx.
add(o->length);
1043 m_build_info.m_bloc_nx.
add(o->n);
1044 m_build_info.m_bloc_px.
add(o->progression);
1047 for(
auto& o : options()->y() ){
1048 m_build_info.m_bloc_ly.
add(o->length);
1049 m_build_info.m_bloc_ny.
add(o->n);
1050 m_build_info.m_bloc_py.
add(o->progression);
1053 for(
auto& o : options()->z() ){
1054 m_build_info.m_bloc_lz.
add(o->length);
1055 m_build_info.m_bloc_nz.
add(o->n);
1056 m_build_info.m_bloc_pz.
add(o->progression);
1062 info() <<
"Cartesian3DMeshGenerator: allocateMeshItems()";
1064 g.setBuildInfo(m_build_info);
1071ARCANE_REGISTER_SERVICE_CARTESIAN3DMESHGENERATOR(Cartesian3D,Cartesian3DMeshGenerator);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions utilitaires sur le maillage.
Generation de la classe de base du Service.
Generation de la classe de base du Service.
Service de génération de maillage cartésien en 2D.
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.
Service de génération de maillage cartésien en en 3D.
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.
bool m_is_generate_sod_groups
Indique si on génère les groupes pour un cas test de sod.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Paramètres nécessaires à la construction d'un maillage.
Classe gérant un vecteur de réel de dimension 2.
Classe gérant un vecteur de réel de dimension 3.
Structure contenant les informations pour créer un service.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
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.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
Int32 Integer
Type représentant un entier.
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