File: writegmsh2.cpp

package info (click to toggle)
netgen 6.2.2601%2Bdfsg1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,076 kB
  • sloc: cpp: 166,627; tcl: 6,310; python: 2,868; sh: 528; makefile: 90
file content (263 lines) | stat: -rw-r--r-- 8,786 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
/*! \file writegmsh2.cpp
*  \brief Export Netgen Mesh in the GMSH v2.xx File format
*  \author Philippose Rajan
*  \date 02 November 2008
*
*  This function extends the export capabilities of
*  Netgen to include the GMSH v2.xx File Format.
*
*  Current features of this function include:
*
*  1. Exports Triangles, Quadrangles and Tetrahedra \n
*  2. Supports upto second order elements of each type
*
*/


#include <mystdlib.h>

#include <myadt.hpp>
#include <linalg.hpp>
#include <csg.hpp>
#include <meshing.hpp>
#include "writeuser.hpp"

namespace netgen
{

  extern MeshingParameters mparam;

   // Mapping of entities from Netgen definitions to GMSH definitions
   enum GMSH_ELEMENTS {GMSH_TRIG = 2, GMSH_TRIG6 = 9,
      GMSH_QUAD = 3, GMSH_QUAD8 = 16,
      GMSH_TET = 4, GMSH_TET10 = 11};
   const int triGmsh[7] = {0,1,2,3,6,4,5};
   const int quadGmsh[9] = {0,1,2,3,4,5,8,6,7};
   const int tetGmsh[11] = {0,1,2,3,4,5,8,6,7,10,9};


   /*! GMSH v2.xx mesh format export function
   *
   *  This function extends the export capabilities of
   *  Netgen to include the GMSH v2.xx File Format.
   *
   *  Current features of this function include:
   *
   *  1. Exports Triangles, Quadrangles and Tetrahedra \n
   *  2. Supports upto second order elements of each type
   *
   */
   void WriteGmsh2Format (const Mesh & mesh,
      const filesystem::path & filename)
   {
      ofstream outfile (filename);
      outfile.precision(6);
      outfile.setf (ios::fixed, ios::floatfield);
      outfile.setf (ios::showpoint);

      int np = mesh.GetNP();  /// number of points in mesh
      int ne = mesh.GetNE();  /// number of 3D elements in mesh
      int nse = mesh.GetNSE();  /// number of surface elements (BC)
      // int i, j, k, l;


      /*
      * 3D section : Volume elements (currently only tetrahedra)
      */

      if ((ne > 0)
          && (mesh.VolumeElements().First().GetNP() <= 10)
          && (mesh.SurfaceElements().First().GetNP() <= 6))
      {
         cout << "Write GMSH v2.xx Format \n";
         cout << "The GMSH v2.xx export is currently available for elements upto 2nd Order\n" << endl;

         int inverttets = mparam.inverttets;
         int invertsurf = mparam.inverttrigs;

         /// Prepare GMSH 2.0 file (See GMSH 2.0 Documentation)
         outfile << "$MeshFormat\n";
         outfile << (float)2.0 << " "
            << (int)0 << " "
            << (int)sizeof(double) << "\n";
         outfile << "$EndMeshFormat\n";

         /// Write nodes
         outfile << "$Nodes\n";
         outfile << np << "\n";

         for (int i = 1; i <= np; i++)
         {
            const Point3d & p = mesh.Point(i);
            outfile << i << " "; /// node number
            outfile << p.X() << " ";
            outfile << p.Y() << " ";
            outfile << p.Z() << "\n";
         }

         outfile << "$EndNodes\n";

         /// write elements (both, surface elements and volume elements)
         outfile << "$Elements\n";
         outfile << ne + nse << "\n";  ////  number of elements + number of surfaces BC

         for (auto sei : Range(mesh.SurfaceElements()))
         {
            int elType = 0;

            Element2d el = mesh[sei]; // .SurfaceElement(i);
            if(invertsurf) el.Invert();
            
            if(el.GetNP() == 3) elType = GMSH_TRIG;	//// GMSH Type for a 3 node triangle
            if(el.GetNP() == 6) elType = GMSH_TRIG6;  //// GMSH Type for a 6 node triangle
            if(elType == 0)
            {
               cout << " Invalid surface element type for Gmsh 2.0 3D-Mesh Export Format !\n";
               return;
            }

            outfile << sei-IndexBASE(sei)+1;  
            outfile << " ";
            outfile << elType;
            outfile << " ";
            outfile << "2";                  //// Number of tags (2 => Physical and elementary entities)
            outfile << " ";
            outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " ";
            /// that means that physical entity = elementary entity (arbitrary approach)
            outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " ";
            for (int j = 1; j <= el.GetNP(); j++)
            {
               outfile << " ";
               outfile << el.PNum(triGmsh[j]);
            }
            outfile << "\n";
         }

         for (ElementIndex ei : Range(mesh.VolumeElements()))
         {
           int i = ei-IndexBASE(ei)+1;
            int elType = 0;

            Element el = mesh[ei];
            if (inverttets) el.Invert();

            if(el.GetNP() == 4) elType = GMSH_TET;    //// GMSH Element type for 4 node tetrahedron
            if(el.GetNP() == 10) elType = GMSH_TET10; //// GMSH Element type for 10 node tetrahedron
            if(elType == 0)
            {
               cout << " Invalid volume element type for Gmsh 2.0 3D-Mesh Export Format !\n";
               return;
            }

            outfile << nse + i;                       //// element number (Remember to add on surface elements)
            outfile << " ";
            outfile << elType;
            outfile << " ";
            outfile << "2";                   //// Number of tags (2 => Physical and elementary entities)
            outfile << " ";
            outfile << 100000 + el.GetIndex();
            /// that means that physical entity = elementary entity (arbitrary approach)
            outfile << " ";
            outfile << 100000 + el.GetIndex();   /// volume number
            outfile << " ";
            for (int j = 1; j <= el.GetNP(); j++)
            {
               outfile << " ";
               outfile << el.PNum(tetGmsh[j]);
            }
            outfile << "\n";
         }
         outfile << "$EndElements\n";
      }
      /*
      * End of 3D section
      */


      /*
      * 2D section : available for triangles and quadrangles
      *              upto 2nd Order
      */
      else if(ne == 0)   /// means that there's no 3D element
      {
         cout << "\n Write Gmsh v2.xx Surface Mesh (triangle and/or quadrangles upto 2nd Order)" << endl;

         /// Prepare GMSH 2.0 file (See GMSH 2.0 Documentation)
         outfile << "$MeshFormat\n";
         outfile << (float)2.0 << " "
            << (int)0 << " "
            << (int)sizeof(double) << "\n";
         outfile << "$EndMeshFormat\n";

         /// Write nodes
         outfile << "$Nodes\n";
         outfile << np << "\n";

         for (int i = 1; i <= np; i++)
         {
            const Point3d & p = mesh.Point(i);
            outfile << i << " "; /// node number
            outfile << p.X() << " ";
            outfile << p.Y() << " ";
            outfile << p.Z() << "\n";
         }
         outfile << "$EndNodes\n";

         /// write triangles & quadrangles
         outfile << "$Elements\n";
         outfile << nse << "\n";

         for (int k = 1; k <= nse; k++)
         {
            int elType = 0;

            const Element2d & el = mesh.SurfaceElement(k);

            if(el.GetNP() == 3) elType = GMSH_TRIG;   //// GMSH Type for a 3 node triangle
            if(el.GetNP() == 6) elType = GMSH_TRIG6;  //// GMSH Type for a 6 node triangle
            if(el.GetNP() == 4) elType = GMSH_QUAD;   //// GMSH Type for a 4 node quadrangle
            if(el.GetNP() == 8) elType = GMSH_QUAD8;  //// GMSH Type for an 8 node quadrangle
            if(elType == 0)
            {
               cout << " Invalid surface element type for Gmsh 2.0 2D-Mesh Export Format !\n";
               return;
            }

            outfile << k;
            outfile << " ";
            outfile << elType;
            outfile << " ";
            outfile << "2";
            outfile << " ";
            outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " ";
            /// that means that physical entity = elementary entity (arbitrary approach)
            outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " ";
            for (int l = 1; l <= el.GetNP(); l++)
            {
               outfile << " ";
               if((elType == GMSH_TRIG) || (elType == GMSH_TRIG6))
               {
                  outfile << el.PNum(triGmsh[l]);
               }
               else if((elType == GMSH_QUAD) || (elType == GMSH_QUAD8))
               {
                  outfile << el.PNum(quadGmsh[l]);
               }
            }
            outfile << "\n";
         }
         outfile << "$EndElements\n";
      }
      /*
      * End of 2D section
      */

      else
      {
         cout << " Invalid element type for Gmsh v2.xx Export Format !\n";
      }
   } // End: WriteGmsh2Format
static RegisterUserFormat reg_gmsh2 ("Gmsh2 Format", {".gmsh2"}, nullopt, WriteGmsh2Format);
} // End: namespace netgen