compiles on openSUSE 15.4 part 2
[engrid-github.git] / src / libengrid / foamwriter.cpp
blobb2f0c2a25d11c03777af8b2a0bced755e164ab3f
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 = 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 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";
246 } else {
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";
258 f << " }\n";
260 f << ")\n\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";
277 f << "FoamFile\n";
278 f << "{\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";
284 f << "}\n\n";
285 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
286 f << m_CellZoneLimits.size() - 1 << "\n";
287 f << "(\n";
288 for (int i = 0; i < m_CellZoneNames.size(); ++i) {
289 f << m_CellZoneNames[i] << "\n";
290 f << "{\n";
291 f << "type cellZone;\n";
292 f << "cellLabels List<label>\n";
293 f << m_CellZoneLimits[i+1] - m_CellZoneLimits[i] << "\n";
294 f << "(\n";
295 for (int j = m_CellZoneLimits[i]; j < m_CellZoneLimits[i+1]; ++j) {
296 f << j << "\n";
298 f << ");\n";
299 f << "}\n";
301 f << ")\n\n";
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();
320 if (i == 0) {
321 poly = new PolyMesh(vol_grid, false, 0.0, false);
322 } else {
323 PolyMesh vol_poly(vol_grid, false, 0.0, false);
324 poly->merge(&vol_poly);
326 m_CellZoneLimits.append(poly->numPolyCells());
328 } else {
329 poly = new PolyMesh(m_Grid, false, 0.0, false);
331 return poly;
335 void FoamWriter::writeSingleVolume()
337 bool is_valid = false;
338 QString file_name;
339 if (!m_NoDialog) {
340 readOutputDirectory();
341 if (isValid()) {
342 is_valid = true;
343 file_name = getFileName();
345 } else {
346 is_valid = true;
347 file_name = m_FixedFileName;
350 if (is_valid) {
351 try {
352 QString p1 = file_name;
353 QString p2 = p1 + "/constant";
354 QDir d1(p1);
355 QDir d2(p2);
356 if (!d1.exists()) {
357 EG_BUG;
359 if (!d2.exists()) {
360 d1.mkdir("constant");
361 d2 = QDir(p2);
363 d1 = d2;
364 p1 = p2;
365 p2 = p1 + "/polyMesh";
366 d2 = QDir(p2);
367 if (!d2.exists()) {
368 d1.mkdir("polyMesh");
370 m_Path = file_name + "/constant/polyMesh/";
371 if (!QDir(m_Path).exists()) {
372 EG_BUG;
374 PolyMesh* poly = createSinglePolyMesh();
375 writePoints(*poly);
376 writeFaces(*poly);
377 writeOwner(*poly);
378 writeNeighbour(*poly);
379 writeBoundary(*poly);
380 if (m_CellZoneLimits.size() >= 2) {
381 writeCellZones();
383 delete poly;
384 } catch (Error err) {
385 err.display();
390 bool FoamWriter::hasNeighbour(int bc)
392 if (m_Bc2Vol[bc].size() == 2) {
393 return true;
395 return false;
398 QString FoamWriter::getNeighbourName(int bc)
400 foreach (QString name, m_Bc2Vol[bc]) {
401 if (name != m_CurrentVolume) {
402 return name;
405 return "unknown";
408 void FoamWriter::writeMultipleVolumes()
410 bool is_valid = false;
411 QString file_name;
412 if (!m_NoDialog) {
413 readOutputDirectory();
414 if (isValid()) {
415 is_valid = true;
416 file_name = getFileName();
418 } else {
419 is_valid = true;
420 file_name = m_FixedFileName;
423 if (is_valid) {
424 try {
425 QList<VolumeDefinition> vols = mainWindow()->getAllVols();
426 QString p1 = file_name;
427 QString p2 = p1 + "/constant";
428 QDir d1(p1);
429 QDir d2(p2);
430 if (!d1.exists()) {
431 EG_BUG;
433 if (!d2.exists()) {
434 d1.mkdir("constant");
435 d2 = QDir(p2);
438 m_Bc2Vol.clear();
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();
455 QDir d3(p3);
456 if (!d3.exists()) {
457 d2.mkdir(vol.getName());
458 d3 = QDir(p3);
460 QString p4 = p3 + "/polyMesh";
461 QDir d4(p4);
462 if (!d4.exists()) {
463 d3.mkdir("polyMesh");
465 m_Path = file_name + "/constant/" + vol.getName() + "/polyMesh/";
466 if (!QDir(m_Path).exists()) {
467 EG_BUG;
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);
474 writePoints(poly);
475 writeFaces(poly);
476 writeOwner(poly);
477 writeNeighbour(poly);
478 writeBoundary(poly);
480 } catch (Error err) {
481 err.display();
486 void FoamWriter::operate()
488 if (mainWindow()->getAllVols().size() <= 1 || m_CreateCellZones) {
489 writeSingleVolume();
490 } else {
491 writeMultipleVolumes();
495 void FoamWriter::setFixedFileName(QString file_name)
497 m_NoDialog = true;
498 m_FixedFileName = file_name;