{ "cells": [ { "cell_type": "markdown", "metadata": { "nbpages": { "level": 0, "link": "[](https://jckantor.github.io/CBE32338/02.06-Four-State-Model.html)", "section": "" } }, "source": [ "\n", "*This notebook contains material from [CBE32338](https://jckantor.github.io/CBE32338);\n", "content is available [on Github](https://github.com/jckantor/CBE32338.git).*\n" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 0, "link": "[](https://jckantor.github.io/CBE32338/02.06-Four-State-Model.html)", "section": "" } }, "source": [ "\n", "< [2.5 Two State Model for a Single Heater](https://jckantor.github.io/CBE32338/02.05-Two-State-Model-for-a-Single-Heater.html) | [Contents](toc.html) | [2.10 TCLab Lab 2: Model Identification](https://jckantor.github.io/CBE32338/02.10-TCLab-Lab-2-Model-Indentification-Solutions.html) >
"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 1,
"link": "[2.6 Four State Model](https://jckantor.github.io/CBE32338/02.06-Four-State-Model.html#2.6-Four-State-Model)",
"section": "2.6 Four State Model"
}
},
"source": [
"# 2.6 Four State Model"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 2,
"link": "[2.6.1 Multivariable Heater/Sensor System](https://jckantor.github.io/CBE32338/02.06-Four-State-Model.html#2.6.1-Multivariable-Heater/Sensor-System)",
"section": "2.6.1 Multivariable Heater/Sensor System"
}
},
"source": [
"## 2.6.1 Multivariable Heater/Sensor System\n",
"\n",
"Model equations\n",
"\n",
"\\begin{align}\n",
"C^H_p\\frac{dT_{H,1}}{dt} & = U_a(T_{amb} - T_{H,1}) + U_b(T_{H,2}-T_{H,1}) + U_c(T_{S,1} - T_{H,1}) + P_1u_1\\\\\n",
"C^S_p\\frac{dT_{S,1}}{dt} & = U_c(T_{H,1} - T_{S,1}) \\\\\n",
"C^H_p\\frac{dT_{H,2}}{dt} & = U_a(T_{amb} - T_{H,2}) + U_b(T_{H,1}-T_{H,2}) + U_c(T_{S,2} - T_{H,2}) + P_2u_2\\\\\n",
"C^S_p\\frac{dT_{S,2}}{dt} & = U_c(T_{H,2} - T_{S,2}) \n",
"\\end{align}\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 2,
"link": "[2.6.2 Deviation variables](https://jckantor.github.io/CBE32338/02.06-Four-State-Model.html#2.6.2-Deviation-variables)",
"section": "2.6.2 Deviation variables"
}
},
"source": [
"## 2.6.2 Deviation variables\n",
"\n",
"\\begin{align}\n",
"\\frac{dT_{H,1}'}{dt} & = -(\\frac{U_a+U_b+U_c}{C^H_p})T_{H,1}' + \\frac{U_b}{C^H_p}T_{H,2}' + \\frac{U_c}{C^H_p}T_{S,1}' + \\frac{P_1}{C^H_p}u_1\\\\\n",
"\\frac{dT_{S,1}'}{dt} & = \\frac{U_c}{C^S_p}(T_{H,1}' - T_{S,1}') \\\\\n",
"\\frac{dT_{H,2}'}{dt} & = -(\\frac{U_a+U_b+U_c}{C^H_p})T_{H,2}' + \\frac{U_b}{C^H_p}T_{H,1}' + \\frac{U_c}{C^H_p}T_{S,2}' + \\frac{P_2}{C^H_p}u_2\\\\\n",
"\\frac{dT_{S,2}'}{dt} & = \\frac{U_c}{C^S_p}(T_{H,2}' - T_{S,2}') \n",
"\\end{align}"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 2,
"link": "[2.6.3 State space](https://jckantor.github.io/CBE32338/02.06-Four-State-Model.html#2.6.3-State-space)",
"section": "2.6.3 State space"
}
},
"source": [
"## 2.6.3 State space\n",
"\n",
"\\begin{align}\n",
"\\left[\\begin{array}{c}\\frac{dT_{H,1}'}{dt} \\\\ \\frac{dT_{S,1}'}{dt} \\\\ \\frac{dT_{H,2}'}{dt} \\\\ \\frac{dT_{S,2}'}{dt}\\end{array}\\right]\n",
"& = \n",
"\\left[\\begin{array}{cccc}\n",
"-(\\frac{U_a+U_b+U_c}{C^H_p}) & \\frac{U_c}{C^H_p} & \\frac{U_b}{C^H_p} & 0 \\\\\n",
"\\frac{U_c}{C^S_p} & -\\frac{U_c}{C^S_p} & 0 & 0 \\\\\n",
"\\frac{U_b}{C^H_p} & 0 & -(\\frac{U_a+U_b+U_c}{C^H_p}) & \\frac{U_c}{C^H_p} \\\\\n",
"0 & 0 & \\frac{U_c}{C^H_p} & -\\frac{U_c}{C^H_p}\n",
"\\end{array}\\right]\n",
"\\left[\\begin{array}{c}T_{H,1}' \\\\ T_{S,1}' \\\\ T_{H,2}' \\\\ T_{S,2}'\\end{array}\\right]\n",
"+\n",
"\\left[\\begin{array}{cc}\\frac{P_1}{C_p} & 0 \\\\ 0 & 0 \\\\ 0 & \\frac{P_2}{C_p} \\\\ 0 & 0 \\end{array}\\right]\n",
"\\left[\\begin{array}{c}u_1 \\\\ u_2\\end{array}\\right]\n",
"\\end{align}"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"nbpages": {
"level": 2,
"link": "[2.6.3 State space](https://jckantor.github.io/CBE32338/02.06-Four-State-Model.html#2.6.3-State-space)",
"section": "2.6.3 State space"
}
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "c4c99cc9b3d34e748ff83fe13f148efc",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"A Jupyter Widget"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"from scipy.integrate import odeint\n",
"from ipywidgets import interact\n",
"\n",
"data = pd.read_csv('Step_Test_Data.csv').set_index('Time')[1:]\n",
"t = data.index\n",
"T1 = data['T1'].values\n",
"T2 = data['T2'].values\n",
"\n",
"# known parameter values\n",
"P1 = 4\n",
"u1 = 0.5 # steady state value of u1 (fraction of total power)\n",
"P2 = 2\n",
"u2 = 0.0\n",
"T_ambient = 21.5\n",
"\n",
"def compare(Ua, Ub, Uc, Cp_H, Cp_S):\n",
"\n",
" def deriv(T,t):\n",
" T_H1, T_S1, T_H2, T_S2 = T\n",
" dT_H1 = -(Ua + Ub + Uc)*T_H1/Cp_H + Ub*T_H2/Cp_H + Uc*T_S1/Cp_H + P1*u1/Cp_H\n",
" dT_S1 = Uc*T_H1/Cp_S - Uc*T_S1/Cp_S\n",
" dT_H2 = -(Ua + Ub + Uc)*T_H2/Cp_H + Ub*T_H1/Cp_H + Uc*T_S2/Cp_H + P2*u2/Cp_H\n",
" dT_S2 = Uc*T_H2/Cp_S - Uc*T_S2/Cp_S\n",
" return [dT_H1, dT_S1, dT_H2, dT_S2]\n",
" T = odeint(deriv, [0,0,0,0], t)\n",
"\n",
" plt.figure(figsize=(12,6))\n",
" plt.subplot(2,1,1)\n",
" plt.plot(t, T[:,1] + T_ambient, t, T[:,3] + T_ambient, t, T1, t, T2)\n",
" plt.xlabel('Time / seconds')\n",
" plt.ylabel('Temperature / °C')\n",
" plt.grid()\n",
" plt.subplot(2,1,2)\n",
" plt.plot(t, T[:,1]-T1+T_ambient)\n",
" plt.plot(t, T[:,3]-T2+T_ambient)\n",
" plt.grid\n",
"\n",
"# parameter values and units\n",
"P1 = 4 # watts\n",
"P2 = 2 # watts\n",
"Ua = 0.044 # watts/deg C\n",
"Ub = 0.018 # watts/deg C\n",
"Cp = 7 # joules/deg C\n",
"\n",
"w = interact(compare, Ua=(0,0.06,0.001), Ub=(0,0.06,0.001), Uc=(0,0.06,0.001), Cp_H=(3,11,0.01), Cp_S = (0.1,2,.01))"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"nbpages": {
"level": 2,
"link": "[2.6.3 State space](https://jckantor.github.io/CBE32338/02.06-Four-State-Model.html#2.6.3-State-space)",
"section": "2.6.3 State space"
}
},
"outputs": [
{
"data": {
"text/plain": [
"array([ -22.64294396, -52.59946787, -124.34799519, -354.43970971])"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import numpy as np\n",
"\n",
"Ua = 0.043\n",
"Ub = 0.022\n",
"Uc = 0.036\n",
"Cp_H = 6.38\n",
"Cp_S = 0.98\n",
"\n",
"A = [[-(Ua+Ub+Uc)/Cp_H, Uc/Cp_H, Ub/Cp_H, 0],\n",
" [Uc/Cp_S, -Uc/Cp_S, 0, 0],\n",
" [Ub/Cp_H, 0, -(Ua+Ub+Uc)/Cp_H, Uc/Cp_H],\n",
" [0, 0, Uc/Cp_H, -Uc/Cp_H]\n",
" ]\n",
"\n",
"evals, evecs = np.linalg.eig(A)\n",
"\n",
"1/evals"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"nbpages": {
"level": 2,
"link": "[2.6.3 State space](https://jckantor.github.io/CBE32338/02.06-Four-State-Model.html#2.6.3-State-space)",
"section": "2.6.3 State space"
}
},
"outputs": [],
"source": [
"def compare(Ua, Ub, Uc, Cp_H, Cp_S):\n",
"\n",
" def deriv(T,t):\n",
" T_H1, T_S1, T_H2, T_S2 = T\n",
" dT_H1 = -(Ua + Ub + Uc)*T_H1/Cp_H + Ub*T_H2/Cp_H + Uc*T_S1/Cp_H + P1*u1/Cp_H\n",
" dT_S1 = Uc*T_H1/Cp_S - Uc*T_S1/Cp_S\n",
" dT_H2 = -(Ua + Ub + Uc)*T_H2/Cp_H + Ub*T_H1/Cp_H + Uc*T_S2/Cp_H + P2*u2/Cp_H\n",
" dT_S2 = Uc*T_H2/Cp_S - Uc*T_S2/Cp_S\n",
" return [dT_H1, dT_S1, dT_H2, dT_S2]\n",
" T = odeint(deriv, [0,0,0,0], t)\n",
"\n",
" plt.figure(figsize=(12,6))\n",
" plt.subplot(2,1,1)\n",
" plt.plot(t, T[:,1] + T_ambient, t, T[:,3] + T_ambient)\n",
" plt.plot(t, T[:,0] + T_ambient)\n",
" plt.plot(t, T[:,2] + T_ambient)\n",
" plt.xlabel('Time / seconds')\n",
" plt.ylabel('Temperature / °C')\n",
" plt.grid()\n",
" plt.subplot(2,1,2)\n",
" plt.plot(t, T[:,1]-T1+T_ambient)\n",
" plt.plot(t, T[:,3]-T2+T_ambient)\n",
" plt.grid\n",
" print(Ua,Ub,Uc,Cp_H,Cp_S)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"nbpages": {
"level": 2,
"link": "[2.6.3 State space](https://jckantor.github.io/CBE32338/02.06-Four-State-Model.html#2.6.3-State-space)",
"section": "2.6.3 State space"
}
},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {
"nbpages": {
"level": 2,
"link": "[2.6.3 State space](https://jckantor.github.io/CBE32338/02.06-Four-State-Model.html#2.6.3-State-space)",
"section": "2.6.3 State space"
}
},
"source": [
"\n",
"< [2.5 Two State Model for a Single Heater](https://jckantor.github.io/CBE32338/02.05-Two-State-Model-for-a-Single-Heater.html) | [Contents](toc.html) | [2.10 TCLab Lab 2: Model Identification](https://jckantor.github.io/CBE32338/02.10-TCLab-Lab-2-Model-Indentification-Solutions.html) >
"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}