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"
23 #include "guimainwindow.h"
28 bool SimpleFoamWriter::face_t::operator<(const face_t
&F
) const
33 } else if (bc
== F
.bc
) {
34 if (owner
< F
.owner
) {
36 } else if (owner
== F
.owner
) {
37 if (neighbour
< F
.neighbour
) {
45 vec3_t
SimpleFoamWriter::face_t::normal(vtkUnstructuredGrid
*m_Grid
)
47 if (node
.size() < 3) EG_BUG
;
49 QVector
<vec3_t
> x(node
.size());
50 for (int i
= 0; i
< node
.size(); ++i
) {
51 m_Grid
->GetPoint(node
[i
],x
[i
].data());
54 xc
*= 1.0/node
.size();
56 for (int i
= 0; i
< node
.size()-1; ++i
) {
58 vec3_t b
= x
[i
+1] - xc
;
59 n
+= 0.5*(a
.cross(b
));
61 vec3_t a
= x
[node
.size()-1] - xc
;
63 n
+= 0.5*(a
.cross(b
));
68 SimpleFoamWriter::SimpleFoamWriter()
70 setFormat("Foam boundary files(boundary)");
74 vtkIdType
SimpleFoamWriter::getNeigh(int i_cells
, int i_neigh
)
76 l2g_t cells
= getPartCells();
77 l2l_t c2c
= getPartC2C();
78 int n
= c2c
[i_cells
][i_neigh
];
79 if (n
>= 0) return cells
[n
];
80 EG_ERR_RETURN("The grid is not suitable for OpenFOAM export (e.g. missing volume mesh).");
84 void SimpleFoamWriter::addFace(face_t F
)
86 if (isVolume(F
.neighbour
,m_Grid
)) {
87 if (F
.neighbour
> F
.owner
) {
92 F
.bc
= m_BC
->GetValue(F
.neighbour
);
98 void SimpleFoamWriter::createFaces()
100 l2g_t cells
= getPartCells();
103 EG_VTKDCC(vtkIntArray
, cell_code
, m_Grid
, "cell_code");
105 m_Eg2Of
.fill(-1,cells
.size());
107 foreach(int i_cells
, cells
) {
110 m_Grid
->GetCellPoints(cells
[i_cells
], Npts
, pts
);
111 vtkIdType type_cell
= m_Grid
->GetCellType(cells
[i_cells
]);
112 vtkIdType id_cell
= cells
[i_cells
];
116 if (type_cell
== VTK_TETRA
) {
117 m_Eg2Of
[id_cell
] = Nvol
++;
119 face_t
F(3,id_cell
,getNeigh(i_cells
,0));
120 F
.node
[0] = pts
[2]; F
.node
[1] = pts
[1]; F
.node
[2] = pts
[0];
124 face_t
F(3,id_cell
,getNeigh(i_cells
,1));
125 F
.node
[0] = pts
[0]; F
.node
[1] = pts
[1]; F
.node
[2] = pts
[3];
129 face_t
F(3,id_cell
,getNeigh(i_cells
,2));
130 F
.node
[0] = pts
[0]; F
.node
[1] = pts
[3]; F
.node
[2] = pts
[2];
134 face_t
F(3,id_cell
,getNeigh(i_cells
,3));
135 F
.node
[0] = pts
[1]; F
.node
[1] = pts
[2]; F
.node
[2] = pts
[3];
142 if (type_cell
== VTK_WEDGE
) {
143 m_Eg2Of
[id_cell
] = Nvol
++;
145 face_t
F(3,id_cell
,getNeigh(i_cells
,0));
146 F
.node
[0] = pts
[0]; F
.node
[1] = pts
[1]; F
.node
[2] = pts
[2];
150 face_t
F(3,id_cell
,getNeigh(i_cells
,1));
151 F
.node
[0] = pts
[3]; F
.node
[1] = pts
[5]; F
.node
[2] = pts
[4];
155 face_t
F(4,id_cell
,getNeigh(i_cells
,2));
156 F
.node
[0] = pts
[3]; F
.node
[1] = pts
[4]; F
.node
[2] = pts
[1]; F
.node
[3] = pts
[0];
160 face_t
F(4,id_cell
,getNeigh(i_cells
,3));
161 F
.node
[0] = pts
[1]; F
.node
[1] = pts
[4]; F
.node
[2] = pts
[5]; F
.node
[3] = pts
[2];
165 face_t
F(4,id_cell
,getNeigh(i_cells
,4));
166 F
.node
[0] = pts
[0]; F
.node
[1] = pts
[2]; F
.node
[2] = pts
[5]; F
.node
[3] = pts
[3];
173 if (type_cell
== VTK_HEXAHEDRON
) {
174 m_Eg2Of
[id_cell
] = Nvol
++;
176 face_t
F(4,id_cell
,getNeigh(i_cells
,0),0);
177 F
.node
[0] = pts
[3]; F
.node
[1] = pts
[2]; F
.node
[2] = pts
[1]; F
.node
[3] = pts
[0];
181 face_t
F(4,id_cell
,getNeigh(i_cells
,1),0);
182 F
.node
[0] = pts
[4]; F
.node
[1] = pts
[5]; F
.node
[2] = pts
[6]; F
.node
[3] = pts
[7];
186 face_t
F(4,id_cell
,getNeigh(i_cells
,2),0);
187 F
.node
[0] = pts
[0]; F
.node
[1] = pts
[1]; F
.node
[2] = pts
[5]; F
.node
[3] = pts
[4];
191 face_t
F(4,id_cell
,getNeigh(i_cells
,3),0);
192 F
.node
[0] = pts
[3]; F
.node
[1] = pts
[7]; F
.node
[2] = pts
[6]; F
.node
[3] = pts
[2];
196 face_t
F(4,id_cell
,getNeigh(i_cells
,4),0);
197 F
.node
[0] = pts
[0]; F
.node
[1] = pts
[4]; F
.node
[2] = pts
[7]; F
.node
[3] = pts
[3];
201 face_t
F(4,id_cell
,getNeigh(i_cells
,5),0);
202 F
.node
[0] = pts
[1]; F
.node
[1] = pts
[2]; F
.node
[2] = pts
[6]; F
.node
[3] = pts
[5];
208 m_Faces
.resize(m_LFaces
.size());
209 qCopy(m_LFaces
.begin(), m_LFaces
.end(), m_Faces
.begin());
215 void SimpleFoamWriter::writePoints()
217 l2g_t nodes
= getPartNodes();
219 QString filename
= m_Path
+ "points";
220 QFile
file(filename
);
221 file
.open(QIODevice::WriteOnly
);
222 QTextStream
f(&file
);
223 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
224 f
<< "| ========= | |\n";
225 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
226 f
<< "| \\ / O peration | Version: 1.5 |\n";
227 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
228 f
<< "| \\/ M anipulation | |\n";
229 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
232 f
<< " version 2.0;\n";
233 f
<< " format ascii;\n";
234 f
<< " class vectorField;\n";
235 f
<< " location \"constant/polyMesh\";\n";
236 f
<< " object points;\n";
238 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
239 f
<< nodes
.size() << "\n(\n";
240 foreach(int i_nodes
, nodes
) {
241 vtkIdType id_node
= nodes
[i_nodes
];
243 m_Grid
->GetPoint(id_node
,x
.data());
244 f
.setRealNumberPrecision(16);
245 f
<< "(" << x
[0] << " " << x
[1] << " " << x
[2] << ")\n";
248 f
<< "// ************************************************************************* //\n\n\n";
251 void SimpleFoamWriter::writeFaces()
253 QString filename
= m_Path
+ "faces";
254 QFile
file(filename
);
255 file
.open(QIODevice::WriteOnly
);
256 QTextStream
f(&file
);
257 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
258 f
<< "| ========= | |\n";
259 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
260 f
<< "| \\ / O peration | Version: 1.5 |\n";
261 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
262 f
<< "| \\/ M anipulation | |\n";
263 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
266 f
<< " version 2.0;\n";
267 f
<< " format ascii;\n";
268 f
<< " class faceList;\n";
269 f
<< " location \"constant/polyMesh\";\n";
270 f
<< " object faces;\n";
272 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
273 f
<< m_Faces
.size() << "\n(\n";
274 foreach (face_t F
, m_Faces
) {
275 f
<< F
.node
.size() << "(";
276 for (int i
= 0; i
< F
.node
.size(); ++i
) {
278 if (i
== F
.node
.size()-1) {
286 f
<< "// ************************************************************************* //\n\n\n";
289 void SimpleFoamWriter::writeOwner()
291 QString filename
= m_Path
+ "owner";
292 QFile
file(filename
);
293 file
.open(QIODevice::WriteOnly
);
294 QTextStream
f(&file
);
295 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
296 f
<< "| ========= | |\n";
297 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
298 f
<< "| \\ / O peration | Version: 1.5 |\n";
299 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
300 f
<< "| \\/ M anipulation | |\n";
301 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
304 f
<< " version 2.0;\n";
305 f
<< " format ascii;\n";
306 f
<< " class labelList;\n";
307 f
<< " location \"constant/polyMesh\";\n";
308 f
<< " object owner;\n";
310 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
311 f
<< m_Faces
.size() << "\n(\n";
312 foreach (face_t F
, m_Faces
) {
313 f
<< m_Eg2Of
[F
.owner
] << "\n";
316 f
<< "// ************************************************************************* //\n\n\n";
319 void SimpleFoamWriter::writeNeighbour()
321 QString filename
= m_Path
+ "neighbour";
322 QFile
file(filename
);
323 file
.open(QIODevice::WriteOnly
);
324 QTextStream
f(&file
);
325 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
326 f
<< "| ========= | |\n";
327 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
328 f
<< "| \\ / O peration | Version: 1.5 |\n";
329 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
330 f
<< "| \\/ M anipulation | |\n";
331 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
334 f
<< " version 2.0;\n";
335 f
<< " format ascii;\n";
336 f
<< " class labelList;\n";
337 f
<< " location \"constant/polyMesh\";\n";
338 f
<< " object neighbour;\n";
340 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
341 f
<< m_Faces
.size() << "\n(\n";
342 foreach (face_t F
, m_Faces
) {
343 if (F
.neighbour
== -1) {
346 f
<< m_Eg2Of
[F
.neighbour
] << "\n";
350 f
<< "// ************************************************************************* //\n\n\n";
353 void SimpleFoamWriter::writeBoundary(int faces_offset
)
355 QString filename
= m_Path
+ "boundary";
356 QFile
file(filename
);
357 file
.open(QIODevice::WriteOnly
);
358 QTextStream
f(&file
);
359 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
360 f
<< "| ========= | |\n";
361 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
362 f
<< "| \\ / O peration | Version: 1.5 |\n";
363 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
364 f
<< "| \\/ M anipulation | |\n";
365 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
368 f
<< " version 2.0;\n";
369 f
<< " format ascii;\n";
370 f
<< " class polyBoundaryMesh;\n";
371 f
<< " location \"constant/polyMesh\";\n";
372 f
<< " object boundary;\n";
374 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
376 foreach (face_t F
, m_Faces
) {
381 f
<< bcs
.size() << "\n(\n";
382 QVector
<patch_t
> patch(bcs
.size());
384 foreach (int bc
, bcs
) {
387 for (int i
= 0; i
< m_Faces
.size(); ++i
) {
388 if (m_Faces
[i
].bc
== bc
) {
390 if (startFace
== -1) {
395 if (startFace
== -1) {
400 P
.startFace
= startFace
;
406 foreach (patch_t P
, patch
) {
407 BoundaryCondition BC
= getBC(P
.bc
);
410 QString name
= BC
.getName();
411 QString type
= BC
.getType();
412 if (GuiMainWindow::pointer()->physicalTypeDefined(type
)) {
413 PhysicalBoundaryCondition PBC
= GuiMainWindow::pointer()->getPhysicalBoundaryCondition(type
);
414 type
= PBC
.getFoamType();
416 if (name
== "unknown") {
419 f
<< " " << name
<< "\n";
421 f
<< " type " << type
<< ";\n";
422 f
<< " nFaces " << P
.nFaces
<< ";\n";
423 f
<< " startFace " << P
.startFace
+ faces_offset
<< ";\n";
427 f
<< "// ************************************************************************* //\n\n\n";
430 void SimpleFoamWriter::operateOnGivenFileName()
433 QString p1
= getFileName();
434 QString p2
= p1
+ "/constant";
441 d1
.mkdir("constant");
446 p2
= p1
+ "/polyMesh";
449 d1
.mkdir("polyMesh");
451 m_Path
= getFileName() + "/constant/polyMesh/";
452 if (!QDir(m_Path
).exists()) {
464 void SimpleFoamWriter::operate()
467 readOutputDirectory();
469 QString p1
= getFileName();
470 QString p2
= p1
+ "/constant";
477 d1
.mkdir("constant");
482 p2
= p1
+ "/polyMesh";
485 d1
.mkdir("polyMesh");
487 m_Path
= getFileName() + "/constant/polyMesh/";
488 if (!QDir(m_Path
).exists()) {
498 } catch (Error err
) {