2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008,2009 Oliver Gloth +
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. +
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. +
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/>. +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 #include "openfoamcase.h"
25 #include "filetemplate.h"
26 #include "guimainwindow.h"
33 OpenFOAMcase::OpenFOAMcase()
37 ///@@@ TODO: Finish this by adding decomposeParDict creation and calling writeMpiParameters from operate
38 void OpenFOAMcase::writeMpiParameters()
40 QString hostfile_text
= GuiMainWindow::pointer()->getXmlSection( "solver/general/host_weight_list" );
42 QVector
<QString
> host
;
43 QVector
<QString
> weight
;
45 QStringList host_weight_list
= hostfile_text
.split(",");
46 foreach(QString host_weight
, host_weight_list
) {
47 if(!host_weight
.isEmpty()){
48 QStringList values
= host_weight
.split(":");
49 qWarning()<<"values="<<values
;
50 host
.push_back(values
[0].trimmed());
51 weight
.push_back(values
[1].trimmed());
55 // create the hostfile
56 QFileInfo
fileinfo( getFileName() + "/" + "hostfile.txt" );
57 QFile
hostfile( fileinfo
.filePath() );
58 if (!hostfile
.open(QIODevice::WriteOnly
| QIODevice::Text
)) {
60 EG_ERR_RETURN( "ERROR: Failed to open file " + fileinfo
.filePath() );
61 } catch ( Error err
) {
65 QTextStream
out( &hostfile
);
66 for(int i
= 0; i
< host
.size(); i
++) {
67 out
<< host
[i
] << endl
;
73 void OpenFOAMcase::writeSolverParameters()
75 int idx
= GuiMainWindow::pointer()->getXmlSection( "solver/general/solver_type" ).toInt();
77 QFileInfo solvers_fileinfo
;
78 solvers_fileinfo
.setFile( ":/resources/solvers/solvers.txt" );
79 QFile
file( solvers_fileinfo
.filePath() );
80 if ( !file
.exists() ) {
81 qDebug() << "ERROR: " << solvers_fileinfo
.filePath() << " not found.";
84 if ( !file
.open( QIODevice::ReadOnly
| QIODevice::Text
) ) {
85 qDebug() << "ERROR: Failed to open file " << solvers_fileinfo
.filePath();
88 QTextStream
text_stream( &file
);
89 QString intext
= text_stream
.readAll();
92 QStringList page_list
= intext
.split( "=" );
93 QString page
= page_list
[idx
];
97 QVector
<QString
> files
;
98 QStringList variable_list
= page
.split( ";" );
99 foreach( QString variable
, variable_list
) {
100 QStringList name_value
= variable
.split( ":" );
101 if ( name_value
[0].trimmed() == "title" ) title
= name_value
[1].trimmed();
102 if ( name_value
[0].trimmed() == "section" ) section
= name_value
[1].trimmed();
103 if ( name_value
[0].trimmed() == "binary" ) binary
= name_value
[1].trimmed();
104 if ( name_value
[0].trimmed() == "files" ) {
105 QStringList file_list
= name_value
[1].split( "," );
106 foreach( QString file
, file_list
) {
107 files
.push_back( file
.trimmed() );
112 for ( int i
= 0; i
< files
.size(); i
++ ) {
113 FileTemplate
file_template( ":/resources/solvers/" + section
+ "/" + files
[i
], section
);
114 QFileInfo
fileinfo_destination( getFileName() + "/" + files
[i
] );
115 QDir destination_dir
= fileinfo_destination
.dir();
116 QString destination
= destination_dir
.absolutePath() + "/" + fileinfo_destination
.completeBaseName();
117 if ( !destination_dir
.mkpath( destination_dir
.absolutePath() ) ) {
118 EG_ERR_RETURN( "ERROR: Could not create directory \n" + destination_dir
.absolutePath() );
120 qDebug() << "Writing to " << destination
;
121 file_template
.exportToOpenFOAM( destination
);
125 void OpenFOAMcase::createBoundaryFaces()
127 QVector
<int> owner( grid
->GetNumberOfCells() );
129 readFile( "constant/polyMesh/owner" );
130 QTextStream
f( getBuffer() );
133 for ( int i
= 0; i
< num_faces
; ++i
) {
136 if ( i
>= getFirstBoundaryFace() ) {
137 owner
[i
- getFirstBoundaryFace()] = o
;
141 EG_VTKDCC( vtkIntArray
, bc
, grid
, "cell_code" );
142 m_Faces
.resize( grid
->GetNumberOfCells() );
143 for ( vtkIdType id_cell
= 0; id_cell
< grid
->GetNumberOfCells(); ++id_cell
) {
145 vtkIdType N_pts
, *pts
;
146 grid
->GetCellPoints( id_cell
, N_pts
, pts
);
147 F
.node
.resize( N_pts
);
148 for ( int i
= 0; i
< N_pts
; ++i
) {
149 F
.node
[i
] = surfToVol( pts
[i
] );
151 F
.owner
= owner
[id_cell
];
152 F
.bc
= bc
->GetValue( id_cell
);
154 m_Faces
[id_cell
] = F
;
159 void OpenFOAMcase::rewriteBoundaryFaces()
161 setCaseDir( getFileName() );
163 QVector
<QVector
<int> > faces( getFirstBoundaryFace() );
165 readFile( "constant/polyMesh/faces" );
166 QTextStream
f( getBuffer() );
169 if ( grid
->GetNumberOfCells() + getFirstBoundaryFace() != num_faces
) {
170 EG_ERR_RETURN( "Current surface mesh does not match the OpenFOAM case." );
172 for ( int i
= 0; i
< getFirstBoundaryFace(); ++i
) {
175 faces
[i
].resize( num_nodes
);
176 for ( int j
= 0; j
< num_nodes
; ++j
) {
182 QString file_name
= getFileName() + "/constant/polyMesh/faces";
183 QFile
file( file_name
);
184 file
.open( QIODevice::WriteOnly
);
185 QTextStream
f( &file
);
186 f
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
187 f
<< "| ========= | |\n";
188 f
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
189 f
<< "| \\ / O peration | Version: 1.5 |\n";
190 f
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
191 f
<< "| \\/ M anipulation | |\n";
192 f
<< "\\*---------------------------------------------------------------------------*/\n\n";
195 f
<< " version 2.0;\n";
196 f
<< " format ascii;\n";
197 f
<< " class faceList;\n";
198 f
<< " location \"constant/polyMesh\";\n";
199 f
<< " object faces;\n";
201 f
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
202 f
<< faces
.size() + grid
->GetNumberOfCells() << "\n(\n";
203 for ( int i
= 0; i
< faces
.size(); ++i
) {
204 f
<< faces
[i
].size() << "(";
205 for ( int j
= 0; j
< faces
[i
].size(); ++j
) {
207 if ( j
== faces
[i
].size() - 1 ) {
215 createBoundaryFaces();
216 foreach( face_t F
, m_Faces
) {
217 f
<< F
.node
.size() << "(";
218 for ( int i
= 0; i
< F
.node
.size(); ++i
) {
220 if ( i
== F
.node
.size() - 1 ) {
229 f
<< "// ************************************************************************* //\n\n\n";
232 readFile( "constant/polyMesh/owner" );
233 QTextStream
f_in( getBuffer() );
234 QString file_name
= getFileName() + "/constant/polyMesh/owner";
235 QFile
file( file_name
);
236 file
.open( QIODevice::WriteOnly
);
237 QTextStream
f_out( &file
);
240 f_out
<< "/*--------------------------------*- C++ -*----------------------------------*\\\n";
241 f_out
<< "| ========= | |\n";
242 f_out
<< "| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n";
243 f_out
<< "| \\ / O peration | Version: 1.5 |\n";
244 f_out
<< "| \\ / A nd | Web: http://www.OpenFOAM.org |\n";
245 f_out
<< "| \\/ M anipulation | |\n";
246 f_out
<< "\\*---------------------------------------------------------------------------*/\n\n";
247 f_out
<< "FoamFile\n";
249 f_out
<< " version 2.0;\n";
250 f_out
<< " format ascii;\n";
251 f_out
<< " class labelList;\n";
252 f_out
<< " location \"constant/polyMesh\";\n";
253 f_out
<< " object owner;\n";
255 f_out
<< "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n\n";
256 f_out
<< num_faces
<< "\n(\n";
257 for ( int i
= 0; i
< getFirstBoundaryFace(); ++i
) {
260 f_out
<< owner
<< "\n";
262 foreach( face_t F
, m_Faces
) {
263 f_out
<< F
.owner
<< "\n";
266 f_out
<< "// ************************************************************************* //\n\n\n";
268 m_Path
= getFileName() + "/constant/polyMesh/";
269 writeBoundary( getFirstBoundaryFace() );
272 void OpenFOAMcase::upateVarFile(QString file_name
, QString bc_txt
)
274 QFile
file(getFileName() + "/0/" + file_name
);
278 file
.open(QIODevice::ReadOnly
);
279 QTextStream
f(&file
);
280 buffer
= f
.readAll();
283 buffer
= buffer
.replace("$$$", bc_txt
);
285 file
.open(QIODevice::WriteOnly
);
286 QTextStream
f(&file
);
293 void OpenFOAMcase::writeBoundaryConditions()
296 EG_VTKDCC(vtkIntArray
, cell_code
, grid
, "cell_code");
297 GuiMainWindow::pointer()->getAllBoundaryCodes(bcs
);
298 QString U_buffer
= "";
299 QString p_buffer
= "";
300 QString T_buffer
= "";
301 QString k_buffer
= "";
302 QString epsilon_buffer
= "";
303 QString omega_buffer
= "";
304 foreach (int bc
, bcs
) {
305 BoundaryCondition BC
= GuiMainWindow::pointer()->getBC(bc
);
306 if (!GuiMainWindow::pointer()->physicalTypeDefined(BC
.getType())) {
309 msg
= "boundary code " + msg
+ " has not been properly defined";
313 for (vtkIdType id_cell
= 0; id_cell
< grid
->GetNumberOfCells(); ++id_cell
) {
314 if (isSurface(id_cell
, grid
)) {
315 if (cell_code
->GetValue(id_cell
) == bc
) {
316 n
+= GeometryTools::cellNormal(grid
, id_cell
);
322 PhysicalBoundaryCondition PBC
= GuiMainWindow::pointer()->getPhysicalBoundaryCondition(BC
.getType());
323 U_buffer
+= " " + BC
.getName() + "\n {\n" + PBC
.getFoamU(n
) + " }\n";
324 p_buffer
+= " " + BC
.getName() + "\n {\n" + PBC
.getFoamP() + " }\n";
325 T_buffer
+= " " + BC
.getName() + "\n {\n" + PBC
.getFoamT() + " }\n";
326 k_buffer
+= " " + BC
.getName() + "\n {\n" + PBC
.getFoamK() + " }\n";
327 epsilon_buffer
+= " " + BC
.getName() + "\n {\n" + PBC
.getFoamEpsilon() + " }\n";
328 omega_buffer
+= " " + BC
.getName() + "\n {\n" + PBC
.getFoamOmega() + " }\n";
330 upateVarFile("U", U_buffer
);
331 upateVarFile("p", p_buffer
);
332 upateVarFile("T", T_buffer
);
333 upateVarFile("k", k_buffer
);
334 upateVarFile("epsilon", epsilon_buffer
);
335 upateVarFile("omega", omega_buffer
);
338 void OpenFOAMcase::operate()
341 if ( getFileName() == "" ) {
342 readOutputDirectory();
345 writeSolverParameters();
346 bool has_volume
= false;
347 for (vtkIdType id_cell
= 0; id_cell
< grid
->GetNumberOfCells(); ++id_cell
) {
348 if (isVolume(id_cell
, grid
)) {
353 SimpleFoamWriter::operateOnGivenFileName();
355 rewriteBoundaryFaces();
357 writeBoundaryConditions();
360 catch ( Error err
) {