pyCaRM-BHE 0.1.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.
Files changed (45) hide show
  1. pycarm_bhe-0.1.0/LICENSE +21 -0
  2. pycarm_bhe-0.1.0/PKG-INFO +185 -0
  3. pycarm_bhe-0.1.0/README.md +146 -0
  4. pycarm_bhe-0.1.0/carm/__init__.py +39 -0
  5. pycarm_bhe-0.1.0/carm/external_environment.py +187 -0
  6. pycarm_bhe-0.1.0/carm/field_layout.py +455 -0
  7. pycarm_bhe-0.1.0/carm/fluid.py +40 -0
  8. pycarm_bhe-0.1.0/carm/initial_conditions/__init__.py +4 -0
  9. pycarm_bhe-0.1.0/carm/initial_conditions/kusuda.py +50 -0
  10. pycarm_bhe-0.1.0/carm/matrix/BheMatrix.py +52 -0
  11. pycarm_bhe-0.1.0/carm/matrix/MatrixFunctions/BHECoaxial.py +201 -0
  12. pycarm_bhe-0.1.0/carm/matrix/MatrixFunctions/BHEDoubleUTube.py +320 -0
  13. pycarm_bhe-0.1.0/carm/matrix/MatrixFunctions/BHEHelical.py +299 -0
  14. pycarm_bhe-0.1.0/carm/matrix/MatrixFunctions/BHESingleUTube.py +243 -0
  15. pycarm_bhe-0.1.0/carm/matrix/MatrixFunctions/GroundMatrix.py +382 -0
  16. pycarm_bhe-0.1.0/carm/matrix/MatrixFunctions/__init__.py +39 -0
  17. pycarm_bhe-0.1.0/carm/matrix/__init__.py +5 -0
  18. pycarm_bhe-0.1.0/carm/matrix/assembly.py +220 -0
  19. pycarm_bhe-0.1.0/carm/model.py +120 -0
  20. pycarm_bhe-0.1.0/carm/properties/__init__.py +27 -0
  21. pycarm_bhe-0.1.0/carm/properties/borehole.py +1322 -0
  22. pycarm_bhe-0.1.0/carm/properties/ground.py +343 -0
  23. pycarm_bhe-0.1.0/carm/properties/soil_moisture.py +253 -0
  24. pycarm_bhe-0.1.0/carm/simulation/__init__.py +6 -0
  25. pycarm_bhe-0.1.0/carm/simulation/heat_flux_mode.py +63 -0
  26. pycarm_bhe-0.1.0/carm/simulation/solver.py +963 -0
  27. pycarm_bhe-0.1.0/carm/state.py +33 -0
  28. pycarm_bhe-0.1.0/carm/thermal_interference/__init__.py +5 -0
  29. pycarm_bhe-0.1.0/carm/thermal_interference/fls.py +178 -0
  30. pycarm_bhe-0.1.0/pyCaRM_BHE.egg-info/PKG-INFO +185 -0
  31. pycarm_bhe-0.1.0/pyCaRM_BHE.egg-info/SOURCES.txt +43 -0
  32. pycarm_bhe-0.1.0/pyCaRM_BHE.egg-info/dependency_links.txt +1 -0
  33. pycarm_bhe-0.1.0/pyCaRM_BHE.egg-info/requires.txt +18 -0
  34. pycarm_bhe-0.1.0/pyCaRM_BHE.egg-info/top_level.txt +1 -0
  35. pycarm_bhe-0.1.0/pyproject.toml +78 -0
  36. pycarm_bhe-0.1.0/setup.cfg +4 -0
  37. pycarm_bhe-0.1.0/tests/test_examples_smoke.py +71 -0
  38. pycarm_bhe-0.1.0/tests/test_external_environment.py +216 -0
  39. pycarm_bhe-0.1.0/tests/test_field.py +252 -0
  40. pycarm_bhe-0.1.0/tests/test_fls.py +154 -0
  41. pycarm_bhe-0.1.0/tests/test_fluid.py +68 -0
  42. pycarm_bhe-0.1.0/tests/test_heat_flux_mode.py +87 -0
  43. pycarm_bhe-0.1.0/tests/test_model.py +220 -0
  44. pycarm_bhe-0.1.0/tests/test_solver.py +712 -0
  45. pycarm_bhe-0.1.0/tests/test_state.py +93 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alessio Tollin, Angelo Zarrella
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,185 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyCaRM-BHE
3
+ Version: 0.1.0
4
+ Summary: Python library for simulation of borehole heat exchanger systems
5
+ Author: Alessio Tollin, Angelo Zarrella
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/BETALAB-team/pyCaRM
8
+ Project-URL: Documentation, https://betalab-team.github.io/pyCaRM/
9
+ Project-URL: Repository, https://github.com/BETALAB-team/pyCaRM
10
+ Project-URL: Bug Tracker, https://github.com/BETALAB-team/pyCaRM/issues
11
+ Keywords: borehole heat exchanger,ground source heat pump,geothermal,BHE,GSHP,thermal simulation
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: numpy
24
+ Requires-Dist: scipy
25
+ Requires-Dist: matplotlib
26
+ Requires-Dist: shapely
27
+ Requires-Dist: networkx
28
+ Provides-Extra: dev
29
+ Requires-Dist: pygfunction; extra == "dev"
30
+ Requires-Dist: pytest; extra == "dev"
31
+ Requires-Dist: pandas; extra == "dev"
32
+ Requires-Dist: openpyxl; extra == "dev"
33
+ Provides-Extra: docs
34
+ Requires-Dist: sphinx; extra == "docs"
35
+ Requires-Dist: sphinxawesome-theme; extra == "docs"
36
+ Provides-Extra: coolprop
37
+ Requires-Dist: CoolProp; extra == "coolprop"
38
+ Dynamic: license-file
39
+
40
+ <p align="center">
41
+ <img src="docs/CaRM_logo.jpg" width="200"/>
42
+ </p>
43
+
44
+ # pyCaRM
45
+
46
+ [![PyPI version](https://img.shields.io/pypi/v/pyCaRM-BHE.svg)](https://pypi.org/project/pyCaRM-BHE/)
47
+ [![Python versions](https://img.shields.io/pypi/pyversions/pyCaRM-BHE.svg)](https://pypi.org/project/pyCaRM-BHE/)
48
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
49
+
50
+ **pyCaRM** (CApacity Resistance Model) is a Python library for the simulation of
51
+ borehole heat exchanger (BHE) systems. It models the transient thermal response
52
+ of the ground and borehole, supporting single and multi-borehole configurations
53
+ with surface boundary conditions.
54
+
55
+ > 📖 **Documentation:** https://betalab-team.github.io/pyCaRM/
56
+
57
+ ## Features
58
+
59
+ - Single and multi-borehole field configurations
60
+ - Supported BHE types: single U-tube, double U-tube, coaxial, helical
61
+ - Ground stratification support
62
+ - Surface boundary conditions (solar radiation, sky radiation, convection)
63
+ - Voronoi-based field decomposition for multi-borehole layouts
64
+ - Finite Line Source (FLS) thermal interference model
65
+ - Parallel and series borehole connection modes
66
+ - Heat flux mode: drive the simulation from a heat pump-side thermal load and
67
+ supply temperature, with heat pump COP/EER performance accounted for
68
+ - Time-variable grout thermophysical properties driven by soil moisture
69
+ content (irrigation/precipitation input)
70
+
71
+ ## Installation
72
+
73
+ Install from PyPI:
74
+ ```bash
75
+ pip install pyCaRM-BHE
76
+ ```
77
+
78
+ Alternatively, clone the repository and install from source:
79
+ ```bash
80
+ git clone https://github.com/BETALAB-team/pyCaRM.git
81
+ cd pyCaRM
82
+ pip install .
83
+ ```
84
+
85
+ **Developers:**
86
+ ```bash
87
+ git clone https://github.com/BETALAB-team/pyCaRM.git
88
+ cd pyCaRM
89
+ pip install -e ".[dev]"
90
+ ```
91
+
92
+ ## Optional Dependencies
93
+
94
+ - [CoolProp](http://www.coolprop.org) — for computing fluid thermophysical properties. Install with `pip install pyCaRM-BHE[coolprop]`. See [Fluid Properties](https://betalab-team.github.io/pyCaRM/fluid_properties.html) for usage.
95
+
96
+ ## Documentation
97
+
98
+ Full documentation is available at **https://betalab-team.github.io/pyCaRM/**.
99
+
100
+ ## Examples
101
+
102
+ Complete working scripts for all supported configurations are available in the
103
+ `examples/` folder. See also the [documentation](https://betalab-team.github.io/pyCaRM/)
104
+ for detailed usage guides.
105
+
106
+ - `SingleUtube_multi_parallel.py` — multi-borehole field, parallel mode
107
+ - `SingleUtube_multi_series.py` — multi-borehole field, series mode
108
+ - `SingleUtube_multi_series_heat_flux.py` — multi-borehole field, series mode, heat flux (COP/EER) mode
109
+ - `SingleUtube.py` — single borehole, single U-tube
110
+ - `DoubleUtube.py` — single borehole, double U-tube
111
+ - `Coaxial.py` — single borehole, coaxial
112
+ - `Helical.py` — single borehole, helical
113
+ - `Helical_variable_properties.py` — single borehole, helical, time-variable grout properties from soil moisture
114
+
115
+ ## Authors
116
+
117
+ Developed at **BETALAB** – Department of Industrial Engineering, University of Padova.
118
+
119
+ - Alessio Tollin
120
+ - Angelo Zarrella
121
+
122
+ ## Citation
123
+
124
+ If you use CaRM in your research, please cite:
125
+ ```
126
+ [Citation will be added after publication]
127
+ ```
128
+
129
+ This library is based on the following works:
130
+
131
+ - De Carli, M., Tonon, M., Zarrella, A., Zecchin, R. (2010). *A computational
132
+ capacity resistance model (CaRM) for vertical ground-coupled heat exchangers.*
133
+ Renewable Energy, 35(7), 1537–1550.
134
+ https://doi.org/10.1016/j.renene.2009.11.034
135
+
136
+ - Zarrella, A., Scarpa, M., De Carli, M. (2011). *Short time step analysis of
137
+ vertical ground-coupled heat exchangers: The approach of CaRM.*
138
+ Renewable Energy, 36(9), 2357–2367.
139
+ https://doi.org/10.1016/j.renene.2011.01.032
140
+
141
+ - Zarrella, A., De Carli, M. (2013). *Heat transfer analysis of short helical
142
+ borehole heat exchangers.* Applied Thermal Engineering, 61(1-2), 34–47.
143
+ https://doi.org/10.1016/j.applthermaleng.2013.08.011
144
+
145
+ - Zarrella, A., Capozza, A., De Carli, M. (2013). *Analysis of short helical
146
+ and double U-tube borehole heat exchangers: A simulation-based comparison.*
147
+ Applied Energy, 112, 358–370.
148
+ https://doi.org/10.1016/j.apenergy.2012.09.012
149
+
150
+ - Najib, A., Zarrella, A., Narayanan, V., Grant, P., Harrington, C. (2019). *A revised
151
+ capacitance resistance model for large diameter shallow bore ground heat exchanger.*
152
+ Applied Thermal Engineering, 162, 114305.
153
+ https://doi.org/10.1016/j.applthermaleng.2019.114305
154
+
155
+ - Claesson, J., Javed, S. (2011). *An analytical method to calculate borehole fluid
156
+ temperatures for time-scales from minutes to decades.*
157
+ ASHRAE Transactions, 117(2), 279–288.
158
+
159
+ - Cimmino, M., Bernier, M. (2014). *A semi-analytical method to generate g-functions
160
+ for geothermal bore fields.* International Journal of Heat and Mass Transfer, 70,
161
+ 641–650. https://doi.org/10.1016/j.ijheatmasstransfer.2013.11.037
162
+
163
+ - Cimmino, M. (2018). *pygfunction: an open-source toolbox for the evaluation of
164
+ thermal response factors for geothermal borehole fields.*
165
+ Proceedings of eSim 2018, Montréal, Canada, 492–501.
166
+
167
+ - Bell, I.H., Wronski, J., Quoilin, S., Lemort, V. (2014). *Pure and pseudo-pure fluid
168
+ thermophysical property evaluation and the open-source thermophysical property library
169
+ CoolProp.* Industrial & Engineering Chemistry Research, 53(6), 2498–2508.
170
+ https://doi.org/10.1021/ie4033999
171
+
172
+ - Chung, S.O., Horton, R. (1987). *Soil heat and water flow with a partial surface
173
+ mulch.* Water Resources Research, 23(12), 2175–2186.
174
+ https://doi.org/10.1029/WR023i012p02175
175
+
176
+ - de Vries, D.A. (1963). *Thermal properties of soils.* In W.R. van Wijk (Ed.),
177
+ Physics of Plant Environment. North-Holland Publishing Company, Amsterdam.
178
+
179
+ - Ruhnau, O., Hirth, L., Praktiknjo, A. (2019). *Time series of heat demand and
180
+ heat pump efficiency for energy system modeling.* Scientific Data, 6, 189.
181
+ https://doi.org/10.1038/s41597-019-0199-y
182
+
183
+ ## License
184
+
185
+ MIT License — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,146 @@
1
+ <p align="center">
2
+ <img src="docs/CaRM_logo.jpg" width="200"/>
3
+ </p>
4
+
5
+ # pyCaRM
6
+
7
+ [![PyPI version](https://img.shields.io/pypi/v/pyCaRM-BHE.svg)](https://pypi.org/project/pyCaRM-BHE/)
8
+ [![Python versions](https://img.shields.io/pypi/pyversions/pyCaRM-BHE.svg)](https://pypi.org/project/pyCaRM-BHE/)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
10
+
11
+ **pyCaRM** (CApacity Resistance Model) is a Python library for the simulation of
12
+ borehole heat exchanger (BHE) systems. It models the transient thermal response
13
+ of the ground and borehole, supporting single and multi-borehole configurations
14
+ with surface boundary conditions.
15
+
16
+ > 📖 **Documentation:** https://betalab-team.github.io/pyCaRM/
17
+
18
+ ## Features
19
+
20
+ - Single and multi-borehole field configurations
21
+ - Supported BHE types: single U-tube, double U-tube, coaxial, helical
22
+ - Ground stratification support
23
+ - Surface boundary conditions (solar radiation, sky radiation, convection)
24
+ - Voronoi-based field decomposition for multi-borehole layouts
25
+ - Finite Line Source (FLS) thermal interference model
26
+ - Parallel and series borehole connection modes
27
+ - Heat flux mode: drive the simulation from a heat pump-side thermal load and
28
+ supply temperature, with heat pump COP/EER performance accounted for
29
+ - Time-variable grout thermophysical properties driven by soil moisture
30
+ content (irrigation/precipitation input)
31
+
32
+ ## Installation
33
+
34
+ Install from PyPI:
35
+ ```bash
36
+ pip install pyCaRM-BHE
37
+ ```
38
+
39
+ Alternatively, clone the repository and install from source:
40
+ ```bash
41
+ git clone https://github.com/BETALAB-team/pyCaRM.git
42
+ cd pyCaRM
43
+ pip install .
44
+ ```
45
+
46
+ **Developers:**
47
+ ```bash
48
+ git clone https://github.com/BETALAB-team/pyCaRM.git
49
+ cd pyCaRM
50
+ pip install -e ".[dev]"
51
+ ```
52
+
53
+ ## Optional Dependencies
54
+
55
+ - [CoolProp](http://www.coolprop.org) — for computing fluid thermophysical properties. Install with `pip install pyCaRM-BHE[coolprop]`. See [Fluid Properties](https://betalab-team.github.io/pyCaRM/fluid_properties.html) for usage.
56
+
57
+ ## Documentation
58
+
59
+ Full documentation is available at **https://betalab-team.github.io/pyCaRM/**.
60
+
61
+ ## Examples
62
+
63
+ Complete working scripts for all supported configurations are available in the
64
+ `examples/` folder. See also the [documentation](https://betalab-team.github.io/pyCaRM/)
65
+ for detailed usage guides.
66
+
67
+ - `SingleUtube_multi_parallel.py` — multi-borehole field, parallel mode
68
+ - `SingleUtube_multi_series.py` — multi-borehole field, series mode
69
+ - `SingleUtube_multi_series_heat_flux.py` — multi-borehole field, series mode, heat flux (COP/EER) mode
70
+ - `SingleUtube.py` — single borehole, single U-tube
71
+ - `DoubleUtube.py` — single borehole, double U-tube
72
+ - `Coaxial.py` — single borehole, coaxial
73
+ - `Helical.py` — single borehole, helical
74
+ - `Helical_variable_properties.py` — single borehole, helical, time-variable grout properties from soil moisture
75
+
76
+ ## Authors
77
+
78
+ Developed at **BETALAB** – Department of Industrial Engineering, University of Padova.
79
+
80
+ - Alessio Tollin
81
+ - Angelo Zarrella
82
+
83
+ ## Citation
84
+
85
+ If you use CaRM in your research, please cite:
86
+ ```
87
+ [Citation will be added after publication]
88
+ ```
89
+
90
+ This library is based on the following works:
91
+
92
+ - De Carli, M., Tonon, M., Zarrella, A., Zecchin, R. (2010). *A computational
93
+ capacity resistance model (CaRM) for vertical ground-coupled heat exchangers.*
94
+ Renewable Energy, 35(7), 1537–1550.
95
+ https://doi.org/10.1016/j.renene.2009.11.034
96
+
97
+ - Zarrella, A., Scarpa, M., De Carli, M. (2011). *Short time step analysis of
98
+ vertical ground-coupled heat exchangers: The approach of CaRM.*
99
+ Renewable Energy, 36(9), 2357–2367.
100
+ https://doi.org/10.1016/j.renene.2011.01.032
101
+
102
+ - Zarrella, A., De Carli, M. (2013). *Heat transfer analysis of short helical
103
+ borehole heat exchangers.* Applied Thermal Engineering, 61(1-2), 34–47.
104
+ https://doi.org/10.1016/j.applthermaleng.2013.08.011
105
+
106
+ - Zarrella, A., Capozza, A., De Carli, M. (2013). *Analysis of short helical
107
+ and double U-tube borehole heat exchangers: A simulation-based comparison.*
108
+ Applied Energy, 112, 358–370.
109
+ https://doi.org/10.1016/j.apenergy.2012.09.012
110
+
111
+ - Najib, A., Zarrella, A., Narayanan, V., Grant, P., Harrington, C. (2019). *A revised
112
+ capacitance resistance model for large diameter shallow bore ground heat exchanger.*
113
+ Applied Thermal Engineering, 162, 114305.
114
+ https://doi.org/10.1016/j.applthermaleng.2019.114305
115
+
116
+ - Claesson, J., Javed, S. (2011). *An analytical method to calculate borehole fluid
117
+ temperatures for time-scales from minutes to decades.*
118
+ ASHRAE Transactions, 117(2), 279–288.
119
+
120
+ - Cimmino, M., Bernier, M. (2014). *A semi-analytical method to generate g-functions
121
+ for geothermal bore fields.* International Journal of Heat and Mass Transfer, 70,
122
+ 641–650. https://doi.org/10.1016/j.ijheatmasstransfer.2013.11.037
123
+
124
+ - Cimmino, M. (2018). *pygfunction: an open-source toolbox for the evaluation of
125
+ thermal response factors for geothermal borehole fields.*
126
+ Proceedings of eSim 2018, Montréal, Canada, 492–501.
127
+
128
+ - Bell, I.H., Wronski, J., Quoilin, S., Lemort, V. (2014). *Pure and pseudo-pure fluid
129
+ thermophysical property evaluation and the open-source thermophysical property library
130
+ CoolProp.* Industrial & Engineering Chemistry Research, 53(6), 2498–2508.
131
+ https://doi.org/10.1021/ie4033999
132
+
133
+ - Chung, S.O., Horton, R. (1987). *Soil heat and water flow with a partial surface
134
+ mulch.* Water Resources Research, 23(12), 2175–2186.
135
+ https://doi.org/10.1029/WR023i012p02175
136
+
137
+ - de Vries, D.A. (1963). *Thermal properties of soils.* In W.R. van Wijk (Ed.),
138
+ Physics of Plant Environment. North-Holland Publishing Company, Amsterdam.
139
+
140
+ - Ruhnau, O., Hirth, L., Praktiknjo, A. (2019). *Time series of heat demand and
141
+ heat pump efficiency for energy system modeling.* Scientific Data, 6, 189.
142
+ https://doi.org/10.1038/s41597-019-0199-y
143
+
144
+ ## License
145
+
146
+ MIT License — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+ from .properties import (
3
+ BoreholeProperties,
4
+ BoreholeGeometry,
5
+ BoreholeMesh,
6
+ BoreholeThermalProperties,
7
+ SingleUtube,
8
+ DoubleUtube,
9
+ Coaxial,
10
+ Helical,
11
+ )
12
+ from .properties import GroundGeometry, GroundMesh, GroundProperties
13
+ from .model import PhysicalModel
14
+ from .simulation import Simulation, HeatFluxMode
15
+ from .fluid import Fluid
16
+ from .external_environment import EnvironmentalProperties, EnvironmentalTimeSeries
17
+ from .field_layout import FieldInput, Field
18
+
19
+ __all__ = [
20
+ "GroundGeometry",
21
+ "GroundMesh",
22
+ "GroundProperties",
23
+ "BoreholeProperties",
24
+ "BoreholeGeometry",
25
+ "BoreholeMesh",
26
+ "BoreholeThermalProperties",
27
+ "SingleUtube",
28
+ "DoubleUtube",
29
+ "Coaxial",
30
+ "Helical",
31
+ "PhysicalModel",
32
+ "Simulation",
33
+ "HeatFluxMode",
34
+ "Fluid",
35
+ "EnvironmentalProperties",
36
+ "EnvironmentalTimeSeries",
37
+ "FieldInput",
38
+ "Field",
39
+ ]
@@ -0,0 +1,187 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Environmental conditions module.
4
+
5
+ Defines the thermal and radiative properties of the external environment
6
+ used as boundary conditions in the borehole heat exchanger simulation.
7
+ """
8
+
9
+ from dataclasses import dataclass, field
10
+
11
+ from typing import Self
12
+ from numpy.typing import NDArray
13
+
14
+ import numpy as np
15
+
16
+
17
+ @dataclass(frozen=True, slots=True)
18
+ class EnvironmentalProperties:
19
+ """
20
+ Physical and thermal properties of the external environment.
21
+
22
+ Groups all site-specific parameters that characterize the surface
23
+ boundary condition: radiative exchange coefficients, surface optical
24
+ properties, and the seasonal air temperature signal.
25
+
26
+ Attributes
27
+ ----------
28
+ R_ext : float
29
+ External thermal resistance [W / (K m²)].
30
+ absorptance : float
31
+ Surface absorptance for solar radiation [-].
32
+ eps : float
33
+ Surface emittance for longwave radiation [-].
34
+ At : float
35
+ Annual amplitude of monthly average air temperature [K].
36
+ tau : float
37
+ Current simulation time [s].
38
+ tau_y : float
39
+ Duration of one year (315,536,000 s) [s].
40
+ tau_shift : float
41
+ Time offset to account for the date of minimum surface temperature [s].
42
+ """
43
+
44
+ R_ext: float # W / (K * m2)
45
+ absorptance: float # -, surface absorptance
46
+ eps: float # -, surface emittance
47
+ At: float # annual amplitude of monthly average air temperature
48
+ tau: float # s, time
49
+ tau_y: float # 315,536,000 s, time of 1 year
50
+ tau_shift: float # s, time to account for the date of minimum surface temperature
51
+
52
+ def __post_init__(self):
53
+ if self.R_ext < 0:
54
+ raise ValueError("R_ext value must be >= 0")
55
+ if self.absorptance < 0:
56
+ raise ValueError("absorptance value must be >= 0")
57
+ if self.eps < 0:
58
+ raise ValueError("eps value must be >= 0")
59
+ if self.At < 0:
60
+ raise ValueError("At value must be >= 0")
61
+ if self.tau < 0:
62
+ raise ValueError("tau value must be >= 0")
63
+ if self.tau_y < 0:
64
+ raise ValueError("tau_y value must be > 0")
65
+ if self.tau_shift < 0:
66
+ raise ValueError("tau_shift value must be > 0")
67
+
68
+
69
+ @dataclass
70
+ class EnvironmentalTimeSeries:
71
+ """
72
+ Time series of external environmental inputs.
73
+
74
+ Stores the external air temperature and solar irradiance arrays
75
+ used to drive the surface boundary condition over the simulation period.
76
+ Instances should be created via the class methods to ensure input validation.
77
+
78
+ Attributes
79
+ ----------
80
+ Tm : float
81
+ Mean annual air temperature [°C].
82
+ T_ext : NDArray[np.float64]
83
+ External air temperature time series [°C].
84
+ SolarRad : NDArray[np.float64]
85
+ Solar irradiance time series [W/m²].
86
+ water_input : NDArray[np.float64] | None = None
87
+ Water input series by irrigation or
88
+ metherological phenomena [m3 / s].
89
+ """
90
+
91
+ Tm: float
92
+ T_ext: NDArray[np.float64]
93
+ SolarRad: NDArray[np.float64]
94
+ water_input: NDArray[np.float64] | None = None
95
+
96
+ @classmethod
97
+ def from_array(
98
+ cls,
99
+ Tm: float,
100
+ T_ext: NDArray[np.float64],
101
+ SolarRad: NDArray[np.float64],
102
+ water_input: NDArray[np.float64] | None = None,
103
+ ) -> Self:
104
+ """
105
+ Construct an instance from NumPy arrays.
106
+
107
+ All values must be finite (no NaN or Inf).
108
+
109
+ Parameters
110
+ ----------
111
+ Tm : float
112
+ Mean annual air temperature [°C].
113
+ T_ext : NDArray[np.float64]
114
+ External air temperature time series [°C].
115
+ SolarRad : NDArray[np.float64]
116
+ Solar irradiance time series [W/m²].
117
+ water_input : NDArray[np.float64] | None = None
118
+ Water input series by irrigation or
119
+ metherological phenomena [m3 / s].
120
+
121
+ Returns
122
+ -------
123
+ EnvironmentalTimeSeries
124
+ A validated instance populated from the arrays.
125
+
126
+ Raises
127
+ ------
128
+ ValueError
129
+ If ``T_ext``, ``SolarRad``, or ``water_input`` contain non-finite values.
130
+
131
+ Examples
132
+ --------
133
+ >>> import numpy as np
134
+ >>> T = np.linspace(-5, 25, 8760)
135
+ >>> rad = np.abs(np.sin(np.linspace(0, 2 * np.pi, 8760))) * 600
136
+ >>> env = EnvironmentalTimeSeries.from_array(12.0, T, rad)
137
+ """
138
+ arrays = {"T_ext": T_ext, "SolarRad": SolarRad}
139
+ if water_input is not None:
140
+ arrays["water_input"] = water_input
141
+
142
+ invalid = [name for name, arr in arrays.items() if not np.all(np.isfinite(arr))]
143
+ if invalid:
144
+ raise ValueError(f"{', '.join(invalid)} may contain invalid values")
145
+
146
+ return cls(Tm, T_ext, SolarRad, water_input)
147
+
148
+
149
+ @dataclass
150
+ class ExternalEnvironment:
151
+ """
152
+ Assembled external environment for simulation boundary conditions.
153
+
154
+ Combines physical properties and time-series inputs, and derives
155
+ the sky radiation temperature from the external air temperature
156
+ at construction time.
157
+
158
+ Attributes
159
+ ----------
160
+ envprops : EnvironmentalProperties
161
+ Static physical and radiative properties of the site.
162
+ envinput : EnvironmentalTimeSeries
163
+ Time-varying environmental inputs (temperature and solar radiation).
164
+ T_sky : NDArray[np.float64]
165
+ Effective sky temperature time series, derived from ``T_ext`` [K].
166
+ boltzmann : float
167
+ Stefan-Boltzmann constant (5.670374419 × 10⁻⁸) [W / (m² K⁴)].
168
+
169
+ Examples
170
+ --------
171
+ >>> env = ExternalEnvironment(envprops=props, envinput=series)
172
+ >>> env.T_sky.shape
173
+ (8760,)
174
+ """
175
+
176
+ envprops: EnvironmentalProperties
177
+ envinput: EnvironmentalTimeSeries
178
+ T_sky: NDArray[np.float64] = field(init=False)
179
+
180
+ boltzmann: float = field(default=5.670374419e-8, init=False)
181
+
182
+ def __post_init__(self) -> None:
183
+ # T_sky calculation
184
+ self._sky_temperature_calc()
185
+
186
+ def _sky_temperature_calc(self) -> None:
187
+ self.T_sky = 0.0552 * (self.envinput.T_ext + 273.15) ** 1.5