Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
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/* Reading a file in Lima MLI or MLI2 format. */
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
77{
78 public:
79
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
141 LimaMalippMeshBase(ITraceMng* trace_mng)
142 : TraceAccessor(trace_mng)
143 {}
144 virtual ~LimaMalippMeshBase() = default;
145
146 public:
147 public:
148
149 virtual bool readMeshPart(ITimerMng* timer_mng, LimaMaliReader* reader, IPrimaryMesh* mesh,
150 const String& filename, Real length_multiplier) = 0;
151
152 protected:
153
154 void _createGroupFromUniqueIds(IMesh* mesh, const String& name, eItemKind ik,
155 Int64ConstArrayView unique_ids);
156 void _createGroupFromHashTable(IMesh* mesh, const String& name, eItemKind ik,
157 Int64ConstArrayView unique_ids,
158 const HashTableMapT<Int64, Int32>& converter);
159 void _setCoords(Real3ConstArrayView coords, HashTableMapT<Int64, Real3>& nodes_coords,
160 Int64 current_unique_id);
161 void _createGroups(IMesh* mesh, eItemKind item_kind, LimaGroupReader<LimaMaliReader>* reader,
162 HashTableMapT<Int64, Int32>* converter);
163
164 private:
165};
166
167/*---------------------------------------------------------------------------*/
168/*---------------------------------------------------------------------------*/
175template <typename ReaderWrapper>
176class LimaMalippReaderT
177: public LimaMalippMeshBase<typename ReaderWrapper::LimaMaliReaderType>
178{
180 using TraceAccessor::log;
182
183 public:
184
185 typedef typename ReaderWrapper::LimaMaliReaderType LimaMaliReader;
186
187 public:
188
189 LimaMalippReaderT(IParallelMng* pm)
190 : LimaMalippMeshBase<LimaMaliReader>(pm->traceMng())
191 , m_cut_infos_reader(new LimaCutInfosReader(pm))
192 {}
193
194 ~LimaMalippReaderT() override
195 {
196 delete m_cut_infos_reader;
197 }
198
199 public:
200 public:
201
202 bool readMeshPart(ITimerMng* timer_mng, LimaMaliReader* reader,
203 IPrimaryMesh* mesh, const String& filename,
204 Real length_multiplier) override;
205
206 private:
207
208 LimaCutInfosReader* m_cut_infos_reader;
209 ReaderWrapper m_wrapper;
210
211 bool _readMeshPart(ITimerMng* timer_mng, LimaMaliReader* reader, IPrimaryMesh* mesh,
212 const String& filename, Real length_multiplier);
213};
214
215/*---------------------------------------------------------------------------*/
216/*---------------------------------------------------------------------------*/
217
218template <typename LimaMaliReader>
219class LimaMalippReaderWrapper
220{
221 public:
222
223 typedef LimaMaliReader LimaMaliReaderType;
224 typedef typename LimaMaliReader::NuageReader LimaNodeGroup;
225
226 public:
227
228 LimaMalippReaderWrapper()
229 : m_mali_reader(0)
230 {}
231 void setReader(LimaMaliReader* reader)
232 {
233 m_mali_reader = reader;
234 }
235 LimaMaliReader* reader()
236 {
237 return m_mali_reader;
238 }
239
240 public:
241
242 Lima::size_type
243 _readGroup(typename LimaMaliReader::SurfaceReader reader,
244 Lima::size_type begin, Lima::size_type n, Lima::size_type* buffer)
245 {
246 return reader.lire_mailles_ids(begin, n, buffer);
247 }
248 Lima::size_type
249 _readGroup(typename LimaMaliReader::VolumeReader reader,
250 Lima::size_type begin, Lima::size_type n, Lima::size_type* buffer)
251 {
252 return reader.lire_mailles_ids(begin, n, buffer);
253 }
254 Lima::size_type
255 _readGroup(typename LimaMaliReader::LigneReader reader,
256 Lima::size_type begin, Lima::size_type n, Lima::size_type* buffer)
257 {
258 return reader.lire_bras_ids(begin, n, buffer);
259 }
260
261 Lima::size_type
262 _readGroup(typename LimaMaliReader::NuageReader reader,
263 Lima::size_type begin, Lima::size_type n, Lima::size_type* buffer)
264 {
265 return reader.lire_noeuds_ids(begin, n, buffer);
266 }
267
268 double* allocateNodesCoordsBuffer(Lima::size_type buf_size)
269 {
270 return m_mali_reader->allouer_tampon_coords(buf_size);
271 }
272 Lima::size_type* allocateNodesIdBuffer(Lima::size_type buf_size)
273 {
274 return m_mali_reader->allouer_tampon_ids(buf_size);
275 }
276 Lima::size_type readNodes(Lima::size_type begin, Lima::size_type count,
277 Lima::size_type* ids, double* coords)
278 {
279 return m_mali_reader->lire_noeuds(begin, count, ids, coords);
280 }
281
282 template <typename LimaGroupReader>
283 void readGroup(LimaGroupReader& reader, Int64Array& items_unique_id)
284 {
285 using namespace Lima;
286 //cout << "----------------------------------------------------------"
287 // << reader.nom();
288 size_type* buffer = 0;
289 const Integer nb_item = CheckedConvert::toInteger(reader.composition().nb_elements);
290 items_unique_id.resize(nb_item);
291 const Integer step_size = nb_item > 10000 ? nb_item / 10 : nb_item;
292 buffer = reader.allouer_tampon_ids(step_size);
293 Integer begin = 0;
294 for (Integer i = 0; i * step_size < nb_item; ++i) {
295 const Integer count = CheckedConvert::toInteger(_readGroup(reader, (size_type)(i * step_size), (size_type)step_size, buffer));
296 size_type* ptr = buffer;
297 for (Integer n = 0; n < count; ++n) {
298 size_type lima_id = *ptr++;
299 items_unique_id[begin + n] = lima_id - 1;
300 //cout << lima_id << " ";
301 }
302 begin += count;
303 }
304 delete[] buffer;
305 //cout << endl;
306 }
307
308 protected:
309
310 LimaMaliReader* m_mali_reader;
314};
315
316/*---------------------------------------------------------------------------*/
317/*---------------------------------------------------------------------------*/
318
319template <typename LimaMaliReader>
320class LimaGroupReader
321{
322 public:
323
324 LimaGroupReader(LimaMalippReaderWrapper<LimaMaliReader>* wrapper)
325 : m_wrapper(wrapper)
326 {}
327 virtual ~LimaGroupReader() {}
328 virtual void read(const String& name, Int64Array& items_unique_id) = 0;
329
330 public:
331
332 virtual StringConstArrayView groupsName()
333 {
334 std::vector<std::string> groups;
335 _getGroupsName(groups);
336 m_groups_name.clear();
337 for (size_t i = 0, is = groups.size(); i < is; ++i)
338 m_groups_name.add(String(groups[i]));
339 return m_groups_name;
340 }
341
342 protected:
343
344 virtual void _getGroupsName(std::vector<std::string>& groups) = 0;
345
346 protected:
347
349
350 private:
351
352 StringUniqueArray m_groups_name;
353};
354
355template <typename LimaMaliReader>
356class NodeGroupReader
357: public LimaGroupReader<LimaMaliReader>
358{
359 public:
360
361 NodeGroupReader(LimaMalippReaderWrapper<LimaMaliReader>* wrapper)
362 : LimaGroupReader<LimaMaliReader>(wrapper)
363 {}
364 virtual void read(const String& name, Int64Array& items_unique_id)
365 {
366 typename LimaMaliReader::NuageReader r = this->m_wrapper->reader()->nuage(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_nuages(groups);
372 }
373
374 private:
375};
376
377template <typename LimaMaliReader>
378class EdgeGroupReader
379: public LimaGroupReader<LimaMaliReader>
380{
381 public:
382
383 EdgeGroupReader(LimaMalippReaderWrapper<LimaMaliReader>* wrapper)
384 : LimaGroupReader<LimaMaliReader>(wrapper)
385 {}
386 virtual void read(const String& name, Int64Array& items_unique_id)
387 {
388 typename LimaMaliReader::LigneReader r = this->m_wrapper->reader()->ligne(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_lignes(groups);
394 }
395
396 private:
397};
398
399template <typename LimaMaliReader>
400class FaceGroupReader
401: public LimaGroupReader<LimaMaliReader>
402{
403 public:
404
405 FaceGroupReader(LimaMalippReaderWrapper<LimaMaliReader>* wrapper)
406 : LimaGroupReader<LimaMaliReader>(wrapper)
407 {
408 }
409 virtual void read(const String& name, Int64Array& items_unique_id)
410 {
411 typename LimaMaliReader::SurfaceReader r = this->m_wrapper->reader()->surface(name.localstr());
412 this->m_wrapper->readGroup(r, items_unique_id);
413 }
414 virtual void _getGroupsName(std::vector<std::string>& groups)
415 {
416 this->m_wrapper->reader()->liste_surfaces(groups);
417 }
418};
419
420template <typename LimaMaliReader>
421class CellGroupReader
422: public LimaGroupReader<LimaMaliReader>
423{
424 public:
425
426 CellGroupReader(LimaMalippReaderWrapper<LimaMaliReader>* wrapper)
427 : LimaGroupReader<LimaMaliReader>(wrapper)
428 {
429 }
430 virtual void read(const String& name, Int64Array& items_unique_id)
431 {
432 typename LimaMaliReader::VolumeReader r = this->m_wrapper->reader()->volume(name.localstr());
433 this->m_wrapper->readGroup(r, items_unique_id);
434 }
435 virtual void _getGroupsName(std::vector<std::string>& groups)
436 {
437 this->m_wrapper->reader()->liste_volumes(groups);
438 }
439
440 private:
441};
442
443/*---------------------------------------------------------------------------*/
444/*---------------------------------------------------------------------------*/
445
446template <typename LimaMaliReader>
448: public LimaMalippReaderWrapper<LimaMaliReader>
449{
450 typedef LimaMalippReaderWrapper<LimaMaliReader> BaseClass;
451 using BaseClass::m_cell_group_reader;
452 using BaseClass::m_face_group_reader;
453 using BaseClass::m_mali_reader;
454 using BaseClass::m_node_group_reader;
455
456 public:
457
458 typedef Lima::Composition LimaComposition;
459 typedef typename LimaMaliReader::SurfaceReader LimaCellGroup;
460 typedef typename LimaMaliReader::LigneReader LimaFaceGroup;
461 typedef typename LimaMaliReader::NuageReader LimaNodeGroup;
462
463 public:
464
465 LimaComposition cells()
466 {
467 return m_mali_reader->composition_polygones();
468 }
469
470 LimaComposition faces()
471 {
472 return m_mali_reader->composition_bras();
473 }
474
475 LimaComposition nodes()
476 {
477 return m_mali_reader->composition_noeuds();
478 }
479
480 std::vector<std::string> cellGroups()
481 {
482 std::vector<std::string> groups;
483 m_mali_reader->liste_surfaces(groups);
484 return groups;
485 }
486
487 LimaGroupReader<LimaMaliReader>* cellGroupReader()
488 {
489 if (!m_cell_group_reader.get())
490 m_cell_group_reader = new FaceGroupReader<LimaMaliReader>(this);
491 return m_cell_group_reader.get();
492 }
493
494 LimaGroupReader<LimaMaliReader>* nodeGroupReader()
495 {
496 if (!m_node_group_reader.get())
497 m_node_group_reader = new NodeGroupReader<LimaMaliReader>(this);
498 return m_node_group_reader.get();
499 }
500
501 LimaGroupReader<LimaMaliReader>* faceGroupReader()
502 {
503 if (!m_face_group_reader.get())
504 m_face_group_reader = new EdgeGroupReader<LimaMaliReader>(this);
505 return m_face_group_reader.get();
506 }
507
508 std::vector<std::string> faceGroups()
509 {
510 std::vector<std::string> groups;
511 m_mali_reader->liste_lignes(groups);
512 return groups;
513 }
514
515 std::vector<std::string> nodeGroups()
516 {
517 std::vector<std::string> groups;
518 m_mali_reader->liste_nuages(groups);
519 return groups;
520 }
521
522 LimaCellGroup cellGroup(const string& name)
523 {
524 return m_mali_reader->surface(name);
525 }
526
527 LimaFaceGroup faceGroup(const string& name)
528 {
529 return m_mali_reader->ligne(name);
530 }
531
532 LimaNodeGroup nodeGroup(const string& name)
533 {
534 return m_mali_reader->nuage(name);
535 }
536
537 Lima::size_type* allocateCellsBuffer(Lima::size_type buf_size)
538 {
539 return m_mali_reader->allouer_tampon_polygones(buf_size);
540 }
541 Lima::size_type readCells(Lima::size_type begin, Lima::size_type count, Lima::size_type* buffer)
542 {
543 return m_mali_reader->lire_polygones(begin, count, buffer);
544 }
545 Integer facesBufferSize(Lima::size_type buf_size)
546 {
547 // Normally, m_mali_reader->allouer_tampon_bras should be used
548 // but only the master process can do it and the others also need
549 // to allocate a buffer.
550 //return m_mali_reader->allouer_tampon_bras(buf_size);
551 return CheckedConvert::toInteger(8 * buf_size);
552 }
553 Lima::size_type readFaces(Lima::size_type begin, Lima::size_type count, Lima::size_type* buffer)
554 {
555 return m_mali_reader->lire_bras(begin, count, buffer);
556 }
557
558 int limaDimension()
559 {
560 return Lima::D2;
561 }
562 Integer dimension()
563 {
564 return 2;
565 }
566 const char* strDimension()
567 {
568 return "2D";
569 }
570 Real3 readNodeCoords(const double* ptr)
571 {
572 return Real3(ptr[0], ptr[1], 0.0);
573 }
574 static Integer cellToType(Integer nb_node)
575 {
576 switch (nb_node) {
577 case 3:
578 return IT_Triangle3;
579 case 4:
580 return IT_Quad4;
581 case 5:
582 return IT_Pentagon5;
583 case 6:
584 return IT_Hexagon6;
585 default:
586 break;
587 }
588 return IT_NullType;
589 }
590};
591
592/*---------------------------------------------------------------------------*/
593/*---------------------------------------------------------------------------*/
594
595template <typename LimaMaliReader>
597: public LimaMalippReaderWrapper<LimaMaliReader>
598{
599 typedef LimaMalippReaderWrapper<LimaMaliReader> BaseClass;
600 using BaseClass::m_cell_group_reader;
601 using BaseClass::m_face_group_reader;
602 using BaseClass::m_mali_reader;
603 using BaseClass::m_node_group_reader;
604
605 public:
606
607 typedef typename LimaMaliReader::VolumeReader LimaCellGroup;
608 typedef typename LimaMaliReader::SurfaceReader LimaFaceGroup;
609 typedef typename LimaMaliReader::NuageReader LimaNodeGroup;
610 typedef Lima::Composition LimaComposition;
611
612 public:
613
614 LimaComposition cells()
615 {
616 return m_mali_reader->composition_polyedres();
617 }
618 LimaComposition faces()
619 {
620 return m_mali_reader->composition_polygones();
621 }
622 LimaComposition nodes()
623 {
624 return m_mali_reader->composition_noeuds();
625 }
626
627 public:
628 public:
629
630 //typedef Lima::Volume LimaCellGroup;
631 typedef Lima::Polyedre LimaCell;
632 //typedef Lima::Surface LimaFaceGroup;
633 typedef Lima::Polygone LimaFace;
634
635 LimaGroupReader<LimaMaliReader>* cellGroupReader()
636 {
637 if (!m_cell_group_reader.get())
638 m_cell_group_reader = new CellGroupReader<LimaMaliReader>(this);
639 return m_cell_group_reader.get();
640 }
641
642 LimaGroupReader<LimaMaliReader>* faceGroupReader()
643 {
644 if (!m_face_group_reader.get())
645 m_face_group_reader = new FaceGroupReader<LimaMaliReader>(this);
646 return m_face_group_reader.get();
647 }
648
649 LimaGroupReader<LimaMaliReader>* nodeGroupReader()
650 {
651 if (!m_node_group_reader.get())
652 m_node_group_reader = new NodeGroupReader<LimaMaliReader>(this);
653 return m_node_group_reader.get();
654 }
655
656 std::vector<std::string> cellGroups()
657 {
658 std::vector<std::string> groups;
659 m_mali_reader->liste_volumes(groups);
660 return groups;
661 }
662
663 std::vector<std::string> faceGroups()
664 {
665 std::vector<std::string> groups;
666 m_mali_reader->liste_surfaces(groups);
667 return groups;
668 }
669
670 std::vector<std::string> nodeGroups()
671 {
672 std::vector<std::string> groups;
673 m_mali_reader->liste_nuages(groups);
674 return groups;
675 }
676
677 LimaCellGroup cellGroup(const string& name)
678 {
679 return m_mali_reader->volume(name);
680 }
681 LimaFaceGroup faceGroup(const string& name)
682 {
683 return m_mali_reader->surface(name);
684 }
685 LimaNodeGroup nodeGroup(const string& name)
686 {
687 return m_mali_reader->nuage(name);
688 }
689 Lima::size_type* allocateCellsBuffer(Lima::size_type buf_size)
690 {
691 return m_mali_reader->allouer_tampon_polyedres(buf_size);
692 }
693 Lima::size_type readCells(Lima::size_type begin, Lima::size_type count, Lima::size_type* buffer)
694 {
695 return m_mali_reader->lire_polyedres(begin, count, buffer);
696 }
697 Integer facesBufferSize(Lima::size_type buf_size)
698 {
699 // Normally, m_mali_reader->allouer_tampon_polygone
700 // should be used but only the master process can do it and the others also need
701 // to allocate a buffer.
702 //return m_mali_reader->allouer_tampon_polygones(buf_size);
703 return CheckedConvert::toInteger(14 * buf_size);
704 }
705 Lima::size_type readFaces(Lima::size_type begin, Lima::size_type count, Lima::size_type* buffer)
706 {
707 return m_mali_reader->lire_polygones(begin, count, buffer);
708 }
709
710 int limaDimension()
711 {
712 return Lima::D3;
713 }
714 Integer dimension()
715 {
716 return 3;
717 }
718 const char* strDimension()
719 {
720 return "3D";
721 }
722 Real3 readNodeCoords(const double* ptr)
723 {
724 return Real3(ptr[0], ptr[1], ptr[2]);
725 }
726 static Integer cellToType(Integer nb_node)
727 {
728 switch (nb_node) {
729 case 4:
730 return IT_Tetraedron4;
731 case 5:
732 return IT_Pyramid5;
733 case 6:
734 return IT_Pentaedron6;
735 case 8:
736 return IT_Hexaedron8;
737 case 10:
738 return IT_Heptaedron10;
739 case 12:
740 return IT_Octaedron12;
741 default:
742 break;
743 }
744 return IT_NullType;
745 }
746};
747
748/*---------------------------------------------------------------------------*/
749/*---------------------------------------------------------------------------*/
753template <typename LimaMaliReader>
754class LimaMalippReader
755: public TraceAccessor
756{
757 public:
758
759 LimaMalippReader(ITraceMng* trace_mng)
760 : TraceAccessor(trace_mng)
761 {}
762
763 public:
764
766 readMeshFromFile(ITimerMng* tm, IPrimaryMesh* mesh,
767 const String& file_name, Real length_multiplier);
768
769 private:
770};
771
772/*---------------------------------------------------------------------------*/
773/*---------------------------------------------------------------------------*/
774
775template <typename LimaMaliReader>
778 const String& filename, Real length_multiplier)
779{
780 if (filename.null() || filename.empty())
782
783 IParallelMng* pm = mesh->parallelMng();
785 bool is_master_io = pm->isMasterIO();
786 Int32 master_io_rank = pm->masterIORank();
787 Integer dimension = 0;
788 if (is_master_io) {
789 try {
790 reader = new LimaMaliReader(filename.localstr(), 1);
791 }
792 catch (const Lima::erreur& ex) {
793 ARCANE_FATAL("Impossible de lire le fichier MLI Lima <{0}> :", filename, ex.what());
794 }
795 catch (...) {
796 ARCANE_FATAL("Impossible de lire le fichier MLI Lima <{0}>", filename);
797 }
798 dimension = reader->dimension();
799 pm->broadcast(IntegerArrayView(1, &dimension), master_io_rank);
800 }
801 else
802 pm->broadcast(IntegerArrayView(1, &dimension), master_io_rank);
804 if (dimension == Lima::D3) {
805 info() << "Maillage 3D";
806 mesh->setDimension(3);
808 }
809 else if (dimension == Lima::D2) {
810 info() << "Maillage 2D";
811 mesh->setDimension(2);
813 }
814 else
815 throw NotSupportedException(A_FUNCINFO, "Can not read Lima 1D mesh");
816
817 if (!lm.get()) {
818 log() << "Dimension du maillage non reconnue par lima";
820 }
821 bool ret = lm->readMeshPart(timer_mng, reader.get(), mesh, filename, length_multiplier);
822 if (ret)
824 return IMeshReader::RTOk;
825}
826
827/*---------------------------------------------------------------------------*/
828/*---------------------------------------------------------------------------*/
829
830template <typename ReaderWrapper>
832readMeshPart(ITimerMng* timer_mng, LimaMaliReader* reader, IPrimaryMesh* mesh,
833 const String& filename, Real length_multiplier)
834{
835 return _readMeshPart(timer_mng, reader, mesh, filename, length_multiplier);
836}
837
838/*---------------------------------------------------------------------------*/
839/*---------------------------------------------------------------------------*/
845template <typename ReaderWrapper>
847_readMeshPart(ITimerMng* timer_mng, LimaMaliReader* reader, IPrimaryMesh* mesh,
848 const String& file_name, Real length_multiplier)
849{
850 typedef Lima::size_type size_type;
851 size_type basic_step = 100000;
852
853 IParallelMng* pm = mesh->parallelMng();
854 bool is_master_io = pm->isMasterIO();
855 Integer master_rank = pm->masterIORank();
856 Int32 nb_rank = pm->commSize();
857
858 Integer nb_edge = 0;
859
860 this->pwarning() << "Chargement Lima du fichier USING MALIPP avec partitionnement '" << file_name << '"';
861 if (basic_step < 100000)
862 this->pwarning() << "Small basic_step value=" << basic_step;
863
864 const char* version = Lima::lima_version();
865 info() << "Utilisation de la version " << version << " de Lima";
866
867 Timer time_to_read(timer_mng, "ReadLima", Timer::TimerReal);
868
869 this->log() << "Début lecture fichier " << file_name;
870
871 ReaderWrapper wrapper;
872 wrapper.setReader(reader);
873
874 if (reader && reader->dimension() != wrapper.limaDimension())
875 ARCANE_FATAL("Le fichier n'est pas un maillage {0}", wrapper.strDimension());
876
877 bool is_3d = (mesh->dimension() == 3);
878
879 Int64 mesh_nb_node = 0;
880 Int64 mesh_nb_cell = 0;
881 Int64 mesh_nb_face = 0;
882
883 // Le proc maitre lit le nombre d'entites et l'envoie aux autres
884 if (is_master_io) {
885 Lima::Composition lima_cells = wrapper.cells();
886 Lima::Composition lima_nodes = wrapper.nodes();
887 Lima::Composition lima_faces = wrapper.faces();
888
889 mesh_nb_node = (Int64)lima_nodes.nb_elements;
890 mesh_nb_cell = (Int64)lima_cells.nb_elements;
891 mesh_nb_face = (Int64)lima_faces.nb_elements;
892 Int64 nb_items[3];
893 nb_items[0] = mesh_nb_node;
894 nb_items[1] = mesh_nb_cell;
895 nb_items[2] = mesh_nb_face;
896 pm->broadcast(Int64ArrayView(3, nb_items), master_rank);
897
898 info() << "Unité de longueur du fichier: " << reader->unite_longueur();
899 if (length_multiplier == 0.0)
900 length_multiplier = 1.0;
901 else
902 length_multiplier *= reader->unite_longueur();
903 pm->broadcast(RealArrayView(1, &length_multiplier), master_rank);
904 }
905 else {
906 Int64 nb_items[3];
907 pm->broadcast(Int64ArrayView(3, nb_items), master_rank);
908 mesh_nb_node = nb_items[0];
909 mesh_nb_cell = nb_items[1];
910 mesh_nb_face = nb_items[2];
911 pm->broadcast(RealArrayView(1, &length_multiplier), master_rank);
912 }
913
914 size_type lima_nb_node = (size_type)mesh_nb_node;
915 nb_edge = 0; //lima.nb_bras();
916
917 info() << "-- Informations sur le maillage (Lima):";
918 info() << "Nombre de noeuds " << mesh_nb_node;
919 info() << "Nombre d'arêtes " << nb_edge;
920 info() << "Nombre de faces " << mesh_nb_face;
921 info() << "Nombre de mailles " << mesh_nb_cell;
922 if (mesh_nb_node == 0) {
923 ARCANE_FATAL("Pas de noeuds dans le fichier de maillage.");
924 }
925
926 // Pour l'instant, laisse à false.
927 // Si true, les uid sont incrémentés pour commencer à un.
928 Int64 uid_to_add = 0;
929 if (!platform::getEnvironmentVariable("ARCANE_LIMA_UNIQUE_ID").null()) {
930 uid_to_add = 1;
931 info() << "WARNING: UniqueId begin at 1";
932 }
933
934 Integer average_nb_cell = CheckedConvert::toInteger(mesh_nb_cell / nb_rank);
935
936 UniqueArray<Int64> own_cells_infos;
937 Integer own_nb_cell = 0;
938
939 // Remplit le tableau contenant les infos des mailles
940 if (is_master_io) {
941 // Tableau contenant les infos aux mailles (voir IMesh::allocateMesh())
942 Int64UniqueArray cells_infos;
943 cells_infos.reserve(average_nb_cell * 2);
944
945 Integer cell_step = average_nb_cell;
946 if (cell_step == 0)
947 ARCANE_FATAL("Number of cells is less than number of sub domains");
948
949 //size_type step_size = (lima_nb_cell>basic_step) ? basic_step : mesh_nb_cell;
950 size_type* buffer = wrapper.allocateCellsBuffer(cell_step + nb_rank);
951 Int64 total_nb_cell = mesh_nb_cell;
952 Integer current_nb_cell = 0;
953 Integer total_count = 0;
954 Integer last_print = 0;
955 for (Integer i = 0; total_count < total_nb_cell; ++i) {
956 if (i >= nb_rank)
957 ARCANE_FATAL("Too many count reading cells i={0} nrank=", i, nb_rank);
958 Int64 wanted_count = cell_step;
959 // The last subdomain takes all remaining cells
960 if ((i + 1) == nb_rank)
961 wanted_count = mesh_nb_cell;
962 Integer count = CheckedConvert::toInteger(wrapper.readCells(i * cell_step, wanted_count, buffer));
963 // Display a progress percentage (every 5%)
964 Integer p = (i * 20) / nb_rank;
965 if (p > last_print) {
966 last_print = p;
967 info() << "Reading cells rank=" << i << " n=" << wanted_count << " count=" << count
968 << " (" << (p * 5) << "%)";
969 }
970 current_nb_cell = count;
971 total_count += count;
972 size_type* ptr = buffer;
973 cells_infos.clear();
974 for (Integer p = 0; p < count; ++p) {
975 Integer cell_local_id = CheckedConvert::toInteger(*ptr++);
976 const Lima::size_type nodeCount = *ptr++;
977 Integer n = CheckedConvert::toInteger(nodeCount);
978 Integer ct = ReaderWrapper::cellToType(n);
979 if (ct == IT_NullType)
980 throw UnknownItemTypeException("LimaMaliPP::readFile: Cell", n, cell_local_id);
981 // Stores the cell type
982 cells_infos.add(ct);
983 // Stores the unique ID of the cell
984 cells_infos.add(uid_to_add + cell_local_id - 1);
985
986 for (Lima::size_type z = 0; z < nodeCount; ++z) {
987 Int64 node_local_id = *ptr++;
988 cells_infos.add(uid_to_add + node_local_id - 1);
989 }
990 }
991 if (i != master_rank) {
992 Integer nb_cells_infos[2];
993 nb_cells_infos[0] = current_nb_cell;
994 nb_cells_infos[1] = cells_infos.size();
995 pm->send(IntegerConstArrayView(2, nb_cells_infos), i);
996 pm->send(cells_infos, i);
997 }
998 else {
999 own_nb_cell = current_nb_cell;
1000 own_cells_infos = cells_infos;
1001 }
1002 } // for (i = 0; i * stepSize < polygonNumber; i++)
1003 delete[] buffer;
1004 }
1005 else {
1006 Integer nb_cells_infos[2];
1007 pm->recv(IntegerArrayView(2, nb_cells_infos), master_rank);
1008 own_nb_cell = nb_cells_infos[0];
1009 own_cells_infos.resize(nb_cells_infos[1]);
1010 pm->recv(own_cells_infos, master_rank);
1011 }
1012 ItemTypeMng* itm = mesh->itemTypeMng();
1013
1014 info() << " READ COORDINATES 1";
1015
1016 HashTableMapT<Int64, Real3> nodes_coords(own_nb_cell * 10, true);
1017 // Fills the hash table with the list of nodes in the subdomain
1018 {
1019 Integer cell_index = 0;
1020 for (Integer i = 0; i < own_nb_cell; ++i) {
1021 Integer type_id = (Integer)own_cells_infos[cell_index];
1022 ++cell_index;
1023 //Int64 cell_uid = own_cells_infos[cell_index];
1024 ++cell_index;
1025 ItemTypeInfo* it = itm->typeFromId(type_id);
1026 Integer current_nb_node = it->nbLocalNode();
1027 for (Integer z = 0; z < current_nb_node; ++z) {
1028 Int64 node_uid = own_cells_infos[cell_index + z];
1029 nodes_coords.add(node_uid, Real3());
1030 }
1031 cell_index += current_nb_node;
1032 }
1033 }
1034
1035 info() << " READ COORDINATES 2";
1036
1037 // Reading coordinates
1038 if (is_master_io) {
1039 size_type step_size = (lima_nb_node > basic_step) ? basic_step : mesh_nb_node;
1040 size_type nodeCount = 0;
1041 size_type* idBuffer = reader->allouer_tampon_ids(step_size);
1042 double* coordsBuffer = reader->allouer_tampon_coords(step_size);
1043 Integer dim_step = reader->dimension();
1044 Real3UniqueArray current_coords;
1045 for (Integer i = 0; i < mesh_nb_node;) {
1046 Integer count = CheckedConvert::toInteger(reader->lire_noeuds(i, step_size, idBuffer, coordsBuffer));
1047 current_coords.clear();
1048 for (Integer n = 0; n < count; ++n, ++nodeCount) {
1049 Real3 coord;
1050 //Integer local_id = idBuffer[n] - 1;
1051 switch (dim_step) {
1052 case 1:
1053 coord.x = coordsBuffer[n];
1054 break;
1055 case 2:
1056 coord.x = coordsBuffer[2 * n];
1057 coord.y = coordsBuffer[(2 * n) + 1];
1058 break;
1059 case 3:
1060 coord.x = coordsBuffer[3 * n];
1061 coord.y = coordsBuffer[(3 * n) + 1];
1062 coord.z = coordsBuffer[(3 * n) + 2];
1063 break;
1064 }
1065 if (length_multiplier != 1.0)
1066 current_coords.add(coord * length_multiplier);
1067 else
1068 current_coords.add(coord);
1069 } // for (size_type n = 0; n < count; n++, nodeCount++)
1070 Integer sizes_info[1];
1071 sizes_info[0] = count;
1072 pm->broadcast(IntegerArrayView(1, sizes_info), master_rank);
1073 //warning() << "SEND COUNT=" << count << '\n';
1074 pm->broadcast(current_coords, master_rank);
1075 this->_setCoords(current_coords, nodes_coords, i + uid_to_add);
1076 i += count;
1077 } // for (i = 0; i < nodes.nb_elements; )
1078 delete[] idBuffer;
1079 delete[] coordsBuffer;
1080 }
1081 else {
1082 Real3UniqueArray current_coords;
1083 for (Int64 i = 0; i < mesh_nb_node;) {
1084 Integer sizes_info[1];
1085 pm->broadcast(IntegerArrayView(1, sizes_info), master_rank);
1086 Integer count = sizes_info[0];
1087 current_coords.resize(count);
1088 //warning() << "RESIZE COUNT=" << count << " begin=" << current_coords.begin() << '\n';
1089 pm->broadcast(current_coords, master_rank);
1090 this->_setCoords(current_coords, nodes_coords, i + uid_to_add);
1091 i += count;
1092 }
1093 }
1094
1095 info() << " READ CELLS";
1096
1097 // We have the list of cells and the coordinates of the associated nodes.
1098 // Checks that the cell volume is positive, otherwise reverses
1099 // the cell topology.
1100 // For now, only processes IT_Hexaedron8 and pyramids
1101 {
1102 Integer cell_index = 0;
1103 Real3UniqueArray local_coords;
1104 local_coords.resize(8);
1105 Integer nb_reoriented = 0;
1106 for (Integer i = 0; i < own_nb_cell; ++i) {
1107 Integer type_id = (Integer)own_cells_infos[cell_index];
1108 ++cell_index;
1109 Int64 cell_uid = own_cells_infos[cell_index];
1110 ++cell_index;
1111 ItemTypeInfo* it = itm->typeFromId(type_id);
1112 Integer current_nb_node = it->nbLocalNode();
1113 local_coords.resize(current_nb_node);
1114 for (Integer z = 0; z < current_nb_node; ++z)
1115 local_coords[z] = nodes_coords.lookupValue(own_cells_infos[cell_index + z]);
1116 if (type_id == IT_Hexaedron8) {
1117 Real volume = LimaVolume::Hexaedron8Volume(local_coords.data());
1118 if (volume < 0.0) {
1119 std::swap(own_cells_infos[cell_index + 0], own_cells_infos[cell_index + 1]);
1120 std::swap(own_cells_infos[cell_index + 3], own_cells_infos[cell_index + 2]);
1121 std::swap(own_cells_infos[cell_index + 4], own_cells_infos[cell_index + 5]);
1122 std::swap(own_cells_infos[cell_index + 7], own_cells_infos[cell_index + 6]);
1123 info() << "Volume negatif Hexaedron8 uid=" << cell_uid << " v=" << volume;
1124 ++nb_reoriented;
1125 }
1126 }
1127 else if (type_id == IT_Pyramid5) {
1128 Real volume = LimaVolume::Pyramid5Volume(local_coords.data());
1129 if (volume < 0.0) {
1130 std::swap(own_cells_infos[cell_index + 0], own_cells_infos[cell_index + 1]);
1131 std::swap(own_cells_infos[cell_index + 2], own_cells_infos[cell_index + 3]);
1132 info() << "Volume negatif Pyramid5 uid=" << cell_uid << " v=" << volume;
1133 ++nb_reoriented;
1134 }
1135 }
1136 else if (type_id == IT_Quad4) {
1137 Real surface = LimaVolume::Quad4Surface(local_coords.data());
1138 if (surface < 0.0) {
1139 std::swap(own_cells_infos[cell_index + 0], own_cells_infos[cell_index + 1]);
1140 std::swap(own_cells_infos[cell_index + 2], own_cells_infos[cell_index + 3]);
1141 info() << "Surface negative Quad4 uid=" << cell_uid << " v=" << surface;
1142 ++nb_reoriented;
1143 }
1144 }
1145 else if (type_id == IT_Triangle3) {
1146 Real surface = LimaVolume::Triangle3Surface(local_coords.data());
1147 if (surface < 0.0) {
1148 std::swap(own_cells_infos[cell_index + 0], own_cells_infos[cell_index + 1]);
1149 info() << "Surface negative Triangle3 uid=" << cell_uid << " v=" << surface;
1150 ++nb_reoriented;
1151 }
1152 }
1153
1154 cell_index += current_nb_node;
1155 }
1156 info() << "NB reoriented cell = " << nb_reoriented;
1157 }
1158
1159 logdate() << "Start mesh allocation";
1160 mesh->allocateCells(own_nb_cell, own_cells_infos, false);
1161 logdate() << "End mesh allocation";
1162
1163 Int32 sid = pm->commRank();
1164 ItemInternalList cells(mesh->itemsInternal(IK_Cell));
1165 for (Integer i = 0, is = cells.size(); i < is; ++i)
1166 cells[i]->setOwner(sid, sid);
1167
1168 mesh->endAllocate();
1169
1170 // After allocation, the ghost cell layer is created.
1171 // However, only the cells have the correct owner.
1172 // For other entities, it must be updated.
1173 mesh->setOwnersFromCells();
1174
1175 this->_createGroups(mesh, IK_Cell, wrapper.cellGroupReader(), 0);
1176 this->_createGroups(mesh, IK_Node, wrapper.nodeGroupReader(), 0);
1177
1178 HashTableMapT<Int64, Int32> faces_local_id(own_nb_cell * 4, true); // Lima face number in the mesh \a mesh
1179
1180 {
1181 Int64UniqueArray faces_first_node_unique_id;
1182 IntegerUniqueArray faces_nb_node;
1183
1184 Int64UniqueArray faces_nodes_unique_id;
1185 Int64UniqueArray orig_nodes_id;
1186 orig_nodes_id.reserve(100);
1187 IntegerUniqueArray face_nodes_index;
1188 face_nodes_index.reserve(100);
1189
1190 ItemInternalList mesh_nodes(mesh->itemsInternal(IK_Node));
1191
1192 size_type face_basic_step = basic_step;
1193 size_type step_size = (mesh_nb_face > (Int64)face_basic_step) ? face_basic_step : mesh_nb_face;
1194 UniqueArray<size_type> buffer(wrapper.facesBufferSize(step_size));
1195 size_type total_nb_face = mesh_nb_face;
1196 Int64 current_nb_face = 0;
1197 Integer nb_lima_face_in_sub_domain = 0;
1198 info() << "Total_nb_face2=" << total_nb_face;
1199 //TODO possible to parallelize the reading:
1200 //1. The master process reads the arrays and sends them to N processes (scatter)
1201 //2. Each process is responsible for reordering the nodes of the faces it received and then sending them back to everyone (gather)
1202 for (size_type i = 0; (i * step_size) < total_nb_face; ++i) {
1203 Integer count = 0;
1204 if (is_master_io) {
1205 count = CheckedConvert::toInteger(wrapper.readFaces(i * step_size, step_size, buffer.data()));
1206 pm->broadcast(Int32ArrayView(1, &count), master_rank);
1207 pm->broadcast(buffer, master_rank);
1208 }
1209 else {
1210 pm->broadcast(Int32ArrayView(1, &count), master_rank);
1211 pm->broadcast(buffer, master_rank);
1212 }
1213 size_type* ptr = buffer.data();
1214 info() << " Read Face2 N=" << i << " count=" << count << " step_size=" << step_size;
1215 orig_nodes_id.clear();
1216 faces_first_node_unique_id.clear();
1217 faces_nb_node.resize(count);
1218 faces_nodes_unique_id.clear();
1219 Integer nodeCount = 0;
1220 for (Integer p = 0; p < count; ++p) {
1221 ++ptr;
1222 if (is_3d) {
1223 nodeCount = CheckedConvert::toInteger(*ptr++);
1224 }
1225 else
1226 nodeCount = 2;
1227 Integer n = nodeCount;
1228 faces_nb_node[p] = n;
1229 orig_nodes_id.resize(n);
1230 face_nodes_index.resize(n);
1231 for (Integer z = 0; z < nodeCount; ++z) {
1232 Integer node_local_id = CheckedConvert::toInteger(*ptr++);
1233 //info() << "P=" << p << " z=" << z << " id=" << node_local_id;
1234 orig_nodes_id[z] = node_local_id - 1;
1235 }
1236
1237 mesh_utils::reorderNodesOfFace2(orig_nodes_id, face_nodes_index);
1238 for (Integer z = 0; z < n; ++z)
1239 faces_nodes_unique_id.add(orig_nodes_id[face_nodes_index[z]]);
1240 faces_first_node_unique_id.add(orig_nodes_id[face_nodes_index[0]]);
1241 }
1242
1243 Int32UniqueArray faces_first_node_local_id(count);
1244 mesh->nodeFamily()->itemsUniqueIdToLocalId(faces_first_node_local_id, faces_first_node_unique_id, false);
1245
1246 Integer faces_nodes_unique_id_index = 0;
1247 for (Integer i_face = 0; i_face < count; ++i_face) {
1248 Integer n = faces_nb_node[i_face];
1249 Int64ConstArrayView face_nodes_id(n, &faces_nodes_unique_id[faces_nodes_unique_id_index]);
1250 Int32 first_node_id = faces_first_node_local_id[i_face];
1251 // Checks that the node is in my subdomain
1252 if (first_node_id != NULL_ITEM_ID) {
1253 Node current_node(mesh_nodes[first_node_id]);
1254 Face face = mesh_utils::getFaceFromNodesUnique(current_node, face_nodes_id);
1255
1256 // Checks that the face is in my subdomain
1257 if (!face.null()) {
1258 faces_local_id.add(current_nb_face + i_face, face.localId());
1259 ++nb_lima_face_in_sub_domain;
1260 }
1261 }
1262 faces_nodes_unique_id_index += n;
1263 }
1264 current_nb_face += count;
1265 }
1266 info() << "NB LIMA FACE IN SUB-DOMAIN =" << nb_lima_face_in_sub_domain;
1267 }
1268
1269 this->_createGroups(mesh, IK_Face, wrapper.faceGroupReader(), &faces_local_id);
1270
1271 {
1272 // Fills the variable containing the node coordinates
1273 VariableNodeReal3& nodes_coord_var(mesh->nodesCoordinates());
1274 ENUMERATE_NODE (i, mesh->ownNodes()) {
1275 const Node& node = *i;
1276 nodes_coord_var[node] = nodes_coords.lookupValue(node.uniqueId().asInt64());
1277 //info() << "Coord: " << node.uniqueId() << " v=" << nodes_coord_var[node];
1278 }
1279 nodes_coord_var.synchronize();
1280 }
1281
1282 logdate() << "End file reading";
1283 return false;
1284}
1285
1286/*---------------------------------------------------------------------------*/
1287/*---------------------------------------------------------------------------*/
1288
1289template <typename LimaMaliReader>
1292 Int64 current_unique_id)
1293{
1294 for (Integer i = 0, is = coords.size(); i < is; ++i) {
1295 Int64 uid = current_unique_id + i;
1296 HashTableMapT<Int64, Real3>::Data* d = nodes_coords.lookup(uid);
1297 if (d)
1298 d->value() = coords[i];
1299 }
1300}
1301
1302/*---------------------------------------------------------------------------*/
1303/*---------------------------------------------------------------------------*/
1304
1305template <typename LimaMaliReader>
1307_createGroups(IMesh* mesh, eItemKind item_kind, LimaGroupReader<LimaMaliReader>* lima_group_reader,
1308 HashTableMapT<Int64, Int32>* converter)
1309{
1310 IParallelMng* pm = mesh->parallelMng();
1311 Integer master_rank = pm->masterIORank();
1312 Integer is_master_io = pm->isMasterIO();
1313 //IItemFamily* item_family = mesh->itemFamily(item_kind);
1314 //ItemInternalList cells(cell_family->itemsInternal());
1315
1316 Int64UniqueArray unique_ids;
1317
1318 // Creation of cell groups
1319 if (is_master_io) {
1320 StringUniqueArray groups_name(lima_group_reader->groupsName());
1321 //std::vector<std::string> groups = wrapper.cellGroups();
1322 Integer nb_group = groups_name.size();
1323 Integer sizes_infos[1];
1324 sizes_infos[0] = nb_group;
1325 pm->broadcast(IntegerArrayView(1, sizes_infos), master_rank);
1326 for (Integer i = 0; i < nb_group; ++i) {
1327 //typename ReaderWrapper::LimaCellGroup group_reader = wrapper.cellGroup(groups[i]);
1328 String group_name = groups_name[i];
1329 pm->broadcastString(group_name, master_rank);
1330 //pwarning() << "Group Name <" << group_name;
1331 //wrapper.readGroup(group_reader,unique_ids);
1332 lima_group_reader->read(group_name, unique_ids);
1333 Integer nb_item_in_group = unique_ids.size();
1334 sizes_infos[0] = nb_item_in_group;
1335 pm->broadcast(IntegerArrayView(1, sizes_infos), master_rank);
1336 pm->broadcast(unique_ids, master_rank);
1337 if (converter)
1338 _createGroupFromHashTable(mesh, group_name, item_kind, unique_ids, *converter);
1339 else
1340 _createGroupFromUniqueIds(mesh, group_name, item_kind, unique_ids);
1341 }
1342 }
1343 else {
1344 Integer sizes_infos[1];
1345 pm->broadcast(IntegerArrayView(1, sizes_infos), master_rank);
1346 Integer nb_group = sizes_infos[0];
1347 for (Integer i = 0; i < nb_group; ++i) {
1348 String group_name;
1349 pm->broadcastString(group_name, master_rank);
1350 //pwarning() << "Group Name <" << group_name;
1351 pm->broadcast(IntegerArrayView(1, sizes_infos), master_rank);
1352 Integer nb_item_in_group = sizes_infos[0];
1353 unique_ids.resize(nb_item_in_group);
1354 pm->broadcast(unique_ids, master_rank);
1355 if (converter)
1356 _createGroupFromHashTable(mesh, group_name, item_kind, unique_ids, *converter);
1357 else
1358 _createGroupFromUniqueIds(mesh, group_name, item_kind, unique_ids);
1359 }
1360 }
1361}
1362
1363/*---------------------------------------------------------------------------*/
1364/*---------------------------------------------------------------------------*/
1365
1366template <typename LimaMaliReader>
1369 Int64ConstArrayView unique_ids)
1370{
1371 Integer nb_item_in_group = unique_ids.size();
1372 Int32UniqueArray local_ids(nb_item_in_group);
1373 IItemFamily* family = mesh->itemFamily(ik);
1374 family->itemsUniqueIdToLocalId(local_ids, unique_ids, false);
1375 Int32UniqueArray group_ids;
1376 for (Integer i = 0; i < nb_item_in_group; ++i) {
1377 if (local_ids[i] != NULL_ITEM_ID)
1378 group_ids.add(local_ids[i]);
1379 }
1380 info() << "Group Name <" << name << "> (" << nb_item_in_group << " elements)";
1381 LimaUtils::createGroup(family, name, group_ids);
1382}
1383
1384/*---------------------------------------------------------------------------*/
1385/*---------------------------------------------------------------------------*/
1386
1387template <typename LimaMaliReader>
1390 Int64ConstArrayView unique_ids,
1391 const HashTableMapT<Int64, Int32>& converter)
1392{
1393 Integer nb_item_in_group = unique_ids.size();
1394 Int32UniqueArray local_ids(nb_item_in_group);
1395 IItemFamily* family = mesh->itemFamily(ik);
1396 Int32UniqueArray group_ids;
1397 for (Integer i = 0; i < nb_item_in_group; ++i) {
1398 const HashTableMapT<Int64, Int32>::Data* data = converter.lookup(unique_ids[i]);
1399 if (data)
1400 group_ids.add(data->value());
1401 }
1402 info() << "Group Name <" << name << "> (" << nb_item_in_group << " elements)";
1403 LimaUtils::createGroup(family, name, group_ids);
1404}
1405
1406/*---------------------------------------------------------------------------*/
1407/*---------------------------------------------------------------------------*/
1408
1409} // End namespace Arcane
1410
1411/*---------------------------------------------------------------------------*/
1412/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Types and macros for iterating over mesh entities.
#define ENUMERATE_NODE(name, group)
Generic enumerator for a node group.
Various mathematical functions.
Utility functions for the mesh.
bool reorderNodesOfFace2(Int64ConstArrayView nodes_unique_id, Int32ArrayView new_index)
Reorders the nodes of a face.
This file contains the various service factories and macros for registering services.
Integer size() const
Number of elements in the vector.
void resize(Int64 s)
Changes the number of elements in the array to s.
void clear()
Removes the elements from the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
const T * data() const
Access to the root of the array without any protection.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
constexpr Integer size() const noexcept
Number of elements in the array.
Face of a cell.
Definition Item.h:1032
Hash table for associative arrays.
Data * lookup(KeyTypeConstRef id)
Searches for the value corresponding to key id.
ValueType & lookupValue(KeyTypeConstRef id)
Searches for the value corresponding to key id.
bool add(KeyTypeConstRef id, const ValueType &value)
Adds the value value corresponding to key id.
Interface of an entity family.
Definition IItemFamily.h:83
eReturnType
Types of return codes for a read or write operation.
Definition IMeshReader.h:38
@ RTIrrelevant
Not relevant to the operation. This means that the file format does not match this reader or that the...
Definition IMeshReader.h:46
@ RTError
Error during the operation.
Definition IMeshReader.h:40
@ RTOk
Operation successfully performed.
Definition IMeshReader.h:39
Interface of the parallelism manager for a subdomain.
virtual ITraceMng * traceMng() const =0
Trace manager.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual void recv(ArrayView< char > values, Int32 rank)=0
virtual bool isMasterIO() const =0
true if the instance is a master I/O manager.
virtual Int32 commSize() const =0
Number of instances in the communicator.
virtual Integer masterIORank() const =0
Rank of the instance managing I/O (for which isMasterIO() is true).
Interface of a timer manager.
Definition ITimerMng.h:50
Info on a mesh entity type.
Integer nbLocalNode() const
Number of nodes of the entity.
Mesh entity type manager.
Definition ItemTypeMng.h:66
ItemTypeInfo * typeFromId(Integer id) const
Type corresponding to the number id.
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Definition Item.h:233
ItemUniqueId uniqueId() const
Unique identifier across all domains.
Definition Item.h:239
constexpr bool null() const
true if the entity is null (i.e. not connected to the mesh)
Definition Item.h:230
Mesh file reader via the LIMA library for '.mli' or 'mli2' files.
Mesh file reader via the LIMA library.
TraceMessage logdate() const
Flow for a log message preceded by the date.
TraceMessage log() const
Flow for a log message.
TraceMessage info() const
Flow for an information message.
bool _readMeshPart(ITimerMng *timer_mng, LimaMaliReader *reader, IPrimaryMesh *mesh, const String &filename, Real length_multiplier)
Mesh reading. Only the master process has a non-null instance of reader. Others must not use it.
Mesh file reader via the LIMA library.
static void createGroup(IItemFamily *family, const String &name, Int32ArrayView local_ids)
Creates a group of entities.
Definition LimaUtils.cc:43
Node of a mesh.
Definition Item.h:598
T * get() const
Returns the object referenced by the instance.
Definition Ptr.h:122
Class managing a 3-dimensional real vector.
Definition Real3.h:132
Encapsulation of an automatically destructing pointer.
Definition ScopedPtr.h:44
bool null() const
Returns true if the string is null.
Definition String.cc:306
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:229
bool empty() const
True if the string is empty (null or "").
Definition String.cc:317
Management of a timer.
Definition Timer.h:63
@ TimerReal
Timer using real time.
Definition Timer.h:77
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage logdate() const
Flow for a log message preceded by the date.
TraceMessage log() const
Flow for a log message.
TraceMessage info() const
Flow for an information message.
TraceMessage pwarning() const
1D data vector with value semantics (STL style).
Exception when a mesh entity is not of a known type.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
__host__ __device__ double log(double v)
Natural logarithm of v.
Definition Math.h:42
__host__ __device__ Real matDet(Real3 u, Real3 v, Real3 w)
Determinant of the matrix u,v,w.
Definition MathUtils.h:173
String getEnvironmentVariable(const String &name)
Environment variable named name.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Array< Int64 > Int64Array
Dynamic one-dimensional array of 64-bit integers.
Definition UtilsTypes.h:125
ArrayView< Int64 > Int64ArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:451
ConstArrayView< Real3 > Real3ConstArrayView
C equivalent of a 1D array of Real3.
Definition UtilsTypes.h:496
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
Definition UtilsTypes.h:339
ConstArrayView< String > StringConstArrayView
C equivalent of a 1D array of strings.
Definition UtilsTypes.h:492
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
UniqueArray< Real3 > Real3UniqueArray
Dynamic 1D array of rank 3 vectors.
Definition UtilsTypes.h:363
ArrayView< Integer > IntegerArrayView
C equivalent of a 1D array of integers.
Definition UtilsTypes.h:457
ConstArrayView< ItemInternal * > ItemInternalList
Type of the internal list of entities.
Definition ItemTypes.h:466
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:480
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
Definition UtilsTypes.h:341
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:453
eItemKind
Mesh entity type.
@ IK_Node
Node mesh entity.
@ IK_Cell
Cell mesh entity.
@ IK_Face
Face mesh entity.
double Real
Type representing a real number.
UniqueArray< String > StringUniqueArray
Dynamic 1D array of strings.
Definition UtilsTypes.h:359
UniqueArray< Integer > IntegerUniqueArray
Dynamic 1D array of integers.
Definition UtilsTypes.h:347
ConstArrayView< Integer > IntegerConstArrayView
C equivalent of a 1D array of integers.
Definition UtilsTypes.h:486
ArrayView< Real > RealArrayView
C equivalent of a 1D array of reals.
Definition UtilsTypes.h:459
std::int32_t Int32
Signed integer type of 32 bits.
Real y
second component of the triplet
Definition Real3.h:36
Real z
third component of the triplet
Definition Real3.h:37
Real x
first component of the triplet
Definition Real3.h:35