14#include "arcane/utils/Array.h"
15#include "arcane/utils/HashTableMap.h"
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/ITraceMng.h"
18#include "arcane/utils/Real3.h"
19#include "arcane/utils/CheckedConvert.h"
21#include "arcane/core/IMeshReader.h"
22#include "arcane/core/ISubDomain.h"
23#include "arcane/core/ICaseDocument.h"
24#include "arcane/core/XmlNode.h"
25#include "arcane/core/Service.h"
26#include "arcane/core/IParallelMng.h"
27#include "arcane/core/Item.h"
28#include "arcane/core/ItemGroup.h"
29#include "arcane/core/IPrimaryMesh.h"
30#include "arcane/core/IItemFamily.h"
31#include "arcane/core/MeshVariable.h"
33#include "arcane/core/ItemPrinter.h"
34#include "arcane/core/FactoryService.h"
35#include "arcane/core/AbstractService.h"
36#include "arcane/core/Properties.h"
37#include "arcane/core/IMeshBuilder.h"
39#include "arcane/std/IMeshGenerator.h"
40#include "arcane/std/SodMeshGenerator.h"
41#include "arcane/std/internal/SodStandardGroupsBuilder.h"
43#include "arcane/std/Sod3DMeshGenerator_axl.h"
74 return m_communicating_sub_domains;
117communicatingSubDomains()
const
120 return m_p->communicatingSubDomains();
127bool SodMeshGenerator::
128readOptions(XmlNode node)
130 Int32 wanted_x = node.child(
"x").valueAsInteger();
133 Int32 mesh_dimension = 1;
134 XmlNode x_node = node.child(
"x");
135 XmlNode y_node = node.child(
"y");
136 XmlNode z_node = node.child(
"z");
137 if (z_node.null() && y_node.null()){
138 info() <<
"[SodMeshGenerator] 1D";
143 else if (z_node.null()){
144 info() <<
"[SodMeshGenerator] 2D";
148 wanted_z = y_node.valueAsInteger();
152 info() <<
"[SodMeshGenerator] 3D";
154 wanted_y = y_node.valueAsInteger();
155 wanted_z = z_node.valueAsInteger();
158 bool z_is_total = z_node.attr(
"total").valueAsBoolean();
160 Real delta0 = x_node.attr(
"delta").valueAsReal();
161 Real delta1 = y_node.attr(
"delta").valueAsReal();
162 Real delta2 = z_node.attr(
"delta").valueAsReal();
164 Real random_coef = node.child(
"random-coef").valueAsReal();
165 if (wanted_x==0 || wanted_y==0 || wanted_z==0){
166 info() <<
"Bad syntax for <meshgenerator>";
167 info() <<
"Expected is <meshgenerator><sod><x>nx</x><y>ny</y><z>nz</z></sod></meshgenerator>";
168 info() <<
"or <meshgenerator><sod><x>nx</x><y>ny</y></sod></meshgenerator>";
169 info() <<
"or <meshgenerator><sod><x>nx</x></sod></meshgenerator>";
170 error() <<
"Bad syntax for <meshgenerator>";
173 m_p = std::make_unique<Impl>(
traceMng(),m_zyx_generate,wanted_x,wanted_y,wanted_z,z_is_total,
174 mesh_dimension,random_coef,delta0,delta1,delta2);
202bool SodMeshGenerator::
205 return m_p->generateMesh(m_mesh);
211bool SodMeshGenerator::Impl::
212generateMesh(IPrimaryMesh* mesh)
214 info() <<
"Generate Mesh from SodMeshGenerator";
216 IParallelMng* pm = mesh->parallelMng();
221 m_wanted_z /= nb_part;
223 Integer nb_cell_x = m_wanted_x;
224 Integer nb_cell_y = m_wanted_y;
225 Integer nb_cell_z = m_wanted_z;
226 info() <<
"nb x=" << nb_cell_x <<
" y=" << nb_cell_y <<
" z=" << nb_cell_z;
231 Properties* mesh_properties = mesh->properties();
232 mesh_properties->setInt64(
"GlobalNbCellX",nb_cell_x);
233 mesh_properties->setInt64(
"GlobalNbCellY",nb_cell_y);
234 mesh_properties->setInt64(
"GlobalNbCellZ",nb_cell_z);
237 bool is_first_proc = (my_part==0);
238 bool is_last_proc = ((1+my_part)==nb_part);
240 Int64 total_para_node_z = total_para_cell_z+1;
241 Int64 first_cell_z = 0;
242 Int64 first_node_z = 0;
244 if (is_first_proc || is_last_proc){
245 m_communicating_sub_domains.resize(1);
246 first_cell_z = nb_cell_z*my_part;
248 m_communicating_sub_domains[0] = my_part+1;
251 else if (is_last_proc){
252 m_communicating_sub_domains[0] = my_part-1;
256 first_node_z = first_cell_z;
259 m_communicating_sub_domains.resize(2);
260 m_communicating_sub_domains[0] = my_part-1;
261 m_communicating_sub_domains[1] = my_part+1;
262 first_cell_z = (nb_cell_z*my_part);
263 first_node_z = first_cell_z;
268 Integer nb_node_x = nb_cell_x+1;
270 Integer nb_node_z = nb_cell_z+1;
272 if (m_mesh_dimension==3){
273 nb_node_y = nb_cell_y + 1;
275 else if (m_mesh_dimension==2){
278 else if (m_mesh_dimension==1){
296 Integer mesh_nb_face = nb_face_x + nb_face_y + nb_face_z;
301 const Int64 uid_multiplier = 1;
304 info() <<
"mesh generation dim=" << m_mesh_dimension;
305 info() <<
"First mesh layer: " << first_cell_z;
306 info() <<
"Number of cells layers: " << nb_cell_z <<
'/' << total_para_cell_z;
307 info() <<
"First node layer: " << first_node_z;
308 info() <<
"Number of nodes layers: " << nb_node_z <<
'/' << total_para_node_z;
310 info() <<
"Number of nodes " << mesh_nb_node;
311 info() <<
"Number of faces " << mesh_nb_face;
312 info() <<
"Number of cells " << mesh_nb_cell;
314 info() <<
"nb node_yz=" << nb_node_yz;
320 HashTableMapT<Int64,NodeInfo> nodes_infos(mesh_nb_node,
true);
322 Real ydelta = (m_xyz_delta[1]==0.0) ? ARCANE_REAL(0.02) : m_xyz_delta[1];
323 Real zdelta = (m_xyz_delta[2]==0.0) ? ARCANE_REAL(0.02) : m_xyz_delta[2];
324 Real xdelta = (m_xyz_delta[0]==0.0) ? ARCANE_REAL(1.0)/(
Real)(nb_cell_x):m_xyz_delta[0];
326 Real middle_x = ARCANE_REAL(0.5);
328 Real middle_height = ARCANE_REAL((nb_cell_y/2)*ydelta);
330 if (m_xyz_delta[0]!=0.0)
331 middle_x = m_xyz_delta[0] * (nb_cell_x/2);
333 if (m_mesh_dimension==2){
335 middle_height = (nb_cell_z/2)*zdelta;
338 info() <<
"Xdelta=" << xdelta<<
", Ydelta=" << ydelta <<
", Zdelta=" << zdelta;
339 info() <<
"middle_x=" << middle_x<<
", middle_height=" << middle_height;
343 if (m_zyx_generate==
false){
345 for( Integer x=0; x<nb_node_x; ++x ){
346 for( Integer z=0; z<nb_node_z; ++z ){
347 for( Integer y=0; y<nb_node_y; ++y ){
351 Real nz = zdelta * (
Real)(z+first_node_z);
352 if (m_mesh_dimension==2){
356 else if (m_mesh_dimension==1){
360 node_unique_id *= uid_multiplier;
362 nodes_unique_id[node_local_id] = node_unique_id;
366 if (z==(nb_node_z-1) && !is_last_proc)
369 nodes_infos.nocheckAdd(node_unique_id,NodeInfo(owner,Real3(nx,ny,nz)));
378 nb_node_local_id = node_local_id;
382 for(Integer z=0; z<nb_node_z; ++z ){
383 for(Integer y=0; y<nb_node_y; ++y ){
384 for(Integer x=0; x<nb_node_x; ++x ){
387 Real nz = zdelta * (
Real)(z+first_node_z);
388 if (m_mesh_dimension==2){
391 }
else if (m_mesh_dimension==1){
395 node_unique_id *= uid_multiplier;
397 nodes_unique_id[node_local_id] = node_unique_id;
401 if (z==(nb_node_z-1) && !is_last_proc) owner = my_part+1;
402 nodes_infos.nocheckAdd(node_unique_id,NodeInfo(owner,Real3(nx,ny,nz)));
410 nb_node_local_id = node_local_id;
421 if (m_mesh_dimension==1){
424 for( Integer x=0; x<nb_cell_x; ++x ){
425 for( Integer z=0; z<nb_cell_z; ++z ){
426 for( Integer y=0; y<nb_cell_y; ++y ){
427 Integer current_cell_nb_node = 2;
430 cell_unique_id *= uid_multiplier;
432 cells_infos[cells_infos_index] = IT_CellLine2;
435 cells_infos[cells_infos_index] = cell_unique_id;
438 Integer base_id = y + z*nb_node_y + x*nb_node_yz;
439 cells_infos[cells_infos_index+0] = nodes_unique_id[base_id];
440 cells_infos[cells_infos_index+1] = nodes_unique_id[base_id + 1];
442 cells_infos_index += current_cell_nb_node;
447 else if (m_mesh_dimension==2){
450 for( Integer x=0; x<nb_cell_x; ++x ){
451 for( Integer z=0; z<nb_cell_z; ++z ){
452 for( Integer y=0; y<nb_cell_y; ++y ){
453 Integer current_cell_nb_node = 4;
456 cell_unique_id *= uid_multiplier;
458 cells_infos[cells_infos_index] = IT_Quad4;
461 cells_infos[cells_infos_index] = cell_unique_id;
464 Integer base_id = y + z*nb_node_y + x*nb_node_yz;
465 cells_infos[cells_infos_index+0] = nodes_unique_id[base_id];
466 cells_infos[cells_infos_index+1] = nodes_unique_id[base_id + nb_node_yz];
467 cells_infos[cells_infos_index+2] = nodes_unique_id[base_id + nb_node_yz + 1];
468 cells_infos[cells_infos_index+3] = nodes_unique_id[base_id + 1];
470 cells_infos_index += current_cell_nb_node;
475 else if (m_mesh_dimension==3){
476 if (m_zyx_generate==
false){
478 for( Integer x=0; x<nb_cell_x; ++x ){
479 for( Integer z=0; z<nb_cell_z; ++z ){
480 for( Integer y=0; y<nb_cell_y; ++y ){
481 Integer current_cell_nb_node = 8;
483 cell_unique_id *= uid_multiplier;
485 cells_infos[cells_infos_index] = IT_Hexaedron8;
487 cells_infos[cells_infos_index] = cell_unique_id;
489 Integer base_id = y + z*nb_node_y + x*nb_node_yz;
490 cells_infos[cells_infos_index+0] = nodes_unique_id[base_id];
491 cells_infos[cells_infos_index+1] = nodes_unique_id[base_id + 1];
492 cells_infos[cells_infos_index+2] = nodes_unique_id[base_id + nb_node_y + 1];
493 cells_infos[cells_infos_index+3] = nodes_unique_id[base_id + nb_node_y + 0];
494 cells_infos[cells_infos_index+4] = nodes_unique_id[base_id + nb_node_yz];
495 cells_infos[cells_infos_index+5] = nodes_unique_id[base_id + nb_node_yz + 1];
496 cells_infos[cells_infos_index+6] = nodes_unique_id[base_id + nb_node_yz + nb_node_y + 1];
497 cells_infos[cells_infos_index+7] = nodes_unique_id[base_id + nb_node_yz + nb_node_y + 0];
498 cells_infos_index += current_cell_nb_node;
504 for( Integer z=0; z<nb_cell_z; ++z ){
505 for( Integer y=0; y<nb_cell_y; ++y ){
506 for( Integer x=0; x<nb_cell_x; ++x ){
507 Integer current_cell_nb_node = 8;
509 cell_unique_id *= uid_multiplier;
510 debug() <<
"[SodMeshGenerator::generateMesh] + m_zyx_generate "<<x<<
"x"<<y<<
"x"<<z<<
":"<<
", uid=" << cell_unique_id;
511 cells_infos[cells_infos_index] = IT_Hexaedron8;
513 cells_infos[cells_infos_index] = cell_unique_id;
515 Integer base_id = x + y*nb_node_x + z*nb_node_xy;
516 cells_infos[cells_infos_index+0] = nodes_unique_id[base_id];
517 cells_infos[cells_infos_index+1] = nodes_unique_id[base_id + 1];
518 cells_infos[cells_infos_index+2] = nodes_unique_id[base_id + nb_node_x + 1];
519 cells_infos[cells_infos_index+3] = nodes_unique_id[base_id + nb_node_x + 0];
520 cells_infos[cells_infos_index+4] = nodes_unique_id[base_id + nb_node_xy];
521 cells_infos[cells_infos_index+5] = nodes_unique_id[base_id + nb_node_xy + 1];
522 cells_infos[cells_infos_index+6] = nodes_unique_id[base_id + nb_node_xy + nb_node_x + 1];
523 cells_infos[cells_infos_index+7] = nodes_unique_id[base_id + nb_node_xy + nb_node_x + 0];
524 debug() <<
"[SodMeshGenerator::generateMesh] + m_zyx_generate nodes: "
525 << cells_infos[cells_infos_index+0] <<
", "
526 << cells_infos[cells_infos_index+1] <<
", "
527 << cells_infos[cells_infos_index+2] <<
", "
528 << cells_infos[cells_infos_index+3] <<
", "
529 << cells_infos[cells_infos_index+4] <<
", "
530 << cells_infos[cells_infos_index+5] <<
", "
531 << cells_infos[cells_infos_index+6] <<
", "
532 << cells_infos[cells_infos_index+7];
533 cells_infos_index += current_cell_nb_node;
540 mesh->setDimension(m_mesh_dimension);
541 mesh->allocateCells(mesh_nb_cell,cells_infos,
true);
547 IItemFamily* family = mesh->itemFamily(
IK_Node);
548 family->itemsUniqueIdToLocalId(nodes_local_id,nodes_unique_id);
549 NodeInfoListView nodes_internal(family);
550 for( Integer i=0; i<nb_node_local_id; ++i ){
551 Node node = nodes_internal[nodes_local_id[i]];
552 Int64 unique_id = nodes_unique_id[i];
553 nodes_coord_var[node] = nodes_infos.lookupValue(unique_id).m_coord;
558 nodes_coord_var.synchronize();
561 SodStandardGroupsBuilder groups_builder(
traceMng());
562 Real max_x = xdelta * nb_cell_x;
563 Real max_y = ydelta * nb_cell_y;
565 if (m_mesh_dimension==2){
567 info()<<
"[SodMeshGenerator::generateMesh] max_y=" << max_y;
570 groups_builder.generateGroups(mesh,Real3::null(),Real3(max_x,max_y,max_z),middle_x,middle_height);
573 bool is_random = !math::isNearlyZero(m_random_coef);
575 if (m_mesh_dimension==1)
576 throw NotImplementedException(A_FUNCINFO,
"Randomisation for 1D mesh");
577 info() <<
"** ** ** Randomize node positions coef=" << m_random_coef;
578 for( Integer x=0; x<nb_node_x; ++x ){
579 for( Integer z=0; z<nb_node_z; ++z ){
580 for( Integer y=0; y<nb_node_y; ++y ){
584 if (x!=0 && (x+1)!=nb_node_x && (z+first_node_z)!=0
585 && (z+first_node_z)!=(total_para_node_z-1)
586 && (m_mesh_dimension==2 || (y!=0 && y!=(nb_node_y-1)))){
591 xd = xd + (xr-0.5)*xdelta*m_random_coef;
592 yd = yd + (yr-0.5)*ydelta*m_random_coef;
593 zd = zd + (zr-0.5)*zdelta*m_random_coef;
596 if (m_mesh_dimension==2){
601 Int64 node_unique_id = y + (z+first_node_z)*nb_node_y + x*nb_node_y*total_para_node_z;
602 Real3 pos = nodes_infos.lookupValue(node_unique_id).m_coord;
604 pos += Real3(xd,yd,zd);
606 nodes_infos.add(node_unique_id,NodeInfo(0,pos));
612 nodes_coord_var[inode] = nodes_infos.lookupValue(node.uniqueId()).m_coord;
614 nodes_coord_var.synchronize();
616 info() <<
"End of mesh generation";
656ARCANE_REGISTER_SERVICE_SOD3DMESHGENERATOR(Sod3D,Sod3DMeshGenerator);
Fonctions utilitaires sur le maillage.
Generation de la classe de base du Service.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual bool isParallel() const =0
Retourne true si l'exécution est parallèle.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Paramètres nécessaires à la construction d'un maillage.
Structure contenant les informations pour créer un service.
Service de génération d'un tube à choc 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.
bool m_zyx_generate
true si on génère en z, puis y et enfin x
bool m_z_is_total
true si z est le nombre total de couche pour l'ensemble des procs.
Real m_xyz_delta[3]
les deltas
Vue constante d'un tableau de type T.
Interface du gestionnaire de traces.
Classe d'accès aux traces.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage error() const
Flot pour un message d'erreur.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
Espace de nom pour l'utilisation des accélérateurs.
Integer multiply(Integer x, Integer y, Integer z)
Multiplie trois 'Integer' et vérifie que le résultat peut être contenu dans un 'Integer'.
Real toReal(Real r)
Converti r en un Real.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int64 _generateCellUniqueId(Integer x, Integer y, Integer z, Integer nb_y, Int64 first_z, Int64 total_para_z)
Génère un UniqueId à partir des indices de bloc (x,y,z).
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
@ IK_Node
Entité de maillage de genre noeud.
ConstArrayView< Integer > IntegerConstArrayView
Equivalent C d'un tableau à une dimension d'entiers.
Int32 Integer
Type représentant un entier.