3D thermal simulation of a building
1. Description
Based on the solution of the stationary heat equation, we create a reduced order model for the simulation of heat exchanges in a 3D building.
The building is composed of a corridor and 5 rooms, each of which contains a heating unit. Internal walls and doors are modelled as having finite thickness, while external walls properties (thickness and insulation) are encoded in the boundary conditions of the problem.
1.1. Mathematical model
Let \(\Omega \subset \mathbb{R}^3\) be the region occupied by the building, and denote \(\Omega_i\), \(i=0,1,2\) its subregions occupied by the air, the internal walls and the internal doors, such that \(\Omega = \cup_{i=0}^2 \Omega_i\). Let \(k_i\) be the thermal conductivities associated with the subregions.
The external boundary of the domain \(\partial \Omega\) is decomposed into two parts: \(\partial \Omega_{ext}\), which corresponds to external walls, and \(\partial \Omega_D\) which corresponds to the front door. We denote by \(\Gamma_i\) the boundary of the \(i\)th heating unit, \(i=0,...,4\). The problem writes as
where \(\sigma\) is the convective heat exchange coefficient associated with the front door.
The parameters \(\mu_i\) correspond to

\(\mu_i \in (300,340)\), for \(i=0,...,4\), are the surface temperatures of the heating units (in Kelvin);

\(\mu_5 \in (270,290)\) is the external temperature (in Kelvin);

\(\mu_6\) is a function of the external wall thickness. The wall is composed of two layers: a cinder layer of thickness \(l_{cinder} \in (0.1,0.3) m\) and an insulation layer of thickness \(l_{insulation} \in (0.1,0.2) m\), and
1.2. Construction of the affine decomposition
The problem presents an affine dependence on the parameters, hence we can explicity compute the terms of the correspondent affine decomposition
where \(N_A = 1\) and \(N_F = 6\).
The first product on the lefthand side is given by \(\theta^A_0(\mu) = 1\) and
where \(\gamma\) is the Nitsche penalty parameter and \(h\) is the local mesh size.
The second product is given by \(\theta^A_1(\mu) = \mu_6\) and
The terms on the righthand side are \(\theta^F_i(\mu) = \mu_i\) for \(i=0,...,4\), corresponding to the temperatures of the heating units, \(\theta^F_5(\mu) = \mu_5\mu_6\), corresponding to the temperature on the internal surface of the external walls, and \(\theta^F_6(\mu) = \mu_5\), corresponding to the external temperature. The corresponding linear forms are
2. Output
The output corresponds to the air mean temperature, and it is computed as
3. Parameters
The table displays the various fixed and variables parameters of this testcase.
Name 
Description 
Range 
Units 
\(\mu_0\) 
Heater temperature living room 
\([300,340\)] 
\(K\) 
\(\mu_1\) 
Heater temperature kitchen 
\([300,340\)] 
\(K\) 
\(\mu_2\) 
Heater temperature bedroom 1 
\([300,340\)] 
\(K\) 
\(\mu_3\) 
Heater temperature bedroom 2 
\([300,340\)] 
\(K\) 
\(\mu_4\) 
Heater temperature bathroom 
\([300,340\)] 
\(K\) 
\(\mu_5\) 
External temperature 
\([270,290\)] 
\(K\) 
\(\mu_6\) 
Exchange coefficient external walls 
Name 
Description 
Value 
\(\gamma\) 
Boundary conditions using Nitsche method 
\(10\) 
\(k_0\) 
Air conductivity 
\(1\) 
\(k_1\) 
Conductivity  internal walls 
\(0.25\) 
\(k_2\) 
Conductivity  internal doors 
\(0.13\) 
\(\sigma\) 
Heat transfer coefficient  front door 
\(\frac{1.0}{0.06+\frac{0.06}{0.150}+\frac{0.1}{0.029}+0.14}\) 
4. Setup for the notebook simulation
girder_path = "https://girder.math.unistra.fr/api/v1/item/64d60522b0e9570499e1eaa1/download"
fpp_name = 'thermalbuilding.fpp'
time = 0
5. Downloading the reduced order model from Girder
The offline creation of the reduced basis has already been performed, and an archive is downloaded from Girder. It contains the basis, the model and the configuration files that are necessary for the online simulation. The following code snippet performs the download.
import requests
r=requests.get(girder_path)
with open(fpp_name,'wb') as f:
f.write(r.content)
6. Running the case using a Jupyter notebook
It is possible to download this page as a Jupyter notebook and run it in an environment that contains a local installation of Feel++ and its Python wrappers.
import feelpp
from feelpp.mor import *
ms=feelpp.mor.MORModels(fpp_name)
muspace = ms.parameterSpace()
sampling = muspace.sampling()
sampling.sample(4, "random")
r=ms.run(sampling,{"N":10})
from pandas import DataFrame as df
from pandas import options as op
from pandas import set_option
outputs={}
errors={}
output_dataframes = list()
errors_dataframes = list()
for i in range(len(r)):
outputs={}
errors={}
for o in range(len(r[i])):
str_time = "Time"
str_output = "Output "+str(o)
str_error = "Error "+str(o)
outputs[str_time] = time
outputs[str_output] = np.array(r[i][o].outputs())
outputs[str_error] = [np.array(r[i][o].errors())]
output_frame = df(data=outputs)
set_option('display.float_format', '{:.2E}'.format)
output_dataframes.append(output_frame)
op.display.max_colwidth = 100
i=0
for frame in output_dataframes:
print("Parameters :",sampling[i])
print(frame)
print("\n")
i=i+1