|
@@ -30895,7 +30895,7 @@
|
|
|
"cell_type": "markdown",
|
|
|
"metadata": {},
|
|
|
"source": [
|
|
|
- "## Exercise: Implement the Gauss Seidel Runner"
|
|
|
+ "## Exercise 1: Implement the Gauss Seidel Runner"
|
|
|
]
|
|
|
},
|
|
|
{
|
|
@@ -31010,12 +31010,122 @@
|
|
|
"plt.show()"
|
|
|
]
|
|
|
},
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "## Exercise 2: Implement the Virtual FMUS\n",
|
|
|
+ "\n",
|
|
|
+ "Copy your implementation of the virtual fmu MSD1, and implement the virtual fmu MSD2.\n",
|
|
|
+ "\n",
|
|
|
+ "Then, run a co-simulation with them."
|
|
|
+ ]
|
|
|
+ },
|
|
|
{
|
|
|
"cell_type": "code",
|
|
|
"execution_count": null,
|
|
|
"metadata": {},
|
|
|
"outputs": [],
|
|
|
- "source": []
|
|
|
+ "source": [
|
|
|
+ "from cosimlibrary.virtual_fmus import VirtualFMU\n",
|
|
|
+ "from fmpy.fmi2 import fmi2True\n",
|
|
|
+ "\n",
|
|
|
+ "# TODO The MSD1 Virtual FMU has been implemented in the previous exercise. Copy that code and paste it here.\n",
|
|
|
+ "class MSD1(VirtualFMU):\n",
|
|
|
+ " def __init__(self, instanceName):\n",
|
|
|
+ " # Declare value references for variables\n",
|
|
|
+ " ref = 0\n",
|
|
|
+ " self.x1 = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.v1 = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.m1 = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.c1 = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.d1 = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.fk = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " super().__init__(instanceName, ref)\n",
|
|
|
+ "\n",
|
|
|
+ " def doStep(self, currentCommunicationPoint, communicationStepSize, noSetFMUStatePriorToCurrentPoint=fmi2True):\n",
|
|
|
+ " h = 1e-3 # Internal step size\n",
|
|
|
+ " t = currentCommunicationPoint\n",
|
|
|
+ " maxT = t + communicationStepSize # Time to terminate the doStep\n",
|
|
|
+ " while (t < maxT):\n",
|
|
|
+ " if t+h > maxT:\n",
|
|
|
+ " h = (maxT - t) # Make sure we leave the co-sim step at time maxT\n",
|
|
|
+ " # Compute derivative of x\n",
|
|
|
+ " der_x = self.state[self.v1]\n",
|
|
|
+ " # Compute derivative of v\n",
|
|
|
+ " der_v = (1.0 / self.state[self.m1]) * (- self.state[self.c1] * self.state[self.x1]\n",
|
|
|
+ " - self.state[self.d1] * self.state[self.v1]\n",
|
|
|
+ " + self.state[self.fk])\n",
|
|
|
+ "\n",
|
|
|
+ " # TODO: Implement forward euler step\n",
|
|
|
+ " self.state[self.x1] = self.state[self.x1] + der_x * h\n",
|
|
|
+ " self.state[self.v1] = self.state[self.v1] + der_v * h\n",
|
|
|
+ " \n",
|
|
|
+ " # Advance time\n",
|
|
|
+ " t=t+h\n",
|
|
|
+ "\n",
|
|
|
+ " \n",
|
|
|
+ "# Implementation of the virtual fmu MSD2\n",
|
|
|
+ "class MSD2(VirtualFMU):\n",
|
|
|
+ " def __init__(self, instanceName):\n",
|
|
|
+ " ref = 0\n",
|
|
|
+ " self.x2 = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.v2 = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.m2 = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.c2 = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.d2 = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.cc = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.dc = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.fk = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.x1 = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ " self.v1 = ref;\n",
|
|
|
+ " ref += 1\n",
|
|
|
+ "\n",
|
|
|
+ " super().__init__(instanceName, ref)\n",
|
|
|
+ " \n",
|
|
|
+ " def doStep(self, currentCommunicationPoint, communicationStepSize, noSetFMUStatePriorToCurrentPoint=fmi2True):\n",
|
|
|
+ " h = 1e-3 # Internal step size\n",
|
|
|
+ " t = currentCommunicationPoint\n",
|
|
|
+ " maxT = t + communicationStepSize # Time to terminate the doStep\n",
|
|
|
+ " \n",
|
|
|
+ " while (t < maxT):\n",
|
|
|
+ " if t+h > maxT:\n",
|
|
|
+ " h = (maxT - t) # Make sure we leave the co-sim step at time maxT\n",
|
|
|
+ " \n",
|
|
|
+ " # Compute fk\n",
|
|
|
+ " self.state[self.fk] = self.state[self.cc] * (self.state[self.x2] - self.state[self.x1]) \\\n",
|
|
|
+ " + self.state[self.dc] * (self.state[self.v2] - self.state[self.v1])\n",
|
|
|
+ "\n",
|
|
|
+ " # TODO Compute derivative of x2\n",
|
|
|
+ " der_x = self.state[self.v2]\n",
|
|
|
+ " \n",
|
|
|
+ " # TODO Compute derivative of v2\n",
|
|
|
+ " der_v = (1.0 / self.state[self.m2]) * (- self.state[self.c2] * self.state[self.x2]\n",
|
|
|
+ " - self.state[self.d2] * self.state[self.v2]\n",
|
|
|
+ " - self.state[self.fk])\n",
|
|
|
+ "\n",
|
|
|
+ " # TODO Implement forward euler step.\n",
|
|
|
+ " self.state[self.x2] = self.state[self.x2] + der_x * h\n",
|
|
|
+ " self.state[self.v2] = self.state[self.v2] + der_v * h\n",
|
|
|
+ " \n",
|
|
|
+ " # Advance time\n",
|
|
|
+ " t=t+h"
|
|
|
+ ]
|
|
|
}
|
|
|
],
|
|
|
"metadata": {
|