tasmet/src/solver/solver.cpp

107 lines
2.5 KiB
C++

// solver.cpp
//
// last-edit-by: J.A. de Jong
//
// Description:
//
//////////////////////////////////////////////////////////////////////
#include "tasmet_tracer.h"
#include "solver.h"
#include "tasmet_exception.h"
#include <chrono>
template<typename system_T,typename result_T>
static void SolverThread(Solver<system_T,result_T>* solver,
system_T* system,
progress_callback* callback);
template<typename system_T,typename result_T>
Solver<system_T,result_T>::Solver(const system_T& sys){
_sys = sys.copy();
if(!_sys)
throw TaSMETBadAlloc();
_running = false;
}
template<typename system_T,typename result_T>
Solver<system_T,result_T>::~Solver(){
stop();
assert(!_running);
assert(!_solver_thread);
delete _sys;
}
template<typename system_T,typename result_T>
void Solver<system_T,result_T>::start(progress_callback* callback,bool wait){
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...");
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>
result_T Solver<system_T,result_T>::getSolution() {
if(_running){
throw TaSMETError("Solver is running");
}
// Cleanup thread resources
stop();
return _sys->getSolution();
}
template<typename system_T,typename result_T>
void SolverThread(Solver<system_T,result_T>* solver,system_T* system,progress_callback* callback) {
assert(system);
solver->_running = true;
solver->start_implementation(*system,callback);
solver->_running = false;
}
// Explicit instantiation for some types of systems and results
template class Solver<NoGradientNonlinearSystem<vd>,vd>;
template class Solver<GradientNonlinearSystem,vd>;
template class Solver<NoGradientNonlinearSystem<d>,d>;
//////////////////////////////////////////////////////////////////////