Arcane  4.1.11.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
LimaMalippT.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* LimaMalippT.h (C) 2000-2026 */
9/* */
10/* Lecture d'un fichier au format Lima MLI ou MLI2. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Iostream.h"
15#include "arcane/utils/StdHeader.h"
16#include "arcane/utils/HashTableMap.h"
17#include "arcane/utils/ValueConvert.h"
18#include "arcane/utils/ScopedPtr.h"
19#include "arcane/utils/ArcanePrecomp.h"
20#include "arcane/utils/ITraceMng.h"
21#include "arcane/utils/Real3.h"
22#include "arcane/utils/PlatformUtils.h"
23#include "arcane/utils/FatalErrorException.h"
24#include "arcane/utils/NotSupportedException.h"
25#include "arcane/utils/CheckedConvert.h"
26
27#include "arcane/core/IMeshReader.h"
28#include "arcane/core/ISubDomain.h"
29#include "arcane/core/IIOMng.h"
30#include "arcane/core/IParallelMng.h"
31#include "arcane/core/IPrimaryMesh.h"
32#include "arcane/core/Item.h"
33#include "arcane/core/ItemTypeMng.h"
34#include "arcane/core/ItemGroup.h"
35#include "arcane/core/ArcaneException.h"
36#include "arcane/core/Service.h"
37#include "arcane/core/Timer.h"
39#include "arcane/core/ServiceInfo.h"
40#include "arcane/core/CaseOptionsMain.h"
43#include "arcane/core/VariableTypes.h"
44#include "arcane/core/ServiceBuildInfo.h"
45#include "arcane/core/XmlNodeList.h"
46#include "arcane/core/IXmlDocumentHolder.h"
47#include "arcane/core/IItemFamily.h"
48#include "arcane/core/FactoryService.h"
49#include "arcane/core/AbstractService.h"
51
52#include "arcane/lima/LimaCutInfosReader.h"
53#include "arcane/lima/internal/LimaUtils.h"
54
55#include <Lima/lima++.h>
56
57#include <memory>
58
59/*---------------------------------------------------------------------------*/
60/*---------------------------------------------------------------------------*/
61
62namespace Arcane
63{
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
68using std::string;
69
70template<typename LimaMaliReader>
71class LimaGroupReader;
72
73
74/*---------------------------------------------------------------------------*/
75/*---------------------------------------------------------------------------*/
76
78{
79 public:
80 static Real Hexaedron8Volume(Real3 n[8])
81 {
82 Real v1 = math::matDet((n[6] - n[1]) + (n[7] - n[0]), n[6] - n[3], n[2] - n[0]);
83 Real v2 = math::matDet(n[7] - n[0], (n[6] - n[3]) + (n[5] - n[0]), n[6] - n[4]);
84 Real v3 = math::matDet(n[6] - n[1], n[5] - n[0], (n[6] - n[4]) + (n[2] - n[0]));
85
86 Real res = (v1 + v2 + v3) / 12.0;
87
88 return res;
89 }
90
91 static Real Pyramid5Volume(Real3 n[5])
92 {
93 return math::matDet(n[1] - n[0], n[3] - n[0], n[4] - n[0]) +
94 math::matDet(n[3] - n[2], n[1] - n[2], n[4] - n[2]);
95 }
96
97 static Real Quad4Surface(Real3 n[4])
98 {
99 Real x1 = n[1].x - n[0].x;
100 Real y1 = n[1].y - n[0].y;
101 Real x2 = n[2].x - n[1].x;
102 Real y2 = n[2].y - n[1].y;
103 Real surface = x1 * y2 - y1 * x2;
104
105 x1 = n[2].x - n[0].x;
106 y1 = n[2].y - n[0].y;
107 x2 = n[3].x - n[2].x;
108 y2 = n[3].y - n[2].y;
109
110 surface += x1 * y2 - y1 * x2;
111
112 return surface;
113 }
114
115 static Real Triangle3Surface(Real3 n[3])
116 {
117 Real x1 = n[1].x - n[0].x;
118 Real y1 = n[1].y - n[0].y;
119 Real x2 = n[2].x - n[1].x;
120 Real y2 = n[2].y - n[1].y;
121
122 return x1 * y2 - y1 * x2;
123 }
124};
125
126/*---------------------------------------------------------------------------*/
127/*---------------------------------------------------------------------------*/
135template<typename LimaMaliReader>
136class LimaMalippMeshBase
137: public TraceAccessor
138{
139 public:
140 LimaMalippMeshBase(ITraceMng* trace_mng)
141 : TraceAccessor(trace_mng) {}
142 virtual ~LimaMalippMeshBase() = default;
143
144 public:
145 public:
146 virtual bool readMeshPart(ITimerMng* timer_mng, LimaMaliReader* reader, IPrimaryMesh* mesh,
147 const String& filename, Real length_multiplier) = 0;
148
149 protected:
150 void _createGroupFromUniqueIds(IMesh* mesh, const String& name, eItemKind ik,
151 Int64ConstArrayView unique_ids);
152 void _createGroupFromHashTable(IMesh* mesh, const String& name, eItemKind ik,
153 Int64ConstArrayView unique_ids,
154 const HashTableMapT<Int64, Int32>& converter);
155 void _setCoords(Real3ConstArrayView coords, HashTableMapT<Int64, Real3>& nodes_coords,
156 Int64 current_unique_id);
157 void _createGroups(IMesh* mesh, eItemKind item_kind, LimaGroupReader<LimaMaliReader>* reader,
158 HashTableMapT<Int64, Int32>* converter);
159 private:
160};
161
162/*---------------------------------------------------------------------------*/
163/*---------------------------------------------------------------------------*/
170template <typename ReaderWrapper>
171class LimaMalippReaderT
172: public LimaMalippMeshBase<typename ReaderWrapper::LimaMaliReaderType>
173{
175 using TraceAccessor::log;
177 public:
178 typedef typename ReaderWrapper::LimaMaliReaderType LimaMaliReader;
179 public:
180 LimaMalippReaderT(IParallelMng* pm)
181 : LimaMalippMeshBase<LimaMaliReader>(pm->traceMng()),
182 m_cut_infos_reader(new LimaCutInfosReader(pm))
183 {}
184
185 ~LimaMalippReaderT() override
186 {
187 delete m_cut_infos_reader;
188 }
189
190 public:
191 public:
192 bool readMeshPart(ITimerMng* timer_mng,LimaMaliReader* reader,
193 IPrimaryMesh* mesh, const String& filename,
194 Real length_multiplier) override;
195
196 private:
197 LimaCutInfosReader* m_cut_infos_reader;
198 ReaderWrapper m_wrapper;
199
200 bool _readMeshPart(ITimerMng* timer_mng,LimaMaliReader* reader, IPrimaryMesh* mesh,
201 const String& filename, Real length_multiplier);
202};
203
204/*---------------------------------------------------------------------------*/
205/*---------------------------------------------------------------------------*/
206
207template<typename LimaMaliReader>
208class LimaMalippReaderWrapper
209{
210 public:
211 typedef LimaMaliReader LimaMaliReaderType;
212 typedef typename LimaMaliReader::NuageReader LimaNodeGroup;
213
214 public:
215 LimaMalippReaderWrapper()
216 : m_mali_reader(0)
217 {}
218 void setReader(LimaMaliReader* reader)
219 {
220 m_mali_reader = reader;
221 }
222 LimaMaliReader* reader()
223 {
224 return m_mali_reader;
225 }
226
227 public:
228 Lima::size_type
229 _readGroup(typename LimaMaliReader::SurfaceReader reader,
230 Lima::size_type begin, Lima::size_type n, Lima::size_type* buffer)
231 {
232 return reader.lire_mailles_ids(begin, n, buffer);
233 }
234 Lima::size_type
235 _readGroup(typename LimaMaliReader::VolumeReader reader,
236 Lima::size_type begin, Lima::size_type n, Lima::size_type* buffer)
237 {
238 return reader.lire_mailles_ids(begin, n, buffer);
239 }
240 Lima::size_type
241 _readGroup(typename LimaMaliReader::LigneReader reader,
242 Lima::size_type begin, Lima::size_type n, Lima::size_type* buffer)
243 {
244 return reader.lire_bras_ids(begin, n, buffer);
245 }
246
247 Lima::size_type
248 _readGroup(typename LimaMaliReader::NuageReader reader,
249 Lima::size_type begin, Lima::size_type n, Lima::size_type* buffer)
250 {
251 return reader.lire_noeuds_ids(begin, n, buffer);
252 }
253
254 double* allocateNodesCoordsBuffer(Lima::size_type buf_size)
255 {
256 return m_mali_reader->allouer_tampon_coords(buf_size);
257 }
258 Lima::size_type* allocateNodesIdBuffer(Lima::size_type buf_size)
259 {
260 return m_mali_reader->allouer_tampon_ids(buf_size);
261 }
262 Lima::size_type readNodes(Lima::size_type begin, Lima::size_type count,
263 Lima::size_type* ids, double* coords)
264 {
265 return m_mali_reader->lire_noeuds(begin, count, ids, coords);
266 }
267
268 template <typename LimaGroupReader>
269 void readGroup(LimaGroupReader& reader, Int64Array& items_unique_id)
270 {
271 using namespace Lima;
272 //cout << "----------------------------------------------------------"
273 // << reader.nom();
274 size_type* buffer = 0;
275 const Integer nb_item = CheckedConvert::toInteger(reader.composition().nb_elements);
276 items_unique_id.resize(nb_item);
277 const Integer step_size = nb_item > 10000 ? nb_item / 10 : nb_item;
278 buffer = reader.allouer_tampon_ids(step_size);
279 Integer begin = 0;
280 for (Integer i = 0; i * step_size < nb_item; ++i) {
281 const Integer count = CheckedConvert::toInteger(_readGroup(reader, (size_type)(i * step_size), (size_type)step_size, buffer));
282 size_type* ptr = buffer;
283 for (Integer n = 0; n < count; ++n) {
284 size_type lima_id = *ptr++;
285 items_unique_id[begin + n] = lima_id - 1;
286 //cout << lima_id << " ";
287 }
288 begin += count;
289 }
290 delete[] buffer;
291 //cout << endl;
292 }
293
294 protected:
295 LimaMaliReader* m_mali_reader;
299};
300
301/*---------------------------------------------------------------------------*/
302/*---------------------------------------------------------------------------*/
303
304template<typename LimaMaliReader>
305class LimaGroupReader
306{
307 public:
308 LimaGroupReader(LimaMalippReaderWrapper<LimaMaliReader>* wrapper)
309 : m_wrapper(wrapper)
310 {}
311 virtual ~LimaGroupReader() {}
312 virtual void read(const String& name, Int64Array& items_unique_id) = 0;
313
314 public:
315 virtual StringConstArrayView groupsName()
316 {
317 std::vector<std::string> groups;
318 _getGroupsName(groups);
319 m_groups_name.clear();
320 for (size_t i = 0, is = groups.size(); i < is; ++i)
321 m_groups_name.add(String(groups[i]));
322 return m_groups_name;
323 }
324
325 protected:
326 virtual void _getGroupsName(std::vector<std::string>& groups) = 0;
327
328 protected:
330
331 private:
332 StringUniqueArray m_groups_name;
333};
334
335template<typename LimaMaliReader>
336class NodeGroupReader
337: public LimaGroupReader<LimaMaliReader>
338{
339 public:
340 NodeGroupReader(LimaMalippReaderWrapper<LimaMaliReader>* wrapper)
341 : LimaGroupReader<LimaMaliReader>(wrapper)
342 {}
343 virtual void read(const String& name, Int64Array& items_unique_id)
344 {
345 typename LimaMaliReader::NuageReader r = this->m_wrapper->reader()->nuage(name.localstr());
346 this->m_wrapper->readGroup(r, items_unique_id);
347 }
348 virtual void _getGroupsName(std::vector<std::string>& groups)
349 {
350 this->m_wrapper->reader()->liste_nuages(groups);
351 }
352
353 private:
354};
355
356template<typename LimaMaliReader>
357class EdgeGroupReader
358: public LimaGroupReader<LimaMaliReader>
359{
360 public:
361 EdgeGroupReader(LimaMalippReaderWrapper<LimaMaliReader>* wrapper)
362 : LimaGroupReader<LimaMaliReader>(wrapper)
363 {}
364 virtual void read(const String& name, Int64Array& items_unique_id)
365 {
366 typename LimaMaliReader::LigneReader r = this->m_wrapper->reader()->ligne(name.localstr());
367 this->m_wrapper->readGroup(r, items_unique_id);
368 }
369 virtual void _getGroupsName(std::vector<std::string>& groups)
370 {
371 this->m_wrapper->reader()->liste_lignes(groups);
372 }
373
374 private:
375};
376
377template<typename LimaMaliReader>
378class FaceGroupReader
379: public LimaGroupReader<LimaMaliReader>
380{
381 public:
382 FaceGroupReader(LimaMalippReaderWrapper<LimaMaliReader>* wrapper)
383 : LimaGroupReader<LimaMaliReader>(wrapper)
384 {
385 }
386 virtual void read(const String& name, Int64Array& items_unique_id)
387 {
388 typename LimaMaliReader::SurfaceReader r = this->m_wrapper->reader()->surface(name.localstr());
389 this->m_wrapper->readGroup(r, items_unique_id);
390 }
391 virtual void _getGroupsName(std::vector<std::string>& groups)
392 {
393 this->m_wrapper->reader()->liste_surfaces(groups);
394 }
395};
396
397template<typename LimaMaliReader>
398class CellGroupReader
399: public LimaGroupReader<LimaMaliReader>
400{
401 public:
402 CellGroupReader(LimaMalippReaderWrapper<LimaMaliReader>* wrapper)
403 : LimaGroupReader<LimaMaliReader>(wrapper)
404 {
405 }
406 virtual void read(const String& name, Int64Array& items_unique_id)
407 {
408 typename LimaMaliReader::VolumeReader r = this->m_wrapper->reader()->volume(name.localstr());
409 this->m_wrapper->readGroup(r, items_unique_id);
410 }
411 virtual void _getGroupsName(std::vector<std::string>& groups)
412 {
413 this->m_wrapper->reader()->liste_volumes(groups);
414 }
415
416 private:
417};
418
419/*---------------------------------------------------------------------------*/
420/*---------------------------------------------------------------------------*/
421
422template<typename LimaMaliReader>
424: public LimaMalippReaderWrapper<LimaMaliReader>
425{
426 typedef LimaMalippReaderWrapper<LimaMaliReader> BaseClass;
427 using BaseClass::m_mali_reader;
428 using BaseClass::m_cell_group_reader;
429 using BaseClass::m_node_group_reader;
430 using BaseClass::m_face_group_reader;
431 public:
432 typedef Lima::Composition LimaComposition;
433 typedef typename LimaMaliReader::SurfaceReader LimaCellGroup;
434 typedef typename LimaMaliReader::LigneReader LimaFaceGroup;
435 typedef typename LimaMaliReader::NuageReader LimaNodeGroup;
436 public:
437 LimaComposition cells()
438 {
439 return m_mali_reader->composition_polygones();
440 }
441
442 LimaComposition faces()
443 {
444 return m_mali_reader->composition_bras();
445 }
446
447 LimaComposition nodes()
448 {
449 return m_mali_reader->composition_noeuds();
450 }
451
452 std::vector<std::string> cellGroups()
453 {
454 std::vector<std::string> groups;
455 m_mali_reader->liste_surfaces(groups);
456 return groups;
457 }
458
459 LimaGroupReader<LimaMaliReader>* cellGroupReader()
460 {
461 if (!m_cell_group_reader.get())
462 m_cell_group_reader = new FaceGroupReader<LimaMaliReader>(this);
463 return m_cell_group_reader.get();
464 }
465
466 LimaGroupReader<LimaMaliReader>* nodeGroupReader()
467 {
468 if (!m_node_group_reader.get())
469 m_node_group_reader = new NodeGroupReader<LimaMaliReader>(this);
470 return m_node_group_reader.get();
471 }
472
473 LimaGroupReader<LimaMaliReader>* faceGroupReader()
474 {
475 if (!m_face_group_reader.get())
476 m_face_group_reader = new EdgeGroupReader<LimaMaliReader>(this);
477 return m_face_group_reader.get();
478 }
479
480 std::vector<std::string> faceGroups()
481 {
482 std::vector<std::string> groups;
483 m_mali_reader->liste_lignes(groups);
484 return groups;
485 }
486
487 std::vector<std::string> nodeGroups()
488 {
489 std::vector<std::string> groups;
490 m_mali_reader->liste_nuages(groups);
491 return groups;
492 }
493
494 LimaCellGroup cellGroup(const string& name)
495 {
496 return m_mali_reader->surface(name);
497 }
498
499 LimaFaceGroup faceGroup(const string& name)
500 {
501 return m_mali_reader->ligne(name);
502 }
503
504 LimaNodeGroup nodeGroup(const string& name)
505 {
506 return m_mali_reader->nuage(name);
507 }
508
509 Lima::size_type* allocateCellsBuffer(Lima::size_type buf_size)
510 {
511 return m_mali_reader->allouer_tampon_polygones(buf_size);
512 }
513 Lima::size_type readCells(Lima::size_type begin, Lima::size_type count, Lima::size_type* buffer)
514 {
515 return m_mali_reader->lire_polygones(begin, count, buffer);
516 }
517 Integer facesBufferSize(Lima::size_type buf_size)
518 {
519 // Normalement il faut utiliser m_mali_reader->allouer_tampon_bras
520 // mais seul le proc maitre peut le faire et les autres ont besoin
521 // aussi d'allouer un tampon.
522 //return m_mali_reader->allouer_tampon_bras(buf_size);
523 return CheckedConvert::toInteger(8 * buf_size);
524 }
525 Lima::size_type readFaces(Lima::size_type begin, Lima::size_type count, Lima::size_type* buffer)
526 {
527 return m_mali_reader->lire_bras(begin, count, buffer);
528 }
529
530 int limaDimension()
531 {
532 return Lima::D2;
533 }
534 Integer dimension()
535 {
536 return 2;
537 }
538 const char* strDimension()
539 {
540 return "2D";
541 }
542 Real3 readNodeCoords(const double* ptr)
543 {
544 return Real3(ptr[0], ptr[1], 0.0);
545 }
546 static Integer cellToType(Integer nb_node)
547 {
548 switch (nb_node) {
549 case 3:
550 return IT_Triangle3;
551 case 4:
552 return IT_Quad4;
553 case 5:
554 return IT_Pentagon5;
555 case 6:
556 return IT_Hexagon6;
557 default:
558 break;
559 }
560 return IT_NullType;
561 }
562};
563
564/*---------------------------------------------------------------------------*/
565/*---------------------------------------------------------------------------*/
566
567template<typename LimaMaliReader>
569: public LimaMalippReaderWrapper<LimaMaliReader>
570{
571 typedef LimaMalippReaderWrapper<LimaMaliReader> BaseClass;
572 using BaseClass::m_mali_reader;
573 using BaseClass::m_cell_group_reader;
574 using BaseClass::m_node_group_reader;
575 using BaseClass::m_face_group_reader;
576 public:
577 typedef typename LimaMaliReader::VolumeReader LimaCellGroup;
578 typedef typename LimaMaliReader::SurfaceReader LimaFaceGroup;
579 typedef typename LimaMaliReader::NuageReader LimaNodeGroup;
580 typedef Lima::Composition LimaComposition;
581
582 public:
583 LimaComposition cells()
584 {
585 return m_mali_reader->composition_polyedres();
586 }
587 LimaComposition faces()
588 {
589 return m_mali_reader->composition_polygones();
590 }
591 LimaComposition nodes()
592 {
593 return m_mali_reader->composition_noeuds();
594 }
595
596 public:
597 public:
598 //typedef Lima::Volume LimaCellGroup;
599 typedef Lima::Polyedre LimaCell;
600 //typedef Lima::Surface LimaFaceGroup;
601 typedef Lima::Polygone LimaFace;
602
603 LimaGroupReader<LimaMaliReader>* cellGroupReader()
604 {
605 if (!m_cell_group_reader.get())
606 m_cell_group_reader = new CellGroupReader<LimaMaliReader>(this);
607 return m_cell_group_reader.get();
608 }
609
610 LimaGroupReader<LimaMaliReader>* faceGroupReader()
611 {
612 if (!m_face_group_reader.get())
613 m_face_group_reader = new FaceGroupReader<LimaMaliReader>(this);
614 return m_face_group_reader.get();
615 }
616
617 LimaGroupReader<LimaMaliReader>* nodeGroupReader()
618 {
619 if (!m_node_group_reader.get())
620 m_node_group_reader = new NodeGroupReader<LimaMaliReader>(this);
621 return m_node_group_reader.get();
622 }
623
624 std::vector<std::string> cellGroups()
625 {
626 std::vector<std::string> groups;
627 m_mali_reader->liste_volumes(groups);
628 return groups;
629 }
630
631 std::vector<std::string> faceGroups()
632 {
633 std::vector<std::string> groups;
634 m_mali_reader->liste_surfaces(groups);
635 return groups;
636 }
637
638 std::vector<std::string> nodeGroups()
639 {
640 std::vector<std::string> groups;
641 m_mali_reader->liste_nuages(groups);
642 return groups;
643 }
644
645 LimaCellGroup cellGroup(const string& name)
646 {
647 return m_mali_reader->volume(name);
648 }
649 LimaFaceGroup faceGroup(const string& name)
650 {
651 return m_mali_reader->surface(name);
652 }
653 LimaNodeGroup nodeGroup(const string& name)
654 {
655 return m_mali_reader->nuage(name);
656 }
657 Lima::size_type* allocateCellsBuffer(Lima::size_type buf_size)
658 {
659 return m_mali_reader->allouer_tampon_polyedres(buf_size);
660 }
661 Lima::size_type readCells(Lima::size_type begin, Lima::size_type count, Lima::size_type* buffer)
662 {
663 return m_mali_reader->lire_polyedres(begin, count, buffer);
664 }
665 Integer facesBufferSize(Lima::size_type buf_size)
666 {
667 // Normalement il faut utiliser m_mali_reader->allouer_tampon_polygone
668 // mais seul le proc maitre peut le faire et les autres ont besoin
669 // aussi d'allouer un tampon.
670 //return m_mali_reader->allouer_tampon_polygones(buf_size);
671 return CheckedConvert::toInteger(14 * buf_size);
672 }
673 Lima::size_type readFaces(Lima::size_type begin, Lima::size_type count, Lima::size_type* buffer)
674 {
675 return m_mali_reader->lire_polygones(begin, count, buffer);
676 }
677
678 int limaDimension()
679 {
680 return Lima::D3;
681 }
682 Integer dimension()
683 {
684 return 3;
685 }
686 const char* strDimension()
687 {
688 return "3D";
689 }
690 Real3 readNodeCoords(const double* ptr)
691 {
692 return Real3(ptr[0], ptr[1], ptr[2]);
693 }
694 static Integer cellToType(Integer nb_node)
695 {
696 switch (nb_node) {
697 case 4:
698 return IT_Tetraedron4;
699 case 5:
700 return IT_Pyramid5;
701 case 6:
702 return IT_Pentaedron6;
703 case 8:
704 return IT_Hexaedron8;
705 case 10:
706 return IT_Heptaedron10;
707 case 12:
708 return IT_Octaedron12;
709 default:
710 break;
711 }
712 return IT_NullType;
713 }
714};
715
716/*---------------------------------------------------------------------------*/
717/*---------------------------------------------------------------------------*/
721template<typename LimaMaliReader>
722class LimaMalippReader
723: public TraceAccessor
724{
725 public:
726 LimaMalippReader(ITraceMng* trace_mng)
727 : TraceAccessor(trace_mng) {}
728
729 public:
731 readMeshFromFile(ITimerMng* tm,IPrimaryMesh* mesh,
732 const String& file_name, Real length_multiplier);
733 private:
734};
735
736/*---------------------------------------------------------------------------*/
737/*---------------------------------------------------------------------------*/
738
739template<typename LimaMaliReader>
742 const String& filename,Real length_multiplier)
743{
744 if (filename.null() || filename.empty())
746
747 IParallelMng* pm = mesh->parallelMng();
749 bool is_master_io = pm->isMasterIO();
750 Int32 master_io_rank = pm->masterIORank();
751 Integer dimension = 0;
752 if (is_master_io) {
753 try {
754 reader = new LimaMaliReader(filename.localstr(), 1);
755 }
756 catch (const Lima::erreur& ex) {
757 ARCANE_FATAL("Impossible de lire le fichier MLI Lima <{0}> :",filename,ex.what());
758 }
759 catch (...) {
760 ARCANE_FATAL("Impossible de lire le fichier MLI Lima <{0}>",filename);
761 }
762 dimension = reader->dimension();
763 pm->broadcast(IntegerArrayView(1, &dimension), master_io_rank);
764 }
765 else
766 pm->broadcast(IntegerArrayView(1, &dimension), master_io_rank);
768 if (dimension == Lima::D3) {
769 info() << "Maillage 3D";
770 mesh->setDimension(3);
772 }
773 else if (dimension == Lima::D2) {
774 info() << "Maillage 2D";
775 mesh->setDimension(2);
777 }
778 else
779 throw NotSupportedException(A_FUNCINFO, "Can not read Lima 1D mesh");
780
781 if (!lm.get()) {
782 log() << "Dimension du maillage non reconnue par lima";
784 }
785 bool ret = lm->readMeshPart(timer_mng,reader.get(), mesh, filename, length_multiplier);
786 if (ret)
788 return IMeshReader::RTOk;
789}
790
791/*---------------------------------------------------------------------------*/
792/*---------------------------------------------------------------------------*/
793
794template <typename ReaderWrapper>
796readMeshPart(ITimerMng* timer_mng,LimaMaliReader* reader, IPrimaryMesh* mesh,
797 const String& filename, Real length_multiplier)
798{
799 return _readMeshPart(timer_mng, reader, mesh, filename, length_multiplier);
800}
801
802/*---------------------------------------------------------------------------*/
803/*---------------------------------------------------------------------------*/
809template <typename ReaderWrapper>
811_readMeshPart(ITimerMng* timer_mng, LimaMaliReader* reader, IPrimaryMesh* mesh,
812 const String& file_name,Real length_multiplier)
813{
814 typedef Lima::size_type size_type;
815 size_type basic_step = 100000;
816
817 IParallelMng* pm = mesh->parallelMng();
818 bool is_master_io = pm->isMasterIO();
819 Integer master_rank = pm->masterIORank();
820 Int32 nb_rank = pm->commSize();
821
822 Integer nb_edge = 0;
823
824 this->pwarning() << "Chargement Lima du fichier USING MALIPP avec partitionnement '" << file_name << '"';
825 if (basic_step < 100000)
826 this->pwarning() << "Small basic_step value=" << basic_step;
827
828 const char* version = Lima::lima_version();
829 info() << "Utilisation de la version " << version << " de Lima";
830
831 Timer time_to_read(timer_mng, "ReadLima", Timer::TimerReal);
832
833 this->log() << "Début lecture fichier " << file_name;
834
835 ReaderWrapper wrapper;
836 wrapper.setReader(reader);
837
838 if (reader && reader->dimension() != wrapper.limaDimension())
839 ARCANE_FATAL("Le fichier n'est pas un maillage {0}",wrapper.strDimension());
840
841 bool is_3d = (mesh->dimension() == 3);
842
843 Int64 mesh_nb_node = 0;
844 Int64 mesh_nb_cell = 0;
845 Int64 mesh_nb_face = 0;
846
847 // Le proc maitre lit le nombre d'entites et l'envoie aux autres
848 if (is_master_io) {
849 Lima::Composition lima_cells = wrapper.cells();
850 Lima::Composition lima_nodes = wrapper.nodes();
851 Lima::Composition lima_faces = wrapper.faces();
852
853 mesh_nb_node = (Int64)lima_nodes.nb_elements;
854 mesh_nb_cell = (Int64)lima_cells.nb_elements;
855 mesh_nb_face = (Int64)lima_faces.nb_elements;
856 Int64 nb_items[3];
857 nb_items[0] = mesh_nb_node;
858 nb_items[1] = mesh_nb_cell;
859 nb_items[2] = mesh_nb_face;
860 pm->broadcast(Int64ArrayView(3, nb_items), master_rank);
861
862 info() << "Unité de longueur du fichier: " << reader->unite_longueur();
863 if (length_multiplier == 0.0)
864 length_multiplier = 1.0;
865 else
866 length_multiplier *= reader->unite_longueur();
867 pm->broadcast(RealArrayView(1, &length_multiplier), master_rank);
868 }
869 else {
870 Int64 nb_items[3];
871 pm->broadcast(Int64ArrayView(3, nb_items), master_rank);
872 mesh_nb_node = nb_items[0];
873 mesh_nb_cell = nb_items[1];
874 mesh_nb_face = nb_items[2];
875 pm->broadcast(RealArrayView(1, &length_multiplier), master_rank);
876 }
877
878 size_type lima_nb_node = (size_type)mesh_nb_node;
879 nb_edge = 0; //lima.nb_bras();
880
881 info() << "-- Informations sur le maillage (Lima):";
882 info() << "Nombre de noeuds " << mesh_nb_node;
883 info() << "Nombre d'arêtes " << nb_edge;
884 info() << "Nombre de faces " << mesh_nb_face;
885 info() << "Nombre de mailles " << mesh_nb_cell;
886 if (mesh_nb_node == 0) {
887 ARCANE_FATAL("Pas de noeuds dans le fichier de maillage.");
888 }
889
890 // Pour l'instant, laisse à false.
891 // Si true, les uid sont incrémentés pour commencer à un.
892 Int64 uid_to_add = 0;
893 if (!platform::getEnvironmentVariable("ARCANE_LIMA_UNIQUE_ID").null()) {
894 uid_to_add = 1;
895 info() << "WARNING: UniqueId begin at 1";
896 }
897
898 Integer average_nb_cell = CheckedConvert::toInteger(mesh_nb_cell / nb_rank);
899
900 UniqueArray<Int64> own_cells_infos;
901 Integer own_nb_cell = 0;
902
903 // Remplit le tableau contenant les infos des mailles
904 if (is_master_io) {
905 // Tableau contenant les infos aux mailles (voir IMesh::allocateMesh())
906 Int64UniqueArray cells_infos;
907 cells_infos.reserve(average_nb_cell * 2);
908
909 Integer cell_step = average_nb_cell;
910 if (cell_step == 0)
911 ARCANE_FATAL("Number of cells is less than number of sub domains");
912
913 //size_type step_size = (lima_nb_cell>basic_step) ? basic_step : mesh_nb_cell;
914 size_type* buffer = wrapper.allocateCellsBuffer(cell_step + nb_rank);
915 Int64 total_nb_cell = mesh_nb_cell;
916 Integer current_nb_cell = 0;
917 Integer total_count = 0;
918 Integer last_print = 0;
919 for (Integer i = 0; total_count < total_nb_cell; ++i) {
920 if (i >= nb_rank)
921 ARCANE_FATAL("Too many count reading cells i={0} nrank=",i,nb_rank);
922 Int64 wanted_count = cell_step;
923 // Le dernier sous-domaine prend toutes les mailles restantes
924 if ((i + 1) == nb_rank)
925 wanted_count = mesh_nb_cell;
926 Integer count = CheckedConvert::toInteger(wrapper.readCells(i * cell_step, wanted_count, buffer));
927 // Afficher un pourcentage de progression (tous les 5%)
928 Integer p = (i * 20) / nb_rank;
929 if (p > last_print) {
930 last_print = p;
931 info() << "Reading cells rank=" << i << " n=" << wanted_count << " count=" << count
932 << " (" << (p * 5) << "%)";
933 }
934 current_nb_cell = count;
935 total_count += count;
936 size_type* ptr = buffer;
937 cells_infos.clear();
938 for (Integer p = 0; p < count; ++p) {
939 Integer cell_local_id = CheckedConvert::toInteger(*ptr++);
940 const Lima::size_type nodeCount = *ptr++;
941 Integer n = CheckedConvert::toInteger(nodeCount);
942 Integer ct = ReaderWrapper::cellToType(n);
943 if (ct == IT_NullType)
944 throw UnknownItemTypeException("LimaMaliPP::readFile: Cell", n, cell_local_id);
945 // Stocke le type de la maille
946 cells_infos.add(ct);
947 // Stocke le numéro unique de la maille
948 cells_infos.add(uid_to_add + cell_local_id - 1);
949
950 for (Lima::size_type z = 0; z < nodeCount; ++z) {
951 Int64 node_local_id = *ptr++;
952 cells_infos.add(uid_to_add + node_local_id - 1);
953 }
954 }
955 if (i != master_rank) {
956 Integer nb_cells_infos[2];
957 nb_cells_infos[0] = current_nb_cell;
958 nb_cells_infos[1] = cells_infos.size();
959 pm->send(IntegerConstArrayView(2, nb_cells_infos), i);
960 pm->send(cells_infos, i);
961 }
962 else {
963 own_nb_cell = current_nb_cell;
964 own_cells_infos = cells_infos;
965 }
966 } // for (i = 0; i * stepSize < polygonNumber; i++)
967 delete[] buffer;
968 }
969 else {
970 Integer nb_cells_infos[2];
971 pm->recv(IntegerArrayView(2, nb_cells_infos), master_rank);
972 own_nb_cell = nb_cells_infos[0];
973 own_cells_infos.resize(nb_cells_infos[1]);
974 pm->recv(own_cells_infos, master_rank);
975 }
976 ItemTypeMng* itm = mesh->itemTypeMng();
977
978 info() << " READ COORDINATES 1";
979
980 HashTableMapT<Int64, Real3> nodes_coords(own_nb_cell * 10, true);
981 // Remplit la table de hachage avec la liste des noeuds du sous-domaine
982 {
983 Integer cell_index = 0;
984 for (Integer i = 0; i < own_nb_cell; ++i) {
985 Integer type_id = (Integer)own_cells_infos[cell_index];
986 ++cell_index;
987 //Int64 cell_uid = own_cells_infos[cell_index];
988 ++cell_index;
989 ItemTypeInfo* it = itm->typeFromId(type_id);
990 Integer current_nb_node = it->nbLocalNode();
991 for (Integer z = 0; z < current_nb_node; ++z) {
992 Int64 node_uid = own_cells_infos[cell_index + z];
993 nodes_coords.add(node_uid, Real3());
994 }
995 cell_index += current_nb_node;
996 }
997 }
998
999 info() << " READ COORDINATES 2";
1000
1001 // Lecture des coordonnées
1002 if (is_master_io) {
1003 size_type step_size = (lima_nb_node > basic_step) ? basic_step : mesh_nb_node;
1004 size_type nodeCount = 0;
1005 size_type* idBuffer = reader->allouer_tampon_ids(step_size);
1006 double* coordsBuffer = reader->allouer_tampon_coords(step_size);
1007 Integer dim_step = reader->dimension();
1008 Real3UniqueArray current_coords;
1009 for (Integer i = 0; i < mesh_nb_node;) {
1010 Integer count = CheckedConvert::toInteger(reader->lire_noeuds(i, step_size, idBuffer, coordsBuffer));
1011 current_coords.clear();
1012 for (Integer n = 0; n < count; ++n, ++nodeCount) {
1013 Real3 coord;
1014 //Integer local_id = idBuffer[n] - 1;
1015 switch (dim_step) {
1016 case 1:
1017 coord.x = coordsBuffer[n];
1018 break;
1019 case 2:
1020 coord.x = coordsBuffer[2 * n];
1021 coord.y = coordsBuffer[(2 * n) + 1];
1022 break;
1023 case 3:
1024 coord.x = coordsBuffer[3 * n];
1025 coord.y = coordsBuffer[(3 * n) + 1];
1026 coord.z = coordsBuffer[(3 * n) + 2];
1027 break;
1028 }
1029 if (length_multiplier != 1.0)
1030 current_coords.add(coord * length_multiplier);
1031 else
1032 current_coords.add(coord);
1033 } // for (size_type n = 0; n < count; n++, nodeCount++)
1034 Integer sizes_info[1];
1035 sizes_info[0] = count;
1036 pm->broadcast(IntegerArrayView(1, sizes_info), master_rank);
1037 //warning() << "SEND COUNT=" << count << '\n';
1038 pm->broadcast(current_coords, master_rank);
1039 this->_setCoords(current_coords, nodes_coords, i + uid_to_add);
1040 i += count;
1041 } // for (i = 0; i < nodes.nb_elements; )
1042 delete[] idBuffer;
1043 delete[] coordsBuffer;
1044 }
1045 else {
1046 Real3UniqueArray current_coords;
1047 for (Int64 i = 0; i < mesh_nb_node;) {
1048 Integer sizes_info[1];
1049 pm->broadcast(IntegerArrayView(1, sizes_info), master_rank);
1050 Integer count = sizes_info[0];
1051 current_coords.resize(count);
1052 //warning() << "RESIZE COUNT=" << count << " begin=" << current_coords.begin() << '\n';
1053 pm->broadcast(current_coords, master_rank);
1054 this->_setCoords(current_coords, nodes_coords, i + uid_to_add);
1055 i += count;
1056 }
1057 }
1058
1059 info() << " READ CELLS";
1060
1061 // On a la liste des mailles et les coordonnées des noeuds associés.
1062 // Vérifie que le volume de la maille est positif, sinon inverse
1063 // la topologie de la maille.
1064 // Pour l'instant, traite uniquement les IT_Hexaedron8 et les pyramides
1065 {
1066 Integer cell_index = 0;
1067 Real3UniqueArray local_coords;
1068 local_coords.resize(8);
1069 Integer nb_reoriented = 0;
1070 for (Integer i = 0; i < own_nb_cell; ++i) {
1071 Integer type_id = (Integer)own_cells_infos[cell_index];
1072 ++cell_index;
1073 Int64 cell_uid = own_cells_infos[cell_index];
1074 ++cell_index;
1075 ItemTypeInfo* it = itm->typeFromId(type_id);
1076 Integer current_nb_node = it->nbLocalNode();
1077 local_coords.resize(current_nb_node);
1078 for (Integer z = 0; z < current_nb_node; ++z)
1079 local_coords[z] = nodes_coords.lookupValue(own_cells_infos[cell_index + z]);
1080 if (type_id == IT_Hexaedron8) {
1081 Real volume = LimaVolume::Hexaedron8Volume(local_coords.data());
1082 if (volume < 0.0) {
1083 std::swap(own_cells_infos[cell_index + 0], own_cells_infos[cell_index + 1]);
1084 std::swap(own_cells_infos[cell_index + 3], own_cells_infos[cell_index + 2]);
1085 std::swap(own_cells_infos[cell_index + 4], own_cells_infos[cell_index + 5]);
1086 std::swap(own_cells_infos[cell_index + 7], own_cells_infos[cell_index + 6]);
1087 info() << "Volume negatif Hexaedron8 uid=" << cell_uid << " v=" << volume;
1088 ++nb_reoriented;
1089 }
1090 }
1091 else if (type_id == IT_Pyramid5) {
1092 Real volume = LimaVolume::Pyramid5Volume(local_coords.data());
1093 if (volume < 0.0) {
1094 std::swap(own_cells_infos[cell_index + 0], own_cells_infos[cell_index + 1]);
1095 std::swap(own_cells_infos[cell_index + 2], own_cells_infos[cell_index + 3]);
1096 info() << "Volume negatif Pyramid5 uid=" << cell_uid << " v=" << volume;
1097 ++nb_reoriented;
1098 }
1099 }
1100 else if (type_id == IT_Quad4) {
1101 Real surface = LimaVolume::Quad4Surface(local_coords.data());
1102 if (surface < 0.0) {
1103 std::swap(own_cells_infos[cell_index + 0], own_cells_infos[cell_index + 1]);
1104 std::swap(own_cells_infos[cell_index + 2], own_cells_infos[cell_index + 3]);
1105 info() << "Surface negative Quad4 uid=" << cell_uid << " v=" << surface;
1106 ++nb_reoriented;
1107 }
1108 }
1109 else if (type_id == IT_Triangle3) {
1110 Real surface = LimaVolume::Triangle3Surface(local_coords.data());
1111 if (surface < 0.0) {
1112 std::swap(own_cells_infos[cell_index + 0], own_cells_infos[cell_index + 1]);
1113 info() << "Surface negative Triangle3 uid=" << cell_uid << " v=" << surface;
1114 ++nb_reoriented;
1115 }
1116 }
1117
1118 cell_index += current_nb_node;
1119 }
1120 info() << "NB reoriented cell = " << nb_reoriented;
1121 }
1122
1123 logdate() << "Début allocation du maillage";
1124 mesh->allocateCells(own_nb_cell, own_cells_infos, false);
1125 logdate() << "Fin allocation du maillage";
1126
1127 Int32 sid = pm->commRank();
1128 ItemInternalList cells(mesh->itemsInternal(IK_Cell));
1129 for (Integer i = 0, is = cells.size(); i < is; ++i)
1130 cells[i]->setOwner(sid, sid);
1131
1132 mesh->endAllocate();
1133
1134 // Après allocation, la couche de mailles fantômes est créée.
1135 // Cependant, seules les mailles ont le propriétaire correcte.
1136 // Pour les autres entités, il faut le mettre à jour.
1137 mesh->setOwnersFromCells();
1138
1139 this->_createGroups(mesh, IK_Cell, wrapper.cellGroupReader(), 0);
1140 this->_createGroups(mesh, IK_Node, wrapper.nodeGroupReader(), 0);
1141
1142 HashTableMapT<Int64, Int32> faces_local_id(own_nb_cell * 4, true); // Numéro de la face lima dans le maillage \a mesh
1143
1144 {
1145 Int64UniqueArray faces_first_node_unique_id;
1146 IntegerUniqueArray faces_nb_node;
1147
1148 Int64UniqueArray faces_nodes_unique_id;
1149 Int64UniqueArray orig_nodes_id;
1150 orig_nodes_id.reserve(100);
1151 IntegerUniqueArray face_nodes_index;
1152 face_nodes_index.reserve(100);
1153
1154 ItemInternalList mesh_nodes(mesh->itemsInternal(IK_Node));
1155
1156 size_type face_basic_step = basic_step;
1157 size_type step_size = (mesh_nb_face > (Int64)face_basic_step) ? face_basic_step : mesh_nb_face;
1158 UniqueArray<size_type> buffer(wrapper.facesBufferSize(step_size));
1159 size_type total_nb_face = mesh_nb_face;
1160 Int64 current_nb_face = 0;
1161 Integer nb_lima_face_in_sub_domain = 0;
1162 info() << "Total_nb_face2=" << total_nb_face;
1163 //TODO possible a paralleliser la lecture:
1164 //1. Le proc maitre lit les tableaux et les envoie a N proc (scatter)
1165 //2. Chaque proc se charge de reordonner les noeuds des faces qu'il a recu puis les renvoient a tout le monde (gather)
1166 for (size_type i = 0; (i * step_size) < total_nb_face; ++i) {
1167 Integer count = 0;
1168 if (is_master_io) {
1169 count = CheckedConvert::toInteger(wrapper.readFaces(i * step_size, step_size, buffer.data()));
1170 pm->broadcast(Int32ArrayView(1, &count), master_rank);
1171 pm->broadcast(buffer, master_rank);
1172 }
1173 else {
1174 pm->broadcast(Int32ArrayView(1, &count), master_rank);
1175 pm->broadcast(buffer, master_rank);
1176 }
1177 size_type* ptr = buffer.data();
1178 info() << " Read Face2 N=" << i << " count=" << count << " step_size=" << step_size;
1179 orig_nodes_id.clear();
1180 faces_first_node_unique_id.clear();
1181 faces_nb_node.resize(count);
1182 faces_nodes_unique_id.clear();
1183 Integer nodeCount = 0;
1184 for (Integer p = 0; p < count; ++p) {
1185 ++ptr;
1186 if (is_3d) {
1187 nodeCount = CheckedConvert::toInteger(*ptr++);
1188 }
1189 else
1190 nodeCount = 2;
1191 Integer n = nodeCount;
1192 faces_nb_node[p] = n;
1193 orig_nodes_id.resize(n);
1194 face_nodes_index.resize(n);
1195 for (Integer z = 0; z < nodeCount; ++z) {
1196 Integer node_local_id = CheckedConvert::toInteger(*ptr++);
1197 //info() << "P=" << p << " z=" << z << " id=" << node_local_id;
1198 orig_nodes_id[z] = node_local_id - 1;
1199 }
1200
1201 mesh_utils::reorderNodesOfFace2(orig_nodes_id, face_nodes_index);
1202 for (Integer z = 0; z < n; ++z)
1203 faces_nodes_unique_id.add(orig_nodes_id[face_nodes_index[z]]);
1204 faces_first_node_unique_id.add(orig_nodes_id[face_nodes_index[0]]);
1205 }
1206
1207 Int32UniqueArray faces_first_node_local_id(count);
1208 mesh->nodeFamily()->itemsUniqueIdToLocalId(faces_first_node_local_id, faces_first_node_unique_id, false);
1209
1210 Integer faces_nodes_unique_id_index = 0;
1211 for (Integer i_face = 0; i_face < count; ++i_face) {
1212 Integer n = faces_nb_node[i_face];
1213 Int64ConstArrayView face_nodes_id(n, &faces_nodes_unique_id[faces_nodes_unique_id_index]);
1214 Int32 first_node_id = faces_first_node_local_id[i_face];
1215 // Vérifie que le noeud est dans mon sous-domaine
1216 if (first_node_id != NULL_ITEM_ID) {
1217 Node current_node(mesh_nodes[first_node_id]);
1218 Face face = mesh_utils::getFaceFromNodesUnique(current_node, face_nodes_id);
1219
1220 // Vérifie que la face est dans mon sous-domaine
1221 if (!face.null()) {
1222 faces_local_id.add(current_nb_face + i_face, face.localId());
1223 ++nb_lima_face_in_sub_domain;
1224 }
1225 }
1226 faces_nodes_unique_id_index += n;
1227 }
1228 current_nb_face += count;
1229 }
1230 info() << "NB LIMA FACE IN SUB-DOMAIN =" << nb_lima_face_in_sub_domain;
1231 }
1232
1233 this->_createGroups(mesh, IK_Face, wrapper.faceGroupReader(), &faces_local_id);
1234
1235 {
1236 // Remplit la variable contenant les coordonnées des noeuds
1237 VariableNodeReal3& nodes_coord_var(mesh->nodesCoordinates());
1238 ENUMERATE_NODE (i, mesh->ownNodes()) {
1239 const Node& node = *i;
1240 nodes_coord_var[node] = nodes_coords.lookupValue(node.uniqueId().asInt64());
1241 //info() << "Coord: " << node.uniqueId() << " v=" << nodes_coord_var[node];
1242 }
1243 nodes_coord_var.synchronize();
1244 }
1245
1246 logdate() << "Fin de lecture du fichier";
1247 return false;
1248}
1249
1250/*---------------------------------------------------------------------------*/
1251/*---------------------------------------------------------------------------*/
1252
1253template <typename LimaMaliReader>
1256 Int64 current_unique_id)
1257{
1258 for (Integer i = 0, is = coords.size(); i < is; ++i) {
1259 Int64 uid = current_unique_id + i;
1260 HashTableMapT<Int64, Real3>::Data* d = nodes_coords.lookup(uid);
1261 if (d)
1262 d->value() = coords[i];
1263 }
1264}
1265
1266/*---------------------------------------------------------------------------*/
1267/*---------------------------------------------------------------------------*/
1268
1269template <typename LimaMaliReader>
1271_createGroups(IMesh* mesh, eItemKind item_kind, LimaGroupReader<LimaMaliReader>* lima_group_reader,
1272 HashTableMapT<Int64, Int32>* converter)
1273{
1274 IParallelMng* pm = mesh->parallelMng();
1275 Integer master_rank = pm->masterIORank();
1276 Integer is_master_io = pm->isMasterIO();
1277 //IItemFamily* item_family = mesh->itemFamily(item_kind);
1278 //ItemInternalList cells(cell_family->itemsInternal());
1279
1280 Int64UniqueArray unique_ids;
1281
1282 // Création des groupes de mailles
1283 if (is_master_io) {
1284 StringUniqueArray groups_name(lima_group_reader->groupsName());
1285 //std::vector<std::string> groups = wrapper.cellGroups();
1286 Integer nb_group = groups_name.size();
1287 Integer sizes_infos[1];
1288 sizes_infos[0] = nb_group;
1289 pm->broadcast(IntegerArrayView(1, sizes_infos), master_rank);
1290 for (Integer i = 0; i < nb_group; ++i) {
1291 //typename ReaderWrapper::LimaCellGroup group_reader = wrapper.cellGroup(groups[i]);
1292 String group_name = groups_name[i];
1293 pm->broadcastString(group_name, master_rank);
1294 //pwarning() << "Group Name <" << group_name;
1295 //wrapper.readGroup(group_reader,unique_ids);
1296 lima_group_reader->read(group_name, unique_ids);
1297 Integer nb_item_in_group = unique_ids.size();
1298 sizes_infos[0] = nb_item_in_group;
1299 pm->broadcast(IntegerArrayView(1, sizes_infos), master_rank);
1300 pm->broadcast(unique_ids, master_rank);
1301 if (converter)
1302 _createGroupFromHashTable(mesh, group_name, item_kind, unique_ids, *converter);
1303 else
1304 _createGroupFromUniqueIds(mesh, group_name, item_kind, unique_ids);
1305 }
1306 }
1307 else {
1308 Integer sizes_infos[1];
1309 pm->broadcast(IntegerArrayView(1, sizes_infos), master_rank);
1310 Integer nb_group = sizes_infos[0];
1311 for (Integer i = 0; i < nb_group; ++i) {
1312 String group_name;
1313 pm->broadcastString(group_name, master_rank);
1314 //pwarning() << "Group Name <" << group_name;
1315 pm->broadcast(IntegerArrayView(1, sizes_infos), master_rank);
1316 Integer nb_item_in_group = sizes_infos[0];
1317 unique_ids.resize(nb_item_in_group);
1318 pm->broadcast(unique_ids, master_rank);
1319 if (converter)
1320 _createGroupFromHashTable(mesh, group_name, item_kind, unique_ids, *converter);
1321 else
1322 _createGroupFromUniqueIds(mesh, group_name, item_kind, unique_ids);
1323 }
1324 }
1325}
1326
1327/*---------------------------------------------------------------------------*/
1328/*---------------------------------------------------------------------------*/
1329
1330template <typename LimaMaliReader>
1333 Int64ConstArrayView unique_ids)
1334{
1335 Integer nb_item_in_group = unique_ids.size();
1336 Int32UniqueArray local_ids(nb_item_in_group);
1337 IItemFamily* family = mesh->itemFamily(ik);
1338 family->itemsUniqueIdToLocalId(local_ids, unique_ids, false);
1339 Int32UniqueArray group_ids;
1340 for (Integer i = 0; i < nb_item_in_group; ++i) {
1341 if (local_ids[i] != NULL_ITEM_ID)
1342 group_ids.add(local_ids[i]);
1343 }
1344 info() << "Group Name <" << name << "> (" << nb_item_in_group << " elements)";
1345 LimaUtils::createGroup(family, name, group_ids);
1346}
1347
1348/*---------------------------------------------------------------------------*/
1349/*---------------------------------------------------------------------------*/
1350
1351template <typename LimaMaliReader>
1354 Int64ConstArrayView unique_ids,
1355 const HashTableMapT<Int64, Int32>& converter)
1356{
1357 Integer nb_item_in_group = unique_ids.size();
1358 Int32UniqueArray local_ids(nb_item_in_group);
1359 IItemFamily* family = mesh->itemFamily(ik);
1360 Int32UniqueArray group_ids;
1361 for (Integer i = 0; i < nb_item_in_group; ++i) {
1362 const HashTableMapT<Int64, Int32>::Data* data = converter.lookup(unique_ids[i]);
1363 if (data)
1364 group_ids.add(data->value());
1365 }
1366 info() << "Group Name <" << name << "> (" << nb_item_in_group << " elements)";
1367 LimaUtils::createGroup(family, name, group_ids);
1368}
1369
1370/*---------------------------------------------------------------------------*/
1371/*---------------------------------------------------------------------------*/
1372
1373} // End namespace Arcane
1374
1375/*---------------------------------------------------------------------------*/
1376/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Types et macros pour itérer sur les entités du maillage.
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
Fonctions mathématiques diverses.
Fonctions utilitaires sur le maillage.
bool reorderNodesOfFace2(Int64ConstArrayView nodes_unique_id, Int32ArrayView new_index)
Réordonne les noeuds d'une face.
Ce fichier contient les différentes fabriques de services et macro pour enregistrer les services.
Integer size() const
Nombre d'éléments du vecteur.
void clear()
Supprime les éléments du tableau.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
const T * data() const
Accès à la racine du tableau hors toute protection.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Face d'une maille.
Definition Item.h:964
Table de hachage pour tableaux associatifs.
Data * lookup(KeyTypeConstRef id)
Recherche la valeur correspondant à la clé id.
ValueType & lookupValue(KeyTypeConstRef id)
Recherche la valeur correspondant à la clé id.
bool add(KeyTypeConstRef id, const ValueType &value)
Ajoute la valeur value correspondant à la clé id.
Interface d'une famille d'entités.
Definition IItemFamily.h:84
eReturnType
Types des codes de retour d'une lecture ou écriture.
Definition IMeshReader.h:37
@ RTIrrelevant
Non concerné par l'opération. Cela signifie que le format de fichier ne correspond pas à ce lecteur o...
Definition IMeshReader.h:45
@ RTError
Erreur lors de l'opération.
Definition IMeshReader.h:39
@ RTOk
Opération effectuée avec succès.
Definition IMeshReader.h:38
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual ITraceMng * traceMng() const =0
Gestionnaire de traces.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual void recv(ArrayView< char > values, Int32 rank)=0
virtual bool isMasterIO() const =0
true si l'instance est un gestionnaire maître des entrées/sorties.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual Integer masterIORank() const =0
Rang de l'instance gérant les entrées/sorties (pour laquelle isMasterIO() est vrai)
Interface d'un gestionnaire de timer.
Definition ITimerMng.h:49
Interface du gestionnaire de traces.
Infos sur un type d'entité du maillage.
Integer nbLocalNode() const
Nombre de noeuds de l'entité
Gestionnaire des types d'entités d'un maillage.
Definition ItemTypeMng.h:65
ItemTypeInfo * typeFromId(Integer id) const
Type correspondant au numéro id.
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Definition Item.h:216
Lecteur des fichiers de maillage via la bibliothèque LIMA pour fichier '.mli' ou 'mli2'.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
TraceMessage logdate() const
Flot pour un message de log précédé de la date.
TraceMessage log() const
Flot pour un message de log.
TraceMessage info() const
Flot pour un message d'information.
bool _readMeshPart(ITimerMng *timer_mng, LimaMaliReader *reader, IPrimaryMesh *mesh, const String &filename, Real length_multiplier)
Lecture du maillage. Seul le proc maitre a une instance de reader non nulle. Les autres ne doivent pa...
Lecteur des fichiers de maillage via la bibliothèque LIMA.
static void createGroup(IItemFamily *family, const String &name, Int32ArrayView local_ids)
Créé un groupe d'entités.
Definition LimaUtils.cc:43
Noeud d'un maillage.
Definition Item.h:582
Exception lorsqu'une opération n'est pas supportée.
T * get() const
Retourne l'objet référé par l'instance.
Definition Ptr.h:121
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
Encapsulation d'un pointeur qui se détruit automatiquement.
Definition ScopedPtr.h:44
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:305
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:228
bool empty() const
Vrai si la chaîne est vide (nulle ou "")
Definition String.cc:316
Gestion d'un timer.
Definition Timer.h:62
@ TimerReal
Timer utilisant le temps réel.
Definition Timer.h:76
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage logdate() const
Flot pour un message de log précédé de la date.
TraceMessage log() const
Flot pour un message de log.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage pwarning() const
Vecteur 1D de données avec sémantique par valeur (style STL).
Exception lorsqu'une entité du maillage n'est pas d'un type connu.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
__host__ __device__ double log(double v)
Logarithme népérien de v.
Definition Math.h:40
__host__ __device__ Real matDet(Real3 u, Real3 v, Real3 w)
Déterminant de la matrice u,v,w.
Definition MathUtils.h:170
String getEnvironmentVariable(const String &name)
Variable d'environnement du nom name.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Array< Int64 > Int64Array
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:125
ArrayView< Int64 > Int64ArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:451
ConstArrayView< Real3 > Real3ConstArrayView
Equivalent C d'un tableau à une dimension de Real3.
Definition UtilsTypes.h:496
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:339
ConstArrayView< String > StringConstArrayView
Equivalent C d'un tableau à une dimension de chaînes de caractères.
Definition UtilsTypes.h:492
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
UniqueArray< Real3 > Real3UniqueArray
Tableau dynamique à une dimension de vecteurs de rang 3.
Definition UtilsTypes.h:363
ArrayView< Integer > IntegerArrayView
Equivalent C d'un tableau à une dimension d'entiers.
Definition UtilsTypes.h:457
ConstArrayView< ItemInternal * > ItemInternalList
Type de la liste interne des entités.
Definition ItemTypes.h:466
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:480
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:341
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:453
eItemKind
Genre d'entité de maillage.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Face
Entité de maillage de genre face.
double Real
Type représentant un réel.
UniqueArray< String > StringUniqueArray
Tableau dynamique à une dimension de chaînes de caractères.
Definition UtilsTypes.h:359
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
Definition UtilsTypes.h:347
ConstArrayView< Integer > IntegerConstArrayView
Equivalent C d'un tableau à une dimension d'entiers.
Definition UtilsTypes.h:486
ArrayView< Real > RealArrayView
Equivalent C d'un tableau à une dimension de réels.
Definition UtilsTypes.h:459
std::int32_t Int32
Type entier signé sur 32 bits.
Real y
deuxième composante du triplet
Definition Real3.h:36
Real z
troisième composante du triplet
Definition Real3.h:37
Real x
première composante du triplet
Definition Real3.h:35