Thermal circuit to state-space#

Binder

This notebook is a go through complete example of how to obtain a state-space representation from the building described by walls and the thermal circuits. The steps are:

  • in a folder, describe the walls (wall type and wall data), the thermal circuits and give the assembling matrix or lists;

  • from walls and thermal circuits obtain the set of disassembled circuits (function dm4bem.bldg2TCd());

  • assemble the set of disassembled thermal circuits (function dm4bem.assemble_TCd_matrix());

  • transform the thermal circuit into state-space representation (function dm4bem.tc2ss()).

import numpy as np
import pandas as pd

import dm4bem

Assembling and converting the thermal circuits to state-space#

Consider the disassembled thermal circuits shown in Figure 1 that we want to assemble as shown in Figure 2 and then obtain the state-space representation.

disassambled_TC

Figure 1. Four disassembled thermal circuits: wall_out, TC0, TC1, TC2, TC3.

disassambled_TC

Figure 2. The assembling of the four circuits from Figure 1.

The steps to obtain a state-space model from thermal circuits described in a folder (link) are:

  1. Obtain the disassembled set of thermal circuits from data given in a folder.

# Disassembled thermal circuits
folder_path = './pd/bldg'
TCd = dm4bem.bldg2TCd(folder_path,
                      TC_auto_number=True)

# For non auto-numbering of thermal circuits TC
# TCd = dm4bem.bldg2TCd(folder_path, TC_auto_number=False)
  1. Assemble the set of thermal circuits

# Assembled thermal circuit:

# from 'assembly_matrix.csv'
ass_mat = pd.read_csv(folder_path + '/assembly_matrix.csv')
TCm = dm4bem.assemble_TCd_matrix(TCd, ass_mat)

# from 'assembly_lists.csv'
ass_lists = pd.read_csv(folder_path + '/assembly_lists.csv')
ass_mat = dm4bem.assemble_lists2matrix(ass_lists)
TCl = dm4bem.assemble_TCd_matrix(TCd, ass_mat)
  1. Transform the thermal circuit into state-space representation.

# State-space from TC
[As, Bs, Cs, Ds, us] = dm4bem.tc2ss(TCl)

The state-space representation is characterized by the matrices A (state), B (input), C (output) and D (feedthrough) and by the input vector u. Note the use of ‘s’ (from state-space) in the names of As, Bs, Cs, Ds, us in order to avoid confusion with the notation for differential-algebraic equations (A, G, C, b, f).

As
c1_θ0 c2_θ0 ow0_θ1 ow0_θ3
c1_θ0 -0.000240 0.000085 0.000000 0.000002
c2_θ0 0.002857 -0.003925 0.000000 0.000790
ow0_θ1 0.000000 0.000000 -0.000024 0.000002
ow0_θ3 0.000011 0.000107 0.000121 -0.000239
Bs
c1_q0 c2_q0 c3_q0 ow0_q0 c1_θ0 c2_θ0 ow0_θ0 ow0_θ4
c1_θ0 0.000152 0.000000 0.0 0.000000 9.182736e-07 0.000000 0.000000e+00 8.022399e-08
c2_θ0 0.000000 0.000278 0.0 0.000000 0.000000e+00 0.000031 0.000000e+00 2.600003e-05
ow0_θ1 0.000000 0.000000 0.0 0.000022 0.000000e+00 0.000000 1.970654e-08 0.000000e+00
ow0_θ3 0.000000 0.000000 0.0 0.000000 0.000000e+00 0.000000 0.000000e+00 2.931595e-07
Cs
c1_θ0 c2_θ0 ow0_θ1 ow0_θ3
c2_θ0 0.0 1.0 0.0 0.0
Ds
c1_q0 c2_q0 c3_q0 ow0_q0 c1_θ0 c2_θ0 ow0_θ0 ow0_θ4
c2_θ0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
pd.DataFrame({'u': us})
u
c1_q0 To
c2_q0 To
c3_q0 Ti_sp
ow0_q0 To
c1_θ0 Φa
c2_θ0 Qa
ow0_θ0 Φo
ow0_θ4 Φi

The state-space representation allows us to do the eigenvalues analysis and to find the maximum time step \(\Delta t_{max} = 2 \min (-1 / \lambda_i) \), where \(\lambda_i\) are the eigenvalues of the state matrix \(A_s\).

λ = np.linalg.eig(As)[0]    # eigenvalues of matrix As
λ = np.sort(λ)

print('Time constants:', [f'{T:.2f} s' for T in -1 / λ])

# maximum time step
dtmax = 2 * min(-1. / λ)
dm4bem.print_rounded_time('Max. time step: ', dtmax)

# settling time
t_settle = 4 * max(-1 / λ)
dm4bem.print_rounded_time('Setting time: ', t_settle)
Time constants: ['249.30 s', '4093.21 s', '6729.13 s', '44033.06 s']
Max. time step:  = 498 s = 8.3 min
Setting time:  = 176132 s = 48.9 h

Comparing the results#

The model used in this notebook is similar to that used in Jupyter Notebook on Toy model house. The notations in the two models are different (see Figure 2 and Figure 3).

thermal_circuit

Figure 3. Thermal circuit for the cubic building used in Toy model house

The correspondences between the notations in the two models (i.e., this notebook and Toy model house) is shown in Tables 1, 2, and 3.

Table 1. Correspondence between states (i.e., temperature nodes with capacities) in Figures 2 and 3.

Fig. 2

ow0_θ1

ow0_θ3

c2_θ0

c1_θ0

Fig. 3

θ1

θ3

θ6

θ7

Table 2. Correspondence between temperature sources in Figures 2 and 3.

Fig. 2

ow0_q0

c1_q0

c2_q0

c3_q0

Fig. 3

q0

q8

q10

q11

Table 3. Correspondence between flow sources in Figures 2 and 3.

Fig. 2

ow0_θ0

ow0_θ4

c2_θ0

c1_θ0

Fig. 3

θ0

θ4

θ6

θ7

θ_order = ['ow0_θ1', 'ow0_θ3', 'c2_θ0', 'c1_θ0']
uT_order = ['ow0_q0', 'c1_q0', 'c2_q0', 'c3_q0']
uQ_order = ['ow0_θ0', 'ow0_θ4', 'c2_θ0', 'c1_θ0']
u_order = uT_order + uQ_order
y_order = ['c2_θ0'] 

By reindexing the matrices of the state-space model, it becomes easier to compare the results from this notebook and Toy model house.

As.reindex(index=θ_order, columns=θ_order)
ow0_θ1 ow0_θ3 c2_θ0 c1_θ0
ow0_θ1 -0.000024 0.000002 0.000000 0.000000
ow0_θ3 0.000121 -0.000239 0.000107 0.000011
c2_θ0 0.000000 0.000790 -0.003925 0.002857
c1_θ0 0.000000 0.000002 0.000085 -0.000240
Bs.reindex(index=θ_order, columns=u_order)
ow0_q0 c1_q0 c2_q0 c3_q0 ow0_θ0 ow0_θ4 c2_θ0 c1_θ0
ow0_θ1 0.000022 0.000000 0.000000 0.0 1.970654e-08 0.000000e+00 0.000000 0.000000e+00
ow0_θ3 0.000000 0.000000 0.000000 0.0 0.000000e+00 2.931595e-07 0.000000 0.000000e+00
c2_θ0 0.000000 0.000000 0.000278 0.0 0.000000e+00 2.600003e-05 0.000031 0.000000e+00
c1_θ0 0.000000 0.000152 0.000000 0.0 0.000000e+00 8.022399e-08 0.000000 9.182736e-07
Cs.reindex(index=y_order, columns=θ_order)
ow0_θ1 ow0_θ3 c2_θ0 c1_θ0
c2_θ0 0.0 0.0 1.0 0.0
Ds.reindex(index=y_order, columns=u_order)
ow0_q0 c1_q0 c2_q0 c3_q0 ow0_θ0 ow0_θ4 c2_θ0 c1_θ0
c2_θ0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

Types of notation#

The notation used for the nodes and flow rates can be symbols or numbers (in the case of autonumbering).

The data used in the next examples is extracted from the paper:

Ghiaus, C. (2013). Causality issue in the heat balance method for calculating the design heating and cooling load. Energy, 50, 292-301.

Thermal circuit file to state-space#

File describing the thermal circuit with symbols#

Let’s consider a thermal circuit that uses symbols for numbering the temperature nodes and the oriented flow branches (Figure 4).

tc_sym

Figure 4. Thermal circuit with symbols.

The thermal circuit from Figure 4 is defined in the file ./TC_tc2ss/TC_tc2ss_sym.csv (link). In this case, symbols are used for the nodes and the branches.

pd.read_csv('./pd/TC_tc2ss/TC_tc2ss_sym.csv')
A θso θw θsi θa G b
0 qw0 -1 1.0 NaN NaN 2.9 NaN
1 qw1 NaN -1.0 1 NaN 2.9 NaN
2 qv NaN NaN NaN 1 38.3 Tov
3 qco 1 NaN NaN NaN 250.0 Tow
4 qci NaN NaN -1 1 125.0 NaN
5 C NaN 4000000.0 NaN 8.2E+04 NaN NaN
6 f Qo NaN Qi Qg NaN NaN
7 y NaN NaN 1 1 NaN NaN

Auto-numbering#

The nodes and the oriented branches can be auto-numbered. The names of the nodes and branches are composed by the name of the circuit and θ0, θ1, … , for nodes and q0, q1, … for branches, e.g., a_θ1 stands for temperature node θ1 of circuit a.

TC_file = "pd/TC_tc2ss/TC_tc2ss_sym.csv"
TC = dm4bem.file2TC(TC_file, name="a",
                    auto_number=True)
[Asa, Bsa, Csa, Dsa, ua] = dm4bem.tc2ss(TC)
Asa
a_θ1 a_θ3
a_θ1 -0.000001 7.085614e-07
a_θ3 0.000035 -5.016371e-04

Symbols#

Alternatively, the nodes and the branches can keep the names given in the TC file (the default value of auto_numberis False).

TC_file = "pd/TC_tc2ss/TC_tc2ss_sym.csv"
TC = dm4bem.file2TC(TC_file, name="s")
[Ass, Bss, Css, Dss, us] = dm4bem.tc2ss(TC)
Ass
sθw sθa
sθw -0.000001 7.085614e-07
sθa 0.000035 -5.016371e-04

Note that the order of symbols correspond to the order given in the description file ./TC_tc2ss/TC_tc2ss_num.csv not to the alphabetical order.

File describing the thermal circuit with numbers#

Instead of using symbols, the thermal circuit can be numbered (Figure 5).

tc_num

Figure 5. Numbered thermal circuit

The thermal circuit from Figure 5 is defined in the file ./TC_tc2ss/TC_tc2ss_num.csv (link). In this case, the nodes and the branches are numbered.

pd.read_csv('./pd/TC_tc2ss/TC_tc2ss_num.csv')
A θ0 θ1 θ2 θ3 G b
0 q0 NaN NaN 1 NaN 38.3 Tov
1 q1 1 NaN NaN NaN 250.0 Tow
2 q2 -1 NaN NaN 1.0 2.9 NaN
3 q3 NaN 1 NaN -1.0 2.9 NaN
4 q4 NaN -1 1 NaN 125.0 NaN
5 C NaN NaN 8.2E+04 4000000.0 NaN NaN
6 f Qo Qi Qg NaN NaN NaN
7 y NaN 1 1 NaN NaN NaN
TC_file = "pd/TC_tc2ss/TC_tc2ss_num.csv"
TC = dm4bem.file2TC(TC_file, name="n")
[Asn, Bsn, Csn, Dsn, un] = dm4bem.tc2ss(TC)
Asn
nθ2 nθ3
nθ2 -5.016371e-04 0.000035
nθ3 7.085614e-07 -0.000001

Note that the values of the state-space representations are the same but the order is different. The order is given by the .cvs files that define the thermal circuit.