1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + This file is part of enGrid. +
5 // + Copyright 2008-2014 enGits GmbH +
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. +
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. +
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/>. +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 #include "guieditboundaryconditions.h"
24 #include "guimainwindow.h"
25 #include "volumedefinition.h"
26 #include "filetemplate.h"
27 #include "physicalboundarycondition.h"
28 #include "multipagewidget.h"
29 #include "multipagewidgetpage.h"
31 #include <QVBoxLayout>
34 GuiEditBoundaryConditions::GuiEditBoundaryConditions()
36 connect(m_Ui
.pushButtonAdd
, SIGNAL(clicked()), this, SLOT(addVol()));
37 connect(m_Ui
.pushButtonDelete
, SIGNAL(clicked()), this, SLOT(delVol()));
38 connect(m_Ui
.pushButtonAddBoundaryType
, SIGNAL(clicked()), this, SLOT(addBoundaryType()));
39 connect(m_Ui
.pushButtonDeleteBoundaryType
, SIGNAL(clicked()), this, SLOT(deleteBoundaryType()));
40 connect(m_Ui
.listWidgetBoundaryType
, SIGNAL(itemSelectionChanged()), this, SLOT(changePhysicalValues()));
41 connect(m_Ui
.pushButton_AddProcess
, SIGNAL(clicked()), this, SLOT(addProcess()));
42 connect(m_Ui
.pushButton_RemoveProcess
, SIGNAL(clicked()), this, SLOT(deleteProcess()));
43 connect(m_Ui
.pushButton_ImportHostFile
, SIGNAL(clicked()), this, SLOT(importHostFile()));
44 connect(m_Ui
.pushButton_ExportHostFile
, SIGNAL(clicked()), this, SLOT(exportHostFile()));
45 connect(m_Ui
.pushButtonAllA
, SIGNAL(clicked()), this, SLOT(allA()));
46 connect(m_Ui
.pushButtonAllB
, SIGNAL(clicked()), this, SLOT(allB()));
47 connect(m_Ui
.pushButtonAllOff
, SIGNAL(clicked()), this, SLOT(allOff()));
53 delegate
= new GuiVolumeDelegate();
54 delegate
->setFirstCol(3);
57 m_Ui
.tabWidget
->setCurrentIndex(0);
60 GuiEditBoundaryConditions::~GuiEditBoundaryConditions()
65 void GuiEditBoundaryConditions::before()
68 resetOrientation(m_Grid
);
69 while (m_Ui
.T
->rowCount()) m_Ui
.T
->removeRow(0);
70 foreach(int i
, m_BoundaryCodes
) {
71 BoundaryCondition bc
= (*m_BcMap
)[i
];
72 m_Ui
.T
->insertRow(m_Ui
.T
->rowCount());
73 int r
= m_Ui
.T
->rowCount() - 1;
74 m_Ui
.T
->setItem(r
, 0, new QTableWidgetItem());
75 m_Ui
.T
->item(r
, 0)->setFlags(m_Ui
.T
->item(r
, 0)->flags() & (~Qt::ItemIsSelectable
));
76 m_Ui
.T
->item(r
, 0)->setFlags(m_Ui
.T
->item(r
, 0)->flags() & (~Qt::ItemIsEditable
));
77 m_Ui
.T
->setItem(r
, 1, new QTableWidgetItem());
78 m_Ui
.T
->setItem(r
, 2, new QTableWidgetItem());
81 m_Ui
.T
->item(r
, 0)->setText(idx
);
82 QString name
= bc
.getName();
83 if (name
== "unknown") name
= QString("BC") + idx
;
84 m_Ui
.T
->item(r
, 1)->setText(name
);
85 m_Ui
.T
->item(r
, 2)->setText(bc
.getType());
89 updatePhysicalBoundaryConditions();
91 m_Ui
.T
->setItemDelegate(delegate
);
94 void GuiEditBoundaryConditions::operate()
96 // BoundaryCondition and VolumeDefinition
97 QVector
<VolumeDefinition
> vols(m_Ui
.T
->columnCount());
98 for (int j
= 3; j
< m_Ui
.T
->columnCount(); ++j
) {
99 QString vol_name
= m_Ui
.T
->horizontalHeaderItem(j
)->text();
100 VolumeDefinition
V(vol_name
, j
- 2);
103 for (int i
= 0; i
< m_Ui
.T
->rowCount(); ++i
) {
104 int bc
= m_Ui
.T
->item(i
, 0)->text().toInt();
105 BoundaryCondition
BC(m_Ui
.T
->item(i
, 1)->text(), m_Ui
.T
->item(i
, 2)->text(), bc
);
107 for (int j
= 3; j
< m_Ui
.T
->columnCount(); ++j
) {
108 QString vol_name
= m_Ui
.T
->horizontalHeaderItem(j
)->text();
109 VolumeDefinition V
= vols
[j
];
110 if (m_Ui
.T
->item(i
, j
)->text() == "A <<") V
.addBC(bc
, 1);
111 else if (m_Ui
.T
->item(i
, j
)->text() == ">> B") V
.addBC(bc
, -1);
116 QList
<VolumeDefinition
> vol_list
;
117 for (int j
= 3; j
< m_Ui
.T
->columnCount(); ++j
) {
118 vol_list
.append(vols
[j
]);
120 GuiMainWindow::pointer()->setAllVols(vol_list
);
122 // PhysicalBoundaryConditions
123 savePhysicalValues();
124 GuiMainWindow::pointer()->setAllPhysicalBoundaryConditions(m_PhysicalBoundaryConditionsMap
);
126 saveSolverParameters();
131 //==========================
133 void GuiEditBoundaryConditions::updateVol()
135 while (m_Ui
.T
->columnCount() > 3) {
136 m_Ui
.T
->removeColumn(3);
138 QList
<VolumeDefinition
> vols
= GuiMainWindow::pointer()->getAllVols();
139 foreach(VolumeDefinition V
, vols
) {
140 m_VolMap
[V
.getName()] = V
;
141 int c
= m_Ui
.T
->columnCount();
142 m_Ui
.T
->insertColumn(c
);
143 m_Ui
.T
->setHorizontalHeaderItem(c
, new QTableWidgetItem(V
.getName()));
144 for (int i
= 0; i
< m_Ui
.T
->rowCount(); ++i
) {
145 int bc
= m_Ui
.T
->item(i
, 0)->text().toInt();
146 if (V
.getSign(bc
) == 1) m_Ui
.T
->setItem(i
, c
, new QTableWidgetItem("A <<"));
147 else if (V
.getSign(bc
) == -1) m_Ui
.T
->setItem(i
, c
, new QTableWidgetItem(">> B"));
148 else m_Ui
.T
->setItem(i
, c
, new QTableWidgetItem(" "));
153 void GuiEditBoundaryConditions::addVol()
155 cout
<< "Adding volume" << endl
;
156 QString name
= m_Ui
.lineEditVolume
->text();
157 if (!name
.isEmpty() && !m_VolMap
.contains(name
)) {
158 VolumeDefinition
NV(name
, m_Ui
.T
->columnCount() - 2);
159 m_VolMap
[NV
.getName()] = NV
;
160 int c
= m_Ui
.T
->columnCount();
161 m_Ui
.T
->insertColumn(c
);
162 m_Ui
.T
->setHorizontalHeaderItem(c
, new QTableWidgetItem(NV
.getName()));
163 for (int i
= 0; i
< m_Ui
.T
->rowCount(); ++i
) {
164 int bc
= m_Ui
.T
->item(i
, 0)->text().toInt();
165 if (NV
.getSign(bc
) == 1) m_Ui
.T
->setItem(i
, c
, new QTableWidgetItem("A <<"));
166 else if (NV
.getSign(bc
) == -1) m_Ui
.T
->setItem(i
, c
, new QTableWidgetItem(">> B"));
167 else m_Ui
.T
->setItem(i
, c
, new QTableWidgetItem(" "));
172 void GuiEditBoundaryConditions::delVol()
174 cout
<< "Deleting volume" << endl
;
175 int col
= m_Ui
.T
->currentColumn();
176 cout
<< "col=" << col
<< endl
;
178 QString name
= m_Ui
.T
->horizontalHeaderItem(col
)->text();
179 cout
<< "name=" << qPrintable(name
) << endl
;
180 m_VolMap
.remove(name
);
181 m_Ui
.T
->removeColumn(col
);
183 cout
<< "Nothing to delete." << endl
;
187 void GuiEditBoundaryConditions::allA()
189 int col
= m_Ui
.T
->currentColumn();
191 for (int i
= 0; i
< m_Ui
.T
->rowCount(); ++i
) {
192 QTableWidgetItem
*item
= m_Ui
.T
->item(i
, col
);
194 item
->setText("A <<");
200 void GuiEditBoundaryConditions::allB()
202 int col
= m_Ui
.T
->currentColumn();
204 for (int i
= 0; i
< m_Ui
.T
->rowCount(); ++i
) {
205 QTableWidgetItem
*item
= m_Ui
.T
->item(i
, col
);
207 item
->setText(">> B");
213 void GuiEditBoundaryConditions::allOff()
215 int col
= m_Ui
.T
->currentColumn();
217 for (int i
= 0; i
< m_Ui
.T
->rowCount(); ++i
) {
218 QTableWidgetItem
*item
= m_Ui
.T
->item(i
, col
);
226 //==========================
228 void GuiEditBoundaryConditions::loadPhysicalValues()
230 while (m_Ui
.tableWidgetPBC
->rowCount()) {
231 m_Ui
.tableWidgetPBC
->removeRow(0);
233 for (int i
= 0; i
< m_PBC_current
.getNumVars(); ++i
) {
234 QString str
= m_PBC_current
.getVarValueAsString(i
);
235 m_Ui
.tableWidgetPBC
->insertRow(m_Ui
.tableWidgetPBC
->rowCount());
236 int r
= m_Ui
.tableWidgetPBC
->rowCount() - 1;
237 m_Ui
.tableWidgetPBC
->setItem(r
, 0, new QTableWidgetItem());
238 m_Ui
.tableWidgetPBC
->item(r
, 0)->setFlags(m_Ui
.tableWidgetPBC
->item(r
, 0)->flags() & (~Qt::ItemIsSelectable
));
239 m_Ui
.tableWidgetPBC
->item(r
, 0)->setFlags(m_Ui
.tableWidgetPBC
->item(r
, 0)->flags() & (~Qt::ItemIsEditable
));
240 m_Ui
.tableWidgetPBC
->setItem(r
, 1, new QTableWidgetItem());
241 m_Ui
.tableWidgetPBC
->item(r
, 1)->setFlags(m_Ui
.tableWidgetPBC
->item(r
, 0)->flags() & (~Qt::ItemIsSelectable
));
242 m_Ui
.tableWidgetPBC
->item(r
, 1)->setFlags(m_Ui
.tableWidgetPBC
->item(r
, 0)->flags() & (~Qt::ItemIsEditable
));
243 m_Ui
.tableWidgetPBC
->setItem(r
, 2, new QTableWidgetItem());
244 m_Ui
.tableWidgetPBC
->item(r
, 0)->setText(m_PBC_current
.getVarType(i
));
245 m_Ui
.tableWidgetPBC
->item(r
, 1)->setText(m_PBC_current
.getVarName(i
));
246 m_Ui
.tableWidgetPBC
->item(r
, 2)->setText(str
);
248 m_Ui
.tableWidgetPBC
->resizeColumnsToContents();
251 void GuiEditBoundaryConditions::savePhysicalValues()
253 if(m_PhysicalBoundaryConditionsMap
.keys().contains(m_PBC_current
.getName())) {
254 for (int i
= 0; i
< m_PBC_current
.getNumVars(); ++i
) {
255 m_PBC_current
.setValueFromString(i
, m_Ui
.tableWidgetPBC
->item(i
, 2)->text());
257 m_PhysicalBoundaryConditionsMap
[m_PBC_current
.getName()] = m_PBC_current
;
261 void GuiEditBoundaryConditions::changePhysicalValues()
263 if (m_Ui
.listWidgetBoundaryType
->count() > 0) {
264 int index
= m_Ui
.listWidgetBoundaryType
->currentRow();
265 QString name
= m_Ui
.listWidgetBoundaryType
->currentItem()->text();
266 savePhysicalValues();
267 if(m_PhysicalBoundaryConditionsMap
.contains(name
)) {
268 m_PBC_current
= m_PhysicalBoundaryConditionsMap
[name
];
269 m_PBC_current
.setIndex(index
);
272 loadPhysicalValues();
276 void GuiEditBoundaryConditions::addBoundaryType()
278 QString name
= m_Ui
.lineEditBoundaryType
->text();
279 if (!name
.isEmpty() && !m_PhysicalBoundaryConditionsMap
.contains(name
)) {
280 PhysicalBoundaryCondition PBC
;
281 PBC
.setName(m_Ui
.lineEditBoundaryType
->text());
282 PBC
.setIndex(m_Ui
.listWidgetBoundaryType
->count());
283 PBC
.setType(m_Ui
.comboBoxBoundaryType
->currentText().replace(" ", "-"));
284 m_PhysicalBoundaryConditionsMap
[PBC
.getName()] = PBC
;
285 m_Ui
.listWidgetBoundaryType
->addItem(PBC
.getName());
289 void GuiEditBoundaryConditions::deleteBoundaryType()
291 int row
= m_Ui
.listWidgetBoundaryType
->currentRow();
292 if (m_Ui
.listWidgetBoundaryType
->count() <= 1) {
293 m_Ui
.listWidgetBoundaryType
->clear();
294 m_PhysicalBoundaryConditionsMap
.clear();
296 else if (0 <= row
&& row
< m_Ui
.listWidgetBoundaryType
->count()) {
297 QListWidgetItem
* list_widget_item
= m_Ui
.listWidgetBoundaryType
->takeItem(row
);
298 m_PhysicalBoundaryConditionsMap
.remove(list_widget_item
->text());
299 delete list_widget_item
;
303 void GuiEditBoundaryConditions::updatePhysicalBoundaryConditions()
306 m_Ui
.listWidgetBoundaryType
->clear();
309 QList
<PhysicalBoundaryCondition
> physical_boundary_conditions
= GuiMainWindow::pointer()->getAllPhysicalBoundaryConditions();
310 foreach(PhysicalBoundaryCondition PBC
, physical_boundary_conditions
) {
311 m_Ui
.listWidgetBoundaryType
->addItem(PBC
.getName());
312 m_PhysicalBoundaryConditionsMap
[PBC
.getName()] = PBC
;
315 // select and load first item
316 if (m_Ui
.listWidgetBoundaryType
->count() > 0) {
317 m_Ui
.listWidgetBoundaryType
->setCurrentRow(0);
318 QString name
= m_Ui
.listWidgetBoundaryType
->currentItem()->text();
319 if(m_PhysicalBoundaryConditionsMap
.contains(name
)) {
320 m_PBC_current
= m_PhysicalBoundaryConditionsMap
[name
];
321 m_PBC_current
.setIndex(0);
324 loadPhysicalValues();
328 //==========================
330 void GuiEditBoundaryConditions::setupSolvers()
332 m_multipagewidget_Solver
= new MultiPageWidget(m_Ui
.tab_Solver
);
333 m_multipagewidget_Solver
->setObjectName(QString::fromUtf8("m_multipagewidget_Solver"));
334 m_Ui
.verticalLayout_Solver
->addWidget(m_multipagewidget_Solver
);
337 fileinfo
.setFile(":/resources/solvers/solvers.txt");
338 QFile
file(fileinfo
.filePath());
339 if (!file
.exists()) {
340 qDebug() << "ERROR: " << fileinfo
.filePath() << " not found.";
343 if (!file
.open(QIODevice::ReadOnly
| QIODevice::Text
)) {
344 qDebug() << "ERROR: Failed to open file " << fileinfo
.filePath();
347 QTextStream
text_stream(&file
);
348 QString intext
= text_stream
.readAll();
351 ///\todo Create a special parser method for this so that it can be reused by other classes
353 QStringList page_list
= intext
.split("=");
354 foreach(QString page
, page_list
) {
358 QVector
<QString
> files
;
359 QStringList variable_list
= page
.split(";");
360 foreach(QString variable
, variable_list
) {
361 QStringList name_value
= variable
.split(":");
362 if (name_value
[0].trimmed() == "title") title
= name_value
[1].trimmed();
363 if (name_value
[0].trimmed() == "section") section
= name_value
[1].trimmed();
364 if (name_value
[0].trimmed() == "binary") binary
= name_value
[1].trimmed();
365 if (name_value
[0].trimmed() == "files") {
366 QStringList file_list
= name_value
[1].split(",");
367 foreach(QString file
, file_list
) {
368 files
.push_back(":/resources/solvers/" + section
+ "/" + file
.trimmed());
373 m_SolverBinary
.push_back(binary
);
374 MultiPageWidgetPage
* widget_page
= new MultiPageWidgetPage(files
, section
, m_multipagewidget_Solver
);
375 m_page_vector
.push_back(widget_page
);
376 m_multipagewidget_Solver
->addPage((QWidget
*) widget_page
);
377 m_multipagewidget_Solver
->setPageTitle(title
, idx
);
382 m_multipagewidget_Solver
->setCurrentIndex(GuiMainWindow::pointer()->getXmlSection("solver/general/solver_type").toInt());
385 void GuiEditBoundaryConditions::saveSolverParameters()
387 //Save solver parameters
388 for (int i
= 0; i
< m_page_vector
.size(); i
++) {
389 m_page_vector
[i
]->saveEgc();
392 int solver_type_index
= m_multipagewidget_Solver
->currentIndex();
393 solver_type
.setNum(solver_type_index
);
394 GuiMainWindow::pointer()->setXmlSection("solver/general/solver_type", solver_type
);
395 GuiMainWindow::pointer()->setXmlSection("solver/general/solver_binary", m_SolverBinary
[solver_type_index
]);
398 //==========================
400 void GuiEditBoundaryConditions::addProcess()
402 int row
= m_Ui
.tableWidget_Processes
->currentRow();
403 QString host
, weight
;
410 host
= m_Ui
.tableWidget_Processes
->item(row
, 0)->text();
411 weight
= m_Ui
.tableWidget_Processes
->item(row
, 1)->text();
413 qDebug()<<"row="<<row
;
414 m_Ui
.tableWidget_Processes
->insertRow(row
);
415 m_Ui
.tableWidget_Processes
->setItem(row
, 0, new QTableWidgetItem());
416 m_Ui
.tableWidget_Processes
->setItem(row
, 1, new QTableWidgetItem());
417 m_Ui
.tableWidget_Processes
->item(row
, 0)->setText(host
);
418 m_Ui
.tableWidget_Processes
->item(row
, 1)->setText(weight
);
419 m_Ui
.tableWidget_Processes
->resizeColumnsToContents();
422 void GuiEditBoundaryConditions::deleteProcess()
424 m_Ui
.tableWidget_Processes
->removeRow(m_Ui
.tableWidget_Processes
->currentRow());
427 void GuiEditBoundaryConditions::importHostFile()
432 void GuiEditBoundaryConditions::exportHostFile()
437 void GuiEditBoundaryConditions::loadMpiParameters()
439 QString hostfile_txt
= GuiMainWindow::pointer()->getXmlSection( "solver/general/host_weight_list" );
440 stringToTable(hostfile_txt
);
443 void GuiEditBoundaryConditions::saveMpiParameters()
445 QString hostfile_txt
= tableToString();
446 GuiMainWindow::pointer()->setXmlSection( "solver/general/host_weight_list", hostfile_txt
);
449 QString
GuiEditBoundaryConditions::tableToString()
451 QString hostfile_txt
;
452 for(int row
= 0; row
< m_Ui
.tableWidget_Processes
->rowCount(); row
++) {
453 QString host
, weight
;
454 host
= m_Ui
.tableWidget_Processes
->item(row
, 0)->text();
455 weight
= m_Ui
.tableWidget_Processes
->item(row
, 1)->text();
456 hostfile_txt
+= host
+ ":" + weight
;
457 if(row
!=m_Ui
.tableWidget_Processes
->rowCount()-1) hostfile_txt
+= ",";
459 return(hostfile_txt
);
462 void GuiEditBoundaryConditions::stringToTable(QString hostfile_txt
)
464 QVector
<QString
> host
;
465 QVector
<QString
> weight
;
467 QStringList host_weight_list
= hostfile_txt
.split(",");
468 foreach(QString host_weight
, host_weight_list
) {
469 if(!host_weight
.isEmpty()){
470 QStringList values
= host_weight
.split(":");
471 // qWarning()<<"values="<<values;
472 host
.push_back(values
[0].trimmed());
473 weight
.push_back(values
[1].trimmed());
477 while (m_Ui
.tableWidget_Processes
->rowCount()) {
478 m_Ui
.tableWidget_Processes
->removeRow(0);
481 for(int i
= 0; i
< host
.size(); i
++) {
482 int row
= m_Ui
.tableWidget_Processes
->rowCount();
483 m_Ui
.tableWidget_Processes
->insertRow(row
);
484 m_Ui
.tableWidget_Processes
->setItem(row
, 0, new QTableWidgetItem());
485 m_Ui
.tableWidget_Processes
->setItem(row
, 1, new QTableWidgetItem());
486 m_Ui
.tableWidget_Processes
->item(row
, 0)->setText(host
[i
]);
487 m_Ui
.tableWidget_Processes
->item(row
, 1)->setText(weight
[i
]);
488 m_Ui
.tableWidget_Processes
->resizeColumnsToContents();