Commit 8ade37a2 authored by Steffen Vogel's avatar Steffen Vogel 🎅🏼
Browse files

simulation: allow simulation to be resetted

parent 61a7d65d
......@@ -107,6 +107,7 @@ namespace Python {
static PyObject* start(Simulation *self, PyObject *args);
static PyObject* step(Simulation *self, PyObject *args);
static PyObject* stop(Simulation *self, PyObject *args);
static PyObject* reset(Simulation *self, PyObject *args);
static PyObject* addEventFD(Simulation *self, PyObject *args);
static PyObject* removeEventFD(Simulation *self, PyObject *args);
static PyObject* setScheduler(Simulation *self, PyObject *args, PyObject *kwargs);
......@@ -126,6 +127,7 @@ namespace Python {
static const char *docStart;
static const char *docPause;
static const char *docStop;
static const char *docReset;
static const char *docStep;
static const char *docAddInterface;
static const char *docAddEvent;
......
......@@ -191,6 +191,8 @@ namespace DPsim {
void sync();
/// Create the schedule for the independent tasks
void schedule();
/// Reset internal state of simulation
void reset();
///
template <typename VarType>
......
......@@ -57,7 +57,7 @@ void Python::Simulation::threadFunction(Python::Simulation *self)
{
Real time, finalTime;
self->sim->schedule();
self->sim->initialize();
Timer timer(Timer::Flags::fail_on_overrun);
......@@ -488,11 +488,18 @@ PyObject* Python::Simulation::start(Simulation *self, PyObject *args)
newState(self, Simulation::State::starting);
self->cond->notify_one();
if (self->thread) {
if (self->thread->joinable())
self->thread->join();
delete self->thread;
}
self->thread = new std::thread(Python::Simulation::threadFunction, self);
}
while (self->state != State::running)
self->cond->wait(lk);
self->cond->wait(lk);
Py_RETURN_NONE;
}
......@@ -512,6 +519,13 @@ PyObject* Python::Simulation::step(Simulation *self, PyObject *args)
newState(self, State::starting);
self->cond->notify_one();
if (self->thread) {
if (self->thread->joinable())
self->thread->join();
delete self->thread;
}
self->thread = new std::thread(threadFunction, self);
}
else if (self->state == State::paused) {
......@@ -554,6 +568,24 @@ PyObject* Python::Simulation::stop(Simulation *self, PyObject *args)
Py_RETURN_NONE;
}
const char *Python::Simulation::docReset =
"reset()\n"
"Reset the simulation and the internal state of the components.";
PyObject* Python::Simulation::reset(Simulation *self, PyObject *args)
{
std::unique_lock<std::mutex> lk(*self->mut);
if (self->state != State::done && self->state != State::stopped) {
PyErr_SetString(PyExc_SystemError, "Simulation can only be resetted from done or stopped state");
return nullptr;
}
self->sim->reset();
newState(self, Simulation::State::stopped);
Py_RETURN_NONE;
}
const char *Python::Simulation::docAddEventFD =
"add_eventfd(flags)\n";
PyObject * Python::Simulation::addEventFD(Simulation *self, PyObject *args) {
......@@ -731,6 +763,7 @@ PyMethodDef Python::Simulation::methods[] = {
{"add_event", (PyCFunction) Python::Simulation::addEvent, METH_VARARGS, (char *) docAddEvent},
{"pause", (PyCFunction) Python::Simulation::pause, METH_NOARGS, (char *) Python::Simulation::docPause},
{"start", (PyCFunction) Python::Simulation::start, METH_NOARGS, (char *) Python::Simulation::docStart},
{"reset", (PyCFunction) Python::Simulation::reset, METH_NOARGS, (char *) Python::Simulation::docReset},
{"step", (PyCFunction) Python::Simulation::step, METH_NOARGS, (char *) Python::Simulation::docStep},
{"stop", (PyCFunction) Python::Simulation::stop, METH_NOARGS, (char *) Python::Simulation::docStop},
{"add_eventfd", (PyCFunction) Python::Simulation::addEventFD, METH_VARARGS, (char *) Python::Simulation::docAddEventFD},
......
......@@ -70,23 +70,20 @@ Simulation::Simulation(String name, SystemTopology system,
mTimeStep = timeStep;
mFinalTime = finalTime;
mDomain = domain;
mSystem = system;
mSolverType = solverType;
mSteadyStateInit = steadyStateInit;
mSplitSubnets = splitSubnets;
mTearComponents = tearComponents;
switch (domain) {
case Domain::DP:
createSolvers<Complex>(system, solverType, steadyStateInit, splitSubnets, tearComponents);
break;
case Domain::EMT:
createSolvers<Real>(system, solverType, steadyStateInit, splitSubnets, tearComponents);
break;
case Domain::Static:
mSolvers.push_back(std::make_shared<NRpolarSolver>(name, system, timeStep, domain, logLevel));
break;
}
mInitialized = true;
mInitialized = false;
}
void Simulation::initialize() {
if (mInitialized)
return;
mSolvers.clear();
switch (mDomain) {
case Domain::DP:
......@@ -100,6 +97,11 @@ void Simulation::initialize() {
break;
}
mTime = 0;
mTimeStepCount = 0;
schedule();
mInitialized = true;
}
......@@ -324,9 +326,7 @@ void Simulation::renderDependencyGraph(std::ostream &os) {
#endif
void Simulation::run() {
if (!mInitialized)
initialize();
schedule();
#ifdef WITH_SHMEM
std::cout << Logger::prefix() << "Opening interfaces." << std::endl;
......@@ -371,3 +371,15 @@ Real Simulation::step() {
mStepTimes.push_back(diff.count());
return mTime;
}
void Simulation::reset() {
// Resets component states
mSystem.reset();
for (auto l : mLoggers)
l->reopen();
// Force reinitialization for next run
mInitialized = false;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment