Commit 55ad902c authored by Markus Mirz's avatar Markus Mirz
Browse files

Merge branch 'fix-feature-notebooks' into 'master'

Fix feature notebooks

Closes #107

See merge request acs/public/simulation/dpsim!83

Former-commit-id: a96e6215
parents 2d4f56a9 4000f9be
Subproject commit adac52c0b39412b0e300e3e6e9638cd35646149d
Subproject commit 2f2f246aee96a2f213a1ccceec3d392a3f0a06a0
%% Cell type:markdown id: tags:
# Asynchronous execution
%% Cell type:markdown id: tags:
DPsim integrates well with event loop implementation like [asyncio](https://docs.python.org/3/library/asyncio.html).
This allows the user to run simulations as a coroutine asynchronously in the background.
%% Cell type:markdown id: tags:
## Example 1
%% Cell type:markdown id: tags:
We start by defining a very simple simulation:
%% Cell type:code id: tags:
``` python
import time
import asyncio
import dpsim
from dpsim.EventChannel import Event
# Nodes
gnd = dpsim.dp.Node.GND()
n1 = dpsim.dp.Node("n1")
# Components
v1 = dpsim.dp.ph1.VoltageSource("v_1", [gnd, n1], V_ref=complex(345,0))
sys = dpsim.SystemTopology(50, [gnd, n1], [v1])
```
%% Cell type:markdown id: tags:
The <code>dpsim.Simulation</code> class has a function called `coro simulate()` which returns a coroutine.
this co-routine can be started in the background via:
%% Cell type:code id: tags:
``` python
sims = []
for i in range(1, 4):
sim = dpsim.RealTimeSimulation("async_demo_%d" % i, sys, timestep = i * 1e-3, duration=3*i, pbar=True)
sim = dpsim.RealTimeSimulation("async_demo_%d" % i, sys, timestep=i*1e-3, duration=3*i+5, pbar=True)
sim.start()
sims += [sim]
for i in range(1, 6):
print("Doing something different: %d" % i)
await asyncio.sleep(1)
_ = await asyncio.wait([ s.wait(Event.done) for s in sims ])
```
%% Output
Doing something different: 1
Doing something different: 2
Doing something different: 3
Doing something different: 4
Doing something different: 5
......
a900c84a78c504b432a402676af094d70035a503
\ No newline at end of file
09f1217f43dcff266ffbd8075774cf35c8cfabb4
\ No newline at end of file
%% Cell type:markdown id: tags:
# Live Plotting
%% Cell type:code id: tags:
``` python
%matplotlib ipympl
import numpy as np
import matplotlib.pyplot as plt
fs = 100 # sample rate
f = 2 # the frequency of the signal
fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion()
fig.show()
fig.canvas.draw()
for j in range(0,100):
x = np.arange(fs) # the points on the x axis for plotting
# compute the value (amplitude) of the sin wave at the for each sample
y = [ np.sin(2*np.pi*f * (i/fs) + j/100*2*np.pi) for i in x]
ax.clear()
plt.plot(x,y)
fig.canvas.draw()
plt.pause(0.05)
```
%% Output
/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/ipympl/backend_nbagg.py:190: MatplotlibDeprecationWarning: The start_event_loop_default function was deprecated in version 2.1.
FigureCanvasBase.start_event_loop_default(self, timeout)
%% Cell type:code id: tags:
``` python
from pylab import *
import time
ion()
tstart = time.time() # for profiling
x = arange(0,2*pi,0.01) # x-array
line, = plot(x,sin(x))
for i in arange(1,200):
line.set_ydata(sin(x+i/10.0)) # update the data
draw() # redraw the canvas
plt.pause(0.05)
print('FPS:' , 200/(time.time()-tstart))
```
%% Cell type:code id: tags:
``` python
```
56315eb7989abb37a7f7f2e79a541ca50809722f
\ No newline at end of file
%% Cell type:markdown id: tags:
# Progressbars
%% Cell type:markdown id: tags:
During long running or real-time simulations it is useful to have a feedback from the running simulation about its current state.
DPsim can show its current progress
%% Cell type:markdown id: tags:
## Example 1
%% Cell type:code id: tags:
``` python
import dpsim
# Nodes
gnd = dpsim.dp.Node.GND()
n1 = dpsim.dp.Node("n1")
n2 = dpsim.dp.Node("n2")
n3 = dpsim.dp.Node("n3")
n4 = dpsim.dp.Node("n4")
# Components
v1 = dpsim.dp.ph1.VoltageSource("v_1", [gnd, n1], V_ref=complex(345,0))
r1 = dpsim.dp.ph1.Resistor("r1", [n1, n2], R=5)
c1 = dpsim.dp.ph1.Capacitor("c_1", [n2, gnd], C=0.002)
rL1 = dpsim.dp.ph1.Resistor("r_load1", [n2, n4], R=6.4)
l1 = dpsim.dp.ph1.Inductor("l_1", [n4, n3], L=0.186)
c2 = dpsim.dp.ph1.Capacitor("c_2", [n3, gnd], C=0.002)
rL2 = dpsim.dp.ph1.Resistor("r_load2", [n3, gnd], R=150)
sys = dpsim.SystemTopology(50, [gnd, n1, n2, n3, n4], [v1, r1, c1, rL1, l1, c2, rL2])
sim = dpsim.Simulation("progress_demo1", sys, duration=20, timestep=0.0005)
```
%% Cell type:code id: tags:
``` python
sim.show_progressbar()
```
%% Output
%% Cell type:code id: tags:
``` python
await sim.simulate()
```
%% Cell type:markdown id: tags:
## Example 2
%% Cell type:markdown id: tags:
Progressbars are also supported for simulations which are executed as a co-routine
%% Cell type:code id: tags:
``` python
import asyncio
async def dummy():
for i in range(1,10):
await asyncio.sleep(1)
print('Doing something different:', i)
sim2 = dpsim.Simulation("progress_demo2", sys, duration=20, timestep=0.00005)
sim2.show_progressbar()
await asyncio.gather(sim2.simulate(), dummy())
```
%% Output
Doing something different: 1
Doing something different: 2
Doing something different: 3
Doing something different: 4
Doing something different: 5
Doing something different: 6
Doing something different: 7
Doing something different: 8
Doing something different: 9
[None, None]
%% Cell type:code id: tags:
``` python
```
......
%% Cell type:markdown id: tags:
# Widgets
This example uses slider widgets to adjust parameters
In this example we will use the [iPyWidgets Jupyter](https://ipywidgets.readthedocs.io) extension to interactively tune simulation or model parameters.
The user will see immediatly the impact of parameter changes as the simulation results are continously updated.
This example uses slider widgets to adjust parameters:
%% Cell type:code id: tags:
``` python
import dpsim
import math, cmath
import time
import os
import matplotlib as plt
import villas.dataprocessing.plottools as pt
import villas.dataprocessing.readtools as rt
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
```
%% Cell type:markdown id: tags:
We start by defining our system topology:
%% Cell type:code id: tags:
``` python
gnd = dpsim.dp.Node.GND()
n1 = dpsim.dp.Node("n1")
n2 = dpsim.dp.Node("n2")
cs = dpsim.dp.ph1.CurrentSource("cs", [gnd, n1])
r1 = dpsim.dp.ph1.Resistor("r_1", [n1, gnd])
c1 = dpsim.dp.ph1.Capacitor("c_1", [n1, n2])
l1 = dpsim.dp.ph1.Inductor("l_1", [n2, gnd])
r2 = dpsim.dp.ph1.Resistor("r_2", [n2, gnd])
sys = dpsim.SystemTopology(50, [gnd, n1, n2], [cs, r1, c1, l1, r2])
sim = dpsim.Simulation("Widgets", sys, duration=0.1)
logger = dpsim.Logger("Widgets")
logger.log_attribute(n1, "v") # v1
logger.log_attribute(n2, "v") # v2
logger.log_attribute(cs, "i_intf") # i12
logger.log_attribute(c1, "i_intf") # i34
sim.add_logger(logger)
```
%% Cell type:markdown id: tags:
Next, we define the simulation callback. This function will be executed on every parameter change.
It will re-run the simulation and plot the updated results.
%% Cell type:code id: tags:
``` python
def simulate(dt, dur, pha, mag, r1, r2, l, c):
gnd = dpsim.dp.Node.GND()
n1 = dpsim.dp.Node("n1")
n2 = dpsim.dp.Node("n2")
cs = dpsim.dp.ph1.CurrentSource("cs", [gnd, n1], I_ref=cmath.rect(mag, pha))
r1 = dpsim.dp.ph1.Resistor("r_1", [n1, gnd], R=r1)
c1 = dpsim.dp.ph1.Capacitor("c_1", [n1, n2], C=c)
l1 = dpsim.dp.ph1.Inductor("l_1", [n2, gnd], L=l*1e-3)