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