Almost finished solver. Plot update needs to run in main thread. Use signaling for progress
This commit is contained in:
parent
cdc144e7d6
commit
9955c37a93
@ -7,6 +7,8 @@ add_library(tasmet_gui
|
|||||||
add_duct_dialog.cpp
|
add_duct_dialog.cpp
|
||||||
add_ductbc_dialog.cpp
|
add_ductbc_dialog.cpp
|
||||||
about_dialog.cpp
|
about_dialog.cpp
|
||||||
|
solver_dialog.cpp
|
||||||
|
solver_worker.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(tasmet_gui qcustomplot)
|
target_link_libraries(tasmet_gui qcustomplot)
|
||||||
|
@ -7,26 +7,30 @@
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "tasmet_config.h"
|
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QDoubleValidator>
|
#include <QDoubleValidator>
|
||||||
#include <QIntValidator>
|
#include <QIntValidator>
|
||||||
#include "gas.h"
|
#include <QFileDialog>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
|
#include "tasmet_config.h"
|
||||||
#include "tasmet_tracer.h"
|
#include "tasmet_tracer.h"
|
||||||
#include "tasmet_assert.h"
|
#include "tasmet_assert.h"
|
||||||
|
#include "tasmet_exception.h"
|
||||||
#include "add_duct_dialog.h"
|
#include "add_duct_dialog.h"
|
||||||
#include "add_ductbc_dialog.h"
|
#include "add_ductbc_dialog.h"
|
||||||
#include "tasystem.h"
|
#include "tasystem.h"
|
||||||
#include "tasmet_exception.h"
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QStandardPaths>
|
|
||||||
#include <sstream>
|
|
||||||
#include "about_dialog.h"
|
|
||||||
#include <google/protobuf/text_format.h>
|
|
||||||
|
|
||||||
|
#include "about_dialog.h"
|
||||||
|
#include "solver_dialog.h"
|
||||||
|
|
||||||
|
#include <google/protobuf/text_format.h>
|
||||||
using google::protobuf::TextFormat;
|
using google::protobuf::TextFormat;
|
||||||
|
|
||||||
const QString default_system_name = QString("Unsaved TaSMET Model") +
|
const QString default_system_name = QString("Unsaved TaSMET Model") +
|
||||||
@ -426,7 +430,7 @@ void TaSMETMainWindow::on_segmentid_valueChanged(int id) {
|
|||||||
_window->removesegment->setEnabled(is_segment);
|
_window->removesegment->setEnabled(is_segment);
|
||||||
|
|
||||||
}
|
}
|
||||||
void TaSMETMainWindow::on_name_textEdited() {
|
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();
|
||||||
@ -444,8 +448,22 @@ void TaSMETMainWindow::on_name_textEdited() {
|
|||||||
|
|
||||||
void TaSMETMainWindow::on_actionSolve_triggered() {
|
void TaSMETMainWindow::on_actionSolve_triggered() {
|
||||||
TRACE(15,"actionSolve()");
|
TRACE(15,"actionSolve()");
|
||||||
TaSystem sys(_system);
|
|
||||||
|
SolverDialog *d;
|
||||||
|
try {
|
||||||
|
d = new SolverDialog(this,_system);
|
||||||
|
}
|
||||||
|
catch(TaSMETError &e) {
|
||||||
|
e.show_user("Solver failed to initialize");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
d->exec();
|
||||||
|
|
||||||
|
// Solution is put in system, system updated from solver
|
||||||
|
// dialog. Therefore we are now probably dirty
|
||||||
|
changed();
|
||||||
|
|
||||||
|
delete d;
|
||||||
}
|
}
|
||||||
bool TaSMETMainWindow::isDirty() const {
|
bool TaSMETMainWindow::isDirty() const {
|
||||||
TRACE(15,"isDirty()");
|
TRACE(15,"isDirty()");
|
||||||
|
@ -54,7 +54,7 @@ private slots:
|
|||||||
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);
|
||||||
void on_name_textEdited();
|
void on_segmentname_textEdited();
|
||||||
|
|
||||||
// Couple slots to functions
|
// Couple slots to functions
|
||||||
void on_actionNew_triggered() { newModel();}
|
void on_actionNew_triggered() { newModel();}
|
||||||
|
@ -347,6 +347,8 @@
|
|||||||
<string>Solver</string>
|
<string>Solver</string>
|
||||||
</property>
|
</property>
|
||||||
<addaction name="actionSolve"/>
|
<addaction name="actionSolve"/>
|
||||||
|
<addaction name="actionReinitialize_solver"/>
|
||||||
|
<addaction name="actionPosprocess_model"/>
|
||||||
</widget>
|
</widget>
|
||||||
<addaction name="menuFile"/>
|
<addaction name="menuFile"/>
|
||||||
<addaction name="menuSolver"/>
|
<addaction name="menuSolver"/>
|
||||||
@ -419,6 +421,16 @@
|
|||||||
<string>Solve...</string>
|
<string>Solve...</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionReinitialize_solver">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reinitialize solver</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionPosprocess_model">
|
||||||
|
<property name="text">
|
||||||
|
<string>Posprocess model...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="tasmet_resources.qrc"/>
|
<include location="tasmet_resources.qrc"/>
|
||||||
|
@ -1,188 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>Dialog</class>
|
|
||||||
<widget class="QDialog" name="Dialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>730</width>
|
|
||||||
<height>362</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>TaSMET Solver</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="solversettings">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Solver Settings</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_14">
|
|
||||||
<property name="text">
|
|
||||||
<string>Maximum iterations:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="label_13">
|
|
||||||
<property name="text">
|
|
||||||
<string>Solver type</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QComboBox" name="solvertype"/>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLineEdit" name="reltol">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_12">
|
|
||||||
<property name="text">
|
|
||||||
<string>Solution tolerance:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_8">
|
|
||||||
<property name="text">
|
|
||||||
<string>Residual tolerance:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="funtol">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QLineEdit" name="maxiter">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="solve_gb">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Solve!</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pushButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Solve</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pushButton_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Stop</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pushButton_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Single iteration</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="progress_gb">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Progress</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QCustomPlot" name="rel_error" native="true"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCustomPlot" name="fun_error" native="true"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>QCustomPlot</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>qcustomplot.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
133
src/gui/solver_dialog.cpp
Normal file
133
src/gui/solver_dialog.cpp
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
// solver_dialog.cpp
|
||||||
|
//
|
||||||
|
// last-edit-by: J.A. de Jong
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "solver_dialog.h"
|
||||||
|
#include "ui_solver_dialog.h"
|
||||||
|
#include "system.pb.h"
|
||||||
|
#include "tasmet_exception.h"
|
||||||
|
#include "tasmet_constants.h"
|
||||||
|
#include "tasmet_tracer.h"
|
||||||
|
#include "solver.pb.h"
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include "solver_worker.h"
|
||||||
|
|
||||||
|
SolverDialog::SolverDialog(QWidget* parent,
|
||||||
|
pb::System& sys):
|
||||||
|
QDialog(parent),
|
||||||
|
_sys(sys),
|
||||||
|
_sparams(sys.solverparams()),
|
||||||
|
_dialog(new Ui::solver_dialog())
|
||||||
|
{
|
||||||
|
|
||||||
|
TRACE(15,"SolverDialog");
|
||||||
|
if(_dialog==nullptr) throw TaSMETBadAlloc();
|
||||||
|
|
||||||
|
_dialog->setupUi(this);
|
||||||
|
|
||||||
|
_dialog->funtol->setValidator(new QDoubleValidator(constants::min_funtol,
|
||||||
|
constants::max_funtol,
|
||||||
|
constants::field_decimals));
|
||||||
|
|
||||||
|
_dialog->reltol->setValidator(new QDoubleValidator(constants::min_funtol,
|
||||||
|
constants::max_funtol,
|
||||||
|
constants::field_decimals));
|
||||||
|
|
||||||
|
// _dialog->maxiter->setValidator(new QIntValidator(constants::min_maxiter,
|
||||||
|
// constants::max_maxiter));
|
||||||
|
|
||||||
|
for(int solvertype = pb::SolverType_MIN;solvertype<=pb::SolverType_MAX;solvertype++){
|
||||||
|
_dialog->solvertype->addItem(QString::fromStdString(SolverType_Name((pb::SolverType) solvertype)));
|
||||||
|
}
|
||||||
|
|
||||||
|
_plot = _dialog->progress_plot;
|
||||||
|
_plot->xAxis->setLabel("Iteration [-]");
|
||||||
|
_plot->yAxis->setLabel("Residual [-]");
|
||||||
|
|
||||||
|
_plot->yAxis->setScaleType(QCPAxis::stLogarithmic);
|
||||||
|
|
||||||
|
QSharedPointer<QCPAxisTicker> ticker(new QCPAxisTickerLog());
|
||||||
|
_plot->yAxis->setTicker(ticker);
|
||||||
|
|
||||||
|
_plot->replot();
|
||||||
|
set(_sys.solverparams());
|
||||||
|
|
||||||
|
}
|
||||||
|
SolverDialog::~SolverDialog() {
|
||||||
|
if(_solver_worker)
|
||||||
|
_solver_worker->solver_stop();
|
||||||
|
}
|
||||||
|
void SolverDialog::set(const pb::SolverParams& sol) {
|
||||||
|
TRACE(15,"set");
|
||||||
|
|
||||||
|
_dialog->solvertype->setCurrentIndex((int) sol.solvertype());
|
||||||
|
_dialog->funtol->setText(QString::number(sol.funtol()));
|
||||||
|
_dialog->reltol->setText(QString::number(sol.reltol()));
|
||||||
|
|
||||||
|
}
|
||||||
|
void SolverDialog::changed() {
|
||||||
|
|
||||||
|
}
|
||||||
|
void SolverDialog::on_stop_clicked(){
|
||||||
|
tasmet_assert(_solver_worker!=nullptr,"No _solver_worker");
|
||||||
|
_solver_worker->solver_stop();
|
||||||
|
}
|
||||||
|
void SolverDialog::on_solve_clicked() {
|
||||||
|
TRACE(15,"on_solve_clicked");
|
||||||
|
_dialog->solve->setEnabled(false);
|
||||||
|
_dialog->singleiteration->setEnabled(false);
|
||||||
|
_dialog->stop->setEnabled(true);
|
||||||
|
|
||||||
|
assert(!_solver_worker);
|
||||||
|
|
||||||
|
_solver_worker = new SolverWorker(_sys);
|
||||||
|
QThread* thread = new QThread;
|
||||||
|
|
||||||
|
_solver_worker->moveToThread(thread);
|
||||||
|
|
||||||
|
|
||||||
|
connect(thread, &QThread::started,
|
||||||
|
_solver_worker, &SolverWorker::solver_start);
|
||||||
|
|
||||||
|
connect(_solver_worker, &SolverWorker::solver_stopped,
|
||||||
|
thread, &QThread::quit);
|
||||||
|
|
||||||
|
connect(_solver_worker, &SolverWorker::solver_stopped,
|
||||||
|
this, &SolverDialog::solver_stopped);
|
||||||
|
|
||||||
|
connect(thread, &QThread::finished,
|
||||||
|
thread, &QThread::deleteLater);
|
||||||
|
|
||||||
|
connect(thread, &QThread::finished,
|
||||||
|
_solver_worker, &SolverWorker::deleteLater);
|
||||||
|
|
||||||
|
|
||||||
|
thread->start();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
void SolverDialog::on_singleiteration_clicked() {
|
||||||
|
_dialog->solve->setEnabled(false);
|
||||||
|
_dialog->singleiteration->setEnabled(false);
|
||||||
|
_dialog->stop->setEnabled(true);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolverDialog::solver_stopped() {
|
||||||
|
_dialog->solve->setEnabled(true);
|
||||||
|
_dialog->singleiteration->setEnabled(true);
|
||||||
|
_dialog->stop->setEnabled(false);
|
||||||
|
|
||||||
|
// stop the solver and delete it
|
||||||
|
if(_solver_worker!=nullptr) {
|
||||||
|
_solver_worker->solver_stop();
|
||||||
|
_solver_worker = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
@ -8,25 +8,59 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef SOLVER_DIALOG_H
|
#ifndef SOLVER_DIALOG_H
|
||||||
#define SOLVER_DIALOG_H
|
#define SOLVER_DIALOG_H
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#include "solver.pb.h"
|
||||||
|
|
||||||
|
namespace pb {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
namespace Ui {
|
||||||
|
class solver_dialog;
|
||||||
|
}
|
||||||
|
class QCustomPlot;
|
||||||
|
class SolverWorker;
|
||||||
|
class SolverDialog: public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
pb::System& _sys; // Reference to system
|
||||||
|
pb::SolverParams _sparams;
|
||||||
|
|
||||||
|
Ui::solver_dialog* _dialog;
|
||||||
|
|
||||||
|
QCustomPlot* _plot;
|
||||||
|
|
||||||
|
SolverWorker* _solver_worker = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SolverDialog(QWidget* parent,
|
||||||
|
pb::System& sys);
|
||||||
|
|
||||||
|
~SolverDialog();
|
||||||
|
|
||||||
|
void set(const pb::SolverParams&);
|
||||||
|
|
||||||
|
|
||||||
// Put here, temporarily
|
private slots:
|
||||||
window->funtol->setText(QString::number(constants::default_funtol));
|
// Connected to the signal from the solver thread. Reactivates the
|
||||||
window->funtol->setValidator(new QDoubleValidator(constants::min_funtol,
|
// buttons
|
||||||
constants::max_funtol,
|
void solver_stopped();
|
||||||
constants::field_decimals));
|
|
||||||
window->reltol->setText(QString::number(constants::default_funtol));
|
|
||||||
window->reltol->setValidator(new QDoubleValidator(constants::min_funtol,
|
|
||||||
constants::max_funtol,
|
|
||||||
constants::field_decimals));
|
|
||||||
|
|
||||||
window->maxiter->setText(QString::number(constants::default_maxiter));
|
void on_solve_clicked();
|
||||||
window->maxiter->setValidator(new QIntValidator(constants::min_maxiter,
|
void on_singleiteration_clicked();
|
||||||
constants::max_maxiter));
|
void on_stop_clicked();
|
||||||
|
|
||||||
for(const SolverType& t: SolverType_vec){
|
void on_funtol_textChanged() { changed();}
|
||||||
window->solvertype->addItem(SolverTypeToString(t));
|
void on_reltol_textChanged() { changed();}
|
||||||
}
|
void on_solvertype_currentIndexChanged(int) { changed();}
|
||||||
|
private:
|
||||||
|
// Called whenever the user changes input values
|
||||||
|
void changed();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // SOLVER_DIALOG_H
|
#endif // SOLVER_DIALOG_H
|
||||||
|
@ -1,86 +1,165 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>Dialog</class>
|
<class>solver_dialog</class>
|
||||||
<widget class="QDialog" name="Dialog">
|
<widget class="QDialog" name="solver_dialog">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>747</width>
|
<width>730</width>
|
||||||
<height>336</height>
|
<height>362</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>TaSMET Solver</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QGroupBox" name="solversettings">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="geometry">
|
<item>
|
||||||
<rect>
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<x>10</x>
|
<item>
|
||||||
<y>40</y>
|
<widget class="QGroupBox" name="solversettings">
|
||||||
<width>306</width>
|
<property name="sizePolicy">
|
||||||
<height>168</height>
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
</rect>
|
<horstretch>0</horstretch>
|
||||||
</property>
|
<verstretch>0</verstretch>
|
||||||
<property name="title">
|
</sizepolicy>
|
||||||
<string>Solver Settings</string>
|
</property>
|
||||||
</property>
|
<property name="title">
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
<string>Solver Settings</string>
|
||||||
<item row="3" column="0">
|
</property>
|
||||||
<widget class="QLabel" name="label_14">
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
<property name="text">
|
<item row="3" column="0">
|
||||||
<string>Maximum iterations:</string>
|
<widget class="QLabel" name="label_13">
|
||||||
</property>
|
<property name="text">
|
||||||
</widget>
|
<string>Solver type</string>
|
||||||
</item>
|
</property>
|
||||||
<item row="4" column="0">
|
</widget>
|
||||||
<widget class="QLabel" name="label_13">
|
</item>
|
||||||
<property name="text">
|
<item row="3" column="1">
|
||||||
<string>Solver type</string>
|
<widget class="QComboBox" name="solvertype"/>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
<item row="2" column="1">
|
||||||
</item>
|
<widget class="QLineEdit" name="reltol">
|
||||||
<item row="4" column="1">
|
<property name="sizePolicy">
|
||||||
<widget class="QComboBox" name="solvertype"/>
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
</item>
|
<horstretch>0</horstretch>
|
||||||
<item row="2" column="1">
|
<verstretch>0</verstretch>
|
||||||
<widget class="QLineEdit" name="reltol">
|
</sizepolicy>
|
||||||
<property name="alignment">
|
</property>
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<property name="alignment">
|
||||||
</property>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item row="2" column="0">
|
</item>
|
||||||
<widget class="QLabel" name="label_12">
|
<item row="2" column="0">
|
||||||
<property name="text">
|
<widget class="QLabel" name="label_12">
|
||||||
<string>Solution tolerance:</string>
|
<property name="text">
|
||||||
</property>
|
<string>Solution tolerance:</string>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item row="1" column="0">
|
</item>
|
||||||
<widget class="QLabel" name="label_8">
|
<item row="1" column="0">
|
||||||
<property name="text">
|
<widget class="QLabel" name="label_8">
|
||||||
<string>Residual tolerance:</string>
|
<property name="text">
|
||||||
</property>
|
<string>Residual tolerance:</string>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item row="1" column="1">
|
</item>
|
||||||
<widget class="QLineEdit" name="funtol">
|
<item row="1" column="1">
|
||||||
<property name="alignment">
|
<widget class="QLineEdit" name="funtol">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<property name="sizePolicy">
|
||||||
</property>
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
</widget>
|
<horstretch>0</horstretch>
|
||||||
</item>
|
<verstretch>0</verstretch>
|
||||||
<item row="3" column="1">
|
</sizepolicy>
|
||||||
<widget class="QLineEdit" name="maxiter">
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="solve_gb">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Solve!</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="solve">
|
||||||
|
<property name="text">
|
||||||
|
<string>Solve</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="stop">
|
||||||
|
<property name="text">
|
||||||
|
<string>Stop</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="singleiteration">
|
||||||
|
<property name="text">
|
||||||
|
<string>Single iteration</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="progress_gb">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Progress</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QCustomPlot" name="progress_plot" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>QCustomPlot</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>qcustomplot.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
95
src/gui/solver_worker.cpp
Normal file
95
src/gui/solver_worker.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// solver_thread.cpp
|
||||||
|
//
|
||||||
|
// last-edit-by: J.A. de Jong
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "solver_worker.h"
|
||||||
|
#include <functional>
|
||||||
|
#include "tasmet_tracer.h"
|
||||||
|
#include "system.pb.h"
|
||||||
|
#include <QThread>
|
||||||
|
#include <qcustomplot.h>
|
||||||
|
SolverWorker::SolverWorker(pb::System& sys):
|
||||||
|
_run(false)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
SolverWorker::~SolverWorker(){
|
||||||
|
TRACE(15,"~SolverWorker");
|
||||||
|
}
|
||||||
|
void SolverWorker::solver_stop() {
|
||||||
|
_run = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolverWorker::solver_start() {
|
||||||
|
TRACE(15,"SolverWorker::solver_start()");
|
||||||
|
using namespace std::placeholders; // for _1, _2 etc.
|
||||||
|
|
||||||
|
_run = true;
|
||||||
|
|
||||||
|
progress_callback callback = std::bind(&SolverWorker::pg_callback,
|
||||||
|
this,_1);
|
||||||
|
|
||||||
|
SolverProgress p;
|
||||||
|
// For testing purposes
|
||||||
|
while(true) {
|
||||||
|
TRACE(15,"Solver start virtual iteration");
|
||||||
|
|
||||||
|
|
||||||
|
SolverAction action = callback(p);
|
||||||
|
if(action == Stop) break;
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
p.fun_err/=10;
|
||||||
|
p.rel_err/=10;
|
||||||
|
p.iteration++;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit solver_stopped();
|
||||||
|
}
|
||||||
|
SolverAction SolverWorker::pg_callback(SolverProgress pg) {
|
||||||
|
TRACE(15,"pg_callback");
|
||||||
|
|
||||||
|
if(!_run) return Stop;
|
||||||
|
|
||||||
|
|
||||||
|
// QCPGraph *_funer,*_reler,*_funtol,*_reltol;
|
||||||
|
|
||||||
|
// _funer = _plot->addGraph();
|
||||||
|
// _reler = _plot->addGraph();
|
||||||
|
|
||||||
|
TRACE(15,"SolverWorker::pg_callback()");
|
||||||
|
|
||||||
|
// VARTRACE(15,progress.fun_err);
|
||||||
|
// VARTRACE(15,progress.iteration);
|
||||||
|
// _funer->addData(progress.iteration,progress.fun_err);
|
||||||
|
// _reler->addData(progress.iteration,progress.rel_err);
|
||||||
|
|
||||||
|
// _plot->xAxis->setRange(0,progress.iteration);
|
||||||
|
|
||||||
|
// _plot->replot();
|
||||||
|
|
||||||
|
// if(progress.done) {
|
||||||
|
// // We are done!
|
||||||
|
|
||||||
|
// QString m = "Solver reached a converged solution.";
|
||||||
|
|
||||||
|
// QMessageBox::information(this,
|
||||||
|
// "Solver done",
|
||||||
|
// m);
|
||||||
|
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
return Continue;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
48
src/gui/solver_worker.h
Normal file
48
src/gui/solver_worker.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// solver_worker.h
|
||||||
|
//
|
||||||
|
// Author: J.A. de Jong
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// Worker which solves the system, updates the progress graph,
|
||||||
|
// etc
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
#pragma once
|
||||||
|
#ifndef SOLVER_WORKER_H
|
||||||
|
#define SOLVER_WORKER_H
|
||||||
|
#include "tasmet_types.h"
|
||||||
|
#include "solver.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include <atomic>
|
||||||
|
#include <QObject>
|
||||||
|
namespace pb{
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(SolverProgress);
|
||||||
|
|
||||||
|
class SolverWorker: public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
std::atomic<bool> _run;
|
||||||
|
Solver<GradientNonlinearSystem,vd>* _solver;
|
||||||
|
public:
|
||||||
|
|
||||||
|
SolverWorker(pb::System& sys);
|
||||||
|
~SolverWorker();
|
||||||
|
void solver_stop();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void solver_start();
|
||||||
|
signals:
|
||||||
|
|
||||||
|
// This signal is emitted when the solver is stopped
|
||||||
|
void solver_stopped();
|
||||||
|
void progress(SolverProgress);
|
||||||
|
private:
|
||||||
|
SolverAction pg_callback(SolverProgress pg);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SOLVER_WORKER_H
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
@ -45,22 +45,17 @@ int main(int argc, char *argv[]) {
|
|||||||
// Q_INIT_RESOURCE(application);
|
// Q_INIT_RESOURCE(application);
|
||||||
INITTRACE(15);
|
INITTRACE(15);
|
||||||
|
|
||||||
std::cout << "hoid" << std::endl;
|
|
||||||
// Initialize PythonQt
|
// Initialize PythonQt
|
||||||
// PythonQt::init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut);
|
// PythonQt::init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut);
|
||||||
PythonQt::init();
|
PythonQt::init();
|
||||||
std::cout << "hoid" << std::endl;
|
|
||||||
PythonQt* pyqt = PythonQt::self();
|
PythonQt* pyqt = PythonQt::self();
|
||||||
PythonQtObjectPtr context = pyqt->getMainModule();
|
PythonQtObjectPtr context = pyqt->getMainModule();
|
||||||
std::cout << "hoid" << std::endl;
|
|
||||||
QVariant rv = context.evalScript("from math import *\n");
|
QVariant rv = context.evalScript("from math import *\n");
|
||||||
if(pyqt->hadError()) {
|
if(pyqt->hadError()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
std::cout << "hoid" << std::endl;
|
|
||||||
// std::cout << rv.typeName() << std::endl;
|
|
||||||
std::cout << (rv.isNull()?"true": "false") << std::endl;
|
|
||||||
std::cout << "hoid" << std::endl;
|
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
16
src/protobuf/solver.proto
Normal file
16
src/protobuf/solver.proto
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
syntax = "proto2";
|
||||||
|
package pb;
|
||||||
|
|
||||||
|
enum SolverType {
|
||||||
|
NewtonRaphson = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameters the solver requires to operate
|
||||||
|
message SolverParams {
|
||||||
|
optional SolverType solvertype = 1 [default=NewtonRaphson];
|
||||||
|
optional double reltol = 3 [default = 1e-6];
|
||||||
|
optional double funtol = 4 [default = 1e-6];
|
||||||
|
optional double fun_err = 5 [default = 1e0];
|
||||||
|
optional double rel_err = 2 [default = 1e0];
|
||||||
|
optional uint32 iteration = 6 [default = 0];
|
||||||
|
}
|
@ -4,6 +4,7 @@ package pb;
|
|||||||
import "duct.proto";
|
import "duct.proto";
|
||||||
import "ductbc.proto";
|
import "ductbc.proto";
|
||||||
import "gas.proto";
|
import "gas.proto";
|
||||||
|
import "solver.proto";
|
||||||
|
|
||||||
enum SystemType {
|
enum SystemType {
|
||||||
TaSystem = 0;
|
TaSystem = 0;
|
||||||
@ -18,4 +19,5 @@ message System {
|
|||||||
map<uint32,Duct> ducts = 7;
|
map<uint32,Duct> ducts = 7;
|
||||||
map<uint32,DuctBc> ductbcs = 8;
|
map<uint32,DuctBc> ductbcs = 8;
|
||||||
repeated double solution = 9;
|
repeated double solution = 9;
|
||||||
|
optional SolverParams solverparams = 10;
|
||||||
}
|
}
|
||||||
|
@ -17,16 +17,15 @@
|
|||||||
|
|
||||||
const d eps = std::numeric_limits<d>::epsilon();
|
const d eps = std::numeric_limits<d>::epsilon();
|
||||||
|
|
||||||
Brent::Brent(const NoGradientNonlinearSystem<d>& sys,us maxiter,d reltol):
|
Brent::Brent(const NoGradientNonlinearSystem<d>& sys,d reltol):
|
||||||
Solver(sys),
|
Solver(sys),
|
||||||
_reltol(reltol),
|
_reltol(reltol)
|
||||||
_maxiter(maxiter)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
TRACE(15,"Brent::Brent");
|
TRACE(15,"Brent::Brent");
|
||||||
#ifdef TASMET_DEBUG
|
#ifdef TASMET_DEBUG
|
||||||
bool ok=true;
|
bool ok=true;
|
||||||
ok&=(maxiter>0);
|
|
||||||
ok&=(reltol >= eps);
|
ok&=(reltol >= eps);
|
||||||
|
|
||||||
if(!ok){
|
if(!ok){
|
||||||
@ -89,7 +88,7 @@ void Brent::start_implementation(NoGradientNonlinearSystem<d>& system,
|
|||||||
bool bisec_flag;
|
bool bisec_flag;
|
||||||
SolverProgress progress;
|
SolverProgress progress;
|
||||||
|
|
||||||
while(_running && progress.iteration <=_maxiter) {
|
while(true) {
|
||||||
|
|
||||||
if((fa!=fc) && (fb!=fc)){
|
if((fa!=fc) && (fb!=fc)){
|
||||||
// Inverse quadratic interpolation
|
// Inverse quadratic interpolation
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
|
|
||||||
class Brent: public Solver<NoGradientNonlinearSystem<d>,d> {
|
class Brent: public Solver<NoGradientNonlinearSystem<d>,d> {
|
||||||
d _reltol;
|
d _reltol;
|
||||||
us _maxiter;
|
|
||||||
public:
|
public:
|
||||||
Brent(const NoGradientNonlinearSystem<d>& sys,us maxiter=10000,d reltol=1e-6);
|
Brent(const NoGradientNonlinearSystem<d>& sys,d reltol=1e-6);
|
||||||
protected:
|
protected:
|
||||||
void start_implementation(NoGradientNonlinearSystem<d>& sys,progress_callback*);
|
void start_implementation(NoGradientNonlinearSystem<d>& sys,progress_callback*);
|
||||||
};
|
};
|
||||||
|
@ -26,7 +26,7 @@ void NewtonRaphson::start_implementation(GradientNonlinearSystem& system,
|
|||||||
SolverProgress progress;
|
SolverProgress progress;
|
||||||
SolverAction action;
|
SolverAction action;
|
||||||
|
|
||||||
while (_running && progress.iteration<=_maxiter) {
|
while (true) {
|
||||||
|
|
||||||
sdmat jac=system.jacobian();
|
sdmat jac=system.jacobian();
|
||||||
|
|
||||||
|
@ -20,70 +20,28 @@ static void SolverThread(Solver<system_T,result_T>* solver,
|
|||||||
template<typename system_T,typename result_T>
|
template<typename system_T,typename result_T>
|
||||||
Solver<system_T,result_T>::Solver(const system_T& sys){
|
Solver<system_T,result_T>::Solver(const system_T& sys){
|
||||||
_sys = sys.copy();
|
_sys = sys.copy();
|
||||||
if(!_sys)
|
if(!_sys) throw TaSMETBadAlloc();
|
||||||
throw TaSMETBadAlloc();
|
|
||||||
_running = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename system_T,typename result_T>
|
template<typename system_T,typename result_T>
|
||||||
Solver<system_T,result_T>::~Solver(){
|
Solver<system_T,result_T>::~Solver(){
|
||||||
|
|
||||||
stop();
|
|
||||||
assert(!_running);
|
|
||||||
assert(!_solver_thread);
|
|
||||||
delete _sys;
|
delete _sys;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename system_T,typename result_T>
|
template<typename system_T,typename result_T>
|
||||||
void Solver<system_T,result_T>::start(progress_callback* callback,bool wait){
|
void Solver<system_T,result_T>::start(progress_callback* callback){
|
||||||
|
|
||||||
if(_running){
|
|
||||||
assert(_solver_thread);
|
|
||||||
throw TaSMETError("Solver already running");
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(_solver_thread == nullptr);
|
|
||||||
|
|
||||||
if(!wait) {
|
|
||||||
this->_solver_thread = new std::thread(SolverThread<system_T,result_T>,
|
|
||||||
this,
|
|
||||||
_sys,
|
|
||||||
callback);
|
|
||||||
if(!_solver_thread)
|
|
||||||
throw TaSMETBadAlloc();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
TRACE(15,"Waiting for solver...");
|
TRACE(15,"Waiting for solver...");
|
||||||
start_implementation(*_sys,callback);
|
start_implementation(*_sys,callback);
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename system_T,typename result_T>
|
|
||||||
void Solver<system_T,result_T>::stop() {
|
|
||||||
|
|
||||||
_running = false;
|
|
||||||
|
|
||||||
if(_solver_thread){
|
|
||||||
|
|
||||||
_solver_thread->join();
|
|
||||||
delete _solver_thread;
|
|
||||||
_solver_thread = nullptr;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template<typename system_T,typename result_T>
|
template<typename system_T,typename result_T>
|
||||||
result_T Solver<system_T,result_T>::getSolution() {
|
result_T Solver<system_T,result_T>::getSolution() {
|
||||||
|
|
||||||
if(_running){
|
|
||||||
throw TaSMETError("Solver is running");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup thread resources
|
|
||||||
stop();
|
|
||||||
|
|
||||||
return _sys->getSolution();
|
return _sys->getSolution();
|
||||||
}
|
}
|
||||||
template<typename system_T,typename result_T>
|
template<typename system_T,typename result_T>
|
||||||
|
@ -21,11 +21,12 @@
|
|||||||
struct SolverProgress
|
struct SolverProgress
|
||||||
{
|
{
|
||||||
size_t iteration = 0;
|
size_t iteration = 0;
|
||||||
d fun_err;
|
d fun_err = 1e0;
|
||||||
d rel_err;
|
d rel_err = 1e0;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum SolverAction{
|
enum SolverAction{
|
||||||
Continue=0,
|
Continue=0,
|
||||||
Stop = 1
|
Stop = 1
|
||||||
@ -38,22 +39,17 @@ class Solver {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
system_T* _sys = nullptr;
|
system_T* _sys = nullptr;
|
||||||
std::thread* _solver_thread = nullptr;
|
|
||||||
std::atomic<bool> _running;
|
|
||||||
public:
|
public:
|
||||||
Solver(const system_T& sys);
|
Solver(const system_T& sys);
|
||||||
Solver(const Solver&)=delete;
|
Solver(const Solver&)=delete;
|
||||||
Solver& operator=(const Solver&)=delete;
|
Solver& operator=(const Solver&)=delete;
|
||||||
|
|
||||||
void start(progress_callback* callback=nullptr,bool wait=true);
|
void start(progress_callback* callback);
|
||||||
void stop(); // Stops the solver
|
|
||||||
|
|
||||||
// Returns the solution of the problem
|
// Returns the solution of the problem
|
||||||
result_T getSolution();
|
result_T getSolution();
|
||||||
|
|
||||||
virtual ~Solver();
|
virtual ~Solver();
|
||||||
template<typename Y,typename rT>
|
|
||||||
friend void SolverThread(Solver<Y,rT>*,Y*,progress_callback*);
|
|
||||||
protected:
|
protected:
|
||||||
virtual void start_implementation(system_T& sys,progress_callback*)=0;
|
virtual void start_implementation(system_T& sys,progress_callback*)=0;
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,10 @@ class NoGradientNonlinearSystem{
|
|||||||
public:
|
public:
|
||||||
virtual T residual() const=0;
|
virtual T residual() const=0;
|
||||||
|
|
||||||
virtual T residual(const T& guess) { updateSolution(guess); return residual();}
|
virtual T residual(const T& guess) {
|
||||||
|
updateSolution(guess);
|
||||||
|
return residual();
|
||||||
|
}
|
||||||
|
|
||||||
// Obtain an initial guess of the solution
|
// Obtain an initial guess of the solution
|
||||||
virtual T getSolution() const=0;
|
virtual T getSolution() const=0;
|
||||||
|
Loading…
Reference in New Issue
Block a user