Arcane  v4.1.0.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,
59 bool z_is_total,Int32 mesh_dimension,Real random_coef,
60 Real delta0,Real delta1,Real delta2)
61 : TraceAccessor(tm),
62 m_wanted_x(wanted_x), m_wanted_y(wanted_y), m_wanted_z(wanted_z),
63 m_zyx_generate(zyx), m_z_is_total(z_is_total), m_mesh_dimension(mesh_dimension),
64 m_random_coef(random_coef)
65 {
66 m_xyz_delta[0] = delta0;
67 m_xyz_delta[1] = delta1;
68 m_xyz_delta[2] = delta2;
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;
87 int m_mesh_dimension;
88 Real m_random_coef;
89
90 private:
91};
92
93/*---------------------------------------------------------------------------*/
94/*---------------------------------------------------------------------------*/
95
96SodMeshGenerator::
97SodMeshGenerator(IPrimaryMesh* mesh,bool zyx)
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
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
195 Int64 unique_id = ay + (az+first_z)*anb_y + ax*anb_y*total_para_z;
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/*---------------------------------------------------------------------------*/
628class Sod3DMeshGenerator
630{
631 public:
632 Sod3DMeshGenerator(const ServiceBuildInfo& sbi)
634 public:
635 void fillMeshBuildInfo(MeshBuildInfo& build_info) override
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;
650 SodMeshGenerator::Impl x(traceMng(),zyx,wanted_x,wanted_y,wanted_z,
651 z_is_total,3,random_coef,delta0,delta1,delta2);
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.
ArcaneSod3DMeshGeneratorObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
CaseOptionsSod3DMeshGenerator * options() const
Options du jeu de données du service.
Interface du gestionnaire de traces.
Paramètres nécessaires à la construction d'un maillage.
Structure contenant les informations pour créer un 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.
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.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage error() const
Flot pour un message d'erreur.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
Espace de nom pour l'utilisation des accélérateurs.
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.
Definition UtilsTypes.h:355
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:357
@ IK_Node
Entité de maillage de genre noeud.
double Real
Type représentant un réel.
ConstArrayView< Integer > IntegerConstArrayView
Equivalent C d'un tableau à une dimension d'entiers.
Definition UtilsTypes.h:502
std::int32_t Int32
Type entier signé sur 32 bits.