Salome HOME
updated copyright message
[tools/medcoupling.git] / src / MEDLoader / MeshFormatWriter.cxx
1 // Copyright (C) 2021-2023  CEA, EDF
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "MeshFormatWriter.hxx"
21 #include "MEDFileMesh.hxx"
22 #include "MEDFileField.hxx"
23 #include "MEDFileData.hxx"
24 #include "MEDCouplingFieldDouble.hxx"
25 #include "libmesh5.hxx"
26 #include "MEDMESHConverterUtilities.hxx"
27 #include <cstring>
28 #include <algorithm>
29 #include <map>
30 #include <cstdlib>
31 #include <fstream>
32
33
34 namespace MEDCoupling {
35   
36 MeshFormatWriter::MeshFormatWriter()
37 {}
38 MeshFormatWriter::MeshFormatWriter(const std::string& meshFileName,
39                                    const std::vector<std::string>& fieldFileNames):_meshFileName(meshFileName),
40                                    _fieldFileNames(fieldFileNames)
41 {}
42 MeshFormatWriter::~MeshFormatWriter()
43 {}
44 void MeshFormatWriter::setMeshFileName(const std::string& meshFileName)
45 {
46     _meshFileName = meshFileName;
47 }
48 void MeshFormatWriter::setFieldFileNames(const std::vector<std::string>& fieldFileNames)
49 {
50     _fieldFileNames = fieldFileNames;
51 }
52 void MeshFormatWriter::setMEDFileDS(MEDCoupling::MEDFileData* mfd)
53 {
54
55     if(!mfd)
56     {
57         addMessage( MeshFormat::Comment(" MEDFileData is nullptr! ") << _meshFileName, /*fatal=*/true );
58         return;
59     }
60     if ( !mfd->getNumberOfMeshes())
61     {
62         addMessage( MeshFormat::Comment("No Mesh in MEDFileData! ") << _meshFileName, /*fatal=*/true );
63         return;
64     }
65     if ( mfd->getNumberOfMeshes() > 1)
66     {
67         addMessage( MeshFormat::Comment("More than One Mesh in File! ") << _meshFileName, /*fatal=*/true );
68         return;
69     }
70
71     MEDCoupling::MEDFileMeshes* meshes  = mfd->getMeshes();
72     _mesh  = meshes->getMeshAtPos(0);
73
74     _mesh->incrRef();
75     MEDCoupling::MEDFileFields* fields = mfd->getFields();
76
77     for (int i = 0; i<fields->getNumberOfFields(); i++ )
78     {
79         MEDCoupling::MEDFileAnyTypeFieldMultiTS* field = fields->getFieldAtPos(i);
80         MEDCoupling::MEDFileFieldMultiTS * f = dynamic_cast<MEDCoupling::MEDFileFieldMultiTS *>(field);
81         _fields.push_back(f);
82     }
83
84
85 }
86
87 void MeshFormatWriter::write()
88 {
89
90     MeshFormat::Localizer loc;
91
92     MEDCoupling::MCAuto<MEDCoupling::MEDCouplingMesh > mesh = _mesh->getMeshAtLevel( 1 );
93     MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh = mesh->buildUnstructured();
94     _dim = umesh->getSpaceDimension();
95
96     if (_dim != 2 && _dim != 3)
97     {
98         addMessage( MeshFormat::Comment("Only 3D or 2D mesh allowed! ") << _meshFileName, /*fatal=*/true );
99         return ;
100     }
101
102
103     _version = sizeof(double) < 8 ? 1 : 2;
104     _writer = MeshFormat::MeshFormatParser();
105     _myCurrentOpenFile = _meshFileName;
106     _myCurrentFileId = _writer.GmfOpenMesh( _meshFileName.c_str(), GmfWrite, _version, _dim );
107     if ( !_myCurrentFileId )
108     {
109         if ( MeshFormat::isMeshExtensionCorrect( _meshFileName ))
110         {
111             addMessage( MeshFormat::Comment("Can't open for writing ") << _meshFileName, /*fatal=*/true );
112             return;
113         }
114
115         else
116         {
117             addMessage( MeshFormat::Comment("Not '.mesh' or '.meshb' extension of file ") << _meshFileName, /*fatal=*/true );
118             return;
119         }
120
121     }
122
123
124     perform();
125     _writer.GmfCloseMesh(_myCurrentFileId);
126     _myCurrentFileId = -1;
127     _myCurrentOpenFile = "";
128     if (_fields.size()) performFields();
129
130
131 }
132
133 MeshFormat::Status MeshFormatWriter::perform()
134 {
135
136
137     MEDCoupling::MCAuto< MEDCoupling::MEDCouplingMesh > mesh1;
138     MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh1;
139     MEDCoupling::MCAuto< MEDCoupling::MEDCouplingMesh > mesh2;
140     MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2;
141     MEDCoupling::MCAuto< MEDCoupling::MEDCouplingMesh > mesh3;
142     MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3;
143
144     std::vector<int> dims = _mesh->getNonEmptyLevelsExt();
145     int dim = _mesh->getMeshDimension();
146     bool threeDElements = false;
147     bool twoDElements = false;
148     bool OneDElements = false;
149     if (dims.size() != 0)
150     {
151         bool maxLevelDimElments = ( std::find(dims.begin(), dims.end(), 0) != dims.end() );
152         bool nextToMaxLevelDimElments = ( std::find(dims.begin(), dims.end(), -1) != dims.end() );
153         bool nextToNextToMaxLevelDimElments = (std::find(dims.begin(), dims.end(), -2) != dims.end() );
154         threeDElements = (dim == 3) ? maxLevelDimElments : false ;
155         twoDElements =  (dim == 3) ? nextToMaxLevelDimElments : maxLevelDimElments ;
156         OneDElements = (dim == 3) ? nextToNextToMaxLevelDimElments : nextToMaxLevelDimElments;
157     }
158
159     MEDCoupling::mcIdType nbEdgesNSEG2 = 0;
160     MEDCoupling::mcIdType nbEdgesNSEG3 = 0;
161     MEDCoupling::mcIdType nbTRI3 = 0;
162     MEDCoupling::mcIdType nbTRI6 = 0;
163     MEDCoupling::mcIdType nbQUAD4 = 0;
164     MEDCoupling::mcIdType nbQUAD8 = 0;
165     MEDCoupling::mcIdType nbQUAD9 = 0;
166     MEDCoupling::mcIdType nbTETRA4 = 0;
167     MEDCoupling::mcIdType nbTETRA10 = 0;
168     MEDCoupling::mcIdType nbPYRA5 = 0;
169     MEDCoupling::mcIdType nbHEXA8 = 0;
170     MEDCoupling::mcIdType nbHEXA20 = 0;
171     MEDCoupling::mcIdType nbHEXA27 = 0;
172     MEDCoupling::mcIdType nbPENTA6 = 0;
173
174     if (OneDElements)
175     {
176         mesh1 = _mesh->getMeshAtLevel( 1-dim );
177         umesh1 = mesh1->buildUnstructured();
178         nbEdgesNSEG2 = umesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_SEG2);
179
180         nbEdgesNSEG3 = umesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_SEG3);
181
182     }
183     if (twoDElements)
184     {
185         mesh2 = _mesh->getMeshAtLevel( 2-dim );
186         umesh2 = mesh2->buildUnstructured();
187         nbTRI3 = umesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TRI3);
188
189         nbTRI6 = umesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TRI6);
190
191         nbQUAD4 = umesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
192
193         nbQUAD8 = umesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD8);
194
195         nbQUAD9 = umesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD9);
196
197     }
198     if (threeDElements)
199     {
200
201         mesh3 = _mesh->getMeshAtLevel( 3-dim );
202         umesh3 = mesh3->buildUnstructured();
203         nbTETRA4 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TETRA4);
204
205         nbTETRA10 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TETRA10);
206
207         nbPYRA5 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_PYRA5);
208
209         nbHEXA8 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8);
210
211         nbHEXA20 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA20);
212
213         nbHEXA27 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA27);
214
215         nbPENTA6 = umesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_PENTA6);
216
217     }
218
219
220
221     MEDCoupling::MCAuto< MEDCoupling::MEDCouplingMesh > mesh0 = _mesh->getMeshAtLevel(1);
222     MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh0 = mesh0->buildUnstructured();
223
224     // nodes
225     getNodes(umesh0);
226
227     // edges SEG2
228     if ( nbEdgesNSEG2 > 0)
229     {
230         getNSEG2( nbEdgesNSEG2, umesh1);
231     }
232     //~// nodes of quadratic edges SEG3
233     if ( nbEdgesNSEG3 > 0)
234     {
235         getNSEG3( nbEdgesNSEG3, umesh1);
236     }
237
238     // triangles TRI3
239     if ( nbTRI3 > 0)
240     {
241         getTRI3( nbTRI3, umesh2);
242     }
243
244     // nodes of quadratic triangles
245     // triangles TRI6
246     if ( nbTRI6 > 0)
247     {
248         getTRI6( nbTRI6, umesh2);
249
250     }
251     //~// quadrangles QUAD4
252     if ( nbQUAD4 > 0)
253     {
254         getQUAD4(nbQUAD4, umesh2);
255     }
256
257     //~// quadrangles quadratic QUAD8
258     if ( nbQUAD8 > 0)
259     {
260         getQUAD8( nbQUAD8, umesh2);
261     }
262
263     //~// quadrangles quadratic QUAD9
264     if ( nbQUAD9 > 0)
265     {
266         getQUAD9( nbQUAD9, umesh2);
267     }
268
269     // terahedra TETRA4
270     if ( nbTETRA4 > 0)
271     {
272         getTETRA4( nbTETRA4, umesh3);
273     }
274     //~terahedra TETRA10
275     if ( nbTETRA10 > 0)
276     {
277         getTETRA10( nbTETRA10, umesh3);
278     }
279
280     //~// pyramids 5
281     if ( nbPYRA5 > 0)
282     {
283         getPYRA5(nbPYRA5, umesh3);
284     }
285     //~// hexahedra 8
286     if ( nbHEXA8 > 0)
287     {
288         getHEXA8( nbHEXA8, umesh3);
289     }
290
291     //~// hexahedra 20
292     if ( nbHEXA20 > 0)
293     {
294         getHEXA20( nbHEXA20, umesh3);
295     }
296
297     //~// hexahedra 27
298     if ( nbHEXA27 > 0)
299     {
300         getHEXA27 (nbHEXA27, umesh3);
301     }
302
303     // prism
304     if ( nbPENTA6 > 0)
305     {
306         getPENTA6(nbPENTA6, umesh3);
307     }
308
309     linkFamilyToCells();
310     writeCells();
311
312
313     return MeshFormat::DRS_OK;
314 }
315
316
317 MeshFormat::Status MeshFormatWriter::performFields()
318 {
319
320     MeshFormat::Status status = MeshFormat::Status::DRS_OK;
321
322     if (_fields.size() != _fieldFileNames.size() )
323     {
324         addMessage( MeshFormat::Comment(" Number of fields and number of input *.sol files must be equal ") << _meshFileName, /*fatal=*/true );
325         status = MeshFormat::Status::DRS_FAIL;
326         return status;
327     }
328
329
330     int  dim = _mesh->getMeshDimension();  // dim mesh  field lying to
331     std::vector<std::string>::const_iterator fieldFileIt = _fieldFileNames.begin();
332     int iField = 0;
333     std::vector<int> levs {0} ;
334     for (; fieldFileIt !=_fieldFileNames.end();  ++fieldFileIt)
335     {
336         // Open files
337         _myCurrentOpenFile = *fieldFileIt;
338
339         MEDCoupling::MEDFileFieldMultiTS* f = _fields[iField];
340
341         if(!f)
342             continue;// why???
343         if ( f->getMeshName() == _mesh->getName() )
344         {
345
346             std::vector< std::vector<MEDCoupling::TypeOfField> > fTypes = f->getTypesOfFieldAvailable();
347             std::vector< std::pair<int,int> >  iters = f->getIterations();
348             const std::vector<std::string>& compInfo = f->getInfo();
349             std::pair<int,int> it = iters[0];
350
351             //~// Open File for writing
352             _myCurrentFileId = _writer.GmfOpenMesh( fieldFileIt->c_str(), GmfWrite, _version, _dim );
353
354             if ( fTypes[0].size() == 1 && fTypes[0][0] == MEDCoupling::ON_NODES )
355             {
356                 setFieldOnNodes(f, it.first,  it.second, compInfo.size());
357             }
358             else
359             {
360                 setFieldOnCells( f, it.first,  it.second, levs );
361             }
362             //~// Close File
363             _writer.GmfCloseMesh( _myCurrentFileId );
364         }
365
366
367         iField++;
368     }
369
370     return status;
371 }
372
373 MeshFormat::Status MeshFormatWriter::setFieldOnNodes(MEDCoupling::MEDFileFieldMultiTS * f, int iteration, int order, size_t compSize)
374 {
375
376
377     std::vector<INTERP_KERNEL::NormalizedCellType> types;
378     std::vector< std::vector<MEDCoupling::TypeOfField> > typesF;
379     std::vector< std::vector<std::string> > pfls, locs;
380     std::vector< std::vector< std::pair<mcIdType,mcIdType> > > valsVec;
381     valsVec = f->getFieldSplitedByType( iteration, order, _mesh->getName().c_str(),
382                                         types, typesF, pfls, locs);
383     // believe that there can be only one type in a nodal field,
384     // so do not perform a loop on types
385     const MEDCoupling::DataArrayDouble* valsArray = f->getUndergroundDataArray(iteration, order);
386     int typTab[] = { getGmfSolKwd((int)compSize, _dim) };
387     _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfSolAtVertices, (int)valsVec[0][0].second, 1, typTab);
388     double* valTab0 = new double[compSize];
389     double* valTab;
390     for ( size_t i = valsVec[0][0].first; i < (std::size_t)valsVec[0][0].second; ++i )
391     {
392
393         for ( size_t j = 0; j < compSize; ++j )
394             valTab0[j] = valsArray->getIJ( i, j );
395             
396     if (compSize == 9 || compSize == 4){ // full matrix ==>uper triangular matrix
397       extractSymetricTensor(valTab0, valTab);
398       _writer.GmfSetLin( _myCurrentFileId, MeshFormat::GmfSolAtVertices, valTab);
399       delete [] valTab;
400       
401     }
402     else  
403         _writer.GmfSetLin( _myCurrentFileId, MeshFormat::GmfSolAtVertices, valTab0);
404
405     }
406     delete [] valTab0;
407
408     return MeshFormat::Status::DRS_OK;
409
410 }
411
412 MeshFormat::Status MeshFormatWriter::setFieldOnCells(MEDCoupling::MEDFileFieldMultiTS * f, int iteration, int order, std::vector<int> levs )
413 {
414
415     int  dim = _mesh->getMeshDimension();  // dim mesh  field lying to
416     int absDim = f->getNonEmptyLevels(iteration, order,  f->getMeshName(), levs);
417
418     MEDCoupling::MEDCouplingFieldDouble**  cellToNodeFldb  = new MEDCoupling::MEDCouplingFieldDouble* [(int)levs.size()] ;
419     MEDCoupling::MEDCouplingFieldDouble**  fldb  = new MEDCoupling::MEDCouplingFieldDouble* [(int)levs.size()] ;
420
421     for (size_t k = 0; k<levs.size(); k++) fldb[k] = f->field( iteration, order,_mesh );
422
423     // turn it node discretization
424     for (size_t l = 0; l < levs.size(); l++) cellToNodeFldb[l] = fldb[l]->cellToNodeDiscretization() ;
425
426     for(size_t j =0; j < levs.size(); j++ )
427     {
428
429         const mcIdType pointsNumber = cellToNodeFldb[j]->getNumberOfTuples();
430         const mcIdType nbComp = (int) cellToNodeFldb[j]->getNumberOfComponents() ;
431
432         MEDCoupling::DataArrayDouble* timeStamp = cellToNodeFldb[j]->getArray();
433         double* values = timeStamp->getPointer();
434
435         int typ = getGmfSolKwd((int)nbComp, _dim) ;
436         if(typ == -1)
437         {
438             addMessage( MeshFormat::Comment(" error with Number of Component   ") << nbComp, /*fatal=*/true );
439             return MeshFormat::Status::DRS_FAIL;
440         }
441
442         int typTab[] = {typ};
443         _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfSolAtVertices, pointsNumber, 1, typTab);
444
445
446         double *valTab;
447         for (int i = 0; i < pointsNumber ; i++ )
448         {
449
450             double valTab0[10]; //max 3x3 matrix +1 for safety ;)
451
452             std::copy(values, values+nbComp, valTab0);
453
454             if (nbComp == 9 || nbComp == 4) // full matrix ==>uper triangular matrix
455             {
456         extractSymetricTensor(valTab0, valTab);
457                 _writer.GmfSetLin( _myCurrentFileId, MeshFormat::GmfSolAtVertices, valTab);
458                 delete [] valTab;
459             }
460             else //sym mat, scalar or vec
461             {
462                 valTab = new double[nbComp];
463                 std::copy(valTab0, valTab0+nbComp, valTab);
464                 _writer.GmfSetLin( _myCurrentFileId, MeshFormat::GmfSolAtVertices, valTab);
465                 delete [] valTab;
466             }
467             values+=nbComp;
468
469         }
470
471
472     }
473
474     for(size_t i = 0; i < levs.size(); i++ )  fldb[i]->decrRef();
475     for(size_t i = 0; i < levs.size(); i++ )  cellToNodeFldb[i]->decrRef();
476     delete [] cellToNodeFldb;
477     delete [] fldb;
478
479     return MeshFormat::Status::DRS_OK;
480 }
481  /*\
482  |*| extract the upper triangular matrix  of fullTensor
483  |*| if _dim == 2 fill symTensor with values at index 0, 1 & 3 of fullTensor
484  |*| |x0 x1|   
485  |*| |x2 x3|  
486  |*| if _dim == 3 fill symTensor with values at index 0, 1, 2, 4, 5 & 8 of fullTensor
487  |*| |x0 x1 x2|
488  |*| |x3 x4 x5|
489  |*| |x6 x7 x8|
490  \*/
491 void MeshFormatWriter::extractSymetricTensor(double fullTensor[], double*& symTensor)
492 {
493      symTensor = new double[_dim*(_dim+1)/2];
494   for (int ii =0; ii<_dim; ii++)
495     for (int jj =ii; jj<_dim; jj++)
496     {
497       int kk = _dim*(_dim-1)/2- (_dim-ii)*(_dim-ii-1)/2+jj;
498       symTensor[kk] = fullTensor[ii+jj*_dim];
499     }  
500 }
501 int MeshFormatWriter::getGmfSolKwd(const int nbComp, const int dim)
502 {
503     if (nbComp== 1) return GmfSca;
504     else if( dim == nbComp) return GmfVec;
505     else if (dim*(dim+1)/2 == nbComp || dim*dim == nbComp ) return GmfSymMat;
506     //~else if (dim*dim == nbComp) return GmfMat; // Not valid in mg-adapt if not sym
507     else  return -1;
508 }
509 bool MeshFormatWriter::checkFileName()
510 {
511     bool ret = true;
512     return ret;
513 }
514 bool MeshFormatWriter::checkFieldFileName()
515 {
516     bool ret = true;
517     return ret;
518
519 }
520
521 std::string MeshFormatWriter::getMeshFileName() const
522 {
523     return _meshFileName;
524 }
525
526
527 std::vector<std::string> MeshFormatWriter::getFieldFileNames() const
528 {
529     return _fieldFileNames;
530 }
531
532 MeshFormat::Status MeshFormatWriter::addMessage(const std::string& msg,
533         const bool         isFatal/*=false*/)
534 {
535     if ( isFatal )
536         _myErrorMessages.clear(); // warnings are useless if a fatal error encounters
537
538     _myErrorMessages.push_back( msg );
539
540     //~MESSAGE(msg);
541 #ifdef _DEBUG_
542     std::cout << msg << std::endl;
543 #endif
544     return ( _myStatus = isFatal ? MeshFormat::DRS_FAIL : MeshFormat::DRS_WARN_SKIP_ELEM );
545 }
546
547
548 void MeshFormatWriter::forward_shift(std::vector<MEDCoupling::mcIdType> &conn)
549 {
550     std::vector<MEDCoupling::mcIdType>::iterator it = conn.begin();
551     for (; it != conn.end(); ++it) *it = *it+1;
552 }
553
554
555 void MeshFormatWriter::getNodes(MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh0)
556 {
557     MEDCoupling::mcIdType nbNodes = 0;
558     nbNodes = umesh0->getNumberOfNodes();
559
560
561     // nodes
562     MEDCoupling::MCAuto<MEDCoupling::DataArrayDouble> coordArray = umesh0->getCoordinatesAndOwner();
563     double* coordPrt = coordArray->getPointer();
564     _writer.GmfSetKwd( _myCurrentFileId, MeshFormat::GmfVertices, nbNodes );
565     double xyz[3];
566     int j = (int)nbNodes;
567
568     int idNode = 0;
569
570     while ( j >0 )
571     {
572
573         std::copy(coordPrt, coordPrt+_dim, xyz);
574
575         MeshFormatNode e(xyz[0], xyz[1], xyz[2], idNode);
576         _idNodeToNode.insert(std::pair <int, MeshFormatNode> (idNode, e));
577
578         coordPrt+= _dim;
579         j--;
580         idNode++;
581     }
582     linkFamilyToNodes();
583     std::map <int, MeshFormatNode>::iterator itNode = _idNodeToNode.begin();
584     for (; itNode!= _idNodeToNode.end(); ++itNode)
585         _dim == 3?  _writer.GmfSetLin( _myCurrentFileId, MeshFormat::GmfVertices, itNode->second.xyz[0],
586                      itNode->second.xyz[1], itNode->second.xyz[2], std::abs(itNode->second._famId) ) :
587                       _writer.GmfSetLin( _myCurrentFileId, MeshFormat::GmfVertices, itNode->second.xyz[0],
588                      itNode->second.xyz[1], std::abs(itNode->second._famId) );
589 }
590
591
592 void MeshFormatWriter::getNSEG2(MEDCoupling::mcIdType nbEdgesNSEG2, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh1)
593 {
594
595     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh1->giveCellsWithType(INTERP_KERNEL::NORM_SEG2);
596     std::map<int, MeshFormatCell> idCellToCell;
597     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
598     {
599         std::vector<MEDCoupling::mcIdType> conn;
600         umesh1->getNodeIdsOfCell(*it,  conn) ;
601         forward_shift(conn);
602
603         MeshFormatCell e(INTERP_KERNEL::NORM_SEG2, (int)*it);
604         e.setConn(conn);
605         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
606     }
607     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_SEG2, idCellToCell) );
608 }
609
610
611 void MeshFormatWriter::getNSEG3( MEDCoupling::mcIdType nbEdgesNSEG3, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh1)
612 {
613
614
615     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh1->giveCellsWithType(INTERP_KERNEL::NORM_SEG3);
616     std::map<int, MeshFormatCell> idCellToCell;
617     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
618     {
619
620         std::vector<MEDCoupling::mcIdType> conn;
621         umesh1->getNodeIdsOfCell(*it,  conn) ;
622         forward_shift(conn);
623         MeshFormatCell e(INTERP_KERNEL::NORM_SEG3, (int)*it);
624         e.setConn(conn);
625         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
626     }
627     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_SEG3, idCellToCell) );
628 }
629
630
631 void MeshFormatWriter::getTRI3( MEDCoupling::mcIdType nbTRI3, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2)
632 {
633
634     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh2->giveCellsWithType(INTERP_KERNEL::NORM_TRI3);
635     std::map<int, MeshFormatCell> idCellToCell;
636     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
637     {
638         std::vector<MEDCoupling::mcIdType> conn;
639         umesh2->getNodeIdsOfCell(*it,  conn) ;
640         forward_shift(conn);
641         MeshFormatCell e(INTERP_KERNEL::NORM_TRI3, (int)*it);
642         e.setConn(conn);
643         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
644     }
645     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_TRI3, idCellToCell) );
646 }
647
648
649 void MeshFormatWriter::getTRI6( MEDCoupling::mcIdType nbTRI6, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2)
650 {
651
652     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh2->giveCellsWithType(INTERP_KERNEL::NORM_TRI6);
653     std::map<int, MeshFormatCell> idCellToCell;
654     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
655     {
656         std::vector<MEDCoupling::mcIdType> conn;
657         umesh2->getNodeIdsOfCell(*it,  conn) ;
658         forward_shift(conn);
659         MeshFormatCell e(INTERP_KERNEL::NORM_TRI6, (int)*it);
660         e.setConn(conn);
661         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
662     }
663
664     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_TRI6, idCellToCell) );
665 }
666
667 void MeshFormatWriter::getQUAD4( MEDCoupling::mcIdType nbQUAD4, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2)
668 {
669
670     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh2->giveCellsWithType(INTERP_KERNEL::NORM_QUAD4);
671     std::map<int, MeshFormatCell> idCellToCell;
672     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
673     {
674         std::vector<MEDCoupling::mcIdType> conn;
675         umesh2->getNodeIdsOfCell(*it,  conn) ;
676         forward_shift(conn);
677         MeshFormatCell e(INTERP_KERNEL::NORM_QUAD4, (int)*it);
678         e.setConn(conn);
679         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
680     }
681     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_QUAD4, idCellToCell) );
682 }
683
684 void MeshFormatWriter::getQUAD8(MEDCoupling::mcIdType nbQUAD8, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2)
685 {
686
687     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh2->giveCellsWithType(INTERP_KERNEL::NORM_QUAD8);
688     std::map<int, MeshFormatCell> idCellToCell;
689     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
690     {
691         std::vector<MEDCoupling::mcIdType> conn;
692         umesh2->getNodeIdsOfCell(*it,  conn) ;
693         forward_shift(conn);
694         MeshFormatCell e(INTERP_KERNEL::NORM_QUAD8, (int)*it);
695         e.setConn(conn);
696         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
697     }
698     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_QUAD8, idCellToCell) );
699 }
700
701 void MeshFormatWriter::getQUAD9(MEDCoupling::mcIdType nbQUAD9, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh2)
702 {
703
704     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh2->giveCellsWithType(INTERP_KERNEL::NORM_QUAD9);
705     std::map<int, MeshFormatCell> idCellToCell;
706     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
707     {
708         std::vector<MEDCoupling::mcIdType> conn;
709         umesh2->getNodeIdsOfCell(*it,  conn) ;
710         forward_shift(conn);
711         MeshFormatCell e(INTERP_KERNEL::NORM_QUAD9, (int)*it);
712         e.setConn(conn);
713         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
714     }
715
716     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_QUAD9, idCellToCell) );
717 }
718
719 void MeshFormatWriter::getTETRA4(MEDCoupling::mcIdType nbTETRA4, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
720 {
721
722     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_TETRA4);
723     std::map<int, MeshFormatCell> idCellToCell;
724     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
725     {
726         std::vector<MEDCoupling::mcIdType> conn;
727         umesh3->getNodeIdsOfCell(*it,  conn) ;
728         forward_shift(conn);
729         MeshFormatCell e(INTERP_KERNEL::NORM_TETRA4, (int)*it);
730         e.setConn(conn);
731         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
732     }
733
734     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_TETRA4, idCellToCell) );
735 }
736
737 void MeshFormatWriter::getTETRA10(MEDCoupling::mcIdType nbTETRA10, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
738 {
739
740     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_TETRA10);
741     std::map<int, MeshFormatCell> idCellToCell;
742     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
743     {
744         std::vector<MEDCoupling::mcIdType> conn;
745         umesh3->getNodeIdsOfCell(*it,  conn) ;
746         forward_shift(conn);
747         MeshFormatCell e(INTERP_KERNEL::NORM_TETRA10, (int)*it);
748         e.setConn(conn);
749         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
750     }
751     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_TETRA10, idCellToCell) );
752 }
753
754 void MeshFormatWriter::getPYRA5(MEDCoupling::mcIdType nbPYRA5, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
755 {
756
757     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_PYRA5);
758     std::map<int, MeshFormatCell> idCellToCell;
759     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
760     {
761         std::vector<MEDCoupling::mcIdType> conn;
762         umesh3->getNodeIdsOfCell(*it,  conn) ;
763         forward_shift(conn);
764         MeshFormatCell e(INTERP_KERNEL::NORM_PYRA5, (int)*it);
765         e.setConn(conn);
766         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
767     }
768     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_PYRA5, idCellToCell) );
769 }
770
771 void MeshFormatWriter::getHEXA8(MEDCoupling::mcIdType nbHEXA8, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
772 {
773
774     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_HEXA8);
775     std::map<int, MeshFormatCell> idCellToCell;
776     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
777     {
778         std::vector<MEDCoupling::mcIdType> conn;
779         umesh3->getNodeIdsOfCell(*it,  conn) ;
780         forward_shift(conn);
781         MeshFormatCell e(INTERP_KERNEL::NORM_HEXA8, (int)*it);
782         e.setConn(conn);
783         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
784     }
785     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_HEXA8, idCellToCell) );
786 }
787 void MeshFormatWriter::getHEXA20(MEDCoupling::mcIdType nbHEXA20, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
788 {
789
790     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_HEXA20);
791     std::map<int, MeshFormatCell> idCellToCell;
792     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
793     {
794         std::vector<MEDCoupling::mcIdType> conn;
795         umesh3->getNodeIdsOfCell(*it,  conn) ;
796         forward_shift(conn);
797         MeshFormatCell e(INTERP_KERNEL::NORM_HEXA20, (int)*it);
798         e.setConn(conn);
799         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
800     }
801     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_HEXA20, idCellToCell) );
802 }
803 void MeshFormatWriter::getHEXA27(MEDCoupling::mcIdType nbHEXA27, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
804 {
805
806     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_HEXA27);
807     std::map<int, MeshFormatCell> idCellToCell;
808     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
809     {
810         std::vector<MEDCoupling::mcIdType> conn;
811         umesh3->getNodeIdsOfCell(*it,  conn) ;
812         forward_shift(conn);
813         MeshFormatCell e(INTERP_KERNEL::NORM_HEXA27, (int)*it);
814         e.setConn(conn);
815         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
816     }
817     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_HEXA27, idCellToCell) );
818 }
819
820 void MeshFormatWriter::getPENTA6(MEDCoupling::mcIdType nbPENTA6, MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh3)
821 {
822
823     MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> elementId = umesh3->giveCellsWithType(INTERP_KERNEL::NORM_PENTA6);
824     std::map<int, MeshFormatCell> idCellToCell;
825     for ( const mcIdType *it=elementId->begin(); it!=elementId->end(); it++ )
826     {
827         std::vector<MEDCoupling::mcIdType> conn;
828         umesh3->getNodeIdsOfCell(*it,  conn) ;
829         forward_shift(conn);
830         MeshFormatCell e(INTERP_KERNEL::NORM_PENTA6, (int)*it);
831         e.setConn(conn);
832         idCellToCell.insert(std::pair <int, MeshFormatCell> (*it, e));
833     }
834     _typeToIdCellToCell.insert(std::pair <INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >(INTERP_KERNEL::NORM_PENTA6, idCellToCell) );
835 }
836
837
838 void MeshFormatWriter::linkFamilyToNodes()
839 {
840
841     std::map<std::string,mcIdType> famInfos =  _mesh->getFamilyInfo();
842     std::map<std::string,mcIdType>::const_iterator famIt =  famInfos.begin();
843     for (; famIt != famInfos.end(); ++famIt)
844     {
845         if(!famIt->second) continue; //FAMILLE_ZERO
846         MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> nodeIds =  _mesh->getNodeFamilyArr(famIt->first);
847         const MEDCoupling::mcIdType * nodeIdsIt = nodeIds->begin(), * famIDEnd = nodeIds->end();
848         for(; nodeIdsIt< famIDEnd; ++nodeIdsIt) {
849
850             std::map <int, MeshFormatNode>::iterator itNode = _idNodeToNode.find((int)*nodeIdsIt);
851             if (itNode == _idNodeToNode.end()) continue;
852             else itNode->second._famId =(int) famIt->second;
853
854
855         }
856     }
857 }
858
859
860
861 void MeshFormatWriter::linkFamilyToCells()
862 {
863
864     std::vector<int> levs =  _mesh->getNonEmptyLevels();
865     for (size_t iDim = 0; iDim < levs.size(); iDim++ )
866     {
867         int meshDimRelToMax = levs[iDim];
868         MEDCoupling::MCAuto< MEDCoupling::MEDCouplingMesh > mesh = _mesh->getMeshAtLevel( meshDimRelToMax);
869         MEDCoupling::MCAuto< MEDCoupling::MEDCouplingUMesh > umesh0 = mesh->buildUnstructured();
870         const MEDCoupling::DataArrayIdType * famIds = _mesh->getFamilyFieldAtLevel(meshDimRelToMax);
871         const MEDCoupling::mcIdType * famID = famIds->begin(), *famIDEnd = famIds->end();
872         for (; famID < famIDEnd; ++famID)
873         {
874             if (!(*famID)) continue; // "FAMILLE_ZERO"
875             std::string famName = _mesh->getFamilyNameGivenId(*famID);
876             MEDCoupling::MCAuto<MEDCoupling::DataArrayIdType> cellIds =  _mesh->getFamilyArr( meshDimRelToMax, famName);
877             const MEDCoupling::mcIdType * cellIdsIt = cellIds->begin(), *cellIDEnd = cellIds->end();
878             for(; cellIdsIt< cellIDEnd; ++cellIdsIt)
879             {
880                 INTERP_KERNEL::NormalizedCellType type = umesh0->getTypeOfCell(*cellIdsIt); //TODO
881                 std::map<INTERP_KERNEL::NormalizedCellType, std::map <int, MeshFormatCell> >::iterator itCellMap = _typeToIdCellToCell.find(type);
882                 if (itCellMap == _typeToIdCellToCell.end()) continue;
883                 else
884                 {
885                     std::map <int, MeshFormatCell>::iterator itCell = itCellMap->second.find((int)*cellIdsIt);
886                     if (itCell == itCellMap->second.end()) continue;
887                     else itCell->second._famId = (int)*famID;
888                 }
889
890             }
891
892
893
894         }
895     }
896 }
897 void MeshFormatWriter::writeCells()
898 {
899
900     std::map < INTERP_KERNEL::NormalizedCellType, std::map<int, MeshFormatCell> >::iterator typeCellMapIt = _typeToIdCellToCell.begin();
901     for (; typeCellMapIt!= _typeToIdCellToCell.end(); ++typeCellMapIt)
902     {
903         std::map<int, MeshFormatCell>::iterator cellMapIt = typeCellMapIt->second.begin();
904         switch (typeCellMapIt->first)
905         {
906         case INTERP_KERNEL::NORM_SEG2 :
907         {
908
909             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfEdges, (int)typeCellMapIt->second.size());
910
911             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
912             {
913                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
914                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfEdges, conn[0], conn[1], std::abs(cellMapIt->second._famId) );
915             }
916             break;
917         }
918         case INTERP_KERNEL::NORM_SEG3 :
919         {
920
921             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfEdges, (int)typeCellMapIt->second.size());
922             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
923             {
924                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
925                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfEdges, conn[0], conn[1], std::abs(cellMapIt->second._famId) );
926             }
927             cellMapIt = typeCellMapIt->second.begin();
928
929             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtEdges, (int)typeCellMapIt->second.size());
930
931             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
932             {
933                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
934                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtEdges, cellMapIt->first+1, 1, conn[2] );
935             }
936             break;
937         }
938         case INTERP_KERNEL::NORM_TRI3 :
939         {
940
941             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfTriangles, (int)typeCellMapIt->second.size());
942
943             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
944             {
945                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
946                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfTriangles, conn[0], conn[1], conn[2], std::abs(cellMapIt->second._famId) );
947             }
948             break;
949         }
950         case INTERP_KERNEL::NORM_TRI6 :
951         {
952
953             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfTriangles, (int)typeCellMapIt->second.size());
954             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
955             {
956                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
957                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfTriangles, conn[0], conn[1], conn[2], std::abs(cellMapIt->second._famId) );
958             }
959
960             cellMapIt = typeCellMapIt->second.begin();
961             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtTriangles, (int)typeCellMapIt->second.size());
962
963             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
964             {
965                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
966                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtTriangles, cellMapIt->first+1, 3, conn[3], conn[4], conn[5] );
967             }
968             break;
969         }
970         case INTERP_KERNEL::NORM_QUAD4 :
971         {
972
973             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, (int)typeCellMapIt->second.size());
974
975             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
976             {
977                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
978                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, conn[0], conn[1], conn[2], conn[3], std::abs(cellMapIt->second._famId) );
979             }
980             break;
981         }
982         case INTERP_KERNEL::NORM_QUAD8 :
983         {
984
985             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, (int)typeCellMapIt->second.size());
986             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
987             {
988                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
989                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, conn[0], conn[1], conn[2], conn[3], std::abs(cellMapIt->second._famId) );
990             }
991             cellMapIt = typeCellMapIt->second.begin();
992             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtQuadrilaterals, (int)typeCellMapIt->second.size());
993
994             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
995             {
996                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
997                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtQuadrilaterals, cellMapIt->first+1, 4, conn[4], conn[5],
998                                   conn[6], conn[7] );
999             }
1000             break;
1001         }
1002         case INTERP_KERNEL::NORM_QUAD9 :
1003         {
1004
1005             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, (int)typeCellMapIt->second.size());
1006             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
1007             {
1008                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
1009                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfQuadrilaterals, conn[0], conn[1], conn[2], conn[3], std::abs(cellMapIt->second._famId) );
1010             }
1011             cellMapIt = typeCellMapIt->second.begin();
1012             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtQuadrilaterals, (int)typeCellMapIt->second.size());
1013
1014             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
1015             {
1016                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
1017                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtQuadrilaterals,cellMapIt->first+1, 5, conn[4], conn[5],
1018                                   conn[6], conn[7], conn[8] );
1019             }
1020             break;
1021         }
1022         case INTERP_KERNEL::NORM_TETRA4 :
1023         {
1024
1025             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfTetrahedra, (int)typeCellMapIt->second.size());
1026
1027             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
1028             {
1029                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
1030                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfTetrahedra, conn[0], conn[2], conn[1], conn[3],  std::abs(cellMapIt->second._famId) );
1031             }
1032             break;
1033         }
1034         case INTERP_KERNEL::NORM_TETRA10 :
1035         {
1036
1037             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtTetrahedra, (int)typeCellMapIt->second.size());
1038             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
1039             {
1040                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
1041                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfTetrahedra, conn[0], conn[2], conn[1], conn[3], std::abs(cellMapIt->second._famId) );
1042             }
1043             cellMapIt = typeCellMapIt->second.begin();
1044             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfTetrahedra, (int)typeCellMapIt->second.size());
1045
1046             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
1047             {
1048                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
1049                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtTetrahedra, cellMapIt->first+1, 6, conn[6], conn[5],
1050                                   conn[4], conn[7], conn[8], conn[9] );
1051             }
1052             break;
1053         }
1054         case INTERP_KERNEL::NORM_PYRA5 :
1055         {
1056
1057             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfPyramids, (int)typeCellMapIt->second.size());
1058
1059             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
1060             {
1061                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
1062                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfPyramids, conn[3], conn[2], conn[1], conn[0], conn[4], std::abs(cellMapIt->second._famId) );
1063
1064             }
1065             break;
1066         }
1067         case INTERP_KERNEL::NORM_HEXA8 :
1068         {
1069
1070             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfHexahedra, (int)typeCellMapIt->second.size());
1071
1072             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
1073             {
1074                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
1075                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfHexahedra, conn[0], conn[3], conn[2], conn[1], conn[4], conn[7], conn[6], conn[5], std::abs(cellMapIt->second._famId) );
1076
1077             }
1078             break;
1079         }
1080         case INTERP_KERNEL::NORM_HEXA20 :
1081         {
1082
1083             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfHexahedra, (int)typeCellMapIt->second.size());
1084             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
1085             {
1086                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
1087                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfHexahedra, conn[0], conn[3], conn[2], conn[1],
1088                                   conn[4], conn[7], conn[6], conn[5], std::abs(cellMapIt->second._famId) );
1089             }
1090             cellMapIt = typeCellMapIt->second.begin();
1091             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra, (int)typeCellMapIt->second.size());
1092
1093             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
1094             {
1095                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
1096                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra,  cellMapIt->first+1, 12, conn[11], conn[10], conn[9],
1097                                   conn[8], conn[15], conn[14], conn[13], conn[12], conn[16], conn[19], conn[18], conn[17] );
1098             }
1099             break;
1100         }
1101         case INTERP_KERNEL::NORM_HEXA27 :
1102         {
1103
1104             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfHexahedra, (int)typeCellMapIt->second.size());
1105             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
1106             {
1107                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
1108                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra, conn[0], conn[3], conn[2], conn[1],
1109                                   conn[4], conn[7], conn[6], conn[5], std::abs(cellMapIt->second._famId) );
1110             }
1111             cellMapIt = typeCellMapIt->second.begin();
1112             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra, (int)typeCellMapIt->second.size());
1113
1114             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
1115             {
1116                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
1117                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfExtraVerticesAtHexahedra, cellMapIt->first+1, 19, conn[11], conn[10], conn[9],
1118                                   conn[8], conn[15], conn[14], conn[13], conn[12], conn[16], conn[19], conn[18], conn[17],
1119                                   conn[20], conn[24], conn[23], conn[22], conn[21], conn[25], conn[26], std::abs(cellMapIt->second._famId) );
1120             }
1121             break;
1122         }
1123         case INTERP_KERNEL::NORM_PENTA6 :
1124         {
1125
1126             _writer.GmfSetKwd(_myCurrentFileId, MeshFormat::GmfPrisms, (int)typeCellMapIt->second.size());
1127
1128             for (; cellMapIt != typeCellMapIt->second.end(); ++cellMapIt)
1129             {
1130                 std::vector<MEDCoupling::mcIdType> conn = cellMapIt->second.conn;
1131                 _writer.GmfSetLin(_myCurrentFileId, MeshFormat::GmfPrisms, conn[0], conn[2], conn[1], conn[3], conn[5], conn[4], std::abs(cellMapIt->second._famId) );
1132             }
1133             break;
1134         }
1135         }
1136     }
1137 }
1138 }