Repository: myokit/myokit (language: python)

Issue:
New cvodesssim doesn't log derivatives
```
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import myokit

m, p, _ = myokit.load('example')

s = myokit.Simulation(m, p)

d = s.run(600)

plt.figure()
ax = plt.subplot(2, 1, 1)
ax.plot(d.time(), d['membrane.V'])
ax = plt.subplot(2, 1, 2)
ax.plot(d.time(), d['dot(membrane.V)'])

plt.show()
```


Discussion / hints:

Fix patch:
diff --git a/myokit/_sim/cmodel.h b/myokit/_sim/cmodel.h
index 71a75bff2..a1ed274cb 100644
--- a/myokit/_sim/cmodel.h
+++ b/myokit/_sim/cmodel.h
@@ -932,7 +932,7 @@ for var in model.states():
     j = i;
 <?
 for var in model.states():
-    print(tab + 'i += Model__AddVariableToLog(model, log_dict, i, "dot(' + var.qname() + ')", &' + v(var)  + ');')
+    print(tab + 'i += Model__AddVariableToLog(model, log_dict, i, "dot(' + var.qname() + ')", &' + v(var.lhs())  + ');')
 ?>
     model->logging_derivatives = (i != j);
 


Test patch:
diff --git a/myokit/tests/test_simulation_cvode.py b/myokit/tests/test_simulation_cvode.py
index 6c680cc25..e3451422f 100755
--- a/myokit/tests/test_simulation_cvode.py
+++ b/myokit/tests/test_simulation_cvode.py
@@ -571,6 +571,39 @@ def test_apd(self):
         self.assertAlmostEqual(apds['duration'][0], 383.88262, places=0)
         self.assertAlmostEqual(apds['duration'][1], 378.31448, places=0)
 
+    def test_derivatives(self):
+        # Tests logging of derivatives by comparing with a finite difference
+        # approximation
+
+        # Run past the upstroke, where finite diff approx is worst
+        self.sim.reset()
+        self.sim.run(52)
+
+        # Now run logged part
+        d = self.sim.run(600).npview()
+        if False:
+            import matplotlib.pyplot as plt
+            plt.figure()
+            ax = plt.subplot(3, 1, 1)
+            ax.plot(d.time(), d['membrane.V'])
+            ax = plt.subplot(3, 1, 2)
+            ax.plot(d.time(), d['dot(membrane.V)'])
+
+        # Get central difference approximation
+        t = d.time()
+        v = d['membrane.V']
+        dv = (v[2:] - v[:-2]) / (t[2:] - t[:-2])
+        e = d['dot(membrane.V)'][1:-1] - dv
+        if False:
+            t = t[1:-1]
+            ax.plot(t, dv, '--')
+            ax = plt.subplot(3, 1, 3)
+            ax.plot(t, e)
+            print(np.max(np.abs(e)))
+
+        # Compare
+        self.assertLess(np.max(np.abs(e)), 0.1)
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/myokit/tests/test_simulation_cvodes.py b/myokit/tests/test_simulation_cvodes.py
index 2d50a3cb2..3d3c779d4 100755
--- a/myokit/tests/test_simulation_cvodes.py
+++ b/myokit/tests/test_simulation_cvodes.py
@@ -717,6 +717,39 @@ def test_apd(self):
         self.assertAlmostEqual(apds['duration'][0], 383.88262, places=1)
         self.assertAlmostEqual(apds['duration'][1], 378.31448, places=1)
 
+    def test_derivatives(self):
+        # Tests logging of derivatives by comparing with a finite difference
+        # approximation
+
+        # Run past the upstroke, where finite diff approx is worst
+        self.sim.reset()
+        self.sim.run(52)
+
+        # Now run logged part
+        d = self.sim.run(600).npview()
+        if False:
+            import matplotlib.pyplot as plt
+            plt.figure()
+            ax = plt.subplot(3, 1, 1)
+            ax.plot(d.time(), d['membrane.V'])
+            ax = plt.subplot(3, 1, 2)
+            ax.plot(d.time(), d['dot(membrane.V)'])
+
+        # Get central difference approximation
+        t = d.time()
+        v = d['membrane.V']
+        dv = (v[2:] - v[:-2]) / (t[2:] - t[:-2])
+        e = d['dot(membrane.V)'][1:-1] - dv
+        if False:
+            t = t[1:-1]
+            ax.plot(t, dv, '--')
+            ax = plt.subplot(3, 1, 3)
+            ax.plot(t, e)
+            print(np.max(np.abs(e)))
+
+        # Compare
+        self.assertLess(np.max(np.abs(e)), 0.1)
+
 
 if __name__ == '__main__':
     unittest.main()