Now working on solving models

This commit is contained in:
J.A. de Jong @ vulgaris 2017-01-02 22:46:22 +01:00
parent 938fb28e94
commit 119214800d
9 changed files with 233 additions and 98 deletions

View File

@ -131,5 +131,6 @@ add_subdirectory(src)
add_subdirectory(testing) add_subdirectory(testing)
add_executable(tasmet src/main.cpp src/gui/tasmet_resources.qrc) add_executable(tasmet src/main.cpp src/gui/tasmet_resources.qrc)
add_executable(tasmet_solvemodel src/tasmet_solvemodel.cpp)
target_link_libraries(tasmet tasmet_gui tasmet_src messages PythonQt Qt5::Widgets openblas) target_link_libraries(tasmet tasmet_gui tasmet_src messages PythonQt Qt5::Widgets openblas)
target_link_libraries(tasmet_solvemodel tasmet_src messages PythonQt openblas)

View File

@ -32,6 +32,8 @@ add_library(tasmet_src
tasmet_assert.cpp tasmet_assert.cpp
tasmet_pyeval.cpp tasmet_pyeval.cpp
protobuf/system_tools.cpp
duct/grid.cpp duct/grid.cpp
duct/geom.cpp duct/geom.cpp
duct/duct.cpp duct/duct.cpp

View File

@ -14,7 +14,7 @@ Duct::Duct(const us id,const pb::Duct& duct):
Segment(id,duct.name()), Segment(id,duct.name()),
Geom(duct) Geom(duct)
{ {
TRACE(15,"Duct::Duct()");
const char* invTsfun = "Invalid solid-temperature prescribing function"; const char* invTsfun = "Invalid solid-temperature prescribing function";
EvaluateFun Tsfun(duct.stempfunc(),invTsfun); EvaluateFun Tsfun(duct.stempfunc(),invTsfun);
Tsfun.addGlobalDef("L",duct.length()); Tsfun.addGlobalDef("L",duct.length());

View File

@ -29,9 +29,7 @@
#include "about_dialog.h" #include "about_dialog.h"
#include "solver_dialog.h" #include "solver_dialog.h"
#include "system_tools.h"
#include <google/protobuf/text_format.h>
using google::protobuf::TextFormat;
const QString default_system_name = QString("Unsaved TaSMET Model") + const QString default_system_name = QString("Unsaved TaSMET Model") +
constants::system_fileext; constants::system_fileext;
@ -41,41 +39,6 @@ const QString start_file_location = QStandardPaths::
const QString filetype = QString("TaSMET Model files (*") + constants::system_fileext + ")"; const QString filetype = QString("TaSMET Model files (*") + constants::system_fileext + ")";
const QString window_title_part = "TaSMET Model Builder - "; const QString window_title_part = "TaSMET Model Builder - ";
namespace { namespace {
pb::System loadSystem(const string& filepath) {
TRACE(15,"loadSystem()");
VARTRACE(15,filepath);
std::ifstream myfile(filepath);
if(!myfile.good()) {
string error = "Read error on ";
error += filepath;
throw TaSMETError(error);
}
pb::System sys;
std::stringstream strStream;
strStream << myfile.rdbuf(); //read the file
string data = strStream.str();//str holds the content of the file
VARTRACE(15,data);
if(!TextFormat::ParseFromString(data,&sys)) {
string error = "Invalid TaSMET Model file: ";
error += filepath;
throw TaSMETError(error);
}
return sys;
}
// // Returns true when the two systems are equal
bool compareSys(const pb::System& s1,const pb::System& s2) {
return (s1.SerializeAsString()==s2.SerializeAsString());
}
int saveFileFirstQuestion(QWidget* parent) { int saveFileFirstQuestion(QWidget* parent) {
@ -127,7 +90,7 @@ TaSMETMainWindow::TaSMETMainWindow():
_window->p0->setValidator(new QDoubleValidator(constants::min_p0, _window->p0->setValidator(new QDoubleValidator(constants::min_p0,
constants::max_p0, constants::max_p0,
constants::field_decimals)); constants::field_decimals));
_window->segmentname->setText(default_system_name); _window->segmentname->setText(default_segment_name);
_window->segmentid->setMaximum(constants::max_segs); _window->segmentid->setMaximum(constants::max_segs);
@ -160,9 +123,9 @@ void TaSMETMainWindow::loadModel() {
QString title = tr("Open existing TaSMET model file"); QString title = tr("Open existing TaSMET model file");
QString filepath = QFileDialog::getOpenFileName(this, QString filepath = QFileDialog::getOpenFileName(this,
title, title,
start_file_location, start_file_location,
filetype); filetype);
string filepath_s = filepath.toStdString(); string filepath_s = filepath.toStdString();
if(filepath.size()!=0) { if(filepath.size()!=0) {
try { try {
@ -190,35 +153,16 @@ void TaSMETMainWindow::saveModel(string* filepath) {
else if(filepath == nullptr) { else if(filepath == nullptr) {
filepath = &_filepath; filepath = &_filepath;
} }
try {
std::ofstream sfile(*filepath); saveSystem(*filepath,_system);
if(!sfile.good()){
QMessageBox::warning(this,
"File error",
"Could not open file for saving");
return;
}
string data;
if(TextFormat::PrintToString(_system,&data)) {
// Can maybe assign to itself. Which is no problem
// according to C++ docs
TRACE(15,"Saving file succeeded");
VARTRACE(15,data);
sfile << data;
// Close file here, such that in can be opened to compare
// whether the file is still dirty
sfile.close();
_filepath = *filepath; _filepath = *filepath;
changed(); changed();
} }
else { catch(TaSMETError &e) {
QMessageBox::warning(this,
"File error", e.show_user("Saving file failed");
"Could not save model to file");
} }
} }
} }
@ -276,8 +220,27 @@ void TaSMETMainWindow::changed() {
_window->segoverview->setPlainText(QString::fromStdString(_system.DebugString())); _window->segoverview->setPlainText(QString::fromStdString(_system.DebugString()));
// Update stuff based on the segments // Update stuff based on the segments
int value = _window->segmentid->value(); int segid = _window->segmentid->value();
on_segmentid_valueChanged(value);
bool is_segment = false;
auto& ductmap = *_system.mutable_ducts();
auto& ductbcmap = *_system.mutable_ductbcs();
if(ductmap.find(segid) != ductmap.end()) {
_window->segmentname->setText(QString::fromStdString(ductmap[segid].name()));
_window->segmenttype->setCurrentIndex((int) Duct);
is_segment = true;
}
if(ductbcmap.find(segid) != ductbcmap.end()) {
_window->segmentname->setText(QString::fromStdString(ductbcmap[segid].name()));
_window->segmenttype->setCurrentIndex((int) DuctBc);
is_segment = true;
}
_window->removesegment->setEnabled(is_segment);
_window->segmenttype->setEnabled(!is_segment);
} }
void TaSMETMainWindow::set(const pb::System& sys) { void TaSMETMainWindow::set(const pb::System& sys) {
@ -388,11 +351,11 @@ void TaSMETMainWindow::on_addsegment_clicked() {
} }
if(exitcode == QDialog::Accepted) { if(exitcode == QDialog::Accepted) {
_window->segmentid->setValue(id+1);
changed(); changed();
} }
} }
void TaSMETMainWindow::on_removesegment_clicked() { void TaSMETMainWindow::on_removesegment_clicked() {
TRACE(15,"on_remove"); TRACE(15,"on_remove");
QString question = "Are you you wish to delete segment "; QString question = "Are you you wish to delete segment ";
@ -411,27 +374,8 @@ void TaSMETMainWindow::on_removesegment_clicked() {
} }
} }
void TaSMETMainWindow::on_segmentid_valueChanged(int id) { void TaSMETMainWindow::on_segmentname_textChanged() {
if(_init) return;
auto& ductmap = *_system.mutable_ducts();
auto& ductbcmap = *_system.mutable_ductbcs();
bool is_segment = false;
if(ductmap.find(id) != ductmap.end()) {
_window->segmentname->setText(QString::fromStdString(ductmap[id].name()));
is_segment = true;
}
if(ductbcmap.find(id) != ductbcmap.end()) {
_window->segmentname->setText(QString::fromStdString(ductbcmap[id].name()));
is_segment = true;
}
_window->removesegment->setEnabled(is_segment);
}
void TaSMETMainWindow::on_segmentname_textEdited() {
auto& ductmap = *_system.mutable_ducts(); auto& ductmap = *_system.mutable_ducts();
auto& ductbcmap = *_system.mutable_ductbcs(); auto& ductbcmap = *_system.mutable_ductbcs();
@ -443,7 +387,7 @@ void TaSMETMainWindow::on_segmentname_textEdited() {
if(ductbcmap.find(id) != ductbcmap.end()) { if(ductbcmap.find(id) != ductbcmap.end()) {
ductbcmap[id].set_name(_window->segmentname->text().toStdString()); ductbcmap[id].set_name(_window->segmentname->text().toStdString());
} }
changed();
} }
void TaSMETMainWindow::on_actionSolve_triggered() { void TaSMETMainWindow::on_actionSolve_triggered() {

View File

@ -53,8 +53,8 @@ private slots:
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
void on_addsegment_clicked(); void on_addsegment_clicked();
void on_removesegment_clicked(); void on_removesegment_clicked();
void on_segmentid_valueChanged(int i); void on_segmentid_valueChanged(int i) {changed();}
void on_segmentname_textEdited(); void on_segmentname_textChanged();
// Couple slots to functions // Couple slots to functions
void on_actionNew_triggered() { newModel();} void on_actionNew_triggered() { newModel();}

View File

@ -80,16 +80,23 @@ SolverDialog::SolverDialog(QWidget* parent,
QSharedPointer<QCPAxisTicker> ticker(new QCPAxisTickerLog()); QSharedPointer<QCPAxisTicker> ticker(new QCPAxisTickerLog());
_plot->yAxis->setTicker(ticker); _plot->yAxis->setTicker(ticker);
// Toggle legend
_plot->legend->setVisible(true); _plot->legend->setVisible(true);
_plot->replot(); _plot->replot();
set(_sys.solverparams()); set(_sys.solverparams());
setEnabled(true);
_init = false; _init = false;
} }
SolverDialog::~SolverDialog() { SolverDialog::~SolverDialog() {
if(_solver_worker) if(_solver_worker) {
// deleteLater is called on this one, so no delete here
_solver_worker->solver_stop(); _solver_worker->solver_stop();
}
} }
void SolverDialog::set(const pb::SolverParams& sol) { void SolverDialog::set(const pb::SolverParams& sol) {
TRACE(15,"set"); TRACE(15,"set");
@ -104,6 +111,7 @@ void SolverDialog::set(const pb::SolverParams& sol) {
} }
void SolverDialog::changed() { void SolverDialog::changed() {
TRACE(15,"changed");
if(_init) return; if(_init) return;
_sys.mutable_solverparams()->set_funtol(_dialog->funtol->text().toDouble()); _sys.mutable_solverparams()->set_funtol(_dialog->funtol->text().toDouble());
_sys.mutable_solverparams()->set_reltol(_dialog->reltol->text().toDouble()); _sys.mutable_solverparams()->set_reltol(_dialog->reltol->text().toDouble());
@ -113,7 +121,6 @@ void SolverDialog::solver_progress(const SolverProgress& progress){
TRACE(15,"SolverDialog::solver_progress()"); TRACE(15,"SolverDialog::solver_progress()");
// VARTRACE(15,progress.fun_err); // VARTRACE(15,progress.fun_err);
// VARTRACE(15,progress.iteration); // VARTRACE(15,progress.iteration);
d funtol = _sys.solverparams().funtol(); d funtol = _sys.solverparams().funtol();
@ -141,6 +148,14 @@ void SolverDialog::on_solve_clicked() {
// Disable buttons // Disable buttons
setEnabled(false); setEnabled(false);
// Clear figure data
QVector<double> empty;
_funer->setData(empty,empty);
_reler->setData(empty,empty);
_funtol->setData(empty,empty);
_reltol->setData(empty,empty);
assert(!_solver_worker); assert(!_solver_worker);
qRegisterMetaType<SolverProgress>(); qRegisterMetaType<SolverProgress>();

View File

@ -0,0 +1,76 @@
// system_tools.cpp
//
// last-edit-by: J.A. de Jong
//
// Description:
//
//////////////////////////////////////////////////////////////////////
#include "system_tools.h"
#include <fstream>
#include <google/protobuf/text_format.h>
#include "tasmet_types.h"
#include "tasmet_io.h"
#include "tasmet_exception.h"
#include <google/protobuf/text_format.h>
using google::protobuf::TextFormat;
pb::System loadSystem(const string& filepath) {
TRACE(15,"loadSystem()");
VARTRACE(15,filepath);
std::ifstream myfile(filepath,ios::binary);
if(!myfile.good()) {
string error = "Read error on ";
error += filepath;
throw TaSMETError(error);
}
pb::System sys;
std::stringstream strStream;
strStream << myfile.rdbuf(); //read the file
string data = strStream.str();//str holds the content of the file
if(!TextFormat::ParseFromString(data,&sys)) {
string error = "Invalid TaSMET Model file: ";
error += filepath;
throw TaSMETError(error);
}
return sys;
}
void saveSystem(const string& filepath,const pb::System& sys) {
std::ofstream sfile(filepath,ios::binary);
if(!sfile.good()){
throw TaSMETError("Could not write to file");
}
string data;
if(TextFormat::PrintToString(sys,&data)) {
// Can maybe assign to itself. Which is no problem
// according to C++ docs
TRACE(15,"Saving file succeeded");
sfile << data << std::flush;
// Close file here, such that in can be opened to compare
// whether the file is still dirty
sfile.close();
}
else {
throw TaSMETError("Could not save model to file");
}
}
// // Returns true when the two systems are equal
bool compareSys(const pb::System& s1,const pb::System& s2) {
return (s1.SerializeAsString()==s2.SerializeAsString());
}
//////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,27 @@
// system_tools.h
//
// Author: J.A. de Jong
//
// Description:
//
//////////////////////////////////////////////////////////////////////
#pragma once
#ifndef SYSTEM_TOOLS_H
#define SYSTEM_TOOLS_H
#include "system.pb.h"
#include "tasmet_tracer.h"
#include "tasmet_types.h"
// Load a system from a filepath
pb::System loadSystem(const string& filepath);
// Save a system to a filepath
void saveSystem(const string& filepath,const pb::System& sys);
// Returns true when the two systems are equal
bool compareSys(const pb::System& s1,const pb::System& s2);
#endif // SYSTEM_TOOLS_H
//////////////////////////////////////////////////////////////////////

70
src/tasmet_solvemodel.cpp Normal file
View File

@ -0,0 +1,70 @@
// tasmet_solvemodel.cpp
//
// last-edit-by: J.A. de Jong
//
// Description:
// Program which can be used to solve a TaSMET Model from the CLI
//////////////////////////////////////////////////////////////////////
#include "protobuf/system_tools.h" // loadSystem, saveSystem
#include "tasmet_io.h"
#include "tasmet_exception.h"
#include "sys/tasystem.h"
// For using python from within Qt
#include <PythonQt.h>
void usage(const char* fn) {
cout << "Usage: " << endl;
cout << fn << " [Input file] " << endl;
}
int main(int argc, char *argv[]) {
INITTRACE(10);
// Initialize PythonQt
// PythonQt::init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut);
PythonQt::init();
PythonQt* pyqt = PythonQt::self();
PythonQtObjectPtr context = pyqt->getMainModule();
QVariant rv = context.evalScript("from math import *\n");
if(pyqt->hadError()) {
return -1;
}
if(argc != 2) {
usage(argv[0]);
return -1;
}
pb::System sys;
string filename = argv[1];
try {
sys = loadSystem(filename);
}
catch(TaSMETError &e) {
cerr << e.what() << endl;
return -1;
}
cout << "Loaded model: " << endl;
cout << sys.DebugString();
TaSystem* system;
try {
system = new TaSystem(sys);
}
catch(TaSMETError &e) {
cerr << "Model initialization error: " << endl;
cerr << e.what() << endl;
return -1;
}
}
//////////////////////////////////////////////////////////////////////