{
"cells": [
{
"cell_type": "markdown",
"id": "35a53b91-f1eb-4c06-983f-3aaa32ac5a87",
"metadata": {
"tags": []
},
"source": [
"# [Weather data and solar radiation](01WeatherData.ipynb)\n",
"\n",
"# [Thermal circuit and state-space representation for a thermal circuit with capacities in every node: simple wall](02SimpleWall.ipynb)\n",
"\n",
"# Thermal circuit and state-space representation for a thermal circuit with capacities in some nodes: cubic building\n",
"\n",
"This tutorial presents the theory of heat transfer in buildings and examplifies it on a [toy model](https://en.m.wikipedia.org/wiki/Toy_model).\n",
"\n",
"**Objectives:**\n",
"- Analyse a cubic building with 5 identical walls & a transparent wall (glass window), air infiltration, and HVAC system controlling the indoor air temperature.\n",
"- Model the heat transfer in the building by a thermal circuit.\n",
"- Obtain the mathematical model as a system of Differential Algebraic Equations (DAE) from the thermal circuit.\n",
"- Transfrom the system of DAE into state-space representation.\n",
"- Find the steady-state solution.\n",
"- Simulate by using Euler methods for numerical integration.."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "764b77e2-3f93-4484-9842-6b328305d517",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import dm4bem"
]
},
{
"cell_type": "markdown",
"id": "dd09d492-4c1d-422d-9a88-55f8631e5836",
"metadata": {
"tags": []
},
"source": [
"## Physical analysis\n",
"\n",
"### Description of the building\n",
"\n",
"\n",
"> Figure 1. Simple ventilated room (5 two-layer walls and 1 glass window) equiped with an HVAC system which acts as a proportional controller.\n",
"\n",
"Let’s consider a cubic building with an HVAC systems acting as a [proportional controller](https://en.m.wikipedia.org/wiki/Proportional_control)."
]
},
{
"cell_type": "markdown",
"id": "d101012e-cfec-4e3d-9268-03e8cc68fceb",
"metadata": {
"tags": []
},
"source": [
"The dimensions and surface areas of the building are:\n",
"- $l=3 \\: \\mathrm{m}$ - edge length of the cube;\n",
"- $S_g=l^2$ - surface area of the glass window;\n",
"- $S_c = S_i = 5 \\times S_g$ - surface area of the 5 (concrete and insulation) walls."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "e81f680f-dfcf-42a7-95f0-25869b407aee",
"metadata": {},
"outputs": [],
"source": [
"l = 3 # m length of the cubic room\n",
"Sg = l**2 # m² surface of the glass wall\n",
"Sc = Si = 5 * Sg # m² surface of concrete & insulation of the 5 walls"
]
},
{
"cell_type": "markdown",
"id": "04249e0b-1f3d-47f5-b8f7-024135cda83b",
"metadata": {},
"source": [
"### Thermo-physical properties\n",
"The thermophysical properties of the air (in SI units) are:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "6b636b8a-a7af-4ebe-9eee-578dea6f7742",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
Density
\n",
"
Specific heat
\n",
"
\n",
" \n",
" \n",
"
\n",
"
Air
\n",
"
1.2
\n",
"
1000
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Density Specific heat\n",
"Air 1.2 1000"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"air = {'Density': 1.2, # kg/m³\n",
" 'Specific heat': 1000} # J/(kg·K)\n",
"# pd.DataFrame.from_dict(air, orient='index', columns=['air'])\n",
"pd.DataFrame(air, index=['Air'])"
]
},
{
"cell_type": "markdown",
"id": "55dcaa59-47e6-4fbd-9c42-ad843a62b4d6",
"metadata": {},
"source": [
"The [thermophysical properties](https://energieplus-lesite.be/donnees/enveloppe44/enveloppe2/conductivite-thermique-des-materiaux/) ([thermal conductivities](https://en.m.wikipedia.org/wiki/List_of_thermal_conductivities), [densities](https://en.wikipedia.org/wiki/Density) and [specific heat capacities](https://en.m.wikipedia.org/wiki/Table_of_specific_heat_capacities)) and the geometry (widths and surface areas) of the three materials (i.e., concrete, insulation, glass) in SI units are:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "2db86dfc-2fd4-4a32-94b2-a21dcd1286c8",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
Conductivity
\n",
"
Density
\n",
"
Specific heat
\n",
"
Width
\n",
"
Surface
\n",
"
\n",
" \n",
" \n",
"
\n",
"
Layer_out
\n",
"
1.400
\n",
"
2300.0
\n",
"
880
\n",
"
0.20
\n",
"
45
\n",
"
\n",
"
\n",
"
Layer_in
\n",
"
0.027
\n",
"
55.0
\n",
"
1210
\n",
"
0.08
\n",
"
45
\n",
"
\n",
"
\n",
"
Glass
\n",
"
1.400
\n",
"
2500.0
\n",
"
1210
\n",
"
0.04
\n",
"
9
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Conductivity Density Specific heat Width Surface\n",
"Layer_out 1.400 2300.0 880 0.20 45\n",
"Layer_in 0.027 55.0 1210 0.08 45\n",
"Glass 1.400 2500.0 1210 0.04 9"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"concrete = {'Conductivity': 1.400,\n",
" 'Density': 2300.0,\n",
" 'Specific heat': 880,\n",
" 'Width': 0.2,\n",
" 'Surface': 5 * l**2}\n",
"\n",
"insulation = {'Conductivity': 0.027,\n",
" 'Density': 55.0,\n",
" 'Specific heat': 1210,\n",
" 'Width': 0.08,\n",
" 'Surface': 5 * l**2}\n",
"\n",
"glass = {'Conductivity': 1.4,\n",
" 'Density': 2500,\n",
" 'Specific heat': 1210,\n",
" 'Width': 0.04,\n",
" 'Surface': l**2}\n",
"\n",
"wall = pd.DataFrame.from_dict({'Layer_out': concrete,\n",
" 'Layer_in': insulation,\n",
" 'Glass': glass},\n",
" orient='index')\n",
"wall"
]
},
{
"cell_type": "markdown",
"id": "fe6a3471-4696-4661-ad9e-3ab90dd18f63",
"metadata": {},
"source": [
"where `Slices` is the number of meshes used in the [numerical discretization](https://en.m.wikipedia.org/wiki/Discretization). "
]
},
{
"cell_type": "markdown",
"id": "30e10ea7-83eb-4a06-889e-d1c83b617b14",
"metadata": {},
"source": [
"### Radiative properties\n",
"\n",
"The [radiative properties](https://en.wikipedia.org/wiki/Emissivity#Absorptivity) of the surfaces are:\n",
"- long wave [emmisivity](https://www.engineeringtoolbox.com/emissivity-coefficients-d_447.html) of concrete (between normal and rough) and glass pyrex;\n",
"- short wave [absortivity of solar radiation](https://www.engineeringtoolbox.com/solar-radiation-absorbed-materials-d_1568.html) of white smooth surfaces;\n",
"- short wave [transmittance](https://www.engineeringtoolbox.com/optical-properties-glazing-materials-d_1355.html) of window glass (thickness of 4 mm);\n",
"- short wave [absortivity and transmittance](https://energieplus-lesite.be/techniques/enveloppe7/composants-de-l-enveloppe/vitrages/vitrage-permettant-le-controle-solaire/) of reflective blue window glass."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "415dff20-125d-4988-b863-90e17919f217",
"metadata": {},
"outputs": [],
"source": [
"# radiative properties\n",
"ε_wLW = 0.85 # long wave emmisivity: wall surface (concrete)\n",
"ε_gLW = 0.90 # long wave emmisivity: glass pyrex\n",
"α_wSW = 0.25 # short wave absortivity: white smooth surface\n",
"α_gSW = 0.38 # short wave absortivity: reflective blue glass\n",
"τ_gSW = 0.30 # short wave transmitance: reflective blue glass"
]
},
{
"cell_type": "markdown",
"id": "702b5007-e07f-48b0-b3d0-c80f6c0dcbd9",
"metadata": {},
"source": [
"The [Stefan-Boltzmann constant](https://en.m.wikipedia.org/wiki/Stefan–Boltzmann_constant) is:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "1de290ff-7474-4623-aca9-fadfd45593ee",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"σ = 5.67e-08 W/(m²⋅K⁴)\n"
]
}
],
"source": [
"σ = 5.67e-8 # W/(m²⋅K⁴) Stefan-Bolzmann constant\n",
"print(f'σ = {σ} W/(m²⋅K⁴)')"
]
},
{
"cell_type": "markdown",
"id": "466314ca-35c9-4327-9ac5-e412f760baed",
"metadata": {},
"source": [
"### Convection coefficients\n",
"\n",
"Conventional values for the [convection coeficients](https://energieplus-lesite.be/theories/enveloppe9/echanges-chaleur-parois/resistance-thermique-d-echange-superficiel/) for indoor and outdoor convection in W/(m²⋅K) are:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "c77bc614-0b91-4d45-93b6-8562947255de",
"metadata": {},
"outputs": [],
"source": [
"h = pd.DataFrame([{'in': 8., 'out': 25}], index=['h']) # W/(m²⋅K)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "a9fd244e-9fcd-42e7-b56a-a6438a41f9fd",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
in
\n",
"
out
\n",
"
\n",
" \n",
" \n",
"
\n",
"
h
\n",
"
8.0
\n",
"
25
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" in out\n",
"h 8.0 25"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"h"
]
},
{
"cell_type": "markdown",
"id": "7999a5df-05f3-4f8a-a1e3-7106dca8222e",
"metadata": {
"tags": []
},
"source": [
"## Thermal network\n",
"\n",
"Thermal networks (or circuits) are weighted [directed graphs](https://en.m.wikipedia.org/wiki/Directed_graph) in which:\n",
"- the **nodes** (or vertices) represent temperatures, $\\theta_i$, of geometrical points, surfaces or volumes;\n",
"- the oriented **branches** (or edges) represent thermal heat flow rates, $q_j$, betweenn the temperature nodes.\n",
"\n",
"\n",
"> Figure 2. Basic thermal network.\n",
"\n",
"A thermal network has at least one oriented branch, $q$, and one node, $\\theta$.\n",
"\n",
"In a node there are a thermal capacity, $C_i$, (which can be positive or zero) and a heat flow rate source, $\\dot Q_i$, (which can be zero).\n",
"\n",
"On a branch, there are a conductane, $G_j > 0$, (which needs to be strictely pozitve) and a temperature source, $T_j$ (which can be zero).\n",
"\n",
"The problem of analysis of thermal circuits (or the simulation problem, or the direct problem) is:\n",
"\n",
"**given**:\n",
"- [incidence matrix](https://en.m.wikipedia.org/wiki/Incidence_matrix) $A$ which indicates how the nodes are connected by oriented branches;\n",
"- conductance diagonal matrix $G$;\n",
"- capacity diagonal matrix $C$;\n",
"- temperature source vector $b$;\n",
"- heat flow source vector $f$;\n",
"\n",
"**find** the temperature vector $\\theta$ and the flow rate vector $q.$\n",
"\n",
"\n",
"For the [toy model](https://en.m.wikipedia.org/wiki/Toy_model) shown in Figure 1, heat transfert is:\n",
"- through the walls (concrete and insulation), \n",
"- through the glass window,\n",
"- by ventilation,\n",
"- from indoor auxiliary sources,\n",
"- from the HVAC system.\n",
"\n",
"The HVAC system is modelled as a proportional controller. There is long wave radiative exchange between the wall and the glass window. The sources are:\n",
"- temperature sources:\n",
" - outdoor atmospheric air;\n",
" - indoor air temperature setpoint;\n",
"- flow rate sources:\n",
" - solar radiation on the outdoor and the indoor walls;\n",
" - auxiliary heat gains in the thermal zone.\n",
"\n",
"\n",
"> Figure 3. Heat processes for the cubic building shown in Figure 1.\n",
"\n",
"\n",
"> Figure 4. Thermal circuit for the cubic building shown in Figure 1 and the heat processes shown in Figure 2. *Note*: space discretization of the walls is done for simplicity."
]
},
{
"cell_type": "markdown",
"id": "4cad06cc-972a-4a7f-859c-4b5de7a1e72d",
"metadata": {
"tags": []
},
"source": [
"Figure 3 shows the models of:\n",
"- concrete & insulation wall: in red;\n",
"- glass window: in green;\n",
"- ventilation: in magenta;\n",
"- indoor volume: in blue (conductances 6 & 7 for convection; conductance 5 for long wave radiation between the walls and the glass window);\n",
"- HVAC system: in black.\n",
"\n",
"The sources are:\n",
"- $T_o$ - outdoor temperature, °C;\n",
"- $T_{i,sp}$ - setpoint temperaure for the indoor air, °C;\n",
"- $\\Phi_o$ - solar radiation absorbed by the outdoor surface of the wall, W;\n",
"- $\\Phi_i$ - solar radiation absorbed by the indoor surface of the wall, W;\n",
"- $\\dot{Q}_a$ - auxiliary heat gains (i.e., occupants, electrical devices, etc.), W;\n",
"- $\\Phi_a$ - solar radiation absorbed by the glass, W.\n",
"\n",
"\n",
"*Note*: The known values, i.e. the elements of the circuit (the conductances $G$ and capacities $C$) and the sources (of temperature $T$ and of flow rate $\\Phi$ or $\\dot{Q}$) are noted in uppercase (majuscule) letters. The unknow variables, i.e. the temperatures in the nodes $\\theta$ and the flow rates on the branches $q$, are noted in lowercase (minuscule) letters."
]
},
{
"cell_type": "markdown",
"id": "3d80e066-38d0-4ca2-b193-0a9f06c26499",
"metadata": {
"tags": []
},
"source": [
"### Thermal coductances\n",
"#### Conduction\n",
"The conductances 1, 2, 3, and 4 of the thermal circuit from Figure 3 model the heat transfer by [conduction](https://en.m.wikipedia.org/wiki/Thermal_conduction). Conduction conductances, in W/K, are of the form:\n",
"$$G_{cd} = \\frac{\\lambda}{w}S$$\n",
"where:\n",
"\n",
"- $\\lambda$ - [thermal conductvity](https://en.m.wikipedia.org/wiki/Thermal_conductivity), W/(m⋅K);\n",
"- $w$ - width of the material, m;\n",
"- $S$ - surface area of the wall, m²."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "23b6045b-18c2-4598-8c3b-a3e95e9fe541",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
Conductance
\n",
"
\n",
" \n",
" \n",
"
\n",
"
Layer_out
\n",
"
315.0000
\n",
"
\n",
"
\n",
"
Layer_in
\n",
"
15.1875
\n",
"
\n",
"
\n",
"
Glass
\n",
"
315.0000
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Conductance\n",
"Layer_out 315.0000\n",
"Layer_in 15.1875\n",
"Glass 315.0000"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# conduction\n",
"G_cd = wall['Conductivity'] / wall['Width'] * wall['Surface']\n",
"pd.DataFrame(G_cd, columns=['Conductance'])"
]
},
{
"cell_type": "markdown",
"id": "58c9a68d-ff08-45bf-913a-814fc9aa0f79",
"metadata": {
"tags": []
},
"source": [
"#### Convection\n",
"The conductances 0, 6 and 7 model the heat transfer by [convection](https://en.m.wikipedia.org/wiki/Convection_(heat_transfer). Convection conductances, in W/K, are of the form:\n",
"$$G_{cv} = {h S}$$\n",
"where:\n",
"- $h$ is the [convection coefficient](https://en.m.wikipedia.org/wiki/Heat_transfer_coefficient), W/(m²⋅K);\n",
"- $S$ - surface area of the wall, m².\n",
"\n",
">Table 1. Surface thermal resistances [Dal Zotto et al. 2014, p. 251]\n",
"\n",
"| Type of wall | Indoor surface |Outdoor surface|\n",
"|--------------|:--------------:|:-------------:|\n",
"| | $h_i$,W/(m²·K) | $h_o$,W/(m²·K)|\n",
"|*Vertical* (tilt > 60°)| 7.7| 25 |\n",
"|*Horizontal* (tilt < 60°)| | |\n",
"|- Upward heat flow | 10| 25 |\n",
"|- Downward heat flow | 5.9| 25 |"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "3df65dcd-7962-42f5-80f2-e71d4cbc6486",
"metadata": {},
"outputs": [],
"source": [
"# convection\n",
"Gw = h * wall['Surface'][0] # wall\n",
"Gg = h * wall['Surface'][2] # glass"
]
},
{
"cell_type": "markdown",
"id": "b800939e-8a50-45f9-83ef-e5cc98fe7c63",
"metadata": {
"tags": []
},
"source": [
"#### Long wave radiation\n",
"##### View factors inside the building\n",
"\n",
"The majority of methods used for modelling the [radiative heat exchange](https://en.m.wikipedia.org/wiki/Thermal_radiation) use the [view factors](https://en.m.wikipedia.org/wiki/View_factor) between surfaces. The view factor $F_{i,j}$ is defined as *the proportion of radiation leaving surface $i$ that is intercepted by surface $j$*. The view factors can be estimated by [differential areas](https://en.m.wikipedia.org/wiki/View_factor#View_factors_of_differential_areas) or for different configurations of surfaces [[5](http://www.thermalradiation.net/indexCat.html)].\n",
"\n",
"The view factors need to satisfy the [summation rule](https://en.m.wikipedia.org/wiki/View_factor#Summation_of_view_factors) \n",
"$$\\sum_{j=0}^{n-1} F_{i,j} = 1$$\n",
"and the [reciprocity theorem](https://en.wikipedia.org/wiki/View_factor#Reciprocity):\n",
"$$F_{i,j} S_i = F_{j,i} S_j$$\n",
"where $S_{i}$ and $S_{j}$ are the surface areas.\n",
"\n",
"For a [convex](https://en.m.wikipedia.org/wiki/Convex_function) surface $i$, the [self-viewing factor](https://en.wikipedia.org/wiki/View_factor#Self-viewing_surfaces) is zero,\n",
"$$F_{i,i} = 0$$\n",
"\n",
"Two simplified relations are used to calculate the view factors for buildings.\n",
"\n",
"In the first one, the view factors are defined by:\n",
"$$\\begin{cases}\n",
"F_{i,j} = \\frac{S_i}{S_T}\\\\ \n",
"F_{i,i} = 0\n",
"\\end{cases}$$\n",
"\n",
"where $S_{T} = \\sum_{j=0}^{n-1} S_j$, i.e. the surface $S_j$ is included in the total surface $S_T$. In this method, the reciprocity theorem is satisfied,\n",
"$$F_{i,j} S_i = F_{j,i} S_j = \\frac{S_i S_j}{S_T}$$\n",
"but summation rule isn't,\n",
"$$\\sum_{j=0}^{n-1} F_{i,j} = \\sum_{j=0, j \\neq i}^{n-1} \\frac{S_j}{S_T} = \\frac {S_T - S_i}{S_T} \\neq 1$$\n",
"\n",
"In this case, the heat balance for each surface would be wrong.\n",
"\n",
"In the second one, the view factors are defined by:\n",
"$$\\begin{cases}\n",
"F_{i,j} = \\frac{S_j}{S_T -S_i}\\\\ \n",
"F_{i,i} = 0\n",
"\\end{cases}$$\n",
"\n",
"where $S_{T} = \\sum_{j=0}^{n-1} S_j$, i.e. the surface $S_i$ is not included in the total surface $S_{T,i} = S_T - S_i$. \n",
"\n",
"In this case, the reciprocty theorem is generally not respected:\n",
"$$F_{i, j} S_i = \\frac{S_j}{S_T - S_i} S_i \\neq F_{j, i} S_j = \\frac{S_i}{S_T - S_j} S_j$$\n",
"but the summation rule is respected:\n",
"$$ \\sum_{i=0}^{n-1} F_{i, j} = \\frac{1}{S_T - S_i} \\sum_{\\substack{j=0\\\\i\\neq j}}^{n-1} S_j = 1 $$"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "728db6f6-aa01-4f5c-8cae-6e3fd8a3ddc4",
"metadata": {},
"outputs": [],
"source": [
"# view factor wall-glass\n",
"Fwg = glass['Surface'] / concrete['Surface']"
]
},
{
"cell_type": "markdown",
"id": "456ebb01-0e0e-41f5-9484-34a2496b2e13",
"metadata": {},
"source": [
"Note: The view factor between two surfaces, $j,k$ that are in the same plan (e.g. a window and a wall) is zero,\n",
"$$F_{j,k} = F_{k,j}=0$$\n",
"\n",
"Therefore the total surface $S_{T,i}$ should be:\n",
"$$S_{T,i} = \\sum_{j=0}^{n-1} S_j - \\sum_k S_k$$\n",
"i.e. the surfaces $S_k$ in the same plan with the surface $S_i$ are not included in $S_{T,i}$."
]
},
{
"cell_type": "markdown",
"id": "b9f00e69-9bae-4b7e-bf1d-afddce3c206a",
"metadata": {},
"source": [
"##### View factor between tilted outdoor walls and sky\n",
"\n",
"The view factor between the top surface of finite wall $w$ tilted relative to an infinite plane of the ground $g$ is [[5](http://www.thermalradiation.net/sectionc/C-9.html), [6](http://www.diva-portal.org/smash/get/diva2:1305017/FULLTEXT01.pdf), eq. 4.18]:\n",
"\n",
"$$ F_{w,g} = \\frac {1 - \\cos \\beta}{2}$$\n",
"\n",
"Therefore, the view factor between the tilted wall $w$ and the sky dome $s$ is [[6](http://www.diva-portal.org/smash/get/diva2:1305017/FULLTEXT01.pdf), eq. 4.17]:\n",
"$$ F_{w,s} = 1 - F_{w,g} = \\frac {1 + \\cos \\beta}{2}$$"
]
},
{
"cell_type": "markdown",
"id": "6b226466-40de-4678-9673-fec8a811b873",
"metadata": {
"tags": []
},
"source": [
"##### Thermal network for long wave radiation\n",
"\n",
"The long-wave heat exchange between surfaces may be modelled by using the concept of [radiosity](https://en.m.wikipedia.org/wiki/Radiosity_(radiometry)) and then linearizing the radiative heat exchange. \n",
"\n",
"\n",
"> Figure 5. Radiative long-wave heat exchange between two surfaces: a) modeled by [emmitance](https://en.m.wikipedia.org/wiki/Radiant_exitance) (source) and [radiosity](https://en.m.wikipedia.org/wiki/Radiosity_(radiometry)) (nodes); b) modeled by linearization of emmitance (temperature sources) and radiosity (temperature nodes).\n",
"\n",
"For two surfaces, shown by temperature nodes 4 and 5 in Figure 3 and by nodes 1 and 2 in Figure 4, the [conductances](https://en.m.wikipedia.org/wiki/Radiosity_(radiometry)#Circuit_analogy), in m², for radiative heat exchange expressed by using the emmitance (or the [radiant excitance](https://en.m.wikipedia.org/wiki/Radiant_exitance)) of the black body, the [radiosity](https://en.m.wikipedia.org/wiki/Radiosity_(radiometry)), and the [reciprocity](https://en.m.wikipedia.org/wiki/View_factor#Reciprocity) of view factors are:\n",
"\n",
"$$G_{1}^{r} = \\frac{\\varepsilon_1}{1 - \\varepsilon_1} S_1$$\n",
"\n",
"$$G_{1,2}^{r} = F_{1,2} S_1 = F_{2,1} S_2$$\n",
"\n",
"$$G_{2}^{r} = \\frac{\\varepsilon_2}{1 - \\varepsilon_2} S_2$$\n",
"\n",
"where:\n",
"- $\\varepsilon_1$ and $\\varepsilon_2$ are the [emmisivities](https://en.m.wikipedia.org/wiki/Emissivity) of the surfaces 1 and 2;\n",
"- $S_1$ and $S_2$ - areas of the surfaces 1 and 2, m²;\n",
"- $F_{1,2}$ - [view factor](https://en.m.wikipedia.org/wiki/View_factor) between surfaces 1 and 2.\n",
"\n",
"\n",
"The [net flows leaving the surfaces 1 and 2](https://en.m.wikipedia.org/wiki/Radiosity_(radiometry)#Circuit_analogy) are:\n",
"\n",
"$$q_{net,1} = \\frac{\\varepsilon_1}{1 - \\varepsilon_1} S_1 (M^o_1 - J_1)= G^r_1 (M_1^o - J_1)$$\n",
"\n",
"$$q_{net,2} = \\frac{\\varepsilon_2}{1 - \\varepsilon_2} S_2 (M^o_2 - J_2)= G^r_2 (M_2^o - J_2)$$\n",
"\n",
"respectively, where:\n",
"- $M^o_1$ and $M^o_2$ are the [emmitances](https://en.m.wikipedia.org/wiki/Radiant_exitance) of the surfaces 1 and 2 when emmiting as black bodies, $M^o = \\sigma T^4$, W/m²;\n",
"- $J_1$ and $J_2$ - [radiosities](https://en.m.wikipedia.org/wiki/Radiosity_(radiometry)) of surfaces 1 and 2, W/m²;\n",
"- $G^r_1$ and $G^r_2$ - conductances for long wave radiative heat exchange, m².\n",
"\n",
"The [net flow between surfaces 1 and 2](https://en.m.wikipedia.org/wiki/Radiosity_(radiometry)#Circuit_analogy) is:\n",
"\n",
"$$q_{1,2} = F_{1,2} S_1 (J_1 - J_2) = F_{2,1} S_2 (J_1 - J_2)= G_{1,2}^r (J_1 - J_2)$$\n",
"\n",
"In order to express the long-wave radiative exchange as a function of temperature differences, a linearization of the difference of temperatures $T_1^4 - T_2^4$ may be used:\n",
"\n",
"$$T_1^4 - T_2^4 = (T_1^2 + T_2^2)(T_1^2 - T_2^2) = (T_1^2 + T_2^2)(T_1 + T_2)(T_1 - T_2) = 4 \\bar{T}^3 (T_1 - T_2)$$\n",
"\n",
"where the mean temperature $\\bar{T}$, measured in kelvin, is:\n",
"\n",
"$$\\bar{T} =\\sqrt[3]{ \\frac{(T_1^2 + T_2^2)(T_1 + T_2)}{4}}$$\n",
"\n",
"The evaluation of mean temperaure, $\\bar{T}$, requires the values of the surface tempetratures, $T_1$ and $T_2$. An initial guess can be used (and then an iterative process, for a more precise evaluation).\n",
"\n",
"After linearization, the conductances, in W/K, for radiative heat exchange are:\n",
"\n",
"$$G_{1} = 4 \\sigma \\bar{T}^3 \\frac{\\varepsilon_1}{1 - \\varepsilon_1} S_1$$\n",
"\n",
"$$G_{1,2} = 4 \\sigma \\bar{T}^3 F_{1,2} S_1 = 4 \\sigma \\bar{T}^3 F_{2,1} S_2$$\n",
"\n",
"$$G_{2} = 4 \\sigma \\bar{T}^3 \\frac{\\varepsilon_2}{1 - \\varepsilon_2} S_2$$"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "f911a20f-4e20-43b3-aa72-a7e329a0b951",
"metadata": {},
"outputs": [],
"source": [
"# long wave radiation\n",
"Tm = 20 + 273 # K, mean temp for radiative exchange\n",
"\n",
"GLW1 = 4 * σ * Tm**3 * ε_wLW / (1 - ε_wLW) * wall['Surface']['Layer_in']\n",
"GLW12 = 4 * σ * Tm**3 * Fwg * wall['Surface']['Layer_in']\n",
"GLW2 = 4 * σ * Tm**3 * ε_gLW / (1 - ε_gLW) * wall['Surface']['Glass']"
]
},
{
"cell_type": "markdown",
"id": "939d7aac-b49a-4ff6-be6b-c0e227b5cd21",
"metadata": {
"tags": []
},
"source": [
"The equivalent conductance, in W/K, for the radiative long-wave heat exchange between the wall and the glass window is:\n",
"$$G = \\frac{1}{1/G_1 + 1/G_{1,2} + 1/G_2}$$"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "8f9999e8-b7ed-4f5b-87c9-5068d576b05e",
"metadata": {},
"outputs": [],
"source": [
"GLW = 1 / (1 / GLW1 + 1 / GLW12 + 1 / GLW2)"
]
},
{
"cell_type": "markdown",
"id": "760164d6-ad67-4326-8c5f-dbc7c2db3c36",
"metadata": {},
"source": [
"*Note*: Resistances in [series or parallel](https://en.m.wikipedia.org/wiki/Series_and_parallel_circuits) can be replaced by their equivalent resistance. "
]
},
{
"cell_type": "markdown",
"id": "bf582ff0-b249-4c75-ac60-07574b741a0a",
"metadata": {
"tags": []
},
"source": [
"#### Advection\n",
"\n",
"The [volumetric flow rate](https://en.m.wikipedia.org/wiki/Volumetric_flow_rate) of the air, in m³/s, is:\n",
"\n",
"$$\\dot{V}_a = \\frac{\\mathrm{ACH}}{3600} V_a$$\n",
"\n",
"where:\n",
"- $\\mathrm{ACH}$ ([air changes per hour](https://en.m.wikipedia.org/wiki/Air_changes_per_hour)) is the air infiltration rate, 1/h;\n",
"- $3600$ - number of seconds in one hour, s/h;\n",
"- $V_a$ - volume of the air in the thermal zone, m³."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "4de7fa16-19de-449b-b932-58a89ad98fb5",
"metadata": {},
"outputs": [],
"source": [
"# ventilation flow rate\n",
"Va = l**3 # m³, volume of air\n",
"ACH = 1 # air changes per hour\n",
"Va_dot = ACH / 3600 * Va # m³/s, air infiltration"
]
},
{
"cell_type": "markdown",
"id": "aa9cba86-76bc-4650-ba65-4a735ddca022",
"metadata": {
"tags": []
},
"source": [
"The net flow rate that the building receives by [advection](https://en.m.wikipedia.org/wiki/Advection), i.e., introducing outdoor air at temperature $T_o$ and extracting indoor air at temperature $\\theta_i$ by [ventilation](https://en.m.wikipedia.org/wiki/Ventilation_(architecture)) and/or [air infiltration](https://en.m.wikipedia.org/wiki/Infiltration_(HVAC)), is:\n",
"\n",
"$$q_v = \\dot{m}_a c_a (T_o - \\theta_i) = \\rho_a c_a \\dot{V}_a (T_o - \\theta_i)$$\n",
"\n",
"where:\n",
"- $\\dot{m}_a$ is the [mass flow rate](https://en.m.wikipedia.org/wiki/Mass_flow_rate) of air, kg/s;\n",
"- $\\dot{V}_a$ - [volumetric flow rate](https://en.m.wikipedia.org/wiki/Volumetric_flow_rate), m³/s;\n",
"- $c_a$ - [specific heat capacity](https://en.m.wikipedia.org/wiki/Specific_heat_capacity) of the air, J/kg·K;\n",
"- $\\rho_a$ - [density](https://en.m.wikipedia.org/wiki/Density) of air, kg/m³;\n",
"- $T_o$ - outdoor air temperature, °C (noted in majuscule because it is a *temperature source* or *input variable*);\n",
"- $\\theta_i$ - indoor air temperature, °C (noted in minuscule because it is a *dependent temperature* or *output variable*).\n",
"\n",
"Therefore, the conductance of [advection](https://en.m.wikipedia.org/wiki/Advection) by [ventilation](https://en.m.wikipedia.org/wiki/Ventilation_(architecture)) and/or [infiltration](https://en.m.wikipedia.org/wiki/Infiltration_(HVAC)), in W/K, is:\n",
"\n",
"$$G_v = \\rho_a c_a \\dot{V}_a$$"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "12396b52-d8be-4445-8360-0f70c905d7f8",
"metadata": {},
"outputs": [],
"source": [
"# ventilation & advection\n",
"Gv = air['Density'] * air['Specific heat'] * Va_dot"
]
},
{
"cell_type": "markdown",
"id": "ba620d83-b3da-4adf-a7ae-6e9dc8bd1516",
"metadata": {},
"source": [
"> Table 2. Typical values for the ventilation rates (in air changes per hour, ACH) as a function of the position of windows (H. Recknagel, E. Spenger, E_R Schramek (2013), Table 1.12.1-4)\n",
"\n",
"| Position of windows | Ventilation rate, ACH [h⁻ⁱ] |\n",
"| --------------------------------------- | ---------------------- |\n",
"| Window closed, doors closed | 0 to 0.5 |\n",
"| Tilted window, venetian blind closed | 0.3 to 1.5 |\n",
"| Tilted window, whitout venetian blind | 0.8 to 4.0 |\n",
"| Window half opened | 5 to 10 |\n",
"| Window fully open | 9 to 15 |\n",
"| Window and French window fully open (cross ventilation) | about 40 |\n"
]
},
{
"cell_type": "markdown",
"id": "3344af80-e018-4cb2-a01c-de4cc9b967d0",
"metadata": {
"tags": []
},
"source": [
"#### Proportional controller\n",
"\n",
"In the simplest representation, the [HVAC system](https://en.m.wikipedia.org/wiki/HVAC_control_system) can be considered as a [proportional controller](https://en.m.wikipedia.org/wiki/Proportional_control) that adjusts the heat flow rate $q_{HVAC}$ in order to control the indoor temperature $\\theta_i$ at its setpoint value $T_{i,sp}$. The heat flow-rate, in W, injected by the [HVAC](https://en.m.wikipedia.org/wiki/Heating,_ventilation,_and_air_conditioning) system into the controlled space is:\n",
"\n",
"$$ q_{HVAC} = K_p (T_{i, sp} - \\theta_i)$$\n",
"\n",
"where:\n",
"- $K_p$ is the proportional gain, W/K;\n",
"- $T_{i, sp}$ - indoor temperature [setpoint](https://en.m.wikipedia.org/wiki/Setpoint_(control_system)), °C (noted in majuscule because it is an *input, i.e. independent, variable*);\n",
"- $\\theta_i$ - indoor temperature, °C (noted in minuscule because it is a *output, i.e. dependent variable*).\n",
"\n",
"This equation shows that the proportional controller can be modelled by a source of temperature, $T_{i, sp}$, and a conductance, $K_p$. If the controller gain tends towards:\n",
"- infinity, $K_p \\rightarrow \\infty$, then the controller is perfect, $\\theta_i \\rightarrow T_{i, sp}$.\n",
"- zero, $K_p \\rightarrow 0$, then the controller is not acting and the building is in free-running, i.e. $q_{HVAC} = 0$ ([Ghiaus 2003](https://doi.org/10.1016/S0378-7788(02)00110-X)).\n",
"\n",
"*Note*: Respecting the [sign convention](https://en.m.wikipedia.org/wiki/Passive_sign_convention#Active_and_passive_components), the flow rate $q_{HVAC}$ is oriented from the lower to the higher potential of the temperature source $T_{i,sp}$."
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "b2e864e6-7854-465c-8049-18967065e84f",
"metadata": {},
"outputs": [],
"source": [
"# P-controler gain\n",
"Kp = 1e4 # almost perfect controller Kp -> ∞\n",
"Kp = 1e-3 # no controller Kp -> 0\n",
"Kp = 0"
]
},
{
"cell_type": "markdown",
"id": "e983632f-041d-4066-a00a-74a2f1bbe18b",
"metadata": {
"tags": []
},
"source": [
"#### Conductances in series and/or parallel\n",
"If conductances are connected to temperature nodes which have no capacity and/or flow rate source, then the conductances can be considered in [series or parallel](https://en.m.wikipedia.org/wiki/Series_and_parallel_circuits) (depending on the connection). Let's consider, for example, the outdoor side of the glass window (Figure 3): the outdoor convection conductance and the conduction conductance (corresponding to half of the width of the glass) are in series:\n",
"\n",
"$$ G_{gs} = \\frac{1}{1/G_{g,cv.out } + 1/(2 G_{g,cd})} = \n",
"\\frac{1}{\\frac{1}{h_{out} S_g} + \\frac{w / 2}{\\lambda S_g}}\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "00673392-3443-4a45-8772-2533b07bfe51",
"metadata": {},
"outputs": [],
"source": [
"# glass: convection outdoor & conduction\n",
"Ggs = float(1 / (1 / Gg.loc['h', 'out'] + 1 / (2 * G_cd['Glass'])))"
]
},
{
"cell_type": "markdown",
"id": "096daa39-110e-4e99-bab0-00dabab6d17b",
"metadata": {
"tags": []
},
"source": [
"### Thermal capacities\n",
"#### Walls\n",
"The [thermal capacities](https://en.m.wikipedia.org/wiki/Heat_capacity) of the wall, in J/kg, are:\n",
"\n",
"$$C_w= m_w c_w= \\rho_w c_w w_w S_w$$\n",
"\n",
"where:\n",
"- $m_w = \\rho_w w_w S_w$ is the mass of the wall, kg;\n",
"- $c_w$ - [specific heat capacity](https://en.m.wikipedia.org/wiki/Specific_heat_capacity), J/(kg⋅K);\n",
"- $\\rho_w$ - [density](https://en.m.wikipedia.org/wiki/Density), kg/m³;\n",
"- $w_w$ - width of the wall, m;\n",
"- $S_w$ - surface area of the wall, m²."
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "069c5751-493f-46a9-9d62-d415c8c86c36",
"metadata": {},
"outputs": [],
"source": [
"C = wall['Density'] * wall['Specific heat'] * wall['Surface'] * wall['Width']"
]
},
{
"cell_type": "markdown",
"id": "c2d7d457-941e-43bf-acb5-59598eaec544",
"metadata": {
"tags": []
},
"source": [
"#### Air\n",
"Similarly, the thermal capacity of the air, in J/kg, is:\n",
"\n",
"$$C_a = m_a c_a = \\rho_a c_a V_a$$\n",
"\n",
"where:\n",
"- $m_a = \\rho_a V_a$ is the mass of the air, kg;\n",
"- $\\rho_w$ - [density](https://en.m.wikipedia.org/wiki/Density) of air, kg/m³;\n",
"- $c_a$ - specific heat capacity of the air, J/(kg⋅K);\n",
"- $V_a$ - volume of the air in the thermal zone, m³."
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "5ad5ddf7-6842-4ad5-adf0-61081c440ef1",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
Capacity
\n",
"
\n",
" \n",
" \n",
"
\n",
"
Layer_out
\n",
"
18216000.0
\n",
"
\n",
"
\n",
"
Layer_in
\n",
"
239580.0
\n",
"
\n",
"
\n",
"
Glass
\n",
"
1089000.0
\n",
"
\n",
"
\n",
"
Air
\n",
"
32400.0
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Capacity\n",
"Layer_out 18216000.0\n",
"Layer_in 239580.0\n",
"Glass 1089000.0\n",
"Air 32400.0"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"C['Air'] = air['Density'] * air['Specific heat'] * Va\n",
"pd.DataFrame(C, columns=['Capacity'])"
]
},
{
"cell_type": "markdown",
"id": "9519c7be-a11b-46cc-b253-c843122e1f8d",
"metadata": {},
"source": [
"### Temperature sources\n",
"\n",
"The [temperature sources](https://en.m.wikipedia.org/wiki/Voltage_source#Ideal_voltage_sources) model temperatures which vary independently of what happens in the themal circuit; they are inputs of the physical model. Generally, the temperature sources are:\n",
"- outdoor air and ground temperature;\n",
"- temperature of adjacent spaces which have controlled temperature;\n",
"- setpoint temperature."
]
},
{
"cell_type": "markdown",
"id": "f12176f0-3744-4a96-8f92-e9253e4d6e34",
"metadata": {
"jp-MarkdownHeadingCollapsed": true,
"tags": []
},
"source": [
"#### Outdoor air and ground temperature\n",
"The hourly values of outdoor temperatures can be obtained from weather data files downloadable from the [Repository of free climate data for building performance simulation](http://climate.onebuilding.org) or from [Weather data for EnergyPlus®](https://energyplus.net/weather) (see the tutorial on [Weather data and solar radiation](01WeatherData.ipynb))."
]
},
{
"cell_type": "markdown",
"id": "88477ba9-030d-49c5-881a-7457ece60d23",
"metadata": {},
"source": [
"#### Adjacent spaces with controlled temperature\n",
"\n",
"If the adjacent spaces are controlled by a HVAC system, it means that their temperature can be considered independent of the studied thermal zone(s); therefore, they can be modelled by a temperature source."
]
},
{
"cell_type": "markdown",
"id": "5be6f99c-ea56-410b-b123-655dd53a0c8a",
"metadata": {
"tags": []
},
"source": [
"#### Setpoint temperature\n",
"\n",
"[Setpoint](https://en.m.wikipedia.org/wiki/Setpoint_(control_system)) temperature does not depend on the heat transfer processes of the analyzed thermal zone. If the HVAC system can deliver the heat flow rate:\n",
"\n",
"$$ q_{HVAC} = K_p (T_{i, sp} - \\theta_i)$$\n",
"\n",
"where:\n",
"- $K_p$ is the proportional gain, W/K;\n",
"- $T_{i, sp}$ - indoor temperature [setpoint](https://en.m.wikipedia.org/wiki/Setpoint_(control_system)), °C;\n",
"- $\\theta_i$ - indoor temperature, °C,\n",
"\n",
"then the setpoint for indoor temperature, $T_{i, sp}$, may be modelled by a source of temperature."
]
},
{
"cell_type": "markdown",
"id": "2f59b264-6a45-428e-a9c6-00132387bd75",
"metadata": {
"tags": []
},
"source": [
"### Heat flow rate sources\n",
"The [heat flow rate sources](https://en.m.wikipedia.org/wiki/Current_source#Background) model flow rates which vary idependently of what happens in the themal circuit. They are inputs of the physical model. Generally, the heat flow rate sources are:\n",
"- solar radiation absorbed by the walls;\n",
"- internal auxiliary sources."
]
},
{
"cell_type": "markdown",
"id": "f4e620b1-b31b-4a70-96ea-bc1dc4943707",
"metadata": {
"tags": []
},
"source": [
"#### Solar radiation absorbed by the walls\n",
"\n",
"The [direct](https://en.m.wikipedia.org/wiki/Direct_insolation), diffuse and reflected components of the [solar radiation](https://en.m.wikipedia.org/wiki/Solar_irradiance) on a tilted surface can be estimated from weather data by using the function `sol_rad_tilt_surf` from the module `dm4bem` (see the tutorial on [Weather data and solar radiation](../t01/t01ReadWeatherData.ipynb))."
]
},
{
"cell_type": "markdown",
"id": "2a081593-6450-4c0b-b25f-929368727023",
"metadata": {
"tags": []
},
"source": [
"##### External wall\n",
"\n",
"The radiation absorbed by the outdoor surface of the wall is:\n",
"\n",
"$$\\Phi_o = \\alpha_{w,SW} S_w E_{tot}$$\n",
"\n",
"where:\n",
"- $\\alpha_{w,SW}$ is the [absorptance](https://en.m.wikipedia.org/wiki/Absorptance) of the outdoor surface of the wall in short wave, $0 \\leqslant \\alpha_{w,SW} \\leqslant 1$;\n",
"- $S_w$ - surface area of the wall, m²;\n",
"- $E_{tot}$ - total [solar irradiance](https://en.m.wikipedia.org/wiki/Solar_irradiance) on the wall, W/m²."
]
},
{
"cell_type": "markdown",
"id": "40f0cfba-4376-4ad5-a5ce-e9a046226a00",
"metadata": {
"tags": []
},
"source": [
"##### Internal walls\n",
"\n",
"The total shortwave incident irradiance on the wall $i$, $E_i$, may be estimated as a function of the direct solar irradiance incident on the surface of the walls, $E_{i}^{o}$:\n",
"\n",
"$$S_i E_i = S_i E_{i}^{o} + \\sum_{j=1}^{n} F_{j,i} S_j \\rho_j E_j$$\n",
"\n",
"where:\n",
"- $S_i$ is the area of the surface of the wall $i$, m²;\n",
"- $E_i$ - total irradiance received directly and by multiple reflections on surface $i$, W/m²;\n",
"- $E_{i}^{o}$ - irradiance received directly from the sun on surface $i$, W/m²;\n",
"- $F_{j, i}$ - [view factor](https://en.m.wikipedia.org/wiki/View_factor) between surface $j$ and surface $i$, $0 ⩽ F_{j,i} ⩽ 1$;\n",
"- $\\rho_j$ - [reflectance](https://en.m.wikipedia.org/wiki/Reflectance) of surface $j$, $0 ⩽ \\rho_j ⩽ 1$.\n",
"\n",
"\n",
"By taking into account the [reciprocity](https://en.m.wikipedia.org/wiki/View_factor#Reciprocity) of the view factors: $S_i F_{i,j} = S_j F_{j,i}$, the set of previous equation becomes:\n",
"\n",
"$$\n",
"\\begin{bmatrix}\n",
"1 - \\rho_1 F_{1,1} & - \\rho_2 F_{1,2} & ... & - \\rho_n F_{1,n}\\\\ \n",
"- \\rho_1 F_{2,1} & 1 - \\rho_2 F_{2,2} & ... & - \\rho_n F_{2,n} \\\\ \n",
"... & ... & ... & ... \\\\ \n",
"- \\rho_1 F_{n,1} & - \\rho_2 F_{n,1} & ... & 1 - \\rho_n F_{n,n}\n",
"\\end{bmatrix} \\begin{bmatrix}\n",
"E_1\\\\ \n",
"E_2\\\\ \n",
"...\\\\ \n",
"E_n\n",
"\\end{bmatrix} = \\begin{bmatrix}\n",
"E_{1}^{o}\\\\ \n",
"E_{2}^{o}\\\\ \n",
"...\\\\ \n",
"E_{n}^{o}\n",
"\\end{bmatrix}\n",
"$$\n",
"\n",
"or\n",
"\n",
"$$(I - \\rho \\circ F) E = E^o$$\n",
"\n",
"The unknown total [irradiances](https://en.m.wikipedia.org/wiki/Irradiance) on walls, in W/m², are then\n",
"\n",
"$$ E = (I - \\rho \\circ F)^{-1} E^o$$\n",
"\n",
"where:\n",
"\n",
"- the symbol $\\circ$ represents the [Hadamard (or element-wise) product](https://en.wikipedia.org/wiki/Hadamard_product_(matrices));\n",
"\n",
"$I =\\begin{bmatrix}\n",
"1 & 0 & ... & 0 \\\\ \n",
"0 & 1 & ... & 0 \\\\ \n",
"... & ... & ... & ...\\\\ \n",
"0 & 0 & ... & 1 \n",
"\\end{bmatrix}, $ is the [identity matrix](https://en.m.wikipedia.org/wiki/Identity_matrix);\n",
"\n",
"$\\rho = \\begin{bmatrix}\n",
"\\rho_1\\\\ \n",
"\\rho_2\\\\ \n",
"...\\\\ \n",
"\\rho_n\n",
"\\end{bmatrix}$ - vector of [reflectances](https://en.m.wikipedia.org/wiki/Reflectance), $0 \\le \\rho_{i,j} \\le 1$;\n",
"\n",
"$F = \\begin{bmatrix}\n",
"F_{1,1} & F_{1,2} & ... & F_{1,n}\\\\ \n",
"F_{2,1} & F_{2,2} & ... & F_{2,n} \\\\ \n",
"... & ... & ... & ...\\\\ \n",
"F_{n,1} & F_{n,2} & ... & F_{n,n}\n",
"\\end{bmatrix}$ - matrix of [view factors](https://en.m.wikipedia.org/wiki/View_factor), $0 \\le F_{i,j} \\le 1$;\n",
"\n",
"$E^o = \\begin{bmatrix}\n",
"E_{1}^{o}\\\\ \n",
"E_{2}^{o}\\\\ \n",
"...\\\\ \n",
"E_{n}^{o}\n",
"\\end{bmatrix}$ - vector of [direct solar irradiances](https://en.m.wikipedia.org/wiki/Solar_irradiance), W/m²;\n",
"\n",
"$E = \\begin{bmatrix}\n",
"E_1\\\\ \n",
"E_2\\\\ \n",
"...\\\\ \n",
"E_n\n",
"\\end{bmatrix}$ - vector of unknown total irradiances, W/m².\n",
"\n",
"\n",
"The radiative short wave (i.e. solar) heat flow rate on each surface is:\n",
"\n",
"$$ \\Phi = S E $$\n",
"\n",
"where:\n",
"\n",
"$\\Phi = \\begin{bmatrix}\n",
"\\Phi_1\\\\ \n",
"\\Phi_2\\\\ \n",
"...\\\\ \n",
"\\Phi_n\n",
"\\end{bmatrix}$ - vector of total heat flow rates due to solar radiation, W; \n",
"\n",
"$S =\\begin{bmatrix}\n",
"S_1 & 0 & ... & 0 \\\\ \n",
"0 & S_2 & ... & 0 \\\\ \n",
"... & ... & ... & ...\\\\ \n",
"0 & 0 & ... & S_n \n",
"\\end{bmatrix}$ - matrix of surface areas of walls $i$, m²."
]
},
{
"cell_type": "markdown",
"id": "55178565-8a30-4c8b-9760-6fe48a5548fc",
"metadata": {},
"source": [
"#### Internal sources\n",
"\n",
"Internal flow rates are generated by occupants and by the electrical equipment (with values given for [offices](https://energieplus-lesite.be/theories/bilan-thermique44/charges-thermiques-internes-pour-les-bureaux/), [commercial spaces](https://energieplus-lesite.be/theories/bilan-thermique44/charges-thermiques-internes-pour-les-commerces/), etc.)."
]
},
{
"cell_type": "markdown",
"id": "5a994858-649e-498d-8115-ad658b4c253d",
"metadata": {
"tags": []
},
"source": [
"## System of algebraic-differential equations (DAE)\n",
"\n",
"The analysis of a thermal circuit, or the direct problem ([Ghiaus 2022](https://hal.archives-ouvertes.fr/hal-03484064/document)), means to find the temperatures in the nodes, $\\theta$, and the heat flows on the branches, $q$, i.e. to solve for $\\theta$ and $q$ the system of [Differential-Algebraic Equations (DAE)](https://en.m.wikipedia.org/wiki/Differential-algebraic_system_of_equations) (Figures 3 and 4):\n",
"\n",
"$$\\left\\{\\begin{array}{ll}\n",
"C \\dot{\\theta} = -(A^T G A) \\theta + A^T G b + f\\\\ \n",
"q = G (-A \\theta + b)\n",
"\\end{array}\\right.$$\n",
"\n",
"where:\n",
"- $\\theta$ is the temperature vector of size $n_\\theta$ equal to the number of nodes;\n",
"- $q$ - heat flow vector of size $n_q$ equal to the number of branches;\n",
"- $A$ - [incidence matrix](https://en.m.wikipedia.org/wiki/Incidence_matrix) of size $n_q$ rows and $n_{\\theta}$ columns, where $n_q$ is the number of flow branches and $n_{\\theta}$ is the number of temperature nodes. It shows how the temperature nodes are connected by oriented branches of heat flows:\n",
" - if flow *m* enters into node *n*, then the element (*m, n*) of the matrix $A$ is 1, i.e., $A_{m,n} = 1$;\n",
" - if flow *m* exits from node *n*, then the element (*m, n*) of the matrix $A$ is -1, i.e., $A_{m,n} = -1$, ; \n",
" - if flow *m* is not connected to node *n*, then the element (*m, n*) of the matrix $A$ is 0, i.e., $A_{m,n} = 0$.\n",
"\n",
"- $G$ - conductance diagonal matrix of size $n_q \\times n_q$, where $n_q$ is the number of flow branches: diagonal matrix containing the conductances. Each branch $k$ needs to contain a conductance $0 < G_{k,k} < \\infty $. \n",
"\n",
"- $C$ - capacity diagonal matrix of size $n_θ \\times n_θ$, where $n_θ$ is the number of temperature nodes: diagonal matrix containing the capacities. If there is no capacity in the node *n*, then $C_{n, n} = 0$.\n",
"\n",
"- $b$ - temperature source vector of size $n_q$: if there is no temperature source on the branch *m*, then $b_m = 0$.\n",
"\n",
"- $f$ - heat flow source vector of size $n_θ$: if there is no heat flow source in the node *n*, then $f_n = 0$.\n",
"\n",
"The resolution is first done for temperatures, $\\theta$, by solving the equation\n",
"$$C \\dot{\\theta} = -(A^T G A) \\theta + A^T G b + f$$\n",
"which, generally, is a system of differential-algebraic equations (DAE). Then, the heat flow rates are found from the equation\n",
"$$q = G (-A \\theta + b)$$\n",
"\n",
"\n",
"> Figure 6. Matrices of the system of Differential-Algebraic Equations (DAE) \n",
"\\begin{aligned}\n",
" &C \\dot{\\theta} = -(A^T G A) \\theta + A^T G b + f \\\\\n",
" &q = G (-A \\theta + b)\n",
"\\end{aligned}"
]
},
{
"cell_type": "markdown",
"id": "e0eeaa18-4cbb-4ac3-b7e9-98b3edbb863f",
"metadata": {},
"source": [
"### A: incidence matrix\n",
"\n",
"The [incidence matrix](https://en.m.wikipedia.org/wiki/Incidence_matrix) is:\n",
"\n",
"$A_{kl} = \\begin{cases}\\phantom{-}\n",
"0 & \\text{if branch } q_k \\text{ is not connected to node } \\theta_l \\\\ \n",
"+1 & \\text{if branch } q_k \\text{ enters into node } \\theta_l\\\\ \n",
"-1 & \\text{if branch } q_k \\text{ gets out of node } \\theta_l \n",
"\\end{cases}$\n",
"\n",
"For the themal circuit shown in Figure 3,\n",
"\n",
"$ A = \\begin{cases}\n",
"A_{0,0} = 1\\\\ \n",
"A_{1,0} = -1, A_{1,1} = 1\\\\ \n",
"...\\\\\n",
"A_{11,6} = 1\\\\\n",
"\\end{cases}$"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "beaddf90-558e-45e4-a912-f5db92f2430a",
"metadata": {},
"outputs": [],
"source": [
"A = np.zeros([12, 8]) # n° of branches X n° of nodes\n",
"A[0, 0] = 1 # branch 0: -> node 0\n",
"A[1, 0], A[1, 1] = -1, 1 # branch 1: node 0 -> node 1\n",
"A[2, 1], A[2, 2] = -1, 1 # branch 2: node 1 -> node 2\n",
"A[3, 2], A[3, 3] = -1, 1 # branch 3: node 2 -> node 3\n",
"A[4, 3], A[4, 4] = -1, 1 # branch 4: node 3 -> node 4\n",
"A[5, 4], A[5, 5] = -1, 1 # branch 5: node 4 -> node 5\n",
"A[6, 4], A[6, 6] = -1, 1 # branch 6: node 4 -> node 6\n",
"A[7, 5], A[7, 6] = -1, 1 # branch 7: node 5 -> node 6\n",
"A[8, 7] = 1 # branch 8: -> node 7\n",
"A[9, 5], A[9, 7] = 1, -1 # branch 9: node 5 -> node 7\n",
"A[10, 6] = 1 # branch 10: -> node 6\n",
"A[11, 6] = 1 # branch 11: -> node 6\n",
"\n",
"# np.set_printoptions(suppress=False)\n",
"# pd.DataFrame(A)"
]
},
{
"cell_type": "markdown",
"id": "2c2db9a2-e612-4077-8cb1-9f14a3111fb2",
"metadata": {},
"source": [
"### G: conductance matrix\n",
"\n",
"The conductance matrix of the themal circuit shown in Figure 3 is diagonal:\n",
"\n",
"$ G = \\begin{cases}\n",
"G_{0,0} = G_{w,out} & \\text{convection outside surface of the wall}\\\\ \n",
"G_{1,1} = G_{2,2} = 2G_{cd,Layer\\,out} & \\text{conduction in half width of the outer layer}\\\\ \n",
"G_{3,3} = G_{4,4} = 2G_{cd,Layer\\,in} & \\text{conduction in half width of the inner layer}\\\\ \n",
"G_{5,5} = G_{LW} & \\text{long-wave radiation walls - window}\\\\\n",
"G_{6,6} = G_{w,in} & \\text{convection inside surface of the wall}\\\\\n",
"G_{7,7} = G_{g,in} & \\text{convection inside surface of the glass}\\\\\n",
"G_{8,8} = G_{gs} & \\text{convection outside surface of the glass}\\\\ & \\text{and conduction in half width of the glass}\\\\\n",
"G_{9,9} = 2G_{cd,glass} & \\text{conduction in half width of the glass}\\\\\n",
"G_{10,10} = G_v & \\text{advection by ventilation}\\\\\n",
"G_{11,11} = K_p & \\text{gain of proportional controller}\n",
"\\end{cases}$"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "8c53e123-581d-40bd-8be5-0013a4b8e74f",
"metadata": {},
"outputs": [],
"source": [
"G = np.diag(np.hstack(\n",
" [Gw['out'],\n",
" 2 * G_cd['Layer_out'], 2 * G_cd['Layer_out'],\n",
" 2 * G_cd['Layer_in'], 2 * G_cd['Layer_in'],\n",
" GLW,\n",
" Gw['in'],\n",
" Gg['in'],\n",
" Ggs,\n",
" 2 * G_cd['Glass'],\n",
" Gv,\n",
" Kp]))\n",
"\n",
"# np.set_printoptions(precision=3, threshold=16, suppress=True)\n",
"# pd.set_option(\"display.precision\", 1)\n",
"# pd.DataFrame(G)"
]
},
{
"cell_type": "markdown",
"id": "0d0d7f02-bc07-497f-a66b-0f07682530fb",
"metadata": {},
"source": [
"### C: capacity matrix\n",
"\n",
"The capacity matrix of the themal circuit shown in Figure 3 is diagonal:\n",
"\n",
"$ C = \\begin{cases}\n",
"C_{1,1} = C_{Layer\\,out} & \\text{outer layer of the wall}\\\\ \n",
"C_{3,3} = C_{Layer\\,in} & \\text{inner layer of the wall}\\\\ \n",
"C_{6,6} = C_{Air} & \\text{air of the room}\\\\ \n",
"C_{7,7} = C_{Glass} & \\text{glass of the windows}\\\\\n",
"\\end{cases}$\n",
"\n",
"The thermal capacities of the air and of the glass can be neglected or not."
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "ca2b5a02-7d8e-4292-8a91-46a4ffcc3200",
"metadata": {},
"outputs": [],
"source": [
"neglect_air_glass = False\n",
"\n",
"if neglect_air_glass:\n",
" C = np.diag([0, C['Layer_out'], 0, C['Layer_in'], 0, 0,\n",
" 0, 0])\n",
"else:\n",
" C = np.diag([0, C['Layer_out'], 0, C['Layer_in'], 0, 0,\n",
" C['Air'], C['Glass']])\n",
"\n",
"# pd.set_option(\"display.precision\", 3)\n",
"# pd.DataFrame(C)"
]
},
{
"cell_type": "markdown",
"id": "efedaf69-3d44-427b-8901-0a68be3edabd",
"metadata": {
"tags": []
},
"source": [
"### b: temperature source vector\n",
"\n",
"The vector of *temperature sources* is $b$, of size $n_q$, the number of branches (in this example 12). An element of the vector $b$ corresponding to a branch without a source is zero. If the flow in a source is from the low potential to the high potential of the source (i.e. from - to +), then the source is positive. If the flow rate in the temperature source is from high potential to low potential (i.e. from + to -), then the source is negative (see [passive sign convention](https://en.m.wikipedia.org/wiki/Passive_sign_convention)). \n",
"\n",
"For the thermal circuit shown in Figure 3,\n",
"\n",
"$$b = [\\begin{matrix}\n",
"T_o &0 &0 &0 &0 &0 &0 &0 &T_o &0 &T_o &T_{i,sp} \n",
"\\end{matrix}]^T$$\n",
"\n",
"i.e. $b_0 = b_8 = b_{10} = T_o$ and $b_{11} = T_{i,sp}$ where:\n",
"- $T_o$ is the outdoor temperature, °C;\n",
"- $T_{i,sp}$ - set-point temperaure for the indoor air, °C.\n",
"\n",
"Since the temperature sorces $T_o$ and $T_{i,sp}$ are [time series](https://en.m.wikipedia.org/wiki/Time_series), in vector $b$ the branches which contain temperature sources are designated by $1$ and the branches without any temeprature source by $0$."
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "26aab83c-5ed8-427a-8ec2-afdf98923cbf",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"b = [1. 0. 0. 0. 0. 0. 0. 0. 1. 0. 1. 1.]\n"
]
}
],
"source": [
"b = np.zeros(12) # branches\n",
"b[[0, 8, 10, 11]] = 1 # branches with temperature sources\n",
"print(f'b = ', b)"
]
},
{
"cell_type": "markdown",
"id": "236ad1c6-64ac-4e42-b7cb-46be011ccc75",
"metadata": {
"tags": []
},
"source": [
"### f: heat flow source vector\n",
"\n",
"The vector of *heat sources* is $f$, of size $n_{\\theta}$, the number of nodes (in this example 8). An element of the vector $f$ corresponding to a node without a heat source is zero.\n",
"\n",
"For the thermal circuit shown in Figure 3,\n",
"\n",
"$$f = [\\begin{matrix}\n",
"\\Phi_o &0 &0 &0 &\\Phi_i &0 &\\dot{Q_a} &\\Phi_a \n",
"\\end{matrix}]^T$$\n",
"\n",
"i.e. $f_0 = \\Phi_o$, $f_4 = \\Phi_i$, $f_6 = \\dot{Q_a}$, and $f_7 = \\Phi_a$, where:\n",
"- $\\Phi_o$ - solar radiation absorbed by the outdoor surface of the wall, W;\n",
"- $\\Phi_i$ - solar radiation absorbed by the indoor surface of the wall, W;\n",
"- $\\dot{Q}_a$ - auxiliary heat gains (i.e., occupants, electrical devices, etc.), W;\n",
"- $\\Phi_a$ - solar radiation absorbed by the glass, W.\n",
"\n",
"Since the flow rate sorces $\\Phi_o$, $\\Phi_i$, $\\dot{Q}_a$ and $\\Phi_a$ are [time series](https://en.m.wikipedia.org/wiki/Time_series), in vector $f$ the nodes which contain flow rate sources are designated by $1$ and the nodes without any flow rate source by $0$."
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "0879a889-03f1-4858-b039-014ba391197d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"f = [1. 0. 0. 0. 1. 0. 1. 1.]\n"
]
}
],
"source": [
"f = np.zeros(8) # nodes\n",
"f[[0, 4, 6, 7]] = 1 # nodes with heat-flow sources\n",
"print(f'f = ', f)"
]
},
{
"cell_type": "markdown",
"id": "5dee59ff-9153-498a-ab9b-a1bedb6b5d35",
"metadata": {
"tags": []
},
"source": [
"### y: output vector\n",
"\n",
"The vector of outputs is $y$, of size $n_{\\theta}$, the number of nodes (in this example 8). The non-zero values of $y$ indicate the nodes which are the outputs of the model.\n",
"\n",
"For the thermal circuit shown in Figure 3, if the output is the indoor air temperature, then the output vector is:\n",
"\n",
"$$y = [\\begin{matrix}\n",
"0 &0 &0 &0 &0 &0 &\\theta_6 &0 \n",
"\\end{matrix}]^T$$\n",
"\n",
"In vector $y$, the nodes for which the temperatures are outputs are noted by $1$ and the other nodes by $0$."
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "19fe1e2e-15aa-4739-9524-8003117eac45",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"y = [0. 0. 0. 0. 0. 0. 1. 0.]\n"
]
}
],
"source": [
"y = np.zeros(8) # nodes\n",
"y[[6]] = 1 # nodes (temperatures) of interest\n",
"print(f'y = ', y)"
]
},
{
"cell_type": "markdown",
"id": "966dd727-c0b3-4c10-b458-6b3383219905",
"metadata": {
"tags": []
},
"source": [
"## State-space representation\n",
"The [differential-algebraic system of equations (DAE)](https://en.m.wikipedia.org/wiki/Differential-algebraic_system_of_equations)\n",
"\n",
"$$C \\dot{\\theta} = -(A^T G A) \\theta + A^T G b + f$$\n",
"\n",
"is transformed in [state-space representation](https://en.m.wikipedia.org/wiki/State-space_representation) ([Ghiaus 2013](https://hal.archives-ouvertes.fr/hal-03605823/document)):\n",
"\n",
"$$\\left\\{\\begin{array}{rr}\n",
"\\dot{\\theta}_s=A_s \\theta_s + B_s u\\\\ \n",
"y = C_s \\theta_s + D_s u\n",
"\\end{array}\\right.$$\n",
"\n",
"where:\n",
"- $\\theta_s$ is the vector of state variables which are the temperatures of nodes containing capacities; the elements are in the same order as in the vector of temperatures, $\\theta$; its dimension, $\\dim \\theta_s$, is equal to the number of capacities from the thermal network; for the circuit presented in Figure 3, $\\theta_s = [\\theta_1, \\theta_3, \\theta_6, \\theta_7]^T$;\n",
"\n",
"- $u = \\begin{bmatrix} b_T \\\\ f_Q\\end{bmatrix}$ - vector of inputs of dimension $\\dim u$ equal to the number of sources (of temperaure, $b_T$, and heat flows, $f_Q$) of the thermal network, where:\n",
"\n",
" - vector $b_T$ of nonzero elements of vector $b$ of temperature sources; for the circuit presented in Figure 3, $b_T = [T_o, T_o, T_o, T_{i,sp}]^T$ corresponds to branches 0, 8, 10 and 11; \n",
" - vector $f_Q$ of nonzero elements of vector $f$ of flow sources; for the circuit presented in Figure 3, $f_Q = [\\Phi_o, \\Phi_i, \\dot{Q}_a, \\Phi_a]^T$ corresponds to nodes 0, 4, 6, and 7;\n",
" \n",
"- $y$ - vector of outputs, a subset of vector $\\theta$ representing temperature nodes which are of interest; for the circuit presented in Figure 3, $y = \\theta_6$, the indoor temperature.\n",
"\n",
"- $A_s$ - state matrix, of dimension $\\dim A_s = \\dim {\\theta_s} \\times \\dim {\\theta_s}$;\n",
"\n",
"- $B_s$ - input matrix, of dimension $\\dim B_s = \\dim {\\theta_s} \\times \\dim u$;\n",
"\n",
"- $C_s$ - output matrix, of dimension $\\dim C_s = \\dim y \\times \\dim {\\theta_s}$;\n",
"\n",
"- $D_s$ - feedthrough (or feedforward) matrix, of dimension $\\dim D_s = \\dim y \\times \\dim u$.\n",
"\n",
"*Note*: The subscript $s$ of the matrices $A_s, B_s, C_s, D_s$ is used to differentiante the matrices $A_s, C_s$ of the state-space represenation of the matrices $A, C$ of the system of DAE."
]
},
{
"cell_type": "markdown",
"id": "c70c3d14-d402-4fb5-a7d0-18a83f556c97",
"metadata": {
"tags": []
},
"source": [
"The [state-space representation](https://en.m.wikipedia.org/wiki/State-space_representation), i.e., matrices $A_s, B_s, C_s, D_s$ is obtained from the system of DAE, i.e., matrices and vectors $A, G, b, C, f, y$ ([Ghiaus 2013](https://hal.archives-ouvertes.fr/hal-03605823/document))."
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "23c9de06-8be7-4dff-a734-027c31349e27",
"metadata": {},
"outputs": [],
"source": [
"[As, Bs, Cs, Ds] = dm4bem.tc2ss(A, G, C, b, f, y)\n",
"θs = ['θ1', 'θ3', 'θ6', 'θ7'] # state temperature nodes\n",
"uT = ['q0', 'q8', 'q10', 'q11'] # temperature sources\n",
"uQ = ['θ0', 'θ4', 'θ6', 'θ7'] # flow sources\n",
"u = uT + uQ # inputs\n",
"y = ['θ6'] # output"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "d2d9e0fb-a580-4747-8309-fb779eef9c9a",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"