1 #include "WriteCGNS.hpp"
2 #include "moab/CN.hpp"
3 #include "MBTagConventions.hpp"
4 #include "MBParallelConventions.h"
5 #include "moab/Interface.hpp"
6 #include "moab/Range.hpp"
7 #include "moab/WriteUtilIface.hpp"
8 #include "moab/FileOptions.hpp"
9 #include "GmshUtil.hpp"
10 
11 #include <fstream>
12 #include <map>
13 #include <set>
14 
15 #include <iostream>
16 
17 namespace moab {
18 
factory(Interface * iface)19 WriterIface *WriteCGNS::factory( Interface* iface )
20   { return new WriteCGNS( iface ); }
21 
WriteCGNS(Interface * impl)22 WriteCGNS::WriteCGNS(Interface *impl)
23     : mbImpl(impl), fileName(NULL), IndexFile(0), BaseName(NULL), IndexBase(0),
24       ZoneName(NULL), IndexZone(0), IndexSection(0), celldim(0), physdim(0),
25       VrtSize(0), EdgeSize(0), FaceSize(0), CellSize(0)
26 {
27   impl->query_interface(mWriteIface);
28   IndexCoord[0] = IndexCoord[1] = IndexCoord[2] = 0;
29   isize[0] = isize[1] = isize[2] = 0;
30 }
31 
~WriteCGNS()32 WriteCGNS::~WriteCGNS()
33 {
34   mbImpl->release_interface(mWriteIface);
35 }
36 
37 //! writes out a file
write_file(const char * file_name,const bool overwrite,const FileOptions &,const EntityHandle *,const int,const std::vector<std::string> &,const Tag *,int,int)38 ErrorCode WriteCGNS::write_file(const char *file_name,
39                                   const bool overwrite,
40                                   const FileOptions& /*options*/,
41                                   const EntityHandle */*output_list*/,
42                                   const int /*num_sets*/,
43                                   const std::vector<std::string>&,
44                                   const Tag*,
45                                   int,
46                                   int )
47 {
48   ErrorCode rval;
49 
50   if (!overwrite){
51     rval = mWriteIface->check_doesnt_exist( file_name );
52     if (MB_SUCCESS != rval)
53       return rval;
54   }
55   std::cout << "THE CGNS CONVERSION ONLY WORKS FOR ENTITIES CITED BELOW:";
56   std::cout << "\n   -MBVERTEX\n   -MBEDGE\n   -MBTRI\n   -MBQUAD";
57   std::cout << "\n   -MBTET\n   -MBPYRAMID\n   -MBHEX\n";
58 
59   // Get entities to write
60   // Get and count vertex entities
61   rval = get_vertex_entities ( VrtSize, Nodes );
62   if (rval != MB_SUCCESS){
63     return rval;
64   }
65   // Get and count edge entities
66   rval = get_edge_entities( EdgeSize, Edges );
67   if (rval != MB_SUCCESS){
68     return rval;
69   }
70   // Get and count face entities
71   rval = get_face_entities( FaceSize, Faces );
72   if (rval != MB_SUCCESS){
73     return rval;
74   }
75   // Get and count cell entities
76   rval = get_cell_entities( CellSize, Cells );
77   if (rval != MB_SUCCESS){
78     return rval;
79   }
80   std::cout << "\nThe Number of Vertex is " << VrtSize << ".\n";
81   std::cout << "The Number of Edges is " << EdgeSize << ".\n";
82   std::cout << "The Number of Faces is " << FaceSize << ".\n";
83   std::cout << "The Number of Cells is " << CellSize << ".\n\n";
84 
85   // save filename to member variable so we don't need to pass as an argument
86   // to called functions
87   fileName = file_name;
88   std::cout << fileName << " file is a " << physdim << "-D mesh.\n";
89 
90   // Open file
91   IndexFile = 0;
92 
93   // open the cgns file
94   // filename:      (input) Name of the CGNS file, including path name if necessary. There is no limit on the
95   //                length of this character variable.
96   // CG_MODE_WRITE: (input) Mode used for opening the file. The modes currently supported are CG_MODE_READ,
97   //                CG_MODE_WRITE, and CG_MODE_MODIFY.
98   // filePtr:       (output) CGNS file index number.
99   if ( cg_open(fileName, CG_MODE_WRITE, &IndexFile) ){
100     std::cout << "Error opening file\n";
101     cg_error_exit();
102   }
103   // Give a base name
104   BaseName = "Cgns Base";
105   if ( cg_base_write(IndexFile,BaseName,celldim,physdim,&IndexBase) ){
106     std::cout << "Error creating CGNS base";
107   }
108   // Give a zone name
109   ZoneName = "Cgns Zone";
110   // isize array contains the total vertex size, cell size, and boundary
111   // vertex size for the zone
112   // Note that for unstructured zones, the index dimension is always 1
113   isize[0] = VrtSize;      // isize[0] contains the total vertex size
114   isize[1] = CellSize;     // isize[1] contains the total cell size
115   isize[2] = 0;            // isize[2] = 0 for unsorted elements
116   // Create zone */
117   // ZoneType_t: Unstructured
118   if ( cg_zone_write(IndexFile,IndexBase,ZoneName,isize,Unstructured,&IndexZone) ){
119     std::cout << "Error creating CGNS zone\n";
120     cg_error_exit();
121   }
122   // Write the vertex coordinates
123   rval = write_coord_cgns( Nodes );
124   if (rval != MB_SUCCESS){
125      return rval;
126    }
127 
128   // Create a vector to hold the Tags
129   std::vector<moab::Tag> TagHandles;
130   // Get Tags
131   rval = mbImpl->tag_get_tags( TagHandles );
132   if (rval != MB_SUCCESS){
133      return rval;
134   }
135   // Get the number of Tags in the mesh
136   int NbTags = TagHandles.size();
137   std:: cout << "\nThe mesh has " << NbTags << " Tags.\n";
138 
139   // Create a vector of size NbTags
140   // Sets have informations about the entity set
141   std::vector<SetStruct> Sets;
142   Sets.reserve(NbTags);
143   // Fill Sets with all information needed
144   rval = set_tag_values( TagHandles, Edges, Faces, Cells, Sets );
145   if (rval != MB_SUCCESS){
146     std::cout << "Problem to set tag values\n";
147     return rval;
148   }
149 
150   // Create a matrix to hold connectivity
151   std::vector < std::vector<cgsize_t> > ConnTable;
152   ConnTable.resize(NbTags);
153 
154   std::vector< int > Begin ( NbTags , 0 );
155   std::vector< int > End ( NbTags , 0 );
156 
157   // Take the connectivity of higher dimension entities
158   cgsize_t BeginSetsIndex = 1;
159   cgsize_t EndSetsIndex;
160   switch ( physdim ){
161     case 1:
162       rval = get_conn_table( Edges, Begin, End, TagHandles, Sets, ConnTable );
163       if (rval != MB_SUCCESS){
164         std::cout << "Problem to fill the connectivity table for 1-D entities\n";
165         return rval;
166       }
167       for (int i = 0; i < NbTags; ++i) {
168         if ( Sets[i].IdSet != -1 ){
169           const char * SectionName = Sets[i].TagName.c_str();
170           EndSetsIndex = BeginSetsIndex + Sets[i].NbEdges - 1;
171           // Write the section in CGNS file
172           if ( cg_section_write( IndexFile, IndexBase, IndexBase, SectionName, Sets[i].CGNSType,
173                                  BeginSetsIndex, EndSetsIndex, 0, &ConnTable[i][0],&IndexSection) ){
174             std::cout << "Issue on writing connectivity - 3-D\n";
175             cg_error_exit();
176           }
177           BeginSetsIndex = EndSetsIndex+1;
178         }
179       }
180       break;
181     case 2:
182       rval = get_conn_table( Edges, Begin, End, TagHandles, Sets, ConnTable );
183       if (rval != MB_SUCCESS){
184         std::cout << "Problem to fill the connectivity table for 1-D entities\n";
185         return rval;
186       }
187       rval = get_conn_table( Faces, Begin, End, TagHandles, Sets, ConnTable );
188       if (rval != MB_SUCCESS){
189         std::cout << "Problem to fill the connectivity table for 2-D entities\n";
190         return rval;
191       }
192       for (int i = 0; i < NbTags; ++i) {
193         if ( Sets[i].IdSet != -1 ){
194             const char * SectionName = Sets[i].TagName.c_str();
195             EndSetsIndex = BeginSetsIndex + Sets[i].NbEdges + Sets[i].NbFaces - 1;
196             // Write the section in CGNS file
197             if ( cg_section_write( IndexFile, IndexBase, IndexBase, SectionName, Sets[i].CGNSType,
198                                    BeginSetsIndex, EndSetsIndex, 0, &ConnTable[i][0],&IndexSection) ){
199             std::cout << "Issue on writing connectivity -- 2-D\n";
200             cg_error_exit();
201           }
202             BeginSetsIndex = EndSetsIndex+1;
203         }
204       }
205       break;
206     case 3:
207       rval = get_conn_table( Faces, Begin, End, TagHandles, Sets, ConnTable );
208       if (rval != MB_SUCCESS){
209         std::cout << "Problem to fill the connectivity table for 2-D entities\n";
210         return rval;
211       }
212       rval = get_conn_table( Cells, Begin, End, TagHandles, Sets, ConnTable );
213       if (rval != MB_SUCCESS){
214         std::cout << "Problem to fill the connectivity table for 3-D entities\n";
215         return rval;
216       }
217       for (int i = 0; i < NbTags; ++i) {
218         if ( Sets[i].IdSet != -1 ){
219           const char * SectionName = Sets[i].TagName.c_str();
220           EndSetsIndex = BeginSetsIndex + Sets[i].NbFaces + Sets[i].NbCells - 1;
221           std::cout << "BeginSetsIndex = " << BeginSetsIndex << "\tEndSetsIndex = " << EndSetsIndex << "\n";
222           // Write the section in CGNS file
223           if ( cg_section_write( IndexFile, IndexBase, IndexBase, SectionName, Sets[i].CGNSType,
224                                  BeginSetsIndex, EndSetsIndex, 0, &ConnTable[i][0],&IndexSection) ){
225             std::cout << "Issue on writing connectivity -- 3-D\n";
226             cg_error_exit();
227           }
228           BeginSetsIndex = EndSetsIndex+1;
229         }
230       }
231       break;
232     default:
233       std::cout << "Issue on Physical dimension\n";
234       return MB_FAILURE;
235   }
236 
237   // Close the CGNS mesh file
238   if ( cg_close(IndexFile) ){
239     std::cout << "Error closing file\n";
240     cg_error_exit();
241   }
242   // done
243   return MB_SUCCESS;
244 }
245 
246 // Get and count vertex entities
get_vertex_entities(cgsize_t & VrtSize_,std::vector<moab::EntityHandle> & Nodes_)247 ErrorCode WriteCGNS::get_vertex_entities ( cgsize_t &VrtSize_, std::vector< moab::EntityHandle > &Nodes_)
248 {
249    ErrorCode rval;
250    // Get vertex entities
251    // The first input is 0 because one queries the entire mesh.
252    // Retrieves all entities of dimension = 0 in "Nodes"
253    rval = mbImpl->get_entities_by_dimension( 0, 0, Nodes_, false );
254    if ( Nodes.size() > 0 ){
255      celldim=0;
256      physdim=0;
257      // get the amout of vertex
258      VrtSize_ =  Nodes_.size();
259    }
260    else { std::cout << "The mesh has not node points.\n"; }
261    // done
262    return rval;
263 }
264 
265 // Get and count edge entities
get_edge_entities(cgsize_t & EdgeSize_,std::vector<moab::EntityHandle> & Edges_)266 ErrorCode WriteCGNS::get_edge_entities(cgsize_t &EdgeSize_, std::vector< moab::EntityHandle > &Edges_)
267 {
268   ErrorCode rval;
269   // The first input is 0 because one queries the entire mesh.
270   // Get all entities of dimension = 1 in Edges
271   rval = mbImpl->get_entities_by_dimension( 0, 1, Edges_, false );
272   if ( Edges_.size() > 0 ){
273     celldim=1;
274     physdim=1;
275     // get the amout of edges
276     EdgeSize_ = Edges_.size();
277   }
278   // done
279   return rval;
280 }
281 
282 // Get and count face entities
get_face_entities(cgsize_t & FaceSize_,std::vector<moab::EntityHandle> & Faces_)283 ErrorCode WriteCGNS::get_face_entities(cgsize_t &FaceSize_, std::vector< moab::EntityHandle > &Faces_)
284 {
285   ErrorCode rval;
286   // The first input is 0 because one queries the entire mesh.
287   // Get all entities of dimension = 2 in Faces
288   rval = mbImpl->get_entities_by_dimension( 0, 2, Faces_, false );
289   if ( Faces_.size() ){
290     celldim=2;
291     physdim=2;
292     // get the amout of faces
293     FaceSize_ = Faces_.size();
294   }
295   // done
296   return rval;
297 }
298 
299 // Get and count cell entities
get_cell_entities(cgsize_t & CellSize_,std::vector<moab::EntityHandle> & Cells_)300 ErrorCode WriteCGNS::get_cell_entities(cgsize_t &CellSize_, std::vector< moab::EntityHandle > &Cells_)
301 {
302   ErrorCode rval;
303   // The first input is 0 because one queries the entire mesh.
304   // Get all entities of dimension = 3 in Cell
305   rval = mbImpl->get_entities_by_dimension( 0, 3, Cells_, false );
306   if ( Cells_.size() ){
307     celldim=3;
308     physdim=3;
309     // get the amout of volumes
310     CellSize_ = Cells_.size();
311   }
312   // done
313   return rval;
314 }
315 
write_coord_cgns(std::vector<moab::EntityHandle> & Nodes_)316 ErrorCode WriteCGNS::write_coord_cgns(std::vector< moab::EntityHandle > &Nodes_)
317 {
318   ErrorCode rval;
319 
320   const int num_entities = (int)Nodes_.size();
321 
322   // Moab works with one vector for the threee coordinates
323   std::vector<double> Coords ( 3*num_entities );
324   std::vector<double>::iterator c = Coords.begin();
325 
326   // CGNS uses one vector for each coordinate
327   std::vector<double> CoordX;
328   std::vector<double> CoordY;
329   std::vector<double> CoordZ;
330 
331   // Summ the values of all coordinates to be sure if it is not zero
332   double SumX=0;
333   double SumY=0;
334   double SumZ=0;
335 
336   // Get the moab coordinates - Coords is the output
337   rval = mbImpl->get_coords( &Nodes_[0], num_entities, &Coords[0] );
338   if (MB_SUCCESS != rval){
339     std::cout << "Error getting coordinates from nodes.\n";
340     return rval;
341   }
342 
343   // Reserve the size of nodes
344   CoordX.reserve( Nodes_.size() );
345   CoordY.reserve( Nodes_.size() );
346   CoordZ.reserve( Nodes_.size() );
347 
348   for (std::vector<moab::EntityHandle>::iterator i=Nodes_.begin(); i != Nodes_.end(); ++i){
349     CoordX.push_back(*c);  // Put the X coordinate in CoordX vector
350     SumX += abs(*c);       // Sum all X coordinates
351     ++c;                   // Move to Y coordinate
352     CoordY.push_back(*c);  // Put the Y coordinate in CoordY vector
353     SumY += abs(*c);       // Sum all Y coordinates
354     ++c;                   // Move to Z coordinate
355     CoordZ.push_back(*c);  // Put the Z coordinate in CoordZ vector
356     SumZ += abs(*c);       // Sum all Z coordinates
357     ++c;                   // Move to X coordinate
358   }
359 
360   // If X coordinate is not empty then write CoordX (user must use SIDS-standard names here)
361   if ( SumX != 0 ){
362     if ( cg_coord_write(IndexFile,IndexBase,IndexZone,RealDouble,"CoordinateX",&CoordX[0],&IndexCoord[0]) ){
363         std::cout << " Error writing X coordinates.\n";
364         cg_error_exit();
365     }
366   }
367   // If Y coordinate is not empty then write CoordY (user must use SIDS-standard names here)
368   if ( SumY != 0 ){
369     if ( cg_coord_write(IndexFile,IndexBase,IndexZone,RealDouble,"CoordinateY",&CoordY[0],&IndexCoord[1]) ){
370         std::cout << " Error writing Y coordinates.\n";
371         cg_error_exit();
372     }
373   }
374   // If Z coordinate is not empty then write CoordZ (user must use SIDS-standard names here)
375   if ( SumZ != 0 ){
376     if ( cg_coord_write(IndexFile,IndexBase,IndexZone,RealDouble,"CoordinateZ",&CoordZ[0],&IndexCoord[2]) ){
377         std::cout << " Error writing Z coordinates.\n";
378         cg_error_exit();
379     }
380   }
381 
382   // Clear vectors
383   Coords.clear();
384   CoordX.clear();
385   CoordY.clear();
386   CoordZ.clear();
387 
388   // done
389   return MB_SUCCESS;
390 }
391 
set_tag_values(std::vector<Tag> & TagHandles,std::vector<moab::EntityHandle> & Edges_,std::vector<moab::EntityHandle> & Faces_,std::vector<moab::EntityHandle> & Cells_,std::vector<WriteCGNS::SetStruct> & Sets)392 ErrorCode WriteCGNS::set_tag_values( std::vector< Tag >& TagHandles,
393 				     std::vector< moab::EntityHandle > &Edges_,
394 				     std::vector< moab::EntityHandle > &Faces_,
395 				     std::vector< moab::EntityHandle > &Cells_,
396 				     std::vector< WriteCGNS::SetStruct >& Sets )
397 {
398   ErrorCode rval;
399 
400   // Get the number of Tags in the mesh
401   int NbTags = TagHandles.size();
402 
403   // Loop over all Tags
404   for (int i = 0; i < NbTags; ++i) {
405 
406     // Allocate another position in the vector of SetStruct using a default constructor
407     Sets.push_back( SetStruct() );
408 
409     // Get the Tag name
410     rval = mbImpl->tag_get_name( TagHandles[i], Sets[i].TagName );
411     if (rval != MB_SUCCESS){
412       std::cout << "Problem to get Tag Name\n";
413       return rval;
414     }
415     std::cout << "Tag name= " << Sets[i].TagName << "\n";
416 
417     // Count all entities by type and put in Sets[i].NbEntities vector
418     rval = get_set_entities( i, TagHandles, Sets);
419     if (rval != MB_SUCCESS ){
420      std::cout << "Problem to get Set entities\n";
421      return rval;
422     }
423 
424     // Get the CGNSTYpe of the Set
425     rval = get_cgns_type ( i, Sets );
426     if (rval != MB_SUCCESS ){
427      std::cout << "Problem to get CGNSType\n";
428      return rval;
429     }
430     std::cout << "\tSets[" << i << "].CGNSType= " << Sets[i].CGNSType << "\n";
431 
432     //int Number;
433 
434     // Set a data index for Edges and TagHandles[i]
435     if ( Sets[i].CGNSType == BAR_2 || Sets[i].CGNSType == TRI_3 || Sets[i].CGNSType == QUAD_4 ||
436          Sets[i].CGNSType == TETRA_4 || Sets[i].CGNSType == PYRA_5 || Sets[i].CGNSType == PENTA_6 ||
437          Sets[i].CGNSType == HEXA_8 || Sets[i].CGNSType == MIXED ){
438 
439       if ( Sets[i].NbEdges > 0 && physdim < 3 ){
440         // Set a data index for Edges and TagHandles[i]
441         const std::vector< int > tag_values ( Edges_.size(), i );
442         rval = mbImpl-> tag_set_data ( TagHandles[i], &Edges_[0], Edges_.size(), &tag_values[0] );
443         if (rval != MB_SUCCESS ){
444           std::cout << "Problem to set data for 1-D entities\n";
445           return rval;
446         }
447       }
448       if ( Sets[i].NbFaces > 0 && physdim > 1 ){
449         // Set a data index for Faces and TagHandles[i]
450         const std::vector< int > tag_values ( Faces.size(), i );
451         rval = mbImpl-> tag_set_data ( TagHandles[i], &Faces_[0], Faces_.size(), &tag_values[0] );
452         if (rval != MB_SUCCESS ){
453          std::cout << "Problem to set data for 2-D entities\n";
454          return rval;
455         }
456       }
457       if ( Sets[i].NbCells > 0 && physdim > 2 ){
458         // Set a data index for Cells and TagHandles[i]
459         const std::vector< int > tag_values ( Cells.size(), i );
460         rval = mbImpl-> tag_set_data ( TagHandles[i], &Cells_[0], Cells_.size(), &tag_values[0] );
461         if (rval != MB_SUCCESS ){
462          std::cout << "Problem to set data for 3-D entities\n";
463          return rval;
464         }
465       }
466       // IdSet gets the Set Index indicating that it is not empty
467       Sets[i].IdSet = i;
468     }
469     std::cout << "\tSets[" << i << "].IdSet = " << Sets[i].IdSet << "\n\n";
470   }
471   return MB_SUCCESS;
472 }
473 
474 // Get Entities in the set
get_set_entities(int i,std::vector<Tag> & TagHandles,std::vector<WriteCGNS::SetStruct> & Sets)475 ErrorCode WriteCGNS::get_set_entities(int i, std::vector< Tag >& TagHandles,
476 				      std::vector< WriteCGNS::SetStruct >& Sets)
477 {
478   ErrorCode rval;
479 
480   // Get the number of MBEDGE entities
481   // NbEntities[0] holds the number of MBEDGE in the "Sets"
482   int Number=0;
483   rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBEDGE, &TagHandles[i], 0, 1, Number );
484   if (rval != MB_SUCCESS ){
485     std::cout << "Problem to get the number of entities by type and tag\n";
486     return rval;
487   }
488   Sets[i].NbEntities.push_back(Number);  // MBEDGE == Sets[i].NbEntities[0]
489   Sets[i].NbEdges += Number;
490   std::cout << "\tNumber of MBEDGE = " << Number << "\n";
491 
492   // Get the number of MBTRI entities
493   // NbEntities[1] holds the number of MBTRI in the "Sets"
494   Number=0;
495   rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBTRI, &TagHandles[i], 0, 1, Number );
496   if (rval != MB_SUCCESS ){
497     std::cout << "Problem to get the number of entities by type and tag\n";
498     return rval;
499   }
500   Sets[i].NbEntities.push_back(Number);  // MBTRI == Sets[i].NbEntities[1]
501   Sets[i].NbFaces += Number;
502   std::cout << "\tNumber of MBTRI = " << Number << "\n";
503 
504   // Get the number of MBQUAD entities
505   // NbEntities[2] holds the number of MBQUAD in the "Sets"
506   Number=0;
507   rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBQUAD, &TagHandles[i], 0, 1, Number );
508   if (rval != MB_SUCCESS ){
509     std::cout << "Problem to get the number of entities by type and tag\n";
510     return rval;
511   }
512   Sets[i].NbEntities.push_back(Number);  // MBQUAD == Sets[i].NbEntities[2]
513   Sets[i].NbFaces += Number;
514   std::cout << "\tNumber of MBQUAD = " << Number << "\n";
515 
516   // Get the number of MBTET entities
517   // NbEntities[3] holds the number of MBTET in the "Sets"
518   Number=0;
519   rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBTET, &TagHandles[i], 0, 1, Number );
520   if (rval != MB_SUCCESS ){
521     std::cout << "Problem to get the number of entities by type and tag\n";
522     return rval;
523   }
524   Sets[i].NbEntities.push_back(Number);  // MBTET == Sets[i].NbEntities[3]
525   Sets[i].NbCells += Number;
526   std::cout << "\tNumber of MBTET = " << Number << "\n";
527 
528   // Get the number of MBPYRAMID entities
529   // NbEntities[4] holds the number of MBPYRAMID in the "Sets"
530   Number=0;
531   rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBPYRAMID, &TagHandles[i], 0, 1, Number );
532   if (rval != MB_SUCCESS ){
533     std::cout << "Problem to get the number of entities by type and tag\n";
534     return rval;
535   }
536   Sets[i].NbEntities.push_back(Number);  // MBPYRAMID == Sets[i].NbEntities[4]
537   Sets[i].NbCells += Number;
538   std::cout << "\tNumber of MBPYRAMID = " << Number << "\n";
539 
540   // Get the number of MBPRISM entities - MBPRISM == PENTA_6
541   // NbEntities[5] holds the number of MBPRISM in the "Sets"
542   Number=0;
543   rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBPRISM, &TagHandles[i], 0, 1, Number );
544   if (rval != MB_SUCCESS ){
545     std::cout << "Problem to get the number of entities by type and tag\n";
546     return rval;
547   }
548   Sets[i].NbEntities.push_back(Number);  // MBPRISM == Sets[i].NbEntities[5]
549   Sets[i].NbCells += Number;
550   std::cout << "\tNumber of MBPRISM = " << Number << "\n";
551 
552   // Get the number of MBHEX entities
553   // NbEntities[6] holds the number of MBHEX in the "Sets"
554   Number=0;
555   rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBHEX, &TagHandles[i], 0, 1, Number );
556   if (rval != MB_SUCCESS ){
557     std::cout << "Problem to get the number of entities by type and tag\n";
558     return rval;
559   }
560   Sets[i].NbEntities.push_back(Number);  // MBHEX == Sets[i].NbEntities[6]
561   Sets[i].NbCells += Number;
562   std::cout << "\tNumber of MBHEX = " << Number << "\n";
563 
564   std::cout << "\tTotal number of Edges = " << Sets[i].NbEdges << "\n";
565   std::cout << "\tTotal number of Faces = " << Sets[i].NbFaces << "\n";
566   std::cout << "\tTotal number of Cells = " << Sets[i].NbCells << "\n";
567 
568   return MB_SUCCESS;
569 }
570 
571 // Get CGNSType
get_cgns_type(int i,std::vector<WriteCGNS::SetStruct> & Sets)572 ErrorCode WriteCGNS::get_cgns_type ( int i, std::vector<WriteCGNS::SetStruct> &Sets )
573 {
574   std::vector<int> Test;
575   int Sum=0;
576 
577   // NbEntities is a vector which has the number of entities of each type
578   // 0-MBEDGE | 1-MBTRI | 2-MBQUAD | 3-MBTET | 4-MBPYRAMID | 5-MBPRISM | 6-MBHEX
579   // if NbEntities[i]>0 then Test[i]=1
580   // else then Test[i]=0
581   for ( int j=0; j< (int)Sets[i].NbEntities.size(); ++j){
582     if ( Sets[i].NbEntities[j] > 0 ){
583       Test.push_back(1);
584       Sum++;
585     }
586     else { Test.push_back(0); }
587   }
588 
589   // Test the Sum
590   // if Sum > 1 then the Set is MIXED
591   // if Sum = 0 then the Set is Homogeneous
592   // else then the Set is empty
593   if ( Sum>1 ){ Sets[i].CGNSType = MIXED; }
594   else if ( Sum==1 ){
595     int j=0;
596     std::cout << "Homogeneous Type\n";
597     while (j < (int)Sets[i].NbEntities.size() && Sets[i].NbEntities[j] != 1){ ++j; }
598     switch ( j ){
599       case 0 :
600         Sets[i].CGNSType = BAR_2;
601         break;
602       case 1 :
603         Sets[i].CGNSType = TRI_3;
604         break;
605       case 2 :
606         Sets[i].CGNSType = QUAD_4;
607         break;
608       case 3 :
609         Sets[i].CGNSType = TETRA_4;
610         break;
611       case 4 :
612         Sets[i].CGNSType = PYRA_5;
613         break;
614       case 5 :
615         Sets[i].CGNSType = PENTA_6;
616         break;
617       case 6 :
618         Sets[i].CGNSType = HEXA_8;
619         break;
620       default :
621         std::cout << "It was not possible to identify the CGNSType\n";
622         return MB_FAILURE;
623     }
624   }
625   else { Sets[i].CGNSType = ElementTypeNull; } // NOT SURE IF THAT'S THE RIGHT WAY.......
626 
627   // Clear the test vector
628   Test.clear();
629 
630   return MB_SUCCESS;
631 
632 }
633 
634 // Fill the connectivity table
get_conn_table(std::vector<moab::EntityHandle> & Elements,std::vector<int> & Begin,std::vector<int> & End,std::vector<moab::Tag> & TagHandles,std::vector<WriteCGNS::SetStruct> & Sets,std::vector<std::vector<cgsize_t>> & ConnTable)635 ErrorCode WriteCGNS::get_conn_table( std::vector< moab::EntityHandle > &Elements,
636 				     std::vector< int > &Begin,
637 				     std::vector< int > &End,
638 				     std::vector<moab::Tag> &TagHandles,
639 				     std::vector<WriteCGNS::SetStruct> &Sets,
640 				     std::vector < std::vector<cgsize_t> > &ConnTable )
641 {
642   ErrorCode rval;
643 
644 //   int Begin = 0; // GOT TO WORK ON THIS
645 //   int End;
646 
647   // Get the number of Tags in the mesh
648   int NbTags = TagHandles.size();
649 
650   // Test all Elements, get their ids and connectivity
651   // to fill ConnTable
652   for (std::vector<moab::EntityHandle>::iterator i=Elements.begin(); i != Elements.end(); ++i){
653     int id;
654     // Test all Tags
655     for ( int j = 0; j < NbTags; ++j ){
656       // Test if the Tag has data
657       if ( Sets[j].IdSet != -1 ){
658         // Try to get data from entity
659         rval = mbImpl->tag_get_data( TagHandles[j], &*i, 1, &id );
660         if (MB_SUCCESS != rval){
661           return rval;
662         }
663         // If successful id==j
664         if ( id == j ){
665           // Get the entity type of the EntityHandle wich points to Cells
666           int num_vtx;                 // Number of MeshVertices in array connectivity.
667           const EntityHandle* conn;    // Array in which connectivity of entity_handle is returned.
668           // Gets a pointer to constant connectivity data of entity_handle
669           rval = mbImpl->get_connectivity( *i, conn, num_vtx );
670           if (MB_SUCCESS != rval){
671             return rval;
672           }
673           // If the Set is MIXED type
674           // push CGNS ENUM type of the entity
675           // before the connectivity
676           if ( Sets[j].CGNSType == MIXED ){
677             ConnTable[j].push_back( moab_cgns_conv(*i) );   // moab_cgns_conv return an int which
678                                                             // represents the CGNS type
679             Begin[j]++;
680           }
681           End[j] = Begin[j] + num_vtx;
682           // Push conn in ConnTable in which "j" is the Set Index
683           for (int k=Begin[j]; k<End[j]; ++k){
684             ConnTable[j].push_back( (cgsize_t)conn[k-Begin[j]] );
685           }
686           Begin[j] =  End[j];
687         }
688       }
689     }
690   }
691   return MB_SUCCESS;
692 }
693 
694 // Read the Moab type and return CGNS type
moab_cgns_conv(const EntityHandle handle)695 int WriteCGNS::moab_cgns_conv(const EntityHandle handle)
696 {
697   EntityType MoabType = mbImpl->type_from_handle( handle );
698   switch ( MoabType ){
699     case MBEDGE :         /**< Mesh Edge */
700       return BAR_2;
701     case MBTRI :          /**< Triangular element (including shells) */
702       return TRI_3;
703     case MBQUAD :         /**< Quadrilateral element (including shells) */
704       return QUAD_4;
705     case MBTET :          /**< Tetrahedral element */
706       return TETRA_4;
707     case MBPYRAMID :      /**< Pyramid element */
708       return PYRA_5;
709     case MBPRISM :        /**< Wedge element */
710       return PENTA_6;
711     case MBHEX :          /**< Hexahedral element */
712       return HEXA_8;
713     default :
714       std::cout << "It was not possible to identify the CGNSType\n";
715       return 0;
716   }
717 }
718 
719 } //namespace moab
720