Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
SodMeshGenerator.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* SodMeshGenerator.cc (C) 2000-2024 */
9/* */
10/* Service de génération d'un maillage à-la 'sod'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
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"
20
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"
38
39#include "arcane/std/IMeshGenerator.h"
40#include "arcane/std/SodMeshGenerator.h"
41#include "arcane/std/internal/SodStandardGroupsBuilder.h"
42
43#include "arcane/std/Sod3DMeshGenerator_axl.h"
44
45/*---------------------------------------------------------------------------*/
46/*---------------------------------------------------------------------------*/
47
48namespace Arcane
49{
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
55: public TraceAccessor
56{
57 public:
58 Impl(ITraceMng* tm,bool zyx,Int32 wanted_x,Int32 wanted_y,Int32 wanted_z,
60 Real delta0,Real delta1,Real delta2)
62 m_wanted_x(wanted_x), m_wanted_y(wanted_y), m_wanted_z(wanted_z),
64 m_random_coef(random_coef)
65 {
69 }
70
71 public:
72 IntegerConstArrayView communicatingSubDomains() const
73 {
74 return m_communicating_sub_domains;
75 }
76 bool generateMesh(IPrimaryMesh* mesh);
77
78 private:
79
80 Integer m_wanted_x;
81 Integer m_wanted_y;
82 Integer m_wanted_z;
83 UniqueArray<Integer> m_communicating_sub_domains;
86 Real m_xyz_delta[3];
87 int m_mesh_dimension;
88 Real m_random_coef;
89
90 private:
91};
92
93/*---------------------------------------------------------------------------*/
94/*---------------------------------------------------------------------------*/
95
96SodMeshGenerator::
97SodMeshGenerator(IPrimaryMesh* mesh,bool zyx)
98: TraceAccessor(mesh->traceMng())
99, m_mesh(mesh)
100, m_zyx_generate(zyx)
101{
102}
103
104/*---------------------------------------------------------------------------*/
105/*---------------------------------------------------------------------------*/
106
107SodMeshGenerator::
108~SodMeshGenerator()
109{
110 // Nécessaire pour std::unique_ptr.
111}
112
113/*---------------------------------------------------------------------------*/
114/*---------------------------------------------------------------------------*/
115
116IntegerConstArrayView SodMeshGenerator::
117communicatingSubDomains() const
118{
119 if (m_p.get())
120 return m_p->communicatingSubDomains();
121 return {};
122}
123
124/*---------------------------------------------------------------------------*/
125/*---------------------------------------------------------------------------*/
126
127bool SodMeshGenerator::
128readOptions(XmlNode node)
129{
130 Int32 wanted_x = node.child("x").valueAsInteger();
131 Int32 wanted_y = 0;
132 Int32 wanted_z = 0;
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";
139 mesh_dimension = 1;
140 wanted_z = 1;
141 wanted_y = 1;
142 }
143 else if (z_node.null()){
144 info() << "[SodMeshGenerator] 2D";
145 // WARNING: In 2D Z and Y are switched
146 mesh_dimension = 2;
147 //z_node = node.child("y");
148 wanted_z = y_node.valueAsInteger();
149 wanted_y = 1;
150 }
151 else{
152 info() << "[SodMeshGenerator] 3D";
153 mesh_dimension = 3;
154 wanted_y = y_node.valueAsInteger();
155 wanted_z = z_node.valueAsInteger();
156 }
157
158 bool z_is_total = z_node.attr("total").valueAsBoolean();
159
160 Real delta0 = x_node.attr("delta").valueAsReal();
161 Real delta1 = y_node.attr("delta").valueAsReal();
162 Real delta2 = z_node.attr("delta").valueAsReal();
163
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>";
171 return true;
172 }
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);
175 return false;
176}
177
178/*---------------------------------------------------------------------------*/
179/*---------------------------------------------------------------------------*/
186inline Int64
187_generateCellUniqueId(Integer x,Integer y,Integer z,Integer nb_y,
188 Int64 first_z,Int64 total_para_z)
189{
190 Int64 ax = x;
191 Int64 ay = y;
192 Int64 az = z;
193 Int64 anb_y = nb_y;
194
196 return unique_id;
197}
198
199/*---------------------------------------------------------------------------*/
200/*---------------------------------------------------------------------------*/
201
202bool SodMeshGenerator::
203generateMesh()
204{
205 return m_p->generateMesh(m_mesh);
206}
207
208/*---------------------------------------------------------------------------*/
209/*---------------------------------------------------------------------------*/
210
211bool SodMeshGenerator::Impl::
212generateMesh(IPrimaryMesh* mesh)
213{
214 info() << "Generate Mesh from SodMeshGenerator";
215
216 IParallelMng* pm = mesh->parallelMng();
217 bool is_parallel = pm->isParallel();
218 Int32 nb_part = pm->commSize();
219 if (is_parallel){
220 if (m_z_is_total)
221 m_wanted_z /= nb_part;
222 }
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;
227
228 // Positionne des propriétés sur le maillage pour qu'il puisse connaître
229 // le nombre de mailles dans chaque direction. Cela est utilisé
230 // notammement par CartesianMesh.
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);
235
236 Int32 my_part = pm->commRank();
237 bool is_first_proc = (my_part==0);
238 bool is_last_proc = ((1+my_part)==nb_part);
239 Int64 total_para_cell_z = ((Int64)nb_cell_z) * ((Int64)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;
243 if (is_parallel){
244 if (is_first_proc || is_last_proc){
245 m_communicating_sub_domains.resize(1);
246 first_cell_z = nb_cell_z*my_part;
247 if (is_first_proc){
248 m_communicating_sub_domains[0] = my_part+1;
249 first_cell_z = 0;
250 }
251 else if (is_last_proc){
252 m_communicating_sub_domains[0] = my_part-1;
253 }
254 else{
255 }
256 first_node_z = first_cell_z;
257 }
258 else{
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;
264 }
265 }
266
267 //Integer nb_face_node = 0;
268 Integer nb_node_x = nb_cell_x+1;
269 Integer nb_node_y = -1;
270 Integer nb_node_z = nb_cell_z+1;
271
272 if (m_mesh_dimension==3){
273 nb_node_y = nb_cell_y + 1;
274 }
275 else if (m_mesh_dimension==2){
276 nb_node_y = 1;
277 }
278 else if (m_mesh_dimension==1){
279 nb_node_y = 1;
280 nb_node_z = 1;
281 }
282
283 Integer nb_node_xy = CheckedConvert::multiply(nb_node_x,nb_node_y);
284 Integer nb_node_yz = CheckedConvert::multiply(nb_node_y,nb_node_z);
285
286 Integer nb_cell_xy = CheckedConvert::multiply(nb_cell_x,nb_cell_y);
287 Integer nb_cell_yz = CheckedConvert::multiply(nb_cell_y,nb_cell_z);
288 Integer nb_cell_xz = CheckedConvert::multiply(nb_cell_x,nb_cell_z);
289
290 Integer nb_face_x = CheckedConvert::multiply(nb_node_x,nb_cell_yz);
291 Integer nb_face_y = CheckedConvert::multiply(nb_node_y,nb_cell_xz);
292 Integer nb_face_z = CheckedConvert::multiply(nb_node_z,nb_cell_xy);
293
294 Integer mesh_nb_cell = CheckedConvert::multiply(nb_cell_x,nb_cell_y,nb_cell_z);
295 Integer mesh_nb_node = CheckedConvert::multiply(nb_node_x,nb_node_y,nb_node_z);
296 Integer mesh_nb_face = nb_face_x + nb_face_y + nb_face_z;
297
298 // Pour tester des uid>32bits, il suffit
299 // de changer ce multiplier et de le mettre
300 // par exemple a 1000000
301 const Int64 uid_multiplier = 1;
302 //const Int64 uid_multiplier = 12500000;
303
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;
309
310 info() << "Number of nodes " << mesh_nb_node;
311 info() << "Number of faces " << mesh_nb_face;
312 info() << "Number of cells " << mesh_nb_cell;
313
314 info() << "nb node_yz=" << nb_node_yz;
315
316 // Création des noeuds
317
318 Int64UniqueArray nodes_unique_id(mesh_nb_node);
319
320 HashTableMapT<Int64,NodeInfo> nodes_infos(mesh_nb_node,true);
321
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];
325 // Le milieu pour determiner ZG et ZD
326 Real middle_x = ARCANE_REAL(0.5);
327 // Le milieu pour determiner HAUT et BAS
328 Real middle_height = ARCANE_REAL((nb_cell_y/2)*ydelta);
329
330 if (m_xyz_delta[0]!=0.0)
331 middle_x = m_xyz_delta[0] * (nb_cell_x/2);
332
333 if (m_mesh_dimension==2){
334 zdelta = ydelta;
335 middle_height = (nb_cell_z/2)*zdelta;
336 }
337
338 info() << "Xdelta=" << xdelta<< ", Ydelta=" << ydelta << ", Zdelta=" << zdelta;
339 info() << "middle_x=" << middle_x<< ", middle_height=" << middle_height;
340
341 // Création des noeuds
342 Integer nb_node_local_id = 0;
343 if (m_zyx_generate==false){
344 Integer node_local_id = 0;
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 ){
348
349 Real nx = xdelta * (Real)(x);
350 Real ny = ydelta * (Real)(y);
351 Real nz = zdelta * (Real)(z+first_node_z);
352 if (m_mesh_dimension==2){
353 ny = nz;
354 nz = 0.0;
355 }
356 else if (m_mesh_dimension==1){
357 ny = nz = 0.0;
358 }
359 Int64 node_unique_id = (Int64)y + ((Int64)z+first_node_z)*(Int64)nb_node_y + (Int64)x*nb_node_y*total_para_node_z;
360 node_unique_id *= uid_multiplier;
361
362 nodes_unique_id[node_local_id] = node_unique_id;
363 Integer owner = my_part;
364 // S'il s'agit de la couche de noeud du dessus (z max),
365 // elle appartient au sous-domaine suivant
366 if (z==(nb_node_z-1) && !is_last_proc)
367 owner = my_part+1;
368
369 nodes_infos.nocheckAdd(node_unique_id,NodeInfo(owner,Real3(nx,ny,nz)));
370
371 //debug(Trace::High) << "Add coord uid=" << node_unique_id << " pos=" << Real3(nx,ny,nz);
372 //info() << "Add coord uid=" << node_unique_id << " pos=" << Real3(nx,ny,nz);
373
374 ++node_local_id;
375 }
376 }
377 }
378 nb_node_local_id = node_local_id;
379 }
380 else{ // m_zyx_generate
381 Integer node_local_id = 0;
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 ){
385 Real nx = xdelta * (Real)(x);
386 Real ny = ydelta * (Real)(y);
387 Real nz = zdelta * (Real)(z+first_node_z);
388 if (m_mesh_dimension==2){
389 ny = nz;
390 nz = 0.0;
391 } else if (m_mesh_dimension==1){
392 ny = nz = 0.0;
393 }
394 Int64 node_unique_id = (Int64)x + (Int64)y*nb_node_x + ((Int64)z+first_node_z)*(Int64)nb_node_x*(Int64)nb_node_y;
395 node_unique_id *= uid_multiplier;
396
397 nodes_unique_id[node_local_id] = node_unique_id;
398 Integer owner = my_part;
399 // S'il s'agit de la couche de noeud du dessus (z max),
400 // elle appartient au sous-domaine suivant
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)));
403 //debug(Trace::High) << "Add coord uid=" << node_unique_id << " pos=" << Real3(nx,ny,nz);
404 //info() << "Add coord uid=" << node_unique_id << " pos=" << Real3(nx,ny,nz);
405 //info() << "[SodMeshGenerator::generateMesh] node @ "<<x<<"x"<<y<<"x"<<z<<":"<<", uid=" << node_unique_id;
406 ++node_local_id;
407 }
408 }
409 }
410 nb_node_local_id = node_local_id;
411 }
412
413 // Création des mailles
414
415 // Infos pour la création des mailles
416 // par maille: 1 pour son unique id,
417 // 1 pour son type,
418 // 8 pour chaque noeud
419 Int64UniqueArray cells_infos(mesh_nb_cell*10);
420
421 if (m_mesh_dimension==1){
422 Integer cells_infos_index = 0;
423
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;
428
429 Int64 cell_unique_id = _generateCellUniqueId(x,y,z,nb_cell_y,first_cell_z,total_para_cell_z);
430 cell_unique_id *= uid_multiplier;
431
432 cells_infos[cells_infos_index] = IT_CellLine2;
433 ++cells_infos_index;
434
435 cells_infos[cells_infos_index] = cell_unique_id;
436 ++cells_infos_index;
437
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];
441
442 cells_infos_index += current_cell_nb_node;
443 }
444 }
445 }
446 }
447 else if (m_mesh_dimension==2){
448 Integer cells_infos_index = 0;
449
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;
454
455 Int64 cell_unique_id = _generateCellUniqueId(x,y,z,nb_cell_y,first_cell_z,total_para_cell_z);
456 cell_unique_id *= uid_multiplier;
457
458 cells_infos[cells_infos_index] = IT_Quad4;
459 ++cells_infos_index;
460
461 cells_infos[cells_infos_index] = cell_unique_id;
462 ++cells_infos_index;
463
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];
469
470 cells_infos_index += current_cell_nb_node;
471 }
472 }
473 }
474 }
475 else if (m_mesh_dimension==3){
476 if (m_zyx_generate==false){
477 Integer cells_infos_index = 0;
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;
482 Int64 cell_unique_id = _generateCellUniqueId(x,y,z,nb_cell_y,first_cell_z,total_para_cell_z);
483 cell_unique_id *= uid_multiplier;
484// info() << "[SodMeshGenerator::generateMesh] "<<x<<"x"<<y<<"x"<<z<<":"<<", uid=" << cell_unique_id;
485 cells_infos[cells_infos_index] = IT_Hexaedron8;
486 ++cells_infos_index;
487 cells_infos[cells_infos_index] = cell_unique_id;
488 ++cells_infos_index;
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;
499 }
500 }
501 }
502 }else{ // m_zyx_generate
503 Integer cells_infos_index = 0;
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;
508 Int64 cell_unique_id = _generateCellUniqueId(x,y,z,nb_cell_y,first_cell_z,total_para_cell_z);
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;
512 ++cells_infos_index;
513 cells_infos[cells_infos_index] = cell_unique_id;
514 ++cells_infos_index;
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;
534 }
535 }
536 }
537 }
538 }
539
540 mesh->setDimension(m_mesh_dimension);
541 mesh->allocateCells(mesh_nb_cell,cells_infos,true);
542
543 VariableNodeReal3& nodes_coord_var(mesh->nodesCoordinates());
544 {
545 // Remplit la variable contenant les coordonnées des noeuds
546 Int32UniqueArray nodes_local_id(nodes_unique_id.size());
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;
554 //info() << "Set coord " << ItemPrinter(node) << " coord=" << nodes_coord_var[node]
555 // << " coord2=" << nodes_infos.lookupValue(unique_id).m_coord;
556 }
557 }
558 nodes_coord_var.synchronize();
559
560 {
561 SodStandardGroupsBuilder groups_builder(traceMng());
562 Real max_x = xdelta * nb_cell_x;
563 Real max_y = ydelta * nb_cell_y;
564 // Dans le cas 2D, nb_cell_z et nb_cell_y sont swappés
565 if (m_mesh_dimension==2){
566 max_y = ydelta * Convert::toReal(total_para_cell_z);
567 info()<< "[SodMeshGenerator::generateMesh] max_y=" << max_y;
568 }
569 const Real max_z = zdelta * Convert::toReal(total_para_cell_z);
570 groups_builder.generateGroups(mesh,Real3::null(),Real3(max_x,max_y,max_z),middle_x,middle_height);
571 }
572
573 bool is_random = !math::isNearlyZero(m_random_coef);
574 if (is_random){
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 ){
581 Real xd = xdelta;
582 Real yd = ydelta;
583 Real zd = zdelta;
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)))){
587 Real xr = (Real)::rand() / (Real)RAND_MAX;
588 Real yr = (Real)::rand() / (Real)RAND_MAX;
589 Real zr = (Real)::rand() / (Real)RAND_MAX;
590 //info() << " xr=" << xr << "yr=" << yr << " zr=" << zr;
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;
594 }
595
596 if (m_mesh_dimension==2){
597 yd = zd;
598 zd = 0.0;
599 }
600
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;
603
604 pos += Real3(xd,yd,zd);
605
606 nodes_infos.add(node_unique_id,NodeInfo(0,pos));
607 }
608 }
609 }
610 ENUMERATE_NODE(inode,mesh->ownNodes()){
611 Node node = *inode;
612 nodes_coord_var[inode] = nodes_infos.lookupValue(node.uniqueId()).m_coord;
613 }
614 nodes_coord_var.synchronize();
615 }
616 info() << "End of mesh generation";
617 return false;
618}
619
620/*---------------------------------------------------------------------------*/
621/*---------------------------------------------------------------------------*/
622
623/*---------------------------------------------------------------------------*/
624/*---------------------------------------------------------------------------*/
630{
631 public:
634 public:
636 {
637 ARCANE_UNUSED(build_info);
638 }
640 {
641 bool zyx = false;
642 Int32 wanted_x = options()->x();
643 Int32 wanted_y = options()->y();
644 Int32 wanted_z = options()->z();
645 Real random_coef = 0.0;
646 Real delta0 = 0.0;
647 Real delta1 = 0.0;
648 Real delta2 = 0.0;
649 bool z_is_total = false;
652 x.generateMesh(pm);
653 }
654};
655
656ARCANE_REGISTER_SERVICE_SOD3DMESHGENERATOR(Sod3D,Sod3DMeshGenerator);
657
658/*---------------------------------------------------------------------------*/
659/*---------------------------------------------------------------------------*/
660
661} // End namespace Arcane
662
663/*---------------------------------------------------------------------------*/
664/*---------------------------------------------------------------------------*/
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
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.
Definition Lima.cc:120
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.
Vue constante d'un tableau de type T.
Interface du gestionnaire de 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.
Definition Convert.h:87
-*- 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.
Definition UtilsTypes.h:513
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:515
@ IK_Node
Entité de maillage de genre noeud.
ConstArrayView< Integer > IntegerConstArrayView
Equivalent C d'un tableau à une dimension d'entiers.
Definition UtilsTypes.h:644
Int32 Integer
Type représentant un entier.