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 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 #include "foamwriter.h"
22 #include "volumedefinition.h"
23 #include "guimainwindow.h"
28 FoamWriter::FoamWriter()
31 setFormat("Foam boundary files(boundary)");
33 m_CreateCellZones
= true;
37 void FoamWriter::writePoints(const PolyMesh
&poly
)
39 QString filename
= m_Path
+ "points";
41 file
.open(QIODevice::WriteOnly
);
43 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
44 f
<< "| ========= | |\n";
45 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
46 f
<< "| \\ / O peration | Version: 1.5 |\n";
47 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
48 f
<< "| \\/ M anipulation | |\n";
49 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
52 f
<< " version 2.0;\n";
53 f
<< " format ascii;\n";
54 f
<< " class vectorField;\n";
55 f
<< " location \"constant/polyMesh\";\n";
56 f
<< " object points;\n";
58 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
59 f
<< poly
.totalNumNodes() << "\n(\n";
60 for (int i
= 0; i
< poly
.totalNumNodes(); ++i
) {
61 vec3_t x
= poly
.nodeVector(i
);
62 f
.setRealNumberPrecision(16);
63 f
<< "(" << x
[0] << " " << x
[1] << " " << x
[2] << ")\n";
66 f
<< "// ************************************************************************* //\n\n\n";
69 void FoamWriter::writeFaces(const PolyMesh
&poly
)
71 QString filename
= m_Path
+ "faces";
73 file
.open(QIODevice::WriteOnly
);
75 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
76 f
<< "| ========= | |\n";
77 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
78 f
<< "| \\ / O peration | Version: 1.5 |\n";
79 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
80 f
<< "| \\/ M anipulation | |\n";
81 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
84 f
<< " version 2.0;\n";
85 f
<< " format ascii;\n";
86 f
<< " class faceList;\n";
87 f
<< " location \"constant/polyMesh\";\n";
88 f
<< " object faces;\n";
90 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
91 f
<< poly
.numFaces() << "\n(\n";
92 for (int i
= 0; i
< poly
.numFaces(); ++i
) {
93 f
<< poly
.numNodes(i
) << "(";
94 for (int j
= 0; j
< poly
.numNodes(i
); ++j
) {
95 f
<< poly
.nodeIndex(i
,j
);
96 if (j
== poly
.numNodes(i
) - 1) {
104 f
<< "// ************************************************************************* //\n\n\n";
107 void FoamWriter::writeOwner(const PolyMesh
&poly
)
109 QString filename
= m_Path
+ "owner";
110 QFile
file(filename
);
111 file
.open(QIODevice::WriteOnly
);
112 QTextStream
f(&file
);
113 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
114 f
<< "| ========= | |\n";
115 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
116 f
<< "| \\ / O peration | Version: 1.5 |\n";
117 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
118 f
<< "| \\/ M anipulation | |\n";
119 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
122 f
<< " version 2.0;\n";
123 f
<< " format ascii;\n";
124 f
<< " class labelList;\n";
125 f
<< " location \"constant/polyMesh\";\n";
126 f
<< " object owner;\n";
128 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
129 f
<< poly
.numFaces() << "\n(\n";
130 for (int i
= 0; i
< poly
.numFaces(); ++i
) {
131 f
<< poly
.owner(i
) << "\n";
134 f
<< "// ************************************************************************* //\n\n\n";
137 void FoamWriter::writeNeighbour(const PolyMesh
&poly
)
139 QString filename
= m_Path
+ "neighbour";
140 QFile
file(filename
);
141 file
.open(QIODevice::WriteOnly
);
142 QTextStream
f(&file
);
143 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
144 f
<< "| ========= | |\n";
145 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
146 f
<< "| \\ / O peration | Version: 1.5 |\n";
147 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
148 f
<< "| \\/ M anipulation | |\n";
149 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
152 f
<< " version 2.0;\n";
153 f
<< " format ascii;\n";
154 f
<< " class labelList;\n";
155 f
<< " location \"constant/polyMesh\";\n";
156 f
<< " object neighbour;\n";
158 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
160 for (int i
= 0; i
< poly
.numFaces(); ++i
) {
161 if (poly
.boundaryCode(i
) != 0) break;
165 for (int i
= 0; i
< N
; ++i
) {
166 f
<< poly
.neighbour(i
) << "\n";
169 f
<< "// ************************************************************************* //\n\n\n";
172 void FoamWriter::writeBoundary(const PolyMesh
&poly
)
174 QString filename
= m_Path
+ "boundary";
175 QFile
file(filename
);
176 file
.open(QIODevice::WriteOnly
);
177 QTextStream
f(&file
);
178 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
179 f
<< "| ========= | |\n";
180 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
181 f
<< "| \\ / O peration | Version: 1.5 |\n";
182 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
183 f
<< "| \\/ M anipulation | |\n";
184 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
187 f
<< " version 2.0;\n";
188 f
<< " format ascii;\n";
189 f
<< " class polyBoundaryMesh;\n";
190 f
<< " location \"constant/polyMesh\";\n";
191 f
<< " object boundary;\n";
193 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
195 for (int i
= 0; i
< poly
.numFaces(); ++i
) {
196 if (poly
.boundaryCode(i
) != 0) break;
199 f
<< poly
.numBCs() << "\n(\n";
201 while (i
< poly
.numFaces()) {
202 int bc
= poly
.boundaryCode(i
);
203 BoundaryCondition BC
= getBC(bc
);
206 bool loop
= (poly
.boundaryCode(i
) == bc
);
210 loop
= (i
< poly
.numFaces());
212 loop
= (poly
.boundaryCode(i
) == bc
);
215 QString bc_name
= BC
.getName();
216 if (bc_name
== "unknown") {
218 bc_name
= "BC_" + bc_name
.rightJustified(4, '0');
220 QString bc_type
= BC
.getType();
221 if (GuiMainWindow::pointer()->physicalTypeDefined(bc_type
)) {
222 PhysicalBoundaryCondition PBC
= GuiMainWindow::pointer()->getPhysicalBoundaryCondition(bc_type
);
223 bc_type
= PBC
.getFoamType();
225 if (hasNeighbour(bc
)) {
226 bc_type
= "mappedWall";
229 QString neigh_name
= bc_name
;
231 if (bc_type
== "mappedWall") {
232 bc_name
+= "_" + m_CurrentVolume
;
235 f
<< " " << bc_name
<< "\n";
237 if (bc_type
== "planar_cyclic") {
238 QString side
= bc_name
.right(1);
239 QString base
= bc_name
.left(bc_name
.size() - 1);
240 f
<< " type cyclicAMI;\n";
241 f
<< " nFaces " << nFaces
<< ";\n";
242 f
<< " startFace " << startFace
<< ";\n";
243 f
<< " transform noOrdering;\n";
244 if (side
== "A") f
<< " neighbourPatch " + base
+ "B;\n";
245 else f
<< " neighbourPatch " + base
+ "A;\n";
247 f
<< " type " << bc_type
<< ";\n";
248 f
<< " nFaces " << nFaces
<< ";\n";
249 f
<< " startFace " << startFace
<< ";\n";
250 if (bc_type
== "mappedWall") {
251 f
<< " sampleMode nearestPatchFace;\n";
252 f
<< " sampleRegion " << getNeighbourName(bc
) << ";\n";
253 f
<< " samplePatch " << neigh_name
+ "_" + getNeighbourName(bc
) << ";\n";
254 f
<< " offsetMode uniform;\n";
255 f
<< " offset ( 0 0 0 );\n";
261 f
<< "// ************************************************************************* //\n\n\n";
264 void FoamWriter::writeCellZones()
266 QString filename
= m_Path
+ "cellZones";
267 QFile
file(filename
);
268 file
.open(QIODevice::WriteOnly
);
269 QTextStream
f(&file
);
270 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
271 f
<< "| ========= | |\n";
272 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
273 f
<< "| \\ / O peration | Version: 1.5 |\n";
274 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
275 f
<< "| \\/ M anipulation | |\n";
276 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
279 f
<< " version 2.0;\n";
280 f
<< " format ascii;\n";
281 f
<< " class regIOobject;\n";
282 f
<< " location \"constant/polyMesh\";\n";
283 f
<< " object cellZones;\n";
285 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
286 f
<< m_CellZoneLimits
.size() - 1 << "\n";
288 for (int i
= 0; i
< m_CellZoneNames
.size(); ++i
) {
289 f
<< m_CellZoneNames
[i
] << "\n";
291 f
<< "type cellZone;\n";
292 f
<< "cellLabels List<label>\n";
293 f
<< m_CellZoneLimits
[i
+1] - m_CellZoneLimits
[i
] << "\n";
295 for (int j
= m_CellZoneLimits
[i
]; j
< m_CellZoneLimits
[i
+1]; ++j
) {
302 f
<< "// ************************************************************************* //\n\n\n";
305 PolyMesh
* FoamWriter::createSinglePolyMesh()
307 m_CellZoneLimits
.clear();
308 m_CellZoneNames
.clear();
309 QList
<VolumeDefinition
> vols
= mainWindow()->getAllVols();
310 PolyMesh
* poly
= NULL
;
311 m_CellZoneLimits
.append(0);
312 if (vols
.size() > 1) {
313 for (int i
= 0; i
< vols
.size(); ++i
) {
314 m_CellZoneNames
.append(vols
[i
].getName());
315 EG_VTKSP(vtkUnstructuredGrid
, vol_grid
);
316 MeshPartition
volume(vols
[i
].getName());
317 volume
.setVolumeOrientation();
318 volume
.extractToVtkGrid(vol_grid
);
319 volume
.setOriginalOrientation();
321 poly
= new PolyMesh(vol_grid
, false, 0.0, false);
323 PolyMesh
vol_poly(vol_grid
, false, 0.0, false);
324 poly
->merge(&vol_poly
);
326 m_CellZoneLimits
.append(poly
->numPolyCells());
329 poly
= new PolyMesh(m_Grid
, false, 0.0, false);
335 void FoamWriter::writeSingleVolume()
337 bool is_valid
= false;
340 readOutputDirectory();
343 file_name
= getFileName();
347 file_name
= m_FixedFileName
;
352 QString p1
= file_name
;
353 QString p2
= p1
+ "/constant";
360 d1
.mkdir("constant");
365 p2
= p1
+ "/polyMesh";
368 d1
.mkdir("polyMesh");
370 m_Path
= file_name
+ "/constant/polyMesh/";
371 if (!QDir(m_Path
).exists()) {
374 PolyMesh
* poly
= createSinglePolyMesh();
378 writeNeighbour(*poly
);
379 writeBoundary(*poly
);
380 if (m_CellZoneLimits
.size() >= 2) {
384 } catch (Error err
) {
390 bool FoamWriter::hasNeighbour(int bc
)
392 if (m_Bc2Vol
[bc
].size() == 2) {
398 QString
FoamWriter::getNeighbourName(int bc
)
400 foreach (QString name
, m_Bc2Vol
[bc
]) {
401 if (name
!= m_CurrentVolume
) {
408 void FoamWriter::writeMultipleVolumes()
410 bool is_valid
= false;
413 readOutputDirectory();
416 file_name
= getFileName();
420 file_name
= m_FixedFileName
;
425 QList
<VolumeDefinition
> vols
= mainWindow()->getAllVols();
426 QString p1
= file_name
;
427 QString p2
= p1
+ "/constant";
434 d1
.mkdir("constant");
439 QSet
<int> bcs
= mainWindow()->getAllBoundaryCodes();
440 foreach (int bc
, bcs
) {
441 foreach (VolumeDefinition vol
, vols
) {
442 if (vol
.getSign(bc
) != 0) {
443 m_Bc2Vol
[bc
].append(vol
.getName());
444 if (m_Bc2Vol
[bc
].size() > 2) {
445 EG_ERR_RETURN("Boundary condition with more than two volumes found!");
451 foreach (VolumeDefinition vol
, vols
) {
452 m_CurrentVolume
= vol
.getName();
454 QString p3
= p2
+ "/" + vol
.getName();
457 d2
.mkdir(vol
.getName());
460 QString p4
= p3
+ "/polyMesh";
463 d3
.mkdir("polyMesh");
465 m_Path
= file_name
+ "/constant/" + vol
.getName() + "/polyMesh/";
466 if (!QDir(m_Path
).exists()) {
469 EG_VTKSP(vtkUnstructuredGrid
, vol_grid
);
470 MeshPartition
volume(vol
.getName());
471 volume
.setVolumeOrientation();
472 volume
.extractToVtkGrid(vol_grid
);
473 PolyMesh
poly(vol_grid
, false, 0.0, false);
477 writeNeighbour(poly
);
480 } catch (Error err
) {
486 void FoamWriter::operate()
488 if (mainWindow()->getAllVols().size() <= 1 || m_CreateCellZones
) {
491 writeMultipleVolumes();
495 void FoamWriter::setFixedFileName(QString file_name
)
498 m_FixedFileName
= file_name
;