Merge branch 'master' of github.com:enGits/engrid
[engrid-github.git] / src / libengrid / foamwriter.cpp
blob71aa09eae7bc96822332cb400711fba709de7004
1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 // + +
3 // + This file is part of enGrid. +
4 // + +
5 // + Copyright 2008-2014 enGits GmbH +
6 // + +
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. +
11 // + +
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. +
16 // + +
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/>. +
19 // + +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 #include "foamwriter.h"
22 #include "volumedefinition.h"
23 #include "guimainwindow.h"
25 #include <QFileInfo>
26 #include <QDir>
28 FoamWriter::FoamWriter()
30 EG_TYPENAME;
31 setFormat("Foam boundary files(boundary)");
32 setExtension("");
33 m_CreateCellZones = false;//true;
34 m_NoDialog = false;
37 void FoamWriter::writePoints(const PolyMesh &poly)
39 QString filename = m_Path + "points";
40 QFile file(filename);
41 file.open(QIODevice::WriteOnly);
42 QTextStream f(&file);
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";
50 f << "FoamFile\n";
51 f << "{\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";
57 f << "}\n\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";
65 f << ")\n\n";
66 f << "// ************************************************************************* //\n\n\n";
69 void FoamWriter::writeFaces(const PolyMesh &poly)
71 QString filename = m_Path + "faces";
72 QFile file(filename);
73 file.open(QIODevice::WriteOnly);
74 QTextStream f(&file);
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";
82 f << "FoamFile\n";
83 f << "{\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";
89 f << "}\n\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) {
97 f << ")\n";
98 } else {
99 f << " ";
103 f << ")\n\n";
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";
120 f << "FoamFile\n";
121 f << "{\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";
127 f << "}\n\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";
133 f << ")\n\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";
150 f << "FoamFile\n";
151 f << "{\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";
157 f << "}\n\n";
158 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
159 int N = 0;
160 for (int i = 0; i < poly.numFaces(); ++i) {
161 if (poly.boundaryCode(i) != 0) break;
162 ++N;
164 f << N << "\n(\n";
165 for (int i = 0; i < N; ++i) {
166 f << poly.neighbour(i) << "\n";
168 f << ")\n\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";
185 f << "FoamFile\n";
186 f << "{\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";
192 f << "}\n\n";
193 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
194 int N = 0;
195 for (int i = 0; i < poly.numFaces(); ++i) {
196 if (poly.boundaryCode(i) != 0) break;
197 ++N;
199 f << poly.numBCs() << "\n(\n";
200 int i = N;
201 while (i < poly.numFaces()) {
202 int bc = poly.boundaryCode(i);
203 BoundaryCondition BC = getBC(bc);
204 int nFaces = 0;
205 int startFace = i;
206 bool loop = (poly.boundaryCode(i) == bc);
207 while (loop) {
208 ++nFaces;
209 ++i;
210 loop = (i < poly.numFaces());
211 if (loop) {
212 loop = (poly.boundaryCode(i) == bc);
215 QString bc_name = BC.getName();
216 if (bc_name == "unknown") {
217 bc_name.setNum(bc);
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";
236 f << " {\n";
237 f << " type " << bc_type << ";\n";
238 f << " nFaces " << nFaces << ";\n";
239 f << " startFace " << startFace << ";\n";
240 if (bc_type == "mappedWall") {
241 f << " startFace " << startFace << ";\n";
242 f << " sampleMode nearestPatchFace;\n";
243 f << " sampleRegion " << getNeighbourName(bc) << ";\n";
244 f << " samplePatch " << neigh_name + "_" + getNeighbourName(bc) << ";\n";
245 f << " offsetMode uniform;\n";
246 f << " offset ( 0 0 0 );\n";
248 f << " }\n";
250 f << ")\n\n";
251 f << "// ************************************************************************* //\n\n\n";
254 void FoamWriter::writeCellZones()
256 QString filename = m_Path + "cellZones";
257 QFile file(filename);
258 file.open(QIODevice::WriteOnly);
259 QTextStream f(&file);
260 f << "/*--------------------------------*- C++ -*----------------------------------*\\\n";
261 f << "| ========= | |\n";
262 f << "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
263 f << "| \\ / O peration | Version: 1.5 |\n";
264 f << "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
265 f << "| \\/ M anipulation | |\n";
266 f << "\\*---------------------------------------------------------------------------*/\n\n";
267 f << "FoamFile\n";
268 f << "{\n";
269 f << " version 2.0;\n";
270 f << " format ascii;\n";
271 f << " class regIOobject;\n";
272 f << " location \"constant/polyMesh\";\n";
273 f << " object cellZones;\n";
274 f << "}\n\n";
275 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
276 f << m_CellZoneLimits.size() - 1 << "\n";
277 f << "(\n";
278 for (int i = 0; i < m_CellZoneNames.size(); ++i) {
279 f << m_CellZoneNames[i] << "\n";
280 f << "{\n";
281 f << "type cellZone;\n";
282 f << "cellLabels List<label>\n";
283 f << m_CellZoneLimits[i+1] - m_CellZoneLimits[i] << "\n";
284 f << "(\n";
285 for (int j = m_CellZoneLimits[i]; j < m_CellZoneLimits[i+1]; ++j) {
286 f << j << "\n";
288 f << ");\n";
289 f << "}\n";
291 f << ")\n\n";
292 f << "// ************************************************************************* //\n\n\n";
295 PolyMesh* FoamWriter::createSinglePolyMesh()
297 m_CellZoneLimits.clear();
298 m_CellZoneNames.clear();
299 QList<VolumeDefinition> vols = mainWindow()->getAllVols();
300 PolyMesh* poly = NULL;
301 m_CellZoneLimits.append(0);
302 if (vols.size() > 1) {
303 for (int i = 0; i < vols.size(); ++i) {
304 m_CellZoneNames.append(vols[i].getName());
305 EG_VTKSP(vtkUnstructuredGrid, vol_grid);
306 MeshPartition volume(vols[i].getName());
307 volume.setVolumeOrientation();
308 volume.extractToVtkGrid(vol_grid);
309 volume.setOriginalOrientation();
310 if (i == 0) {
311 poly = new PolyMesh(vol_grid, false, 0.0, false);
312 } else {
313 PolyMesh vol_poly(vol_grid, false, 0.0, false);
314 poly->merge(&vol_poly);
316 m_CellZoneLimits.append(poly->numPolyCells());
318 } else {
319 poly = new PolyMesh(m_Grid, false, 0.0, false);
321 return poly;
325 void FoamWriter::writeSingleVolume()
327 bool is_valid = false;
328 QString file_name;
329 if (!m_NoDialog) {
330 readOutputDirectory();
331 if (isValid()) {
332 is_valid = true;
333 file_name = getFileName();
335 } else {
336 is_valid = true;
337 file_name = m_FixedFileName;
340 if (is_valid) {
341 try {
342 QString p1 = file_name;
343 QString p2 = p1 + "/constant";
344 QDir d1(p1);
345 QDir d2(p2);
346 if (!d1.exists()) {
347 EG_BUG;
349 if (!d2.exists()) {
350 d1.mkdir("constant");
351 d2 = QDir(p2);
353 d1 = d2;
354 p1 = p2;
355 p2 = p1 + "/polyMesh";
356 d2 = QDir(p2);
357 if (!d2.exists()) {
358 d1.mkdir("polyMesh");
360 m_Path = file_name + "/constant/polyMesh/";
361 if (!QDir(m_Path).exists()) {
362 EG_BUG;
364 PolyMesh* poly = createSinglePolyMesh();
365 writePoints(*poly);
366 writeFaces(*poly);
367 writeOwner(*poly);
368 writeNeighbour(*poly);
369 writeBoundary(*poly);
370 if (m_CellZoneLimits.size() >= 2) {
371 writeCellZones();
373 delete poly;
374 } catch (Error err) {
375 err.display();
380 bool FoamWriter::hasNeighbour(int bc)
382 if (m_Bc2Vol[bc].size() == 2) {
383 return true;
385 return false;
388 QString FoamWriter::getNeighbourName(int bc)
390 foreach (QString name, m_Bc2Vol[bc]) {
391 if (name != m_CurrentVolume) {
392 return name;
395 return "unknown";
398 void FoamWriter::writeMultipleVolumes()
400 bool is_valid = false;
401 QString file_name;
402 if (!m_NoDialog) {
403 readOutputDirectory();
404 if (isValid()) {
405 is_valid = true;
406 file_name = getFileName();
408 } else {
409 is_valid = true;
410 file_name = m_FixedFileName;
413 if (is_valid) {
414 try {
415 QList<VolumeDefinition> vols = mainWindow()->getAllVols();
416 QString p1 = file_name;
417 QString p2 = p1 + "/constant";
418 QDir d1(p1);
419 QDir d2(p2);
420 if (!d1.exists()) {
421 EG_BUG;
423 if (!d2.exists()) {
424 d1.mkdir("constant");
425 d2 = QDir(p2);
428 m_Bc2Vol.clear();
429 QSet<int> bcs = mainWindow()->getAllBoundaryCodes();
430 foreach (int bc, bcs) {
431 foreach (VolumeDefinition vol, vols) {
432 if (vol.getSign(bc) != 0) {
433 m_Bc2Vol[bc].append(vol.getName());
434 if (m_Bc2Vol[bc].size() > 2) {
435 EG_ERR_RETURN("Boundary condition with more than two volumes found!");
441 foreach (VolumeDefinition vol, vols) {
442 m_CurrentVolume = vol.getName();
444 QString p3 = p2 + "/" + vol.getName();
445 QDir d3(p3);
446 if (!d3.exists()) {
447 d2.mkdir(vol.getName());
448 d3 = QDir(p3);
450 QString p4 = p3 + "/polyMesh";
451 QDir d4(p4);
452 if (!d4.exists()) {
453 d3.mkdir("polyMesh");
455 m_Path = file_name + "/constant/" + vol.getName() + "/polyMesh/";
456 if (!QDir(m_Path).exists()) {
457 EG_BUG;
459 EG_VTKSP(vtkUnstructuredGrid, vol_grid);
460 MeshPartition volume(vol.getName());
461 volume.setVolumeOrientation();
462 volume.extractToVtkGrid(vol_grid);
463 PolyMesh poly(vol_grid, false, 0.0, false);
464 writePoints(poly);
465 writeFaces(poly);
466 writeOwner(poly);
467 writeNeighbour(poly);
468 writeBoundary(poly);
470 } catch (Error err) {
471 err.display();
476 void FoamWriter::operate()
478 if (mainWindow()->getAllVols().size() <= 1 || m_CreateCellZones) {
479 writeSingleVolume();
480 } else {
481 writeMultipleVolumes();
485 void FoamWriter::setFixedFileName(QString file_name)
487 m_NoDialog = true;
488 m_FixedFileName = file_name;