wall-ctf 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wall_ctf-1.0.0/.gitignore +10 -0
- wall_ctf-1.0.0/1-s2.0-S0378778805000538-main.pdf +0 -0
- wall_ctf-1.0.0/1-s2.0-S1359431104001656-main.pdf +0 -0
- wall_ctf-1.0.0/CITATION.cff +49 -0
- wall_ctf-1.0.0/LICENSE +43 -0
- wall_ctf-1.0.0/PKG-INFO +459 -0
- wall_ctf-1.0.0/README.md +435 -0
- wall_ctf-1.0.0/cati/__init__.py +29 -0
- wall_ctf-1.0.0/cati/__main__.py +145 -0
- wall_ctf-1.0.0/cati/ctf.py +1059 -0
- wall_ctf-1.0.0/cati/wall.py +118 -0
- wall_ctf-1.0.0/docs/ctf_vs_fourier.png +0 -0
- wall_ctf-1.0.0/examples/heavy_wall.json +51 -0
- wall_ctf-1.0.0/examples/insulated_wall.json +67 -0
- wall_ctf-1.0.0/main.py +6 -0
- wall_ctf-1.0.0/pyproject.toml +50 -0
- wall_ctf-1.0.0/scripts/generate_figures.py +124 -0
- wall_ctf-1.0.0/tests/__init__.py +0 -0
- wall_ctf-1.0.0/tests/test_ctf.py +202 -0
- wall_ctf-1.0.0/token pypi.txt +5 -0
- wall_ctf-1.0.0/uv.lock +508 -0
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software, please cite the following publications."
|
|
3
|
+
title: "wall-ctf (CATI) - Conduction Transfer Function Coefficients"
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
date-released: 2026-04-08
|
|
6
|
+
authors:
|
|
7
|
+
- family-names: Lo Brano
|
|
8
|
+
given-names: Valerio
|
|
9
|
+
email: valerio.lobrano@unipa.it
|
|
10
|
+
affiliation: "Universita degli Studi di Palermo"
|
|
11
|
+
orcid: ""
|
|
12
|
+
license: CC-BY-NC-4.0
|
|
13
|
+
repository-code: "https://github.com/valeriolobrano/wall-ctf"
|
|
14
|
+
preferred-citation:
|
|
15
|
+
type: article
|
|
16
|
+
authors:
|
|
17
|
+
- family-names: Beccali
|
|
18
|
+
given-names: Giorgio
|
|
19
|
+
- family-names: Cellura
|
|
20
|
+
given-names: Maurizio
|
|
21
|
+
- family-names: Lo Brano
|
|
22
|
+
given-names: Valerio
|
|
23
|
+
- family-names: Orioli
|
|
24
|
+
given-names: Aldo
|
|
25
|
+
title: "Single thermal zone balance solved by Transfer Function Method"
|
|
26
|
+
journal: "Energy and Buildings"
|
|
27
|
+
volume: 37
|
|
28
|
+
start: 1268
|
|
29
|
+
end: 1277
|
|
30
|
+
year: 2005
|
|
31
|
+
doi: "10.1016/j.enbuild.2005.02.010"
|
|
32
|
+
references:
|
|
33
|
+
- type: article
|
|
34
|
+
authors:
|
|
35
|
+
- family-names: Beccali
|
|
36
|
+
given-names: Giorgio
|
|
37
|
+
- family-names: Cellura
|
|
38
|
+
given-names: Maurizio
|
|
39
|
+
- family-names: Lo Brano
|
|
40
|
+
given-names: Valerio
|
|
41
|
+
- family-names: Orioli
|
|
42
|
+
given-names: Aldo
|
|
43
|
+
title: "Is the transfer function method reliable in a European building context? A theoretical analysis and a case study in the south of Italy"
|
|
44
|
+
journal: "Applied Thermal Engineering"
|
|
45
|
+
volume: 25
|
|
46
|
+
start: 341
|
|
47
|
+
end: 357
|
|
48
|
+
year: 2005
|
|
49
|
+
doi: "10.1016/j.applthermaleng.2004.06.010"
|
wall_ctf-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2005-2026 Valerio Lo Brano
|
|
4
|
+
Universita degli Studi di Palermo
|
|
5
|
+
Dipartimento di Ingegneria
|
|
6
|
+
|
|
7
|
+
This work is licensed under the Creative Commons
|
|
8
|
+
Attribution-NonCommercial 4.0 International License.
|
|
9
|
+
|
|
10
|
+
You are free to:
|
|
11
|
+
|
|
12
|
+
- Share: copy and redistribute the material in any medium or format
|
|
13
|
+
- Adapt: remix, transform, and build upon the material
|
|
14
|
+
|
|
15
|
+
Under the following terms:
|
|
16
|
+
|
|
17
|
+
- Attribution: You must give appropriate credit, provide a link to the
|
|
18
|
+
license, and indicate if changes were made. You must cite the following
|
|
19
|
+
publications:
|
|
20
|
+
|
|
21
|
+
[1] G. Beccali, M. Cellura, V. Lo Brano, A. Orioli,
|
|
22
|
+
"Single thermal zone balance solved by Transfer Function Method",
|
|
23
|
+
Energy and Buildings, 37 (2005) 1268-1277.
|
|
24
|
+
DOI: 10.1016/j.enbuild.2005.02.010
|
|
25
|
+
|
|
26
|
+
[2] G. Beccali, M. Cellura, V. Lo Brano, A. Orioli,
|
|
27
|
+
"Is the transfer function method reliable in a European building
|
|
28
|
+
context? A theoretical analysis and a case study in the south
|
|
29
|
+
of Italy", Applied Thermal Engineering, 25 (2005) 341-357.
|
|
30
|
+
DOI: 10.1016/j.applthermaleng.2004.06.010
|
|
31
|
+
|
|
32
|
+
- NonCommercial: You may not use the material for commercial purposes
|
|
33
|
+
without obtaining prior written permission from the copyright holder.
|
|
34
|
+
|
|
35
|
+
For commercial licensing inquiries, contact:
|
|
36
|
+
Valerio Lo Brano
|
|
37
|
+
valerio.lobrano@unipa.it
|
|
38
|
+
Universita degli Studi di Palermo
|
|
39
|
+
|
|
40
|
+
No additional restrictions: You may not apply legal terms or technological
|
|
41
|
+
measures that legally restrict others from doing anything the license permits.
|
|
42
|
+
|
|
43
|
+
Full license text: https://creativecommons.org/licenses/by-nc/4.0/legalcode
|
wall_ctf-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wall-ctf
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: wall-ctf (CATI) - Conduction Transfer Function (CTF) coefficients for multilayer walls using the Mitalas-Stephenson / Z-transform method
|
|
5
|
+
Project-URL: Homepage, https://github.com/valeriolobrano/wall-ctf
|
|
6
|
+
Project-URL: Documentation, https://github.com/valeriolobrano/wall-ctf#readme
|
|
7
|
+
Project-URL: Issues, https://github.com/valeriolobrano/wall-ctf/issues
|
|
8
|
+
Author-email: Valerio Lo Brano <valerio.lobrano@unipa.it>
|
|
9
|
+
License: CC-BY-NC-4.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ASHRAE,CTF,Mitalas,TRNSYS,Z-transform,building-simulation,conduction,heat-transfer,multilayer,thermal,transfer-function,wall
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Education
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: Other/Proprietary License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Requires-Dist: numpy>=1.26
|
|
21
|
+
Provides-Extra: plot
|
|
22
|
+
Requires-Dist: matplotlib>=3.8; extra == 'plot'
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# wall-ctf (CATI) - Conduction Transfer Function Coefficients
|
|
26
|
+
|
|
27
|
+
**Version 1.0.0** | **Author:** Valerio Lo Brano, Universita degli Studi di Palermo
|
|
28
|
+
|
|
29
|
+
CATI computes the Conduction Transfer Function (CTF) coefficients for
|
|
30
|
+
multilayer wall assemblies using the Z-transform method. This is the same
|
|
31
|
+
mathematical approach used by TRNSYS, DOE-2, BLAST, TARP, and the ASHRAE
|
|
32
|
+
Transfer Function Method (TFM) for dynamic thermal simulation of buildings.
|
|
33
|
+
|
|
34
|
+
Given the thermophysical properties of a wall (layer thicknesses, densities,
|
|
35
|
+
specific heats, conductivities), CATI determines the Z-domain transfer function
|
|
36
|
+
coefficients that allow to compute, at each time step, the heat flux at the
|
|
37
|
+
internal surface as a function of the external (sol-air) temperature history
|
|
38
|
+
and the internal air temperature.
|
|
39
|
+
|
|
40
|
+

|
|
41
|
+
|
|
42
|
+
*Comparison between the Z-transform (CTF) and Fourier (harmonic analysis)
|
|
43
|
+
solutions for a heavy concrete wall (plaster 2cm + concrete 25cm + plaster 2cm).
|
|
44
|
+
The two curves are virtually indistinguishable, with a Percentage Mean Error
|
|
45
|
+
of 0.15%.*
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Table of contents
|
|
50
|
+
|
|
51
|
+
- [Theoretical background](#theoretical-background)
|
|
52
|
+
- [Installation](#installation)
|
|
53
|
+
- [Quick start](#quick-start)
|
|
54
|
+
- [Input format](#input-format)
|
|
55
|
+
- [Parameters and guidelines](#parameters-and-guidelines)
|
|
56
|
+
- [Examples](#examples)
|
|
57
|
+
- [Validation](#validation)
|
|
58
|
+
- [How to cite](#how-to-cite)
|
|
59
|
+
- [License](#license)
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Theoretical background
|
|
64
|
+
|
|
65
|
+
### The thermal transmission matrix
|
|
66
|
+
|
|
67
|
+
The non-steady-state heat transfer through a homogeneous isotropic layer can
|
|
68
|
+
be described in the Laplace domain by a 2x2 transmission matrix that relates
|
|
69
|
+
temperatures and heat fluxes on the two sides of the layer:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
| T_e | | a b | | T_i |
|
|
73
|
+
| | = | | x | |
|
|
74
|
+
| Q_e | | c d | | Q_i |
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
where, for a material layer of thickness *L*, conductivity *k*,
|
|
78
|
+
density *rho*, specific heat *Cp*, and diffusivity *alpha = k/(rho\*Cp)*:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
a = d = cosh(L * sqrt(s/alpha))
|
|
82
|
+
b = sinh(L * sqrt(s/alpha)) / (k * sqrt(s/alpha))
|
|
83
|
+
c = k * sqrt(s/alpha) * sinh(L * sqrt(s/alpha))
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
For surface resistance layers (convective + radiative films) and air gaps,
|
|
87
|
+
the matrix reduces to `[[1, R], [0, 1]]` where *R* is the thermal resistance.
|
|
88
|
+
|
|
89
|
+
For a multilayer wall, the overall matrix **M(s)** is the ordered product of
|
|
90
|
+
all individual layer matrices, from the external surface to the internal one.
|
|
91
|
+
|
|
92
|
+
### From Laplace to Z-domain
|
|
93
|
+
|
|
94
|
+
The heat flux at the internal surface can be expressed as:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Q_i(z) = [1/B(z)] * T_e(z) - [A(z)/B(z)] * T_i(z)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
where A and B are elements of the overall transmission matrix. The Z-transform
|
|
101
|
+
coefficients are obtained through:
|
|
102
|
+
|
|
103
|
+
1. Finding the poles *s_n* (zeros of B(s) on the negative real axis)
|
|
104
|
+
2. Heaviside partial-fraction expansion of the ramp response
|
|
105
|
+
3. **Procedure I**: optimal selection of significant poles/residues
|
|
106
|
+
4. Computation of the Z-domain denominator and numerator polynomials
|
|
107
|
+
|
|
108
|
+
The resulting recursive formula is:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
q_i(n*Delta) = SUM_j b_j * T_e((n-j)*Delta)
|
|
112
|
+
- SUM_j d_j * q_i((n-j)*Delta)
|
|
113
|
+
- T_i * SUM_j c_j
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Procedure I: optimal pole selection
|
|
117
|
+
|
|
118
|
+
As demonstrated in Ref. [2], for massive building walls typical of the
|
|
119
|
+
Mediterranean architectural heritage, a naive application of the TFM with
|
|
120
|
+
many poles can produce **worse** results than using fewer poles. The Percentage
|
|
121
|
+
Mean Error (PME) can increase from < 1% to > 1000% when using 15 poles
|
|
122
|
+
instead of 5.
|
|
123
|
+
|
|
124
|
+
CATI implements **Procedure I** from Ref. [2]: residues are sorted by absolute
|
|
125
|
+
value in descending order, and only those above a significance threshold
|
|
126
|
+
(|res_n| > 10^-10) are retained. This guarantees PME < 1% for all standard
|
|
127
|
+
wall constructions at 1-hour sampling period.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Installation
|
|
132
|
+
|
|
133
|
+
### With uv (recommended)
|
|
134
|
+
|
|
135
|
+
[uv](https://docs.astral.sh/uv/) is the fastest way to manage Python projects:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Clone the repository
|
|
139
|
+
git clone https://github.com/valeriolobrano/wall-ctf.git
|
|
140
|
+
cd wall-ctf
|
|
141
|
+
|
|
142
|
+
# Install with uv (creates virtualenv automatically)
|
|
143
|
+
uv sync
|
|
144
|
+
|
|
145
|
+
# Run tests
|
|
146
|
+
uv run pytest
|
|
147
|
+
|
|
148
|
+
# Run the CLI
|
|
149
|
+
uv run cati examples/heavy_wall.json
|
|
150
|
+
|
|
151
|
+
# Run with optional plotting support
|
|
152
|
+
uv add matplotlib
|
|
153
|
+
uv run python scripts/generate_figures.py
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### With pip
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
pip install wall-ctf
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Or from source:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
git clone https://github.com/valeriolobrano/wall-ctf.git
|
|
166
|
+
cd wall-ctf
|
|
167
|
+
pip install .
|
|
168
|
+
|
|
169
|
+
# With plotting support
|
|
170
|
+
pip install ".[plot]"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Requirements
|
|
174
|
+
|
|
175
|
+
- Python >= 3.12
|
|
176
|
+
- NumPy >= 1.26
|
|
177
|
+
- matplotlib >= 3.8 (optional, for plotting)
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Quick start
|
|
182
|
+
|
|
183
|
+
### Basic example: single wall
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
from cati import Wall, Layer, compute_ctf
|
|
187
|
+
|
|
188
|
+
# Define a wall from outside to inside:
|
|
189
|
+
# external surface resistance -> material layers -> internal surface resistance
|
|
190
|
+
# All values in SI units
|
|
191
|
+
wall = Wall(layers=[
|
|
192
|
+
Layer(name="External surface", resistance=0.04), # m2*K/W
|
|
193
|
+
Layer(name="Concrete", thickness=0.25, density=2400, # m, kg/m3
|
|
194
|
+
specific_heat=1000, conductivity=1.4), # J/(kg*K), W/(m*K)
|
|
195
|
+
Layer(name="Internal surface", resistance=0.13),
|
|
196
|
+
])
|
|
197
|
+
|
|
198
|
+
result = compute_ctf(wall, n_roots=30, n_coefficients=20)
|
|
199
|
+
|
|
200
|
+
print(f"U-value: {result.thermal_transmittance:.3f} W/(m2*K)")
|
|
201
|
+
print(f"Significant poles: {result.n_poles}")
|
|
202
|
+
print(f"Effective coefficients: {result.n_coefficients}")
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### With Fourier validation
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
import numpy as np
|
|
209
|
+
|
|
210
|
+
# 24-hour sol-air temperature profile (hourly, 25 values with wrap-around)
|
|
211
|
+
profile = np.array([
|
|
212
|
+
25.0, 24.0, 23.5, 23.0, 22.5, 23.0, # 0h-5h
|
|
213
|
+
24.0, 26.0, 28.0, 30.0, 32.0, 34.0, # 6h-11h
|
|
214
|
+
36.0, 37.0, 37.5, 37.0, 36.0, 34.0, # 12h-17h
|
|
215
|
+
32.0, 30.0, 28.0, 27.0, 26.0, 25.5, # 18h-23h
|
|
216
|
+
25.0, # 24h = 0h
|
|
217
|
+
])
|
|
218
|
+
|
|
219
|
+
result = compute_ctf(
|
|
220
|
+
wall,
|
|
221
|
+
n_roots=30,
|
|
222
|
+
n_coefficients=20,
|
|
223
|
+
temperature_profile=profile,
|
|
224
|
+
T_int=24.0, # constant internal temperature [C]
|
|
225
|
+
sampling_time=1.0, # sampling period [hours]
|
|
226
|
+
n_periods=20, # periods to exit transient
|
|
227
|
+
validate_fourier=True, # compare with harmonic solution
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
print(f"Fourier validation error: {result.fourier_error:.2f}%")
|
|
231
|
+
# Output: Fourier validation error: 0.15%
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Using the CTF coefficients in a simulation
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
nc = result.n_coefficients # number of effective coefficients
|
|
238
|
+
b = result.b_coeffs[:nc+1] # numerator for external temperature
|
|
239
|
+
c = result.c_coeffs[:nc+1] # numerator for internal temperature
|
|
240
|
+
d = result.d_coeffs[:nc+1] # denominator (common)
|
|
241
|
+
|
|
242
|
+
# Simulation loop (hourly time step)
|
|
243
|
+
T_int = 24.0
|
|
244
|
+
q = np.zeros(8760) # one year, hourly
|
|
245
|
+
|
|
246
|
+
for n in range(1, 8760):
|
|
247
|
+
# b * T_external (convolution)
|
|
248
|
+
q[n] = sum(b[j] * T_ext_hourly[max(0, n-j)] for j in range(nc+1))
|
|
249
|
+
# - d * q_past (recursive feedback)
|
|
250
|
+
q[n] -= sum(d[j] * q[max(0, n-j)] for j in range(1, nc+1))
|
|
251
|
+
# - c * T_internal (constant offset)
|
|
252
|
+
q[n] -= T_int * sum(c)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Parallel computation for multiple walls
|
|
256
|
+
|
|
257
|
+
```python
|
|
258
|
+
from cati import compute_ctf_batch
|
|
259
|
+
|
|
260
|
+
# Compute CTF for all walls of a building in parallel
|
|
261
|
+
walls = [wall_north, wall_south, wall_east, wall_west, roof, floor]
|
|
262
|
+
results = compute_ctf_batch(walls, n_roots=30, n_coefficients=20)
|
|
263
|
+
|
|
264
|
+
for wall, result in zip(walls, results):
|
|
265
|
+
print(f"{wall.name}: U={result.thermal_transmittance:.3f}, "
|
|
266
|
+
f"poles={result.n_poles}, coeffs={result.n_coefficients}")
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Command-line interface
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
# Compute and print CTF coefficients as JSON
|
|
273
|
+
uv run cati examples/heavy_wall.json --roots 30 --coefficients 20
|
|
274
|
+
|
|
275
|
+
# Save results to file
|
|
276
|
+
uv run cati examples/heavy_wall.json -o results.json
|
|
277
|
+
|
|
278
|
+
# Custom parameters
|
|
279
|
+
uv run cati wall.json --sampling-time 2 --periods 30 --t-int 26
|
|
280
|
+
|
|
281
|
+
# Skip Fourier validation (faster)
|
|
282
|
+
uv run cati wall.json --no-fourier
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Loading walls from JSON
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
from cati import Wall
|
|
289
|
+
|
|
290
|
+
# From a JSON file
|
|
291
|
+
wall = Wall.from_json("examples/heavy_wall.json")
|
|
292
|
+
|
|
293
|
+
# From a Python dictionary
|
|
294
|
+
wall = Wall.from_dict({
|
|
295
|
+
"name": "My wall",
|
|
296
|
+
"layers": [
|
|
297
|
+
{"name": "Ext", "resistance": 0.04},
|
|
298
|
+
{"name": "Brick", "thickness": 0.12, "density": 1700,
|
|
299
|
+
"specific_heat": 800, "conductivity": 0.84},
|
|
300
|
+
{"name": "Int", "resistance": 0.13},
|
|
301
|
+
]
|
|
302
|
+
})
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Input format
|
|
308
|
+
|
|
309
|
+
### JSON wall definition
|
|
310
|
+
|
|
311
|
+
```json
|
|
312
|
+
{
|
|
313
|
+
"name": "Concrete wall with plaster",
|
|
314
|
+
"layers": [
|
|
315
|
+
{"name": "External surface", "thickness": 0.0, "resistance": 0.04},
|
|
316
|
+
{"name": "External plaster", "thickness": 0.02, "density": 1800,
|
|
317
|
+
"specific_heat": 1000, "conductivity": 0.9},
|
|
318
|
+
{"name": "Concrete block", "thickness": 0.25, "density": 2400,
|
|
319
|
+
"specific_heat": 1000, "conductivity": 1.4},
|
|
320
|
+
{"name": "Internal plaster", "thickness": 0.02, "density": 1400,
|
|
321
|
+
"specific_heat": 1000, "conductivity": 0.7},
|
|
322
|
+
{"name": "Internal surface", "thickness": 0.0, "resistance": 0.13}
|
|
323
|
+
],
|
|
324
|
+
"temperature_profile": [25, 24, 23.5, 23, 22.5, 23, 24, 26, 28, 30,
|
|
325
|
+
32, 34, 36, 37, 37.5, 37, 36, 34, 32, 30,
|
|
326
|
+
28, 27, 26, 25.5]
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Units (SI)
|
|
331
|
+
|
|
332
|
+
| Property | Unit | Description |
|
|
333
|
+
|---|---|---|
|
|
334
|
+
| `thickness` | m | Layer thickness (0 for surface resistance or air gap) |
|
|
335
|
+
| `density` | kg/m^3 | Material density |
|
|
336
|
+
| `specific_heat` | J/(kg\*K) | Specific heat capacity |
|
|
337
|
+
| `conductivity` | W/(m\*K) | Thermal conductivity |
|
|
338
|
+
| `resistance` | m^2\*K/W | Thermal resistance (for air gaps and surface films) |
|
|
339
|
+
|
|
340
|
+
### Wall structure rules
|
|
341
|
+
|
|
342
|
+
A wall must contain **at least 3 layers**:
|
|
343
|
+
|
|
344
|
+
1. **First layer**: external surface resistance (combined convective and radiative exchange coefficient)
|
|
345
|
+
2. **Intermediate layers**: material layers or air gaps, ordered from outside to inside
|
|
346
|
+
3. **Last layer**: internal surface resistance
|
|
347
|
+
|
|
348
|
+
Typical surface resistance values (EN ISO 6946):
|
|
349
|
+
|
|
350
|
+
| Surface | Resistance [m^2\*K/W] | Notes |
|
|
351
|
+
|---|---|---|
|
|
352
|
+
| External, normal exposure | 0.04 | Wind speed > 4 m/s |
|
|
353
|
+
| External, sheltered | 0.06 | Wind speed 1-4 m/s |
|
|
354
|
+
| Internal, horizontal flow | 0.13 | Vertical walls |
|
|
355
|
+
| Internal, upward flow | 0.10 | Floors (heating) |
|
|
356
|
+
| Internal, downward flow | 0.17 | Ceilings (heating) |
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Parameters and guidelines
|
|
361
|
+
|
|
362
|
+
| Parameter | Default | Description |
|
|
363
|
+
|---|---|---|
|
|
364
|
+
| `n_roots` | 50 | Number of zeros of B(s) to find |
|
|
365
|
+
| `n_coefficients` | 49 | Maximum number of Z-domain coefficients |
|
|
366
|
+
| `sampling_time` | 1.0 | Sampling period [hours] (must divide 24) |
|
|
367
|
+
| `n_periods` | 10 | Number of 24h periods for transient decay |
|
|
368
|
+
| `n_harmonics` | 120 | Harmonics for Fourier validation |
|
|
369
|
+
| `T_int` | 24.0 | Constant internal air temperature [C] |
|
|
370
|
+
| `use_mitalas` | True | Apply Mitalas instruction (recommended) |
|
|
371
|
+
|
|
372
|
+
### Recommendations
|
|
373
|
+
|
|
374
|
+
Based on the analysis in Ref. [2]:
|
|
375
|
+
|
|
376
|
+
1. **Do not use too many poles.** For most walls, 20-30 roots with automatic
|
|
377
|
+
Procedure I selection gives optimal results. The effective number of
|
|
378
|
+
poles is determined automatically.
|
|
379
|
+
|
|
380
|
+
2. **Increase the sampling period for massive walls.** For walls with total
|
|
381
|
+
thickness > 0.4 m (typical of historical European buildings), a sampling
|
|
382
|
+
period of 2 h may give better results than 1 h.
|
|
383
|
+
|
|
384
|
+
3. **Procedure I is enabled by default.** It sorts residues by significance
|
|
385
|
+
and discards negligible ones, preventing the numerical problems that
|
|
386
|
+
affect naive implementations.
|
|
387
|
+
|
|
388
|
+
4. **Check the Fourier validation error.** A PME below 5% indicates
|
|
389
|
+
reliable coefficients. If the error is high, try:
|
|
390
|
+
- Increasing the sampling period
|
|
391
|
+
- Reducing `n_roots`
|
|
392
|
+
- Checking wall data for unrealistic property values
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Examples
|
|
397
|
+
|
|
398
|
+
The `examples/` directory contains ready-to-use JSON wall definitions:
|
|
399
|
+
|
|
400
|
+
- **`heavy_wall.json`**: Plaster + concrete 25cm + plaster (U = 2.50 W/m^2K)
|
|
401
|
+
- **`insulated_wall.json`**: Insulated cavity wall with air gap (U = 0.33 W/m^2K)
|
|
402
|
+
|
|
403
|
+
Run them with:
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
uv run cati examples/heavy_wall.json --roots 30 --coefficients 20
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## Validation
|
|
412
|
+
|
|
413
|
+
The CTF output is validated against an independent Fourier steady-state
|
|
414
|
+
solution (harmonic analysis using the complex thermal quadrupole). The
|
|
415
|
+
Percentage Mean Error (PME) is computed as in Ref. [2], Eq. (4-5):
|
|
416
|
+
|
|
417
|
+
```
|
|
418
|
+
PME = (1/24) * SUM_{tau=1}^{24} |T_Z(tau) - T_F(tau)| / |T_F(tau)| * 100
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Typical results:
|
|
422
|
+
|
|
423
|
+
| Wall type | Thickness | U [W/m^2K] | PME |
|
|
424
|
+
|---|---|---|---|
|
|
425
|
+
| Heavy concrete + plaster | 0.29 m | 2.50 | **0.15%** |
|
|
426
|
+
| Brick + concrete (2 layers) | 0.27 m | ~2.5 | **< 5%** |
|
|
427
|
+
| Lightweight wood | 0.10 m | 1.20 | **~5%** |
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
## How to cite
|
|
432
|
+
|
|
433
|
+
If you use CATI in your research, please cite the following publications:
|
|
434
|
+
|
|
435
|
+
> G. Beccali, M. Cellura, V. Lo Brano, A. Orioli, *"Single thermal zone
|
|
436
|
+
> balance solved by Transfer Function Method"*, Energy and Buildings 37 (2005)
|
|
437
|
+
> 1268-1277. DOI: [10.1016/j.enbuild.2005.02.010](https://doi.org/10.1016/j.enbuild.2005.02.010)
|
|
438
|
+
|
|
439
|
+
> G. Beccali, M. Cellura, V. Lo Brano, A. Orioli, *"Is the transfer function
|
|
440
|
+
> method reliable in a European building context? A theoretical analysis and
|
|
441
|
+
> a case study in the south of Italy"*, Applied Thermal Engineering 25 (2005)
|
|
442
|
+
> 341-357. DOI: [10.1016/j.applthermaleng.2004.06.010](https://doi.org/10.1016/j.applthermaleng.2004.06.010)
|
|
443
|
+
|
|
444
|
+
BibTeX entries are available in the [`CITATION.cff`](CITATION.cff) file.
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## License
|
|
449
|
+
|
|
450
|
+
**CC BY-NC 4.0** (Creative Commons Attribution-NonCommercial 4.0 International)
|
|
451
|
+
|
|
452
|
+
- **Free** for academic, educational, and non-commercial use with proper attribution.
|
|
453
|
+
- **Commercial use** requires prior written permission from the copyright holder.
|
|
454
|
+
- **Attribution** must include a citation of the publications listed above.
|
|
455
|
+
- Contact for commercial licensing: valerio.lobrano@unipa.it
|
|
456
|
+
|
|
457
|
+
Copyright (c) 2005-2026 Valerio Lo Brano, Universita degli Studi di Palermo.
|
|
458
|
+
|
|
459
|
+
See [`LICENSE`](LICENSE) for the full license text.
|