1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + This file is part of enGrid. +
5 // + Copyright 2008-2014 enGits GmbH +
7 // + enGrid is free software: you can redistribute it and/or modify +
8 // + it under the terms of the GNU General Public License as published by +
9 // + the Free Software Foundation, either version 3 of the License, or +
10 // + (at your option) any later version. +
12 // + enGrid is distributed in the hope that it will be useful, +
13 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
14 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
15 // + GNU General Public License for more details. +
17 // + You should have received a copy of the GNU General Public License +
18 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 #include "simplefoamwriter.h"
24 #include "guimainwindow.h"
29 bool SimpleFoamWriter::face_t::operator<(const face_t
&F
) const
34 } else if (bc
== F
.bc
) {
35 if (owner
< F
.owner
) {
37 } else if (owner
== F
.owner
) {
38 if (neighbour
< F
.neighbour
) {
46 vec3_t
SimpleFoamWriter::face_t::normal(vtkUnstructuredGrid
*m_Grid
)
48 if (node
.size() < 3) EG_BUG
;
50 QVector
<vec3_t
> x(node
.size());
51 for (int i
= 0; i
< node
.size(); ++i
) {
52 m_Grid
->GetPoint(node
[i
],x
[i
].data());
55 xc
*= 1.0/node
.size();
57 for (int i
= 0; i
< node
.size()-1; ++i
) {
59 vec3_t b
= x
[i
+1] - xc
;
60 n
+= 0.5*(a
.cross(b
));
62 vec3_t a
= x
[node
.size()-1] - xc
;
64 n
+= 0.5*(a
.cross(b
));
69 SimpleFoamWriter::SimpleFoamWriter()
71 setFormat("Foam boundary files(boundary)");
75 vtkIdType
SimpleFoamWriter::getNeigh(int i_cells
, int i_neigh
)
77 l2g_t cells
= getPartCells();
78 l2l_t c2c
= getPartC2C();
79 int n
= c2c
[i_cells
][i_neigh
];
80 if (n
>= 0) return cells
[n
];
81 EG_ERR_RETURN("The grid is not suitable for OpenFOAM export (e.g. missing volume mesh).");
85 void SimpleFoamWriter::addFace(face_t F
)
87 if (isVolume(F
.neighbour
,m_Grid
)) {
88 if (F
.neighbour
> F
.owner
) {
93 F
.bc
= m_BC
->GetValue(F
.neighbour
);
99 void SimpleFoamWriter::createFaces()
101 l2g_t cells
= getPartCells();
104 EG_VTKDCC(vtkIntArray
, cell_code
, m_Grid
, "cell_code");
106 m_Eg2Of
.fill(-1,cells
.size());
108 foreach(int i_cells
, cells
) {
109 EG_GET_CELL(cells
[i_cells
], m_Grid
);
110 vtkIdType id_cell
= cells
[i_cells
];
114 if (type_cell
== VTK_TETRA
) {
115 m_Eg2Of
[id_cell
] = Nvol
++;
117 face_t
F(3,id_cell
,getNeigh(i_cells
,0));
118 F
.node
[0] = pts
[2]; F
.node
[1] = pts
[1]; F
.node
[2] = pts
[0];
122 face_t
F(3,id_cell
,getNeigh(i_cells
,1));
123 F
.node
[0] = pts
[0]; F
.node
[1] = pts
[1]; F
.node
[2] = pts
[3];
127 face_t
F(3,id_cell
,getNeigh(i_cells
,2));
128 F
.node
[0] = pts
[0]; F
.node
[1] = pts
[3]; F
.node
[2] = pts
[2];
132 face_t
F(3,id_cell
,getNeigh(i_cells
,3));
133 F
.node
[0] = pts
[1]; F
.node
[1] = pts
[2]; F
.node
[2] = pts
[3];
140 if (type_cell
== VTK_WEDGE
) {
141 m_Eg2Of
[id_cell
] = Nvol
++;
143 face_t
F(3,id_cell
,getNeigh(i_cells
,0));
144 F
.node
[0] = pts
[0]; F
.node
[1] = pts
[1]; F
.node
[2] = pts
[2];
148 face_t
F(3,id_cell
,getNeigh(i_cells
,1));
149 F
.node
[0] = pts
[3]; F
.node
[1] = pts
[5]; F
.node
[2] = pts
[4];
153 face_t
F(4,id_cell
,getNeigh(i_cells
,2));
154 F
.node
[0] = pts
[3]; F
.node
[1] = pts
[4]; F
.node
[2] = pts
[1]; F
.node
[3] = pts
[0];
158 face_t
F(4,id_cell
,getNeigh(i_cells
,3));
159 F
.node
[0] = pts
[1]; F
.node
[1] = pts
[4]; F
.node
[2] = pts
[5]; F
.node
[3] = pts
[2];
163 face_t
F(4,id_cell
,getNeigh(i_cells
,4));
164 F
.node
[0] = pts
[0]; F
.node
[1] = pts
[2]; F
.node
[2] = pts
[5]; F
.node
[3] = pts
[3];
171 if (type_cell
== VTK_HEXAHEDRON
) {
172 m_Eg2Of
[id_cell
] = Nvol
++;
174 face_t
F(4,id_cell
,getNeigh(i_cells
,0),0);
175 F
.node
[0] = pts
[3]; F
.node
[1] = pts
[2]; F
.node
[2] = pts
[1]; F
.node
[3] = pts
[0];
179 face_t
F(4,id_cell
,getNeigh(i_cells
,1),0);
180 F
.node
[0] = pts
[4]; F
.node
[1] = pts
[5]; F
.node
[2] = pts
[6]; F
.node
[3] = pts
[7];
184 face_t
F(4,id_cell
,getNeigh(i_cells
,2),0);
185 F
.node
[0] = pts
[0]; F
.node
[1] = pts
[1]; F
.node
[2] = pts
[5]; F
.node
[3] = pts
[4];
189 face_t
F(4,id_cell
,getNeigh(i_cells
,3),0);
190 F
.node
[0] = pts
[3]; F
.node
[1] = pts
[7]; F
.node
[2] = pts
[6]; F
.node
[3] = pts
[2];
194 face_t
F(4,id_cell
,getNeigh(i_cells
,4),0);
195 F
.node
[0] = pts
[0]; F
.node
[1] = pts
[4]; F
.node
[2] = pts
[7]; F
.node
[3] = pts
[3];
199 face_t
F(4,id_cell
,getNeigh(i_cells
,5),0);
200 F
.node
[0] = pts
[1]; F
.node
[1] = pts
[2]; F
.node
[2] = pts
[6]; F
.node
[3] = pts
[5];
206 m_Faces
.resize(m_LFaces
.size());
207 qCopy(m_LFaces
.begin(), m_LFaces
.end(), m_Faces
.begin());
213 void SimpleFoamWriter::writePoints()
215 l2g_t nodes
= getPartNodes();
217 QString filename
= m_Path
+ "points";
218 QFile
file(filename
);
219 file
.open(QIODevice::WriteOnly
);
220 QTextStream
f(&file
);
221 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
222 f
<< "| ========= | |\n";
223 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
224 f
<< "| \\ / O peration | Version: 1.5 |\n";
225 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
226 f
<< "| \\/ M anipulation | |\n";
227 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
230 f
<< " version 2.0;\n";
231 f
<< " format ascii;\n";
232 f
<< " class vectorField;\n";
233 f
<< " location \"constant/polyMesh\";\n";
234 f
<< " object points;\n";
236 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
237 f
<< nodes
.size() << "\n(\n";
238 foreach(int i_nodes
, nodes
) {
239 vtkIdType id_node
= nodes
[i_nodes
];
241 m_Grid
->GetPoint(id_node
,x
.data());
242 f
.setRealNumberPrecision(16);
243 f
<< "(" << x
[0] << " " << x
[1] << " " << x
[2] << ")\n";
246 f
<< "// ************************************************************************* //\n\n\n";
249 void SimpleFoamWriter::writeFaces()
251 QString filename
= m_Path
+ "faces";
252 QFile
file(filename
);
253 file
.open(QIODevice::WriteOnly
);
254 QTextStream
f(&file
);
255 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
256 f
<< "| ========= | |\n";
257 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
258 f
<< "| \\ / O peration | Version: 1.5 |\n";
259 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
260 f
<< "| \\/ M anipulation | |\n";
261 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
264 f
<< " version 2.0;\n";
265 f
<< " format ascii;\n";
266 f
<< " class faceList;\n";
267 f
<< " location \"constant/polyMesh\";\n";
268 f
<< " object faces;\n";
270 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
271 f
<< m_Faces
.size() << "\n(\n";
272 foreach (face_t F
, m_Faces
) {
273 f
<< F
.node
.size() << "(";
274 for (int i
= 0; i
< F
.node
.size(); ++i
) {
276 if (i
== F
.node
.size()-1) {
284 f
<< "// ************************************************************************* //\n\n\n";
287 void SimpleFoamWriter::writeOwner()
289 QString filename
= m_Path
+ "owner";
290 QFile
file(filename
);
291 file
.open(QIODevice::WriteOnly
);
292 QTextStream
f(&file
);
293 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
294 f
<< "| ========= | |\n";
295 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
296 f
<< "| \\ / O peration | Version: 1.5 |\n";
297 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
298 f
<< "| \\/ M anipulation | |\n";
299 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
302 f
<< " version 2.0;\n";
303 f
<< " format ascii;\n";
304 f
<< " class labelList;\n";
305 f
<< " location \"constant/polyMesh\";\n";
306 f
<< " object owner;\n";
308 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
309 f
<< m_Faces
.size() << "\n(\n";
310 foreach (face_t F
, m_Faces
) {
311 f
<< m_Eg2Of
[F
.owner
] << "\n";
314 f
<< "// ************************************************************************* //\n\n\n";
317 void SimpleFoamWriter::writeNeighbour()
319 QString filename
= m_Path
+ "neighbour";
320 QFile
file(filename
);
321 file
.open(QIODevice::WriteOnly
);
322 QTextStream
f(&file
);
323 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
324 f
<< "| ========= | |\n";
325 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
326 f
<< "| \\ / O peration | Version: 1.5 |\n";
327 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
328 f
<< "| \\/ M anipulation | |\n";
329 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
332 f
<< " version 2.0;\n";
333 f
<< " format ascii;\n";
334 f
<< " class labelList;\n";
335 f
<< " location \"constant/polyMesh\";\n";
336 f
<< " object neighbour;\n";
338 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
339 f
<< m_Faces
.size() << "\n(\n";
340 foreach (face_t F
, m_Faces
) {
341 if (F
.neighbour
== -1) {
344 f
<< m_Eg2Of
[F
.neighbour
] << "\n";
348 f
<< "// ************************************************************************* //\n\n\n";
351 void SimpleFoamWriter::writeBoundary(int faces_offset
)
353 QString filename
= m_Path
+ "boundary";
354 QFile
file(filename
);
355 file
.open(QIODevice::WriteOnly
);
356 QTextStream
f(&file
);
357 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
358 f
<< "| ========= | |\n";
359 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
360 f
<< "| \\ / O peration | Version: 1.5 |\n";
361 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
362 f
<< "| \\/ M anipulation | |\n";
363 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
366 f
<< " version 2.0;\n";
367 f
<< " format ascii;\n";
368 f
<< " class polyBoundaryMesh;\n";
369 f
<< " location \"constant/polyMesh\";\n";
370 f
<< " object boundary;\n";
372 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
374 foreach (face_t F
, m_Faces
) {
379 f
<< bcs
.size() << "\n(\n";
380 QVector
<patch_t
> patch(bcs
.size());
382 foreach (int bc
, bcs
) {
385 for (int i
= 0; i
< m_Faces
.size(); ++i
) {
386 if (m_Faces
[i
].bc
== bc
) {
388 if (startFace
== -1) {
393 if (startFace
== -1) {
398 P
.startFace
= startFace
;
404 foreach (patch_t P
, patch
) {
405 BoundaryCondition BC
= getBC(P
.bc
);
408 QString name
= BC
.getName();
409 QString type
= BC
.getType();
410 if (GuiMainWindow::pointer()->physicalTypeDefined(type
)) {
411 PhysicalBoundaryCondition PBC
= GuiMainWindow::pointer()->getPhysicalBoundaryCondition(type
);
412 type
= PBC
.getFoamType();
414 if (name
== "unknown") {
417 f
<< " " << name
<< "\n";
419 f
<< " type " << type
<< ";\n";
420 f
<< " nFaces " << P
.nFaces
<< ";\n";
421 f
<< " startFace " << P
.startFace
+ faces_offset
<< ";\n";
425 f
<< "// ************************************************************************* //\n\n\n";
428 void SimpleFoamWriter::operateOnGivenFileName()
431 QString p1
= getFileName();
432 QString p2
= p1
+ "/constant";
439 d1
.mkdir("constant");
444 p2
= p1
+ "/polyMesh";
447 d1
.mkdir("polyMesh");
449 m_Path
= getFileName() + "/constant/polyMesh/";
450 if (!QDir(m_Path
).exists()) {
462 void SimpleFoamWriter::operate()
465 readOutputDirectory();
467 QString p1
= getFileName();
468 QString p2
= p1
+ "/constant";
475 d1
.mkdir("constant");
480 p2
= p1
+ "/polyMesh";
483 d1
.mkdir("polyMesh");
485 m_Path
= getFileName() + "/constant/polyMesh/";
486 if (!QDir(m_Path
).exists()) {
496 } catch (Error err
) {