various improvements to speed up surface meshing of BRL-CAD geometries
[engrid.git] / src / libengrid / foamwriter.cpp
blob124407931ff91d6d7b35d981061c54c66bb8059e
1 //
2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + +
4 // + This file is part of enGrid. +
5 // + +
6 // + Copyright 2008-2013 enGits GmbH +
7 // + +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
12 // + +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
17 // + +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
20 // + +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 //
23 #include "foamwriter.h"
24 #include "volumedefinition.h"
25 #include "guimainwindow.h"
27 #include <QFileInfo>
28 #include <QDir>
30 FoamWriter::FoamWriter()
32 EG_TYPENAME;
33 setFormat("Foam boundary files(boundary)");
34 setExtension("");
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 (hasNeighbour(bc)) {
222 bc_type = "mappedWall";
225 QString neigh_name = bc_name;
227 if (bc_type == "mappedWall") {
228 bc_name += "_" + m_CurrentVolume;
231 f << " " << bc_name << "\n";
232 f << " {\n";
233 f << " type " << bc_type << ";\n";
234 f << " nFaces " << nFaces << ";\n";
235 f << " startFace " << startFace << ";\n";
236 if (bc_type == "mappedWall") {
237 f << " startFace " << startFace << ";\n";
238 f << " sampleMode nearestPatchFace;\n";
239 f << " sampleRegion " << getNeighbourName(bc) << ";\n";
240 f << " samplePatch " << neigh_name + "_" + getNeighbourName(bc) << ";\n";
241 f << " offsetMode uniform;\n";
242 f << " offset ( 0 0 0 );\n";
244 f << " }\n";
246 f << ")\n\n";
247 f << "// ************************************************************************* //\n\n\n";
250 void FoamWriter::writeSingleVolume()
252 try {
253 readOutputDirectory();
254 if (isValid()) {
255 QString p1 = getFileName();
256 QString p2 = p1 + "/constant";
257 QDir d1(p1);
258 QDir d2(p2);
259 if (!d1.exists()) {
260 EG_BUG;
262 if (!d2.exists()) {
263 d1.mkdir("constant");
264 d2 = QDir(p2);
266 d1 = d2;
267 p1 = p2;
268 p2 = p1 + "/polyMesh";
269 d2 = QDir(p2);
270 if (!d2.exists()) {
271 d1.mkdir("polyMesh");
273 m_Path = getFileName() + "/constant/polyMesh/";
274 if (!QDir(m_Path).exists()) {
275 EG_BUG;
277 PolyMesh poly(m_Grid);
278 writePoints(poly);
279 writeFaces(poly);
280 writeOwner(poly);
281 writeNeighbour(poly);
282 writeBoundary(poly);
284 } catch (Error err) {
285 err.display();
289 bool FoamWriter::hasNeighbour(int bc)
291 if (m_Bc2Vol[bc].size() == 2) {
292 return true;
294 return false;
297 QString FoamWriter::getNeighbourName(int bc)
299 foreach (QString name, m_Bc2Vol[bc]) {
300 if (name != m_CurrentVolume) {
301 return name;
304 return "unknown";
307 void FoamWriter::writeMultipleVolumes()
309 try {
310 readOutputDirectory();
311 if (isValid()) {
312 QList<VolumeDefinition> vols = mainWindow()->getAllVols();
313 QString p1 = getFileName();
314 QString p2 = p1 + "/constant";
315 QDir d1(p1);
316 QDir d2(p2);
317 if (!d1.exists()) {
318 EG_BUG;
320 if (!d2.exists()) {
321 d1.mkdir("constant");
322 d2 = QDir(p2);
325 m_Bc2Vol.clear();
326 QSet<int> bcs = mainWindow()->getAllBoundaryCodes();
327 foreach (int bc, bcs) {
328 foreach (VolumeDefinition vol, vols) {
329 if (vol.getSign(bc) != 0) {
330 m_Bc2Vol[bc].append(vol.getName());
331 if (m_Bc2Vol[bc].size() > 2) {
332 EG_ERR_RETURN("Boundary condition with more than two volumes found!");
338 foreach (VolumeDefinition vol, vols) {
339 m_CurrentVolume = vol.getName();
341 QString p3 = p2 + "/" + vol.getName();
342 QDir d3(p3);
343 if (!d3.exists()) {
344 d2.mkdir(QString("constant") + "/" + vol.getName());
345 d3 = QDir(p3);
347 QString p4 = p3 + "/polyMesh";
348 QDir d4(p4);
349 if (!d4.exists()) {
350 d3.mkdir("polyMesh");
352 m_Path = getFileName() + "/constant/" + vol.getName() + "/polyMesh/";
353 if (!QDir(m_Path).exists()) {
354 EG_BUG;
356 EG_VTKSP(vtkUnstructuredGrid, vol_grid);
357 MeshPartition volume(vol.getName());
358 volume.setVolumeOrientation();
359 volume.extractToVtkGrid(vol_grid);
360 PolyMesh poly(vol_grid);
361 writePoints(poly);
362 writeFaces(poly);
363 writeOwner(poly);
364 writeNeighbour(poly);
365 writeBoundary(poly);
369 } catch (Error err) {
370 err.display();
374 void FoamWriter::operate()
376 if (mainWindow()->getAllVols().size() <= 1) {
377 writeSingleVolume();
378 } else {
379 writeMultipleVolumes();