compiles on openSUSE 15.4 part 2
[engrid-github.git] / src / libengrid / simplefoamwriter.cpp
bloba4ff482074495db9703ce339634b78423a9a2f5a
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 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 #include "simplefoamwriter.h"
23 #include "engrid.h"
24 #include "guimainwindow.h"
26 #include <QFileInfo>
27 #include <QDir>
29 bool SimpleFoamWriter::face_t::operator<(const face_t &F) const
31 bool less = false;
32 if (bc < F.bc) {
33 less = true;
34 } else if (bc == F.bc) {
35 if (owner < F.owner) {
36 less = true;
37 } else if (owner == F.owner) {
38 if (neighbour < F.neighbour) {
39 less = true;
43 return less;
46 vec3_t SimpleFoamWriter::face_t::normal(vtkUnstructuredGrid *m_Grid)
48 if (node.size() < 3) EG_BUG;
49 vec3_t xc(0,0,0);
50 QVector<vec3_t> x(node.size());
51 for (int i = 0; i < node.size(); ++i) {
52 m_Grid->GetPoint(node[i],x[i].data());
53 xc += x[i];
55 xc *= 1.0/node.size();
56 vec3_t n(0,0,0);
57 for (int i = 0; i < node.size()-1; ++i) {
58 vec3_t a = x[i] - xc;
59 vec3_t b = x[i+1] - xc;
60 n += 0.5*(a.cross(b));
62 vec3_t a = x[node.size()-1] - xc;
63 vec3_t b = x[0] - xc;
64 n += 0.5*(a.cross(b));
65 return n;
69 SimpleFoamWriter::SimpleFoamWriter()
71 setFormat("Foam boundary files(boundary)");
72 setExtension("");
75 vtkIdType SimpleFoamWriter::getNeigh(int i_cells, int i_neigh)
77 l2g_t cells = getPartCells();
78 l2l_t c2c = getPartC2C();
79 int n = c2c[i_cells][i_neigh];
80 if (n >= 0) return cells[n];
81 EG_ERR_RETURN("The grid is not suitable for OpenFOAM export (e.g. missing volume mesh).");
82 return -1;
85 void SimpleFoamWriter::addFace(face_t F)
87 if (isVolume(F.neighbour,m_Grid)) {
88 if (F.neighbour > F.owner) {
89 F.bc = 0;
90 m_LFaces.append(F);
92 } else {
93 F.bc = m_BC->GetValue(F.neighbour);
94 F.neighbour = -1;
95 m_LFaces.append(F);
99 void SimpleFoamWriter::createFaces()
101 l2g_t cells = getPartCells();
103 m_LFaces.clear();
104 EG_VTKDCC(vtkIntArray, cell_code, m_Grid, "cell_code");
105 m_BC = cell_code;
106 m_Eg2Of.fill(-1,cells.size());
107 int Nvol = 0;
108 foreach(int i_cells, cells) {
109 EG_GET_CELL(cells[i_cells], m_Grid);
110 vtkIdType id_cell = cells[i_cells];
112 // tetras
114 if (type_cell == VTK_TETRA) {
115 m_Eg2Of[id_cell] = Nvol++;
117 face_t F(3,id_cell,getNeigh(i_cells,0));
118 F.node[0] = pts[2]; F.node[1] = pts[1]; F.node[2] = pts[0];
119 addFace(F);
122 face_t F(3,id_cell,getNeigh(i_cells,1));
123 F.node[0] = pts[0]; F.node[1] = pts[1]; F.node[2] = pts[3];
124 addFace(F);
127 face_t F(3,id_cell,getNeigh(i_cells,2));
128 F.node[0] = pts[0]; F.node[1] = pts[3]; F.node[2] = pts[2];
129 addFace(F);
132 face_t F(3,id_cell,getNeigh(i_cells,3));
133 F.node[0] = pts[1]; F.node[1] = pts[2]; F.node[2] = pts[3];
134 addFace(F);
138 // prisms
140 if (type_cell == VTK_WEDGE) {
141 m_Eg2Of[id_cell] = Nvol++;
143 face_t F(3,id_cell,getNeigh(i_cells,0));
144 F.node[0] = pts[0]; F.node[1] = pts[1]; F.node[2] = pts[2];
145 addFace(F);
148 face_t F(3,id_cell,getNeigh(i_cells,1));
149 F.node[0] = pts[3]; F.node[1] = pts[5]; F.node[2] = pts[4];
150 addFace(F);
153 face_t F(4,id_cell,getNeigh(i_cells,2));
154 F.node[0] = pts[3]; F.node[1] = pts[4]; F.node[2] = pts[1]; F.node[3] = pts[0];
155 addFace(F);
158 face_t F(4,id_cell,getNeigh(i_cells,3));
159 F.node[0] = pts[1]; F.node[1] = pts[4]; F.node[2] = pts[5]; F.node[3] = pts[2];
160 addFace(F);
163 face_t F(4,id_cell,getNeigh(i_cells,4));
164 F.node[0] = pts[0]; F.node[1] = pts[2]; F.node[2] = pts[5]; F.node[3] = pts[3];
165 addFace(F);
169 // hexes
171 if (type_cell == VTK_HEXAHEDRON) {
172 m_Eg2Of[id_cell] = Nvol++;
174 face_t F(4,id_cell,getNeigh(i_cells,0),0);
175 F.node[0] = pts[3]; F.node[1] = pts[2]; F.node[2] = pts[1]; F.node[3] = pts[0];
176 addFace(F);
179 face_t F(4,id_cell,getNeigh(i_cells,1),0);
180 F.node[0] = pts[4]; F.node[1] = pts[5]; F.node[2] = pts[6]; F.node[3] = pts[7];
181 addFace(F);
184 face_t F(4,id_cell,getNeigh(i_cells,2),0);
185 F.node[0] = pts[0]; F.node[1] = pts[1]; F.node[2] = pts[5]; F.node[3] = pts[4];
186 addFace(F);
189 face_t F(4,id_cell,getNeigh(i_cells,3),0);
190 F.node[0] = pts[3]; F.node[1] = pts[7]; F.node[2] = pts[6]; F.node[3] = pts[2];
191 addFace(F);
194 face_t F(4,id_cell,getNeigh(i_cells,4),0);
195 F.node[0] = pts[0]; F.node[1] = pts[4]; F.node[2] = pts[7]; F.node[3] = pts[3];
196 addFace(F);
199 face_t F(4,id_cell,getNeigh(i_cells,5),0);
200 F.node[0] = pts[1]; F.node[1] = pts[2]; F.node[2] = pts[6]; F.node[3] = pts[5];
201 addFace(F);
206 m_Faces.resize(m_LFaces.size());
207 qCopy(m_LFaces.begin(), m_LFaces.end(), m_Faces.begin());
208 qSort(m_Faces);
213 void SimpleFoamWriter::writePoints()
215 l2g_t nodes = getPartNodes();
217 QString filename = m_Path + "points";
218 QFile file(filename);
219 file.open(QIODevice::WriteOnly);
220 QTextStream f(&file);
221 f << "/*--------------------------------*- C++ -*----------------------------------*\\\n";
222 f << "| ========= | |\n";
223 f << "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
224 f << "| \\ / O peration | Version: 1.5 |\n";
225 f << "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
226 f << "| \\/ M anipulation | |\n";
227 f << "\\*---------------------------------------------------------------------------*/\n\n";
228 f << "FoamFile\n";
229 f << "{\n";
230 f << " version 2.0;\n";
231 f << " format ascii;\n";
232 f << " class vectorField;\n";
233 f << " location \"constant/polyMesh\";\n";
234 f << " object points;\n";
235 f << "}\n\n";
236 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
237 f << nodes.size() << "\n(\n";
238 foreach(int i_nodes, nodes) {
239 vtkIdType id_node = nodes[i_nodes];
240 vec3_t x;
241 m_Grid->GetPoint(id_node,x.data());
242 f.setRealNumberPrecision(16);
243 f << "(" << x[0] << " " << x[1] << " " << x[2] << ")\n";
245 f << ")\n\n";
246 f << "// ************************************************************************* //\n\n\n";
249 void SimpleFoamWriter::writeFaces()
251 QString filename = m_Path + "faces";
252 QFile file(filename);
253 file.open(QIODevice::WriteOnly);
254 QTextStream f(&file);
255 f << "/*--------------------------------*- C++ -*----------------------------------*\\\n";
256 f << "| ========= | |\n";
257 f << "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
258 f << "| \\ / O peration | Version: 1.5 |\n";
259 f << "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
260 f << "| \\/ M anipulation | |\n";
261 f << "\\*---------------------------------------------------------------------------*/\n\n";
262 f << "FoamFile\n";
263 f << "{\n";
264 f << " version 2.0;\n";
265 f << " format ascii;\n";
266 f << " class faceList;\n";
267 f << " location \"constant/polyMesh\";\n";
268 f << " object faces;\n";
269 f << "}\n\n";
270 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
271 f << m_Faces.size() << "\n(\n";
272 foreach (face_t F, m_Faces) {
273 f << F.node.size() << "(";
274 for (int i = 0; i < F.node.size(); ++i) {
275 f << F.node[i];
276 if (i == F.node.size()-1) {
277 f << ")\n";
278 } else {
279 f << " ";
283 f << ")\n\n";
284 f << "// ************************************************************************* //\n\n\n";
287 void SimpleFoamWriter::writeOwner()
289 QString filename = m_Path + "owner";
290 QFile file(filename);
291 file.open(QIODevice::WriteOnly);
292 QTextStream f(&file);
293 f << "/*--------------------------------*- C++ -*----------------------------------*\\\n";
294 f << "| ========= | |\n";
295 f << "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
296 f << "| \\ / O peration | Version: 1.5 |\n";
297 f << "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
298 f << "| \\/ M anipulation | |\n";
299 f << "\\*---------------------------------------------------------------------------*/\n\n";
300 f << "FoamFile\n";
301 f << "{\n";
302 f << " version 2.0;\n";
303 f << " format ascii;\n";
304 f << " class labelList;\n";
305 f << " location \"constant/polyMesh\";\n";
306 f << " object owner;\n";
307 f << "}\n\n";
308 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
309 f << m_Faces.size() << "\n(\n";
310 foreach (face_t F, m_Faces) {
311 f << m_Eg2Of[F.owner] << "\n";
313 f << ")\n\n";
314 f << "// ************************************************************************* //\n\n\n";
317 void SimpleFoamWriter::writeNeighbour()
319 QString filename = m_Path + "neighbour";
320 QFile file(filename);
321 file.open(QIODevice::WriteOnly);
322 QTextStream f(&file);
323 f << "/*--------------------------------*- C++ -*----------------------------------*\\\n";
324 f << "| ========= | |\n";
325 f << "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
326 f << "| \\ / O peration | Version: 1.5 |\n";
327 f << "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
328 f << "| \\/ M anipulation | |\n";
329 f << "\\*---------------------------------------------------------------------------*/\n\n";
330 f << "FoamFile\n";
331 f << "{\n";
332 f << " version 2.0;\n";
333 f << " format ascii;\n";
334 f << " class labelList;\n";
335 f << " location \"constant/polyMesh\";\n";
336 f << " object neighbour;\n";
337 f << "}\n\n";
338 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
339 f << m_Faces.size() << "\n(\n";
340 foreach (face_t F, m_Faces) {
341 if (F.neighbour == -1) {
342 f << "-1\n";
343 } else {
344 f << m_Eg2Of[F.neighbour] << "\n";
347 f << ")\n\n";
348 f << "// ************************************************************************* //\n\n\n";
351 void SimpleFoamWriter::writeBoundary(int faces_offset)
353 QString filename = m_Path + "boundary";
354 QFile file(filename);
355 file.open(QIODevice::WriteOnly);
356 QTextStream f(&file);
357 f << "/*--------------------------------*- C++ -*----------------------------------*\\\n";
358 f << "| ========= | |\n";
359 f << "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
360 f << "| \\ / O peration | Version: 1.5 |\n";
361 f << "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
362 f << "| \\/ M anipulation | |\n";
363 f << "\\*---------------------------------------------------------------------------*/\n\n";
364 f << "FoamFile\n";
365 f << "{\n";
366 f << " version 2.0;\n";
367 f << " format ascii;\n";
368 f << " class polyBoundaryMesh;\n";
369 f << " location \"constant/polyMesh\";\n";
370 f << " object boundary;\n";
371 f << "}\n\n";
372 f << "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
373 QSet<int> bcs;
374 foreach (face_t F, m_Faces) {
375 if (F.bc != 0) {
376 bcs.insert(F.bc);
379 f << bcs.size() << "\n(\n";
380 QVector<patch_t> patch(bcs.size());
381 int N_bc = 0;
382 foreach (int bc, bcs) {
383 int nFaces = 0;
384 int startFace = -1;
385 for (int i = 0; i < m_Faces.size(); ++i) {
386 if (m_Faces[i].bc == bc) {
387 ++nFaces;
388 if (startFace == -1) {
389 startFace = i;
393 if (startFace == -1) {
394 EG_BUG;
396 patch_t P;
397 P.bc = bc;
398 P.startFace = startFace;
399 P.nFaces = nFaces;
400 patch[N_bc] = P;
401 ++N_bc;
403 qSort(patch);
404 foreach (patch_t P, patch) {
405 BoundaryCondition BC = getBC(P.bc);
406 QString num;
407 num.setNum(P.bc);
408 QString name = BC.getName();
409 QString type = BC.getType();
410 if (GuiMainWindow::pointer()->physicalTypeDefined(type)) {
411 PhysicalBoundaryCondition PBC = GuiMainWindow::pointer()->getPhysicalBoundaryCondition(type);
412 type = PBC.getFoamType();
414 if (name == "unknown") {
415 name = "BC_" + num;
417 f << " " << name << "\n";
418 f << " {\n";
419 f << " type " << type << ";\n";
420 f << " nFaces " << P.nFaces << ";\n";
421 f << " startFace " << P.startFace + faces_offset << ";\n";
422 f << " }\n";
424 f << ")\n\n";
425 f << "// ************************************************************************* //\n\n\n";
428 void SimpleFoamWriter::operateOnGivenFileName()
430 if (isValid()) {
431 QString p1 = getFileName();
432 QString p2 = p1 + "/constant";
433 QDir d1(p1);
434 QDir d2(p2);
435 if (!d1.exists()) {
436 EG_BUG;
438 if (!d2.exists()) {
439 d1.mkdir("constant");
440 d2 = QDir(p2);
442 d1 = d2;
443 p1 = p2;
444 p2 = p1 + "/polyMesh";
445 d2 = QDir(p2);
446 if (!d2.exists()) {
447 d1.mkdir("polyMesh");
449 m_Path = getFileName() + "/constant/polyMesh/";
450 if (!QDir(m_Path).exists()) {
451 EG_BUG;
453 createFaces();
454 writePoints();
455 writeFaces();
456 writeOwner();
457 writeNeighbour();
458 writeBoundary();
462 void SimpleFoamWriter::operate()
464 try {
465 readOutputDirectory();
466 if (isValid()) {
467 QString p1 = getFileName();
468 QString p2 = p1 + "/constant";
469 QDir d1(p1);
470 QDir d2(p2);
471 if (!d1.exists()) {
472 EG_BUG;
474 if (!d2.exists()) {
475 d1.mkdir("constant");
476 d2 = QDir(p2);
478 d1 = d2;
479 p1 = p2;
480 p2 = p1 + "/polyMesh";
481 d2 = QDir(p2);
482 if (!d2.exists()) {
483 d1.mkdir("polyMesh");
485 m_Path = getFileName() + "/constant/polyMesh/";
486 if (!QDir(m_Path).exists()) {
487 EG_BUG;
489 createFaces();
490 writePoints();
491 writeFaces();
492 writeOwner();
493 writeNeighbour();
494 writeBoundary();
496 } catch (Error err) {
497 err.display();