Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
VoronoiMeshIOService.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* VoronoiMeshIOService.cc (C) 2000-2009 */
9/* */
10/* Lecture/Ecriture d'un maillage voronoi. Format provisoire. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15
16#include "arcane/utils/Iostream.h"
17#include "arcane/utils/StdHeader.h"
18#include "arcane/utils/HashTableMap.h"
19#include "arcane/utils/ValueConvert.h"
20#include "arcane/utils/ScopedPtr.h"
21#include "arcane/utils/ITraceMng.h"
22#include "arcane/utils/String.h"
23#include "arcane/utils/IOException.h"
24#include "arcane/utils/Collection.h"
25#include "arcane/utils/Enumerator.h"
26
27#include "arcane/utils/Real3.h"
28
29#include "arcane/FactoryService.h"
30#include "arcane/IMeshReader.h"
31#include "arcane/ISubDomain.h"
32#include "arcane/IMeshSubMeshTransition.h"
33#include "arcane/IItemFamily.h"
34#include "arcane/Item.h"
35#include "arcane/ItemEnumerator.h"
36#include "arcane/VariableTypes.h"
37#include "arcane/IVariableAccessor.h"
38#include "arcane/IParallelMng.h"
39#include "arcane/IIOMng.h"
40#include "arcane/IMeshUtilities.h"
41#include "arcane/IMeshWriter.h"
42#include "arcane/BasicService.h"
43#include "arcane/XmlNode.h"
44
45/*---------------------------------------------------------------------------*/
46/*---------------------------------------------------------------------------*/
47
48ARCANE_BEGIN_NAMESPACE
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53class VoronoiFile;
54
55/*---------------------------------------------------------------------------*/
56/*---------------------------------------------------------------------------*/
69: public BasicService
70, public IMeshReader
71{
72public:
73
75
77
78public:
79
80 virtual void build() {}
81
82public:
83
84 virtual bool allowExtension(const String& str)
85 {
86 return str=="vor";
87 }
88
89 public:
90
91 virtual eReturnType readMeshFromFile(IPrimaryMesh* mesh,const XmlNode& mesh_node,const String& file_name,
93
94 virtual bool hasCutInfos() const { return false; }
95 virtual ConstArrayView<Integer> communicatingSubDomains() const { return ConstArrayView<Integer>(); }
96
97 private:
98
99 bool _readMesh(IPrimaryMesh* mesh,const String& file_name,const String& dir_name,bool use_internal_partition);
100 bool _readHybridGrid(IPrimaryMesh* mesh,VoronoiFile& voronoi_file,bool use_internal_partition);
101 void _readCellVariable(IMesh* mesh,VoronoiFile& voronoi_file,const String& name_str,Integer nb_cell);
102 void _readItemGroup(IMesh* mesh,VoronoiFile& voronoi_file,const String& name_str,Integer nb_item,
103 eItemKind ik,ConstArrayView<Integer> local_ids);
104 void _createFaceGroup(IMesh* mesh,const String& name,ConstArrayView<Integer> faces_lid);
105 bool _readData(IMesh* mesh,VoronoiFile& voronoi_file,bool use_internal_partition,eItemKind cell_kind,
106 ConstArrayView<Integer> local_ids);
107 void _readNodesHybridGrid(IMesh* mesh,VoronoiFile& voronoi_file,Array<Real3>& node_coords);
108 void _readCellsHybridGrid(IMesh* mesh,VoronoiFile& voronoi_file,
109 Array<Integer>& cells_nb_node,
110 Array<Integer>& cells_type,
111 Array<Int64>& cells_connectivity,
112 Integer& mesh_dimension);
113 void _readFacesMesh(IMesh* mesh,const String& file_name,
114 const String& dir_name,bool use_internal_partition);
115
116private:
119};
120
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123
125{
126 public:
127 static const int BUFSIZE = 10000;
128 public:
129 VoronoiFile(std::istream* stream) : m_stream(stream) {}
130 const char* getNextLine();
131 Real getReal();
132 Integer getInteger();
133 bool isEnd(){ (*m_stream) >> ws; return m_stream->eof(); }
134 private:
135 std::istream* m_stream;
136 char m_buf[BUFSIZE];
137};
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
142const char* VoronoiFile::
143getNextLine()
144{
145 while (m_stream->good()){
146 m_stream->getline(m_buf,sizeof(m_buf)-1);
147 if (m_stream->eof())
148 break;
149 bool is_comment = true;
150 if (m_buf[0]=='\n' || m_buf[0]=='\r')
151 continue;
152 // Regarde si un caractère de commentaire est présent
153 for( int i=0; i<BUFSIZE && m_buf[i]!='\0'; ++i ){
154 if (!isspace(m_buf[i])){
155 is_comment = (m_buf[i]=='#');
156 break;
157 }
158 }
159 if (!is_comment){
160
161 // Supprime le '\n' ou '\r' final
162 for( int i=0; i<BUFSIZE && m_buf[i]!='\0'; ++i ){
163 //cout << " V=" << m_buf[i] << " I=" << (int)m_buf[i] << "\n";
164 if (m_buf[i]=='\n' || m_buf[i]=='\r'){
165 m_buf[i] = '\0';
166 break;
167 }
168 }
169 return m_buf;
170 }
171 }
172 throw IOException("VoronoiFile::getNexLine()","Unexpected EndOfFile");
173}
174
175/*---------------------------------------------------------------------------*/
176/*---------------------------------------------------------------------------*/
177
178Real VoronoiFile::
179getReal()
180{
181 Real v = 0.;
182 (*m_stream) >> ws >> v;
183 if (m_stream->good())
184 return v;
185 throw IOException("VoronoiFile::getReal()","Bad Real");
186}
187
188/*---------------------------------------------------------------------------*/
189/*---------------------------------------------------------------------------*/
190
191Integer VoronoiFile::
192getInteger()
193{
194 Integer v = 0;
195 (*m_stream) >> ws >> v;
196 if (m_stream->good())
197 return v;
198 throw IOException("VoronoiFile::getInteger()","Bad Integer");
199}
200
201/*---------------------------------------------------------------------------*/
202/*---------------------------------------------------------------------------*/
203
204ARCANE_REGISTER_SUB_DOMAIN_FACTORY(VoronoiMeshIOService,IMeshReader,VoronoiMeshIO);
205
206/*---------------------------------------------------------------------------*/
207/*---------------------------------------------------------------------------*/
208
209VoronoiMeshIOService::
210VoronoiMeshIOService(const ServiceBuildInfo& sbi)
211: BasicService(sbi)
212{
213}
214
215/*---------------------------------------------------------------------------*/
216/*---------------------------------------------------------------------------*/
217
218VoronoiMeshIOService::
219~VoronoiMeshIOService()
220{
221 const Integer size = m_variables.size();
222 for(Integer i=0;i<size;++i)
223 {
224 delete m_variables[i];
225 m_variables[i] = NULL;
226 }
227}
228
229/*---------------------------------------------------------------------------*/
230/*---------------------------------------------------------------------------*/
236 const String& filename,const String& dir_name,
238{
239 ARCANE_UNUSED(mesh_node);
240 ARCANE_UNUSED(use_internal_partition);
241
242 bool ret = _readMesh(mesh,filename,dir_name,use_internal_partition);
243 if (ret)
244 return RTError;
245
246 return RTOk;
247}
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
251
252bool VoronoiMeshIOService::
253_readMesh(IPrimaryMesh* mesh,const String& file_name,const String& dir_name,
255{
256 ARCANE_UNUSED(dir_name);
257
258 std::ifstream ifile(file_name.localstr());
259 if (!ifile){
260 error() << "Unable to read file '" << file_name << "'";
261 return true;
262 }
263 VoronoiFile voronoi_file(&ifile);
264
265 // Lecture du type de maillage
266 // TODO: en parallèle, avec use_internal_partition vrai, seul le processeur 0
267 // lit les données. Dans ce cas, inutile que les autres ouvre le fichier.
268
269 bool ret = true;
270 ret = _readHybridGrid(mesh,voronoi_file,use_internal_partition);
271 return ret;
272}
273
274/*---------------------------------------------------------------------------*/
275/*---------------------------------------------------------------------------*/
276
277
278
279/*---------------------------------------------------------------------------*/
280/*---------------------------------------------------------------------------*/
286{
287 ARCANE_UNUSED(mesh);
288
289 const char* func_name = "VoronoiMeshIOService::_readNodesHybridGrid()";
290 const char* buf = voronoi_file.getNextLine();
291 std::istringstream iline(buf);
292 std::string points_str;
293 std::string data_type_str;
294 Integer nb_node = 0;
295 iline >> ws >> nb_node;
296 if (!iline)
297 throw IOException(func_name,"Syntax error while reading number of nodes");
298 if (nb_node<0){
299 String msg = String("Invalid number of nodes: n=") + nb_node;
300 throw IOException(func_name,msg);
301 }
302
303 info() << " Info: " << nb_node;
304
305 // Lecture les coordonnées
306 node_coords.resize(nb_node);
307 {
308 for( Integer i=0; i<nb_node; ++i ){
309 Real nx = voronoi_file.getReal();
310 Real ny = voronoi_file.getReal();
311 Real nz = voronoi_file.getReal();
312 node_coords[i] = Real3(nx,ny,nz);
313 }
314 }
315}
316
317/*---------------------------------------------------------------------------*/
318/*---------------------------------------------------------------------------*/
326 Array<Integer>& cells_nb_node,
327 Array<Integer>& cells_type,
328 Array<Int64>& cells_connectivity,
329 Integer& mesh_dimension)
330{
331 ARCANE_UNUSED(mesh);
332
333 const char* func_name = "VoronoiMeshIOService::_readCellsHybridGrid()";
334 const char* buf = voronoi_file.getNextLine();
335 std::istringstream iline(buf);
336 std::string cells_str;
337 Integer nb_cell = 0;
338 Integer nb_cell_node = 0;
339 iline >> ws >> nb_cell >> ws >> nb_cell_node;
340 if (!iline)
341 throw IOException(func_name,"Syntax error while reading cells");
342 if (nb_cell<0 || nb_cell_node<0){
343 throw IOException(func_name,String::format("Invalid dimensions: nb_cell={0} nb_cell_node={1}",nb_cell,nb_cell_node));
344 }
345
347
348 mesh_dimension = 3; // will be set to two if for all types, nb_edges == nb_faces
349 bool is_mesh_2d = true;
350
351 cells_nb_node.resize(nb_cell);
352 cells_type.resize(nb_cell);
353 cells_connectivity.resize(nb_cell_node);
354 {
355 Integer connectivity_index = 0;
356 for( Integer i=0; i<nb_cell; ++i ){
357 const Integer user_cell_type = voronoi_file.getInteger();
359 cells_type[i] = internal_cell_type;
361 fatal() << "Bad item type " << user_cell_type;
362 /* const Integer n_check = */ voronoi_file.getInteger();
363 ItemTypeInfo* item_type = item_type_mng->typeFromId(internal_cell_type);
364 is_mesh_2d = is_mesh_2d && (item_type->nbLocalEdge() == item_type->nbLocalFace());
365 // optimisable avec un cache local
366 const Integer n = item_type->nbLocalNode();
367 cells_nb_node[i] = n;
368 for( Integer j=0; j<n; ++j ){
369 const Integer node_id = voronoi_file.getInteger();
370 cells_connectivity[connectivity_index] = node_id;
372 }
373 }
374 }
375 if (is_mesh_2d) mesh_dimension = 2;
376}
377
378/*---------------------------------------------------------------------------*/
379/*---------------------------------------------------------------------------*/
380
381bool VoronoiMeshIOService::
383{
384 // const char* func_name = "VoronoiMeshIOService::_readUnstructuredGrid()";
385 //IParallelMng* pm = subDomain()->parallelMng();
386 Integer nb_cell = 0;
387 Integer nb_cell_node = 0;
388 Integer sid = subDomain()->subDomainId();
389 UniqueArray<Real3> node_coords;
393 // Si on utilise le partitionneur interne, seul le sous-domaine lit le maillage
394 bool need_read = true;
395 Integer mesh_dimension(-1);
397 need_read = (sid==0);
398
399 if (need_read){
400 _readNodesHybridGrid(mesh,voronoi_file,node_coords);
401 //nb_node = node_coords.size();
402
403 // Lecture des infos des mailles
404 // Lecture de la connectivité
405 UniqueArray<Integer> cells_nb_node;
406 UniqueArray<Int64> cells_connectivity;
407 UniqueArray<Integer> cells_type;
408 _readCellsHybridGrid(mesh,voronoi_file,cells_nb_node,cells_type,cells_connectivity, mesh_dimension);
409 nb_cell = cells_nb_node.size();
410 nb_cell_node = cells_connectivity.size();
411 cells_local_id.resize(nb_cell);
412
413 // Création des mailles
414 // Infos pour la création des mailles
415 // par maille: 1 pour son unique id,
416 // 1 pour son type,
417 // 1 pour chaque noeud
418 cells_infos.resize(nb_cell*2 + nb_cell_node);
419 {
420 Integer cells_infos_index = 0;
421 Integer connectivity_index = 0;
422 for( Integer i=0; i<nb_cell; ++i ){
423 Integer current_cell_nb_node = cells_nb_node[i];
424 Integer cell_unique_id = i;
425
426 cells_local_id[i] = i;
427
428 cells_infos[cells_infos_index] = cells_type[i];
430
433
434 for( Integer z=0; z<current_cell_nb_node; ++z ){
435 cells_infos[cells_infos_index+z] = cells_connectivity[connectivity_index+z];
436 }
437 cells_infos_index += current_cell_nb_node;
438 connectivity_index += current_cell_nb_node;
439 }
440 }
441
442 }
443
444 Integer dimension = subDomain()->parallelMng()->reduce(Parallel::ReduceMax,mesh_dimension);
445 mesh->setDimension(dimension);
446 mesh->allocateCells(nb_cell,cells_infos,false);
447 mesh->endAllocate();
448
449 // Positionne les coordonnées
450 {
451 VariableNodeReal3& nodes_coord_var(mesh->nodesCoordinates());
452 ENUMERATE_NODE(inode,mesh->allNodes()){
453 Node node = *inode;
454 Int32 node_uid = node.uniqueId().asInt32();
455 nodes_coord_var[inode] = node_coords[node_uid];
456 }
457 }
458
459 // Maintenant, regarde s'il existe des données associées aux fichier
460 bool r = _readData(mesh,voronoi_file,use_internal_partition,IK_Cell,cells_local_id);
461 if (r)
462 return r;
463
464 return false;
465}
466
467
468/*---------------------------------------------------------------------------*/
469/*---------------------------------------------------------------------------*/
470
471bool VoronoiMeshIOService::
472_readData(IMesh* mesh,VoronoiFile& voronoi_file,bool use_internal_partition,
473 eItemKind cell_kind,ConstArrayView<Integer> local_ids)
474{
475 ARCANE_UNUSED(use_internal_partition);
476 ARCANE_UNUSED(local_ids);
477
478 // Seul le sous-domain maitre lit les valeurs. Par contre, les autres
479 // sous-domaines doivent connaitre la liste des variables
480 Integer sid = subDomain()->subDomainId();
481 Integer nb_cell_kind = mesh->nbItem(cell_kind);
482 if (sid==0){
483 _readCellVariable(mesh,voronoi_file,"CellCenter",nb_cell_kind);
484 }
485 if (sid!=0){
486 VariableCellReal3 * var = new VariableCellReal3(VariableBuildInfo(mesh,"CellCenter"));
487 m_variables.add(var);
488 }
489
490 return false;
491}
492
493
494/*---------------------------------------------------------------------------*/
495/*---------------------------------------------------------------------------*/
496
497void VoronoiMeshIOService::
498_readCellVariable(IMesh* mesh,VoronoiFile& voronoi_file,const String& var_name,Integer nb_cell)
499{
500 //TODO Faire la conversion uniqueId() vers localId() correcte
501 Real cx,cy,cz;
502 info() << "Reading values for variable: " << var_name << " n=" << nb_cell;
503 VariableCellReal3 * var = new VariableCellReal3(VariableBuildInfo(mesh,var_name));
504 m_variables.add(var);
505 Real3ArrayView values(var->asArray());
506 for( Integer i=0; i<nb_cell; ++i ){
507 cx = voronoi_file.getReal();
508 cy = voronoi_file.getReal();
509 cz = voronoi_file.getReal();
510 values[i] = Real3(cx,cy,cz);
511 }
512 info() << "Variable build done: " << voronoi_file.isEnd();
513}
514
515/*---------------------------------------------------------------------------*/
516/*---------------------------------------------------------------------------*/
517
518void VoronoiMeshIOService::
519_readItemGroup(IMesh* mesh,VoronoiFile& voronoi_file,const String& name,Integer nb_item,
520 eItemKind ik,ConstArrayView<Integer> local_ids)
521{
522 IItemFamily* item_family = mesh->itemFamily(ik);
523 info() << "Reading group inf for group: " << name;
524
526 for( Integer i=0; i<nb_item; ++i ){
527 Integer v = voronoi_file.getInteger();
528 if (v!=0)
529 ids.add(local_ids[i]);
530 }
531 info() << "Building group: " << name << " nb_element=" << ids.size();
532
533 item_family->createGroup(name,ids);
534}
535
536/*---------------------------------------------------------------------------*/
537/*---------------------------------------------------------------------------*/
538
539ARCANE_END_NAMESPACE
540
541/*---------------------------------------------------------------------------*/
542/*---------------------------------------------------------------------------*/
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Classe de base de service lié à un sous-domaine.
virtual NodeGroup allNodes()=0
Groupe de tous les noeuds.
Interface du service gérant la lecture d'un maillage.
Definition IMeshReader.h:37
eReturnType
Types des codes de retour d'une lecture ou écriture.
Definition IMeshReader.h:42
@ RTError
Erreur lors de l'opération.
Definition IMeshReader.h:44
@ RTOk
Opération effectuée avec succès.
Definition IMeshReader.h:43
virtual ItemTypeMng * itemTypeMng() const =0
Gestionnaire de types d'entités associé
Exception lorsqu'une erreur d'entrée/sortie est détectée.
Definition IOException.h:32
virtual VariableNodeReal3 & nodesCoordinates()=0
Coordonnées des noeuds.
virtual void allocateCells(Integer nb_cell, Int64ConstArrayView cells_infos, bool one_alloc=true)=0
Allocation d'un maillage.
virtual void endAllocate()=0
Indique une fin d'allocation de mailles.
virtual void setDimension(Integer dim)=0
Positionne la dimension du maillage (1D, 2D ou 3D).
Infos sur un type d'entité du maillage.
Integer nbLocalEdge() const
Nombre d'arêtes de l'entité
Integer nbLocalNode() const
Nombre de noeuds de l'entité
Integer nbLocalFace() const
Nombre de faces de l'entité
Gestionnaire des types d'entités de maillage.
Definition ItemTypeMng.h:66
static Integer nbBasicItemType()
nombre de types disponibles
static Integer nbBuiltInItemType()
nombre de types intégrés (hors types additionnels)
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
Structure contenant les informations pour créer un service.
Lecteur des fichiers de maillage au format Voronoi interne IFP.
virtual void build()
Construction de niveau build du service.
UniqueArray< VariableCellReal3 * > m_variables
Table des variables crées localement par lecture du maillage.
virtual eReturnType readMeshFromFile(IPrimaryMesh *mesh, const XmlNode &mesh_node, const String &file_name, const String &dir_name, bool use_internal_partition)
void _readCellsHybridGrid(IMesh *mesh, VoronoiFile &voronoi_file, Array< Integer > &cells_nb_node, Array< Integer > &cells_type, Array< Int64 > &cells_connectivity, Integer &mesh_dimension)
Lecture des mailles et de leur connectivité.
void _readNodesHybridGrid(IMesh *mesh, VoronoiFile &voronoi_file, Array< Real3 > &node_coords)
Lecture des noeuds et de leur coordonnées.
virtual bool allowExtension(const String &str)
Vérifie si le service supporte les fichiers avec l'extension str.
Noeud d'un arbre DOM.
Definition XmlNode.h:51
Chaîne de caractères unicode.
TraceMessage error() const
Flot pour un message d'erreur.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
MeshVariableScalarRefT< Cell, Real3 > VariableCellReal3
Grandeur au centre des mailles de type coordonnées.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
ArrayView< Real3 > Real3ArrayView
Equivalent C d'un tableau à une dimension de Real3.
Definition UtilsTypes.h:625
eItemKind
Genre d'entité de maillage.
@ IK_Cell
Entité de maillage de genre maille.
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
Definition UtilsTypes.h:519
Int32 Integer
Type représentant un entier.