moved UpdateNodeType to class Operation
[engrid.git] / simplefoamwriter.cpp
blob10cfbef3d35b0a062e820137212166d234b3e2d2
1 //
2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + +
4 // + This file is part of enGrid. +
5 // + +
6 // + Copyright 2008,2009 Oliver Gloth +
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 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 #include "simplefoamwriter.h"
25 #include <QFileInfo>
26 #include <QDir>
28 bool SimpleFoamWriter::face_t::operator<(const face_t &F) const
30 bool less = false;
31 if (bc < F.bc) {
32 less = true;
33 } else if (bc == F.bc) {
34 if (owner < F.owner) {
35 less = true;
36 } else if (owner == F.owner) {
37 if (neighbour < F.neighbour) {
38 less = true;
42 return less;
45 vec3_t SimpleFoamWriter::face_t::normal(vtkUnstructuredGrid *grid)
47 if (node.size() < 3) EG_BUG;
48 vec3_t xc(0,0,0);
49 QVector<vec3_t> x(node.size());
50 for (int i = 0; i < node.size(); ++i) {
51 grid->GetPoint(node[i],x[i].data());
52 xc += x[i];
54 xc *= 1.0/node.size();
55 vec3_t n(0,0,0);
56 for (int i = 0; i < node.size()-1; ++i) {
57 vec3_t a = x[i] - xc;
58 vec3_t b = x[i+1] - xc;
59 n += 0.5*(a.cross(b));
61 vec3_t a = x[node.size()-1] - xc;
62 vec3_t b = x[0] - xc;
63 n += 0.5*(a.cross(b));
64 return n;
68 SimpleFoamWriter::SimpleFoamWriter()
70 setFormat("Foam boundary files(boundary)");
71 setExtension("");
74 vtkIdType SimpleFoamWriter::getNeigh(int i_cells, int i_neigh)
76 int n = c2c[i_cells][i_neigh];
77 if (n >= 0) return cells[n];
78 EG_BUG;
79 return -1;
82 void SimpleFoamWriter::addFace(face_t F)
84 if (isVolume(F.neighbour,grid)) {
85 if (F.neighbour > F.owner) {
86 F.bc = 0;
87 lfaces.append(F);
89 } else {
90 F.bc = bc->GetValue(F.neighbour);
91 F.neighbour = -1;
92 lfaces.append(F);
96 void SimpleFoamWriter::createFaces()
98 lfaces.clear();
99 EG_VTKDCC(vtkIntArray, cell_code, grid, "cell_code");
100 bc = cell_code;
101 eg2of.fill(-1,cells.size());
102 int Nvol = 0;
103 foreach(int i_cells, cells) {
104 vtkIdType *pts;
105 vtkIdType Npts;
106 grid->GetCellPoints(cells[i_cells], Npts, pts);
107 vtkIdType type_cell = grid->GetCellType(cells[i_cells]);
108 vtkIdType id_cell = cells[i_cells];
110 // tetras
112 if (type_cell == VTK_TETRA) {
113 eg2of[id_cell] = Nvol++;
115 face_t F(3,id_cell,getNeigh(i_cells,0));
116 F.node[0] = pts[2]; F.node[1] = pts[1]; F.node[2] = pts[0];
117 addFace(F);
120 face_t F(3,id_cell,getNeigh(i_cells,1));
121 F.node[0] = pts[0]; F.node[1] = pts[1]; F.node[2] = pts[3];
122 addFace(F);
125 face_t F(3,id_cell,getNeigh(i_cells,2));
126 F.node[0] = pts[0]; F.node[1] = pts[3]; F.node[2] = pts[2];
127 addFace(F);
130 face_t F(3,id_cell,getNeigh(i_cells,3));
131 F.node[0] = pts[1]; F.node[1] = pts[2]; F.node[2] = pts[3];
132 addFace(F);
136 // prisms
138 if (type_cell == VTK_WEDGE) {
139 eg2of[id_cell] = Nvol++;
141 face_t F(3,id_cell,getNeigh(i_cells,0));
142 F.node[0] = pts[0]; F.node[1] = pts[1]; F.node[2] = pts[2];
143 addFace(F);
146 face_t F(3,id_cell,getNeigh(i_cells,1));
147 F.node[0] = pts[3]; F.node[1] = pts[5]; F.node[2] = pts[4];
148 addFace(F);
151 face_t F(4,id_cell,getNeigh(i_cells,2));
152 F.node[0] = pts[3]; F.node[1] = pts[4]; F.node[2] = pts[1]; F.node[3] = pts[0];
153 addFace(F);
156 face_t F(4,id_cell,getNeigh(i_cells,3));
157 F.node[0] = pts[1]; F.node[1] = pts[4]; F.node[2] = pts[5]; F.node[3] = pts[2];
158 addFace(F);
161 face_t F(4,id_cell,getNeigh(i_cells,4));
162 F.node[0] = pts[0]; F.node[1] = pts[2]; F.node[2] = pts[5]; F.node[3] = pts[3];
163 addFace(F);
167 // hexes
169 if (type_cell == VTK_HEXAHEDRON) {
170 eg2of[id_cell] = Nvol++;
172 face_t F(4,id_cell,getNeigh(i_cells,0),0);
173 F.node[0] = pts[3]; F.node[1] = pts[2]; F.node[2] = pts[1]; F.node[3] = pts[0];
174 addFace(F);
177 face_t F(4,id_cell,getNeigh(i_cells,1),0);
178 F.node[0] = pts[4]; F.node[1] = pts[5]; F.node[2] = pts[6]; F.node[3] = pts[7];
179 addFace(F);
182 face_t F(4,id_cell,getNeigh(i_cells,2),0);
183 F.node[0] = pts[0]; F.node[1] = pts[1]; F.node[2] = pts[5]; F.node[3] = pts[4];
184 addFace(F);
187 face_t F(4,id_cell,getNeigh(i_cells,3),0);
188 F.node[0] = pts[3]; F.node[1] = pts[7]; F.node[2] = pts[6]; F.node[3] = pts[2];
189 addFace(F);
192 face_t F(4,id_cell,getNeigh(i_cells,4),0);
193 F.node[0] = pts[0]; F.node[1] = pts[4]; F.node[2] = pts[7]; F.node[3] = pts[3];
194 addFace(F);
197 face_t F(4,id_cell,getNeigh(i_cells,5),0);
198 F.node[0] = pts[1]; F.node[1] = pts[2]; F.node[2] = pts[6]; F.node[3] = pts[5];
199 addFace(F);
204 faces.resize(lfaces.size());
205 qCopy(lfaces.begin(),lfaces.end(),faces.begin());
206 qSort(faces);
211 void SimpleFoamWriter::writePoints()
213 QString filename = path + "points";
214 QFile file(filename);
215 file.open(QIODevice::WriteOnly);
216 QTextStream f(&file);
217 f << "/*--------------------------------*- C++ -*----------------------------------*\\\n";
218 f << "| ========= | |\n";
219 f << "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
220 f << "| \\ / O peration | Version: 1.5 |\n";
221 f << "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
222 f << "| \\/ M anipulation | |\n";
223 f << "\\*---------------------------------------------------------------------------*/\n\n";
224 f << "FoamFile\n";
225 f << "{\n";
226 f << " version 2.0;\n";
227 f << " format ascii;\n";
228 f << " class vectorField;\n";
229 f << " location \"constant/polyMesh\";\n";
230 f << " object points;\n";
231 f << "}\n\n";
232 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
233 f << nodes.size() << "\n(\n";
234 foreach(int i_nodes, nodes) {
235 vtkIdType id_node = nodes[i_nodes];
236 vec3_t x;
237 grid->GetPoint(id_node,x.data());
238 f.setRealNumberPrecision(16);
239 f << "(" << x[0] << " " << x[1] << " " << x[2] << ")\n";
241 f << ")\n\n";
242 f << "// ************************************************************************* //\n\n\n";
245 void SimpleFoamWriter::writeFaces()
247 QString filename = path + "faces";
248 QFile file(filename);
249 file.open(QIODevice::WriteOnly);
250 QTextStream f(&file);
251 f << "/*--------------------------------*- C++ -*----------------------------------*\\\n";
252 f << "| ========= | |\n";
253 f << "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
254 f << "| \\ / O peration | Version: 1.5 |\n";
255 f << "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
256 f << "| \\/ M anipulation | |\n";
257 f << "\\*---------------------------------------------------------------------------*/\n\n";
258 f << "FoamFile\n";
259 f << "{\n";
260 f << " version 2.0;\n";
261 f << " format ascii;\n";
262 f << " class faceList;\n";
263 f << " location \"constant/polyMesh\";\n";
264 f << " object faces;\n";
265 f << "}\n\n";
266 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
267 f << faces.size() << "\n(\n";
268 foreach (face_t F, faces) {
269 f << F.node.size() << "(";
270 for (int i = 0; i < F.node.size(); ++i) {
271 f << F.node[i];
272 if (i == F.node.size()-1) {
273 f << ")\n";
274 } else {
275 f << " ";
279 f << ")\n\n";
280 f << "// ************************************************************************* //\n\n\n";
283 void SimpleFoamWriter::writeOwner()
285 QString filename = path + "owner";
286 QFile file(filename);
287 file.open(QIODevice::WriteOnly);
288 QTextStream f(&file);
289 f << "/*--------------------------------*- C++ -*----------------------------------*\\\n";
290 f << "| ========= | |\n";
291 f << "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
292 f << "| \\ / O peration | Version: 1.5 |\n";
293 f << "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
294 f << "| \\/ M anipulation | |\n";
295 f << "\\*---------------------------------------------------------------------------*/\n\n";
296 f << "FoamFile\n";
297 f << "{\n";
298 f << " version 2.0;\n";
299 f << " format ascii;\n";
300 f << " class labelList;\n";
301 f << " location \"constant/polyMesh\";\n";
302 f << " object owner;\n";
303 f << "}\n\n";
304 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
305 f << faces.size() << "\n(\n";
306 foreach (face_t F, faces) {
307 f << eg2of[F.owner] << "\n";
309 f << ")\n\n";
310 f << "// ************************************************************************* //\n\n\n";
313 void SimpleFoamWriter::writeNeighbour()
315 QString filename = path + "neighbour";
316 QFile file(filename);
317 file.open(QIODevice::WriteOnly);
318 QTextStream f(&file);
319 f << "/*--------------------------------*- C++ -*----------------------------------*\\\n";
320 f << "| ========= | |\n";
321 f << "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
322 f << "| \\ / O peration | Version: 1.5 |\n";
323 f << "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
324 f << "| \\/ M anipulation | |\n";
325 f << "\\*---------------------------------------------------------------------------*/\n\n";
326 f << "FoamFile\n";
327 f << "{\n";
328 f << " version 2.0;\n";
329 f << " format ascii;\n";
330 f << " class labelList;\n";
331 f << " location \"constant/polyMesh\";\n";
332 f << " object neighbour;\n";
333 f << "}\n\n";
334 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
335 f << faces.size() << "\n(\n";
336 foreach (face_t F, faces) {
337 if (F.neighbour == -1) {
338 f << "-1\n";
339 } else {
340 f << eg2of[F.neighbour] << "\n";
343 f << ")\n\n";
344 f << "// ************************************************************************* //\n\n\n";
347 void SimpleFoamWriter::writeBoundary()
349 QString filename = path + "boundary";
350 QFile file(filename);
351 file.open(QIODevice::WriteOnly);
352 QTextStream f(&file);
353 f << "/*--------------------------------*- C++ -*----------------------------------*\\\n";
354 f << "| ========= | |\n";
355 f << "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
356 f << "| \\ / O peration | Version: 1.5 |\n";
357 f << "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
358 f << "| \\/ M anipulation | |\n";
359 f << "\\*---------------------------------------------------------------------------*/\n\n";
360 f << "FoamFile\n";
361 f << "{\n";
362 f << " version 2.0;\n";
363 f << " format ascii;\n";
364 f << " class polyBoundaryMesh;\n";
365 f << " location \"constant/polyMesh\";\n";
366 f << " object boundary;\n";
367 f << "}\n\n";
368 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
369 QSet<int> bcs;
370 foreach (face_t F, faces) {
371 if (F.bc != 0) {
372 bcs.insert(F.bc);
375 f << bcs.size() << "\n(\n";
376 foreach (int bc, bcs) {
377 int nFaces = 0;
378 int startFace = -1;
379 for (int i = 0; i < faces.size(); ++i) {
380 if (faces[i].bc == bc) {
381 ++nFaces;
382 if (startFace == -1) {
383 startFace = i;
387 if (startFace == -1) {
388 EG_BUG;
390 BoundaryCondition BC = getBC(bc);
391 f << " " << BC.getName() << "\n";
392 f << " {\n";
393 f << " type " << BC.getType() << ";\n";
394 f << " nFaces " << nFaces << ";\n";
395 f << " startFace " << startFace << ";\n";
396 f << " }\n";
398 f << ")\n\n";
399 f << "// ************************************************************************* //\n\n\n";
402 void SimpleFoamWriter::operate()
404 try {
405 readOutputDirectory();
406 if (isValid()) {
407 QString p1 = getFileName();
408 QString p2 = p1 + "/constant";
409 QDir d1(p1);
410 QDir d2(p2);
411 if (!d1.exists()) {
412 EG_BUG;
414 if (!d2.exists()) {
415 d1.mkdir("constant");
416 d2 = QDir(p2);
418 d1 = d2;
419 p1 = p2;
420 p2 = p1 + "/polyMesh";
421 d2 = QDir(p2);
422 if (!d2.exists()) {
423 d1.mkdir("polyMesh");
425 path = getFileName() + "/constant/polyMesh/";
426 if (!QDir(path).exists()) {
427 EG_BUG;
429 createFaces();
430 writePoints();
431 writeFaces();
432 writeOwner();
433 writeNeighbour();
434 writeBoundary();
436 } catch (Error err) {
437 err.display();