Commit 14229902 authored by Georg Martin Reinke's avatar Georg Martin Reinke
Browse files

Simulation: supoprt more loggers, add update_matrix() method

Former-commit-id: d2c96994
parent 06cd02dc
...@@ -8,10 +8,11 @@ using namespace DPsim; ...@@ -8,10 +8,11 @@ using namespace DPsim;
static PyMethodDef PySimulation_methods[] = { static PyMethodDef PySimulation_methods[] = {
{"lvector", PySimulation::lvector, METH_NOARGS, "Returns the left-side vector from the last step."}, {"lvector", PySimulation::lvector, METH_NOARGS, "Returns the left-side vector from the last step."},
{"pause", PySimulation::pause, METH_NOARGS, "Pause the already running simulation."},
{"start", PySimulation::start, METH_NOARGS, "Start the simulation, or resume if it is paused."}, {"start", PySimulation::start, METH_NOARGS, "Start the simulation, or resume if it is paused."},
{"step", PySimulation::step, METH_NOARGS, "Perform a single simulation step."}, {"step", PySimulation::step, METH_NOARGS, "Perform a single simulation step."},
{"stop", PySimulation::stop, METH_NOARGS, "Cancel the running simulation."}, {"stop", PySimulation::stop, METH_NOARGS, "Cancel the running simulation."},
{"pause", PySimulation::pause, METH_NOARGS, "Pause the already running simulation."}, {"update_matrix", PySimulation::updateMatrix, METH_NOARGS, "Update the system matrix to reflect changes to components."},
{"wait", PySimulation::wait, METH_NOARGS, "Wait for the simulation to finish."}, {"wait", PySimulation::wait, METH_NOARGS, "Wait for the simulation to finish."},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
...@@ -60,12 +61,11 @@ PyTypeObject DPsim::PySimulationType = { ...@@ -60,12 +61,11 @@ PyTypeObject DPsim::PySimulationType = {
void PySimulation::simThreadFunction(PySimulation* pySim) { void PySimulation::simThreadFunction(PySimulation* pySim) {
bool notDone = true; bool notDone = true;
Logger rlog("rvector.csv"), llog("lvector.csv");
std::unique_lock<std::mutex> lk(*pySim->mut, std::defer_lock); std::unique_lock<std::mutex> lk(*pySim->mut, std::defer_lock);
pySim->numStep = 0; pySim->numStep = 0;
while (pySim->running && notDone) { while (pySim->running && notDone) {
notDone = pySim->sim->step(*pySim->log, llog, rlog); notDone = pySim->sim->step(*pySim->log, *pySim->llog, *pySim->rlog);
pySim->numStep++; pySim->numStep++;
pySim->sim->increaseByTimeStep(); pySim->sim->increaseByTimeStep();
if (pySim->sigPause) { if (pySim->sigPause) {
...@@ -92,17 +92,18 @@ PyObject* PySimulation::newfunc(PyTypeObject* type, PyObject *args, PyObject *kw ...@@ -92,17 +92,18 @@ PyObject* PySimulation::newfunc(PyTypeObject* type, PyObject *args, PyObject *kw
// implement them as pointers // implement them as pointers
self->cond = new std::condition_variable(); self->cond = new std::condition_variable();
self->mut = new std::mutex(); self->mut = new std::mutex();
self->numSwitch = 0;
} }
return (PyObject*) self; return (PyObject*) self;
} }
int PySimulation::init(PySimulation* self, PyObject *args, PyObject *kwds) { int PySimulation::init(PySimulation* self, PyObject *args, PyObject *kwds) {
static char *kwlist[] = {"components", "frequency", "timestep", "duration", "log", NULL}; static char *kwlist[] = {"components", "frequency", "timestep", "duration", "log", "llog", "rlog", NULL};
double frequency = 50, timestep = 1e-3, duration = DBL_MAX; double frequency = 50, timestep = 1e-3, duration = DBL_MAX;
const char *log = nullptr; const char *log = nullptr, *llog = nullptr, *rlog = nullptr;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|ddds", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|dddsss", kwlist,
&self->pyComps, &frequency, &timestep, &duration, &log)) &self->pyComps, &frequency, &timestep, &duration, &log, &llog, &rlog))
return -1; return -1;
if (!compsFromPython(self->pyComps, self->comps)) { if (!compsFromPython(self->pyComps, self->comps)) {
PyErr_SetString(PyExc_TypeError, "Invalid components argument (must by list of dpsim.Component)"); PyErr_SetString(PyExc_TypeError, "Invalid components argument (must by list of dpsim.Component)");
...@@ -113,6 +114,14 @@ int PySimulation::init(PySimulation* self, PyObject *args, PyObject *kwds) { ...@@ -113,6 +114,14 @@ int PySimulation::init(PySimulation* self, PyObject *args, PyObject *kwds) {
self->log = new Logger(log); self->log = new Logger(log);
else else
self->log = new Logger(); self->log = new Logger();
if (rlog)
self->rlog = new Logger(rlog);
else
self->rlog = new Logger();
if (llog)
self->llog = new Logger(llog);
else
self->llog = new Logger();
self->sim = new Simulation(self->comps, 2*PI*frequency, timestep, duration, *self->log); self->sim = new Simulation(self->comps, 2*PI*frequency, timestep, duration, *self->log);
return 0; return 0;
}; };
...@@ -130,6 +139,10 @@ void PySimulation::dealloc(PySimulation* self) { ...@@ -130,6 +139,10 @@ void PySimulation::dealloc(PySimulation* self) {
delete self->sim; delete self->sim;
if (self->log) if (self->log)
delete self->log; delete self->log;
if (self->llog)
delete self->llog;
if (self->rlog)
delete self->rlog;
delete self->mut; delete self->mut;
delete self->cond; delete self->cond;
...@@ -155,6 +168,21 @@ PyObject* PySimulation::lvector(PyObject *self, PyObject *args) { ...@@ -155,6 +168,21 @@ PyObject* PySimulation::lvector(PyObject *self, PyObject *args) {
return list; return list;
} }
PyObject* PySimulation::pause(PyObject *self, PyObject *args) {
PySimulation *pySim = (PySimulation*) self;
std::unique_lock<std::mutex> lk(*pySim->mut);
if (pySim->state != StateRunning) {
PyErr_SetString(PyExc_SystemError, "Simulation not currently running");
return nullptr;
}
pySim->sigPause = 1;
pySim->cond->notify_one();
while (pySim->state == StateRunning)
pySim->cond->wait(lk);
Py_INCREF(Py_None);
return Py_None;
}
PyObject* PySimulation::start(PyObject *self, PyObject *args) { PyObject* PySimulation::start(PyObject *self, PyObject *args) {
PySimulation *pySim = (PySimulation*) self; PySimulation *pySim = (PySimulation*) self;
std::unique_lock<std::mutex> lk(*pySim->mut); std::unique_lock<std::mutex> lk(*pySim->mut);
...@@ -212,17 +240,12 @@ PyObject* PySimulation::stop(PyObject *self, PyObject *args) { ...@@ -212,17 +240,12 @@ PyObject* PySimulation::stop(PyObject *self, PyObject *args) {
return Py_None; return Py_None;
} }
PyObject* PySimulation::pause(PyObject *self, PyObject *args) { PyObject* PySimulation::updateMatrix(PyObject *self, PyObject *args) {
PySimulation *pySim = (PySimulation*) self; PySimulation *pySim = (PySimulation*) self;
std::unique_lock<std::mutex> lk(*pySim->mut); // TODO: this is a quick-and-dirty method that keeps the old matrix in
if (pySim->state != StateRunning) { // memory
PyErr_SetString(PyExc_SystemError, "Simulation not currently running"); pySim->sim->addSystemTopology(pySim->comps);
return nullptr; pySim->sim->switchSystemMatrix(++pySim->numSwitch);
}
pySim->sigPause = 1;
pySim->cond->notify_one();
while (pySim->state == StateRunning)
pySim->cond->wait(lk);
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
......
...@@ -24,7 +24,7 @@ namespace DPsim { ...@@ -24,7 +24,7 @@ namespace DPsim {
PyObject_HEAD PyObject_HEAD
Simulation *sim; Simulation *sim;
Logger *log; // TODO other loggers Logger *log, *llog, *rlog;
std::condition_variable *cond; std::condition_variable *cond;
std::mutex *mut; std::mutex *mut;
...@@ -35,6 +35,7 @@ namespace DPsim { ...@@ -35,6 +35,7 @@ namespace DPsim {
PyObject* pyComps; // Components as a (Python) list of PyComponents PyObject* pyComps; // Components as a (Python) list of PyComponents
std::vector<BaseComponent*> comps; std::vector<BaseComponent*> comps;
int numSwitch;
// Function executed by the simulation thread // Function executed by the simulation thread
static void simThreadFunction(PySimulation* pySim); static void simThreadFunction(PySimulation* pySim);
...@@ -49,10 +50,11 @@ namespace DPsim { ...@@ -49,10 +50,11 @@ namespace DPsim {
// Methods that are actually available from Python // Methods that are actually available from Python
static PyObject* lvector(PyObject *self, PyObject *args); static PyObject* lvector(PyObject *self, PyObject *args);
static PyObject* pause(PyObject *self, PyObject *args);
static PyObject* start(PyObject *self, PyObject *args); static PyObject* start(PyObject *self, PyObject *args);
static PyObject* step(PyObject *self, PyObject *args); static PyObject* step(PyObject *self, PyObject *args);
static PyObject* stop(PyObject *self, PyObject *args); static PyObject* stop(PyObject *self, PyObject *args);
static PyObject* pause(PyObject *self, PyObject *args); static PyObject* updateMatrix(PyObject *self, PyObject *args);
static PyObject* wait(PyObject *self, PyObject *args); static PyObject* wait(PyObject *self, PyObject *args);
}; };
......
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