geoloop 1.0.0b1__tar.gz → 1.0.2__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.
- {geoloop-1.0.0b1/src/geoloop.egg-info → geoloop-1.0.2}/PKG-INFO +22 -14
- geoloop-1.0.2/README.md +92 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/pyproject.toml +4 -3
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/configuration.py +21 -1
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/constants.py +0 -17
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/geoloopcore/b2g_ana.py +2 -21
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/lithology/process_lithology.py +15 -7
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/plotting/create_plots.py +19 -14
- geoloop-1.0.2/src/geoloop/utils/__init__.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2/src/geoloop.egg-info}/PKG-INFO +22 -14
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop.egg-info/SOURCES.txt +1 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/test/test_b2g.py +2 -1
- {geoloop-1.0.0b1 → geoloop-1.0.2}/test/test_b2g_ana.py +2 -1
- {geoloop-1.0.0b1 → geoloop-1.0.2}/test/test_h5.py +2 -1
- {geoloop-1.0.0b1 → geoloop-1.0.2}/test/test_lithology.py +2 -1
- {geoloop-1.0.0b1 → geoloop-1.0.2}/test/test_loadflowdata.py +2 -1
- {geoloop-1.0.0b1 → geoloop-1.0.2}/test/test_plotting.py +2 -1
- {geoloop-1.0.0b1 → geoloop-1.0.2}/test/test_pyg_ana.py +2 -1
- {geoloop-1.0.0b1 → geoloop-1.0.2}/test/test_pygfield_ana.py +2 -1
- geoloop-1.0.0b1/README.md +0 -84
- {geoloop-1.0.0b1 → geoloop-1.0.2}/LICENSE.md +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/setup.cfg +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/__init__.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/axisym/AxisymetricEL.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/axisym/__init__.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/bin/Flowdatamain.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/bin/Lithologymain.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/bin/Loadprofilemain.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/bin/Plotmain.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/bin/Runbatch.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/bin/Runmain.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/bin/SingleRunSim.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/bin/__init__.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/cli/__init__.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/cli/batch.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/cli/main.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/geoloopcore/CoaxialPipe.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/geoloopcore/CustomPipe.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/geoloopcore/__init__.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/geoloopcore/b2g.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/geoloopcore/boreholedesign.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/geoloopcore/getloaddata.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/geoloopcore/pyg_ana.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/geoloopcore/pygfield_ana.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/geoloopcore/simulationparameters.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/geoloopcore/soilproperties.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/geoloopcore/strat_interpolator.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/lithology/__init__.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/lithology/plot_lithology.py +0 -0
- {geoloop-1.0.0b1/src/geoloop/utils → geoloop-1.0.2/src/geoloop/lithology/resources}/__init__.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/loadflowdata/__init__.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/loadflowdata/flow_data.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/loadflowdata/loadprofile.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/plotting/__init__.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/plotting/load_data.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/utils/RunManager.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop/utils/helpers.py +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop.egg-info/dependency_links.txt +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop.egg-info/entry_points.txt +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop.egg-info/requires.txt +0 -0
- {geoloop-1.0.0b1 → geoloop-1.0.2}/src/geoloop.egg-info/top_level.txt +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: geoloop
|
|
3
|
-
Version: 1.0.
|
|
4
|
-
Summary: This is a Python package for simulation of (deep) Borehole Heat Exchanger (BHE) systems
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: This is a Python package for simulation of (deep) vertical Borehole Heat Exchanger (BHE) systems
|
|
5
5
|
Author-email: Zanne Korevaar <zanne.korevaar@tno.nl>, Jan-Diederik van Wees <jan_diederik.vanwees@tno.nl>
|
|
6
|
-
License: Apache
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
7
|
Keywords: borehole heat exchanger,BHE,geothermal,ground-source heat pump,deep borehole heat exchanger
|
|
8
8
|
Requires-Python: <3.14,>=3.12
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
@@ -33,20 +33,22 @@ Dynamic: license-file
|
|
|
33
33
|
|
|
34
34
|
## What is **Geoloop**?
|
|
35
35
|
|
|
36
|
-
**Geoloop** is a Python package for simulating borehole heat exchanger (BHE) systems,
|
|
37
|
-
with a focus on
|
|
36
|
+
**Geoloop** is a Python package for simulating vertical borehole heat exchanger (BHE) systems,
|
|
37
|
+
with a focus on the impact of depth-dependent thermal properties and geothermal gradient and their impact on system performance.
|
|
38
38
|
|
|
39
39
|
**Geoloop** incorporates (uncertainty in) depth-variations in subsurface thermal conductivity, subsurface temperature,
|
|
40
40
|
BHE design and diverse operational boundary conditions such as seasonal load variations or
|
|
41
|
-
minimum fluid temperatures
|
|
42
|
-
for optimization of the system design and operation. This makes Geoloop
|
|
41
|
+
minimum fluid temperatures. It allows for deterministic or stochastic performance analyses with the opportunity
|
|
42
|
+
for optimization of the system design and operation. This makes Geoloop well suited for scenario analyses and sensitivity
|
|
43
43
|
studies in both research and practical applications.
|
|
44
44
|
|
|
45
|
-
**Geoloop**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
**Geoloop** provides a novel depth-dependent approach for thermal response calculations.
|
|
46
|
+
A detailed description and benchmark of this depth-dependent semi-analytical method is provided in Korevaar et al. (2026).
|
|
47
|
+
**Geoloop** uses the *pygfunction* package, developed by Cimmino & Cook (2022), including its implementation
|
|
48
|
+
of *g*-functions, time aggregation schemes for varying loads, borehole and fluid thermal properties, and various visualization capabilities
|
|
49
|
+
|
|
50
|
+
**Geoloop's** generic framework allows for easy switching between simulation methods, including the
|
|
51
|
+
depth-dependent model, the depth-uniform implementation of g-functions as implemented in *pygfunction* and a numerical
|
|
50
52
|
finite volume approach.
|
|
51
53
|
|
|
52
54
|
---
|
|
@@ -66,7 +68,7 @@ see the [Installation Guide](https://geoloop-8f7a36.ci.tno.nl/installation/insta
|
|
|
66
68
|
|
|
67
69
|
## Requirements
|
|
68
70
|
|
|
69
|
-
Geoloop requires **Python 3.12
|
|
71
|
+
Geoloop requires **Python version >=3.12,<3.14**.
|
|
70
72
|
|
|
71
73
|
Core dependencies include:
|
|
72
74
|
- pygfunction
|
|
@@ -105,8 +107,14 @@ See the [LICENSE.md](LICENSE.md) file for details.
|
|
|
105
107
|
|
|
106
108
|
## Acknowledgments
|
|
107
109
|
|
|
108
|
-
Developed with the support of the
|
|
110
|
+
Developed with the support of the **Netherlands Enterprise Agency (RVO)**, in a consortium project with grant nr. MOOI322009.
|
|
109
111
|
|
|
110
112
|
---
|
|
111
113
|
|
|
112
114
|
|
|
115
|
+
## References
|
|
116
|
+
|
|
117
|
+
- Cimmino, M. and Cook, J.: pygfunction 2.2: New features and improvements in accuracy and computational efficiency,
|
|
118
|
+
in: Proceedings of the IGSHPA Research Track 2022, International Ground Source Heat Pump Association,
|
|
119
|
+
https://doi.org/10.22488/okstate.22.000015, 2022.
|
|
120
|
+
- Korevaar, Z., Brett, H., Lourens, A. and Van Wees, J.D.: Geoloop (v1.0) – a stochastic, depth-dependent borehole heat exchanger model, Geoscientific Model Development (in prep), 2026
|
geoloop-1.0.2/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Geoloop: A BHE Calculator for Python
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/geoloop/)
|
|
4
|
+
[](https://geoloop-8f7a36.ci.tno.nl/)
|
|
5
|
+
|
|
6
|
+
## What is **Geoloop**?
|
|
7
|
+
|
|
8
|
+
**Geoloop** is a Python package for simulating vertical borehole heat exchanger (BHE) systems,
|
|
9
|
+
with a focus on the impact of depth-dependent thermal properties and geothermal gradient and their impact on system performance.
|
|
10
|
+
|
|
11
|
+
**Geoloop** incorporates (uncertainty in) depth-variations in subsurface thermal conductivity, subsurface temperature,
|
|
12
|
+
BHE design and diverse operational boundary conditions such as seasonal load variations or
|
|
13
|
+
minimum fluid temperatures. It allows for deterministic or stochastic performance analyses with the opportunity
|
|
14
|
+
for optimization of the system design and operation. This makes Geoloop well suited for scenario analyses and sensitivity
|
|
15
|
+
studies in both research and practical applications.
|
|
16
|
+
|
|
17
|
+
**Geoloop** provides a novel depth-dependent approach for thermal response calculations.
|
|
18
|
+
A detailed description and benchmark of this depth-dependent semi-analytical method is provided in Korevaar et al. (2026).
|
|
19
|
+
**Geoloop** uses the *pygfunction* package, developed by Cimmino & Cook (2022), including its implementation
|
|
20
|
+
of *g*-functions, time aggregation schemes for varying loads, borehole and fluid thermal properties, and various visualization capabilities
|
|
21
|
+
|
|
22
|
+
**Geoloop's** generic framework allows for easy switching between simulation methods, including the
|
|
23
|
+
depth-dependent model, the depth-uniform implementation of g-functions as implemented in *pygfunction* and a numerical
|
|
24
|
+
finite volume approach.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
Install from PyPI using:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install geoloop
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
For detailed setup instructions (including uv-based environments and development setup),
|
|
37
|
+
see the [Installation Guide](https://geoloop-8f7a36.ci.tno.nl/installation/install/).
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Requirements
|
|
42
|
+
|
|
43
|
+
Geoloop requires **Python version >=3.12,<3.14**.
|
|
44
|
+
|
|
45
|
+
Core dependencies include:
|
|
46
|
+
- pygfunction
|
|
47
|
+
- matplotlib
|
|
48
|
+
- numpy
|
|
49
|
+
- scipy
|
|
50
|
+
- h5py
|
|
51
|
+
- xarray
|
|
52
|
+
- pandas
|
|
53
|
+
- seaborn
|
|
54
|
+
- tqdm
|
|
55
|
+
- netCDF4
|
|
56
|
+
- SecondaryCoolantProps
|
|
57
|
+
- openpyxl
|
|
58
|
+
- h5netcdf
|
|
59
|
+
- pathlib
|
|
60
|
+
- pydantic
|
|
61
|
+
- typer
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Quick Start
|
|
66
|
+
|
|
67
|
+
Explore the [Examples](docs/examples/) folder to get started quickly with Geoloop.
|
|
68
|
+
|
|
69
|
+
Read the full documenation [here](https://geoloop-8f7a36.ci.tno.nl/).
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
This project is licensed under the Apache 2.0 License.
|
|
76
|
+
See the [LICENSE.md](LICENSE.md) file for details.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Acknowledgments
|
|
81
|
+
|
|
82
|
+
Developed with the support of the **Netherlands Enterprise Agency (RVO)**, in a consortium project with grant nr. MOOI322009.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
## References
|
|
88
|
+
|
|
89
|
+
- Cimmino, M. and Cook, J.: pygfunction 2.2: New features and improvements in accuracy and computational efficiency,
|
|
90
|
+
in: Proceedings of the IGSHPA Research Track 2022, International Ground Source Heat Pump Association,
|
|
91
|
+
https://doi.org/10.22488/okstate.22.000015, 2022.
|
|
92
|
+
- Korevaar, Z., Brett, H., Lourens, A. and Van Wees, J.D.: Geoloop (v1.0) – a stochastic, depth-dependent borehole heat exchanger model, Geoscientific Model Development (in prep), 2026
|
|
@@ -4,14 +4,15 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "geoloop"
|
|
7
|
-
version = "1.0.
|
|
8
|
-
description = "This is a Python package for simulation of (deep) Borehole Heat Exchanger (BHE) systems"
|
|
7
|
+
version = "1.0.2"
|
|
8
|
+
description = "This is a Python package for simulation of (deep) vertical Borehole Heat Exchanger (BHE) systems"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Zanne Korevaar", email = "zanne.korevaar@tno.nl" },
|
|
11
11
|
{ name = "Jan-Diederik van Wees", email = "jan_diederik.vanwees@tno.nl" }
|
|
12
12
|
]
|
|
13
13
|
readme = "README.md"
|
|
14
|
-
license =
|
|
14
|
+
license = "Apache-2.0"
|
|
15
|
+
license-files = ["LICENSE.md"]
|
|
15
16
|
requires-python = ">=3.12,<3.14"
|
|
16
17
|
keywords = [
|
|
17
18
|
"borehole heat exchanger", "BHE", "geothermal", "ground-source heat pump",
|
|
@@ -19,6 +19,8 @@ class LithologyConfig(BaseModel):
|
|
|
19
19
|
Path to the JSON configuration file that created this object.
|
|
20
20
|
out_dir_lithology : str or Path
|
|
21
21
|
Directory where lithology outputs will be written.
|
|
22
|
+
lithology_properties_path: str or Path
|
|
23
|
+
Path to the Excel table with lithology properties.
|
|
22
24
|
borehole_lithology_path : str or Path
|
|
23
25
|
Path to the Excel or CSV file containing lithology data.
|
|
24
26
|
borehole_lithology_sheetname : str
|
|
@@ -48,6 +50,7 @@ class LithologyConfig(BaseModel):
|
|
|
48
50
|
config_file_path: str | Path
|
|
49
51
|
out_dir_lithology: str | Path
|
|
50
52
|
input_dir_lithology: str | Path
|
|
53
|
+
lithology_properties_path: str |Path | None = None
|
|
51
54
|
borehole_lithology_path: str | Path
|
|
52
55
|
borehole_lithology_sheetname: str
|
|
53
56
|
out_table: str
|
|
@@ -89,6 +92,23 @@ class LithologyConfig(BaseModel):
|
|
|
89
92
|
if not isinstance(self.out_dir_lithology, Path):
|
|
90
93
|
self.out_dir_lithology = base_dir_lithology / Path(self.out_dir_lithology)
|
|
91
94
|
|
|
95
|
+
# Lithology properties table
|
|
96
|
+
# Resolve user-supplied path
|
|
97
|
+
if self.lithology_properties_path is not None:
|
|
98
|
+
if not isinstance(self.lithology_properties_path, Path):
|
|
99
|
+
self.lithology_properties_path = Path(self.lithology_properties_path)
|
|
100
|
+
|
|
101
|
+
if not self.lithology_properties_path.is_absolute():
|
|
102
|
+
self.lithology_properties_path = (
|
|
103
|
+
base_dir_lithology / self.lithology_properties_path
|
|
104
|
+
).resolve()
|
|
105
|
+
|
|
106
|
+
if not self.lithology_properties_path.exists():
|
|
107
|
+
raise FileNotFoundError(
|
|
108
|
+
f"Lithology properties file not found: "
|
|
109
|
+
f"{self.lithology_properties_path}"
|
|
110
|
+
)
|
|
111
|
+
|
|
92
112
|
return self
|
|
93
113
|
|
|
94
114
|
|
|
@@ -399,7 +419,7 @@ class SingleRunConfig(BaseModel, extra="allow"):
|
|
|
399
419
|
fluid_percent : float or int
|
|
400
420
|
Mixture percentage for the fluid dissolved in water.
|
|
401
421
|
m_flow : float
|
|
402
|
-
Mass flow rate
|
|
422
|
+
Mass flow rate [kg/s].
|
|
403
423
|
epsilon : float
|
|
404
424
|
Pipe roughness [m].
|
|
405
425
|
r_in : list of float, optional
|
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
repo_path = Path(__file__).parent.parent.parent
|
|
4
|
-
|
|
5
|
-
# Test directories
|
|
6
|
-
test_dir = repo_path / "test"
|
|
7
|
-
tests_input_path = test_dir / "input"
|
|
8
|
-
test_output_path = test_dir / "output"
|
|
9
|
-
|
|
10
|
-
# Resources directory
|
|
11
|
-
resources_path = repo_path / "resources"
|
|
12
|
-
|
|
13
|
-
# Lithology resources directory
|
|
14
|
-
lithology_properties_xlsx = (
|
|
15
|
-
resources_path / "lithology_properties" / "lithology_properties.xlsx"
|
|
16
|
-
)
|
|
17
|
-
|
|
18
1
|
# Dictionary of units for various parameters in the model.
|
|
19
2
|
units_dict = {
|
|
20
3
|
"Q_b": "W",
|
|
@@ -110,28 +110,9 @@ class B2G_ana:
|
|
|
110
110
|
for k in range(nsegments):
|
|
111
111
|
la = gt.load_aggregation.ClaessonJaved(sim_params.dt, sim_params.tmax)
|
|
112
112
|
LoadAgg.append(la)
|
|
113
|
-
|
|
113
|
+
|
|
114
114
|
# The field contains only one borehole
|
|
115
|
-
|
|
116
|
-
# The field contains only one borehole, but needs one extra at very large distance to be correct, ie. gfunc plateaus at 6.7)
|
|
117
|
-
boreField = [
|
|
118
|
-
gt.boreholes.Borehole(
|
|
119
|
-
custom_pipe.b.H,
|
|
120
|
-
custom_pipe.b.D,
|
|
121
|
-
custom_pipe.b.r_b,
|
|
122
|
-
x=0.0,
|
|
123
|
-
y=0.0,
|
|
124
|
-
tilt=np.radians(0.1),
|
|
125
|
-
),
|
|
126
|
-
gt.boreholes.Borehole(
|
|
127
|
-
custom_pipe.b.H,
|
|
128
|
-
custom_pipe.b.D,
|
|
129
|
-
custom_pipe.b.r_b,
|
|
130
|
-
x=1000.0,
|
|
131
|
-
y=0.0,
|
|
132
|
-
tilt=np.radians(0.1),
|
|
133
|
-
),
|
|
134
|
-
]
|
|
115
|
+
boreField = [gt.boreholes.Borehole(custom_pipe.b.H, custom_pipe.b.D, custom_pipe.b.r_b, x=0., y=0.)]
|
|
135
116
|
|
|
136
117
|
# Get time values needed for g-function evaluation
|
|
137
118
|
time_req = LoadAgg[0].get_times_for_simulation()
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import math
|
|
2
2
|
from pathlib import Path
|
|
3
|
+
from importlib.resources import files
|
|
3
4
|
|
|
4
5
|
import numpy as np
|
|
5
6
|
import pandas as pd
|
|
6
7
|
import xarray as xr
|
|
7
8
|
|
|
8
9
|
from geoloop.configuration import LithologyConfig
|
|
9
|
-
from geoloop.constants import lithology_properties_xlsx
|
|
10
10
|
from geoloop.geoloopcore.strat_interpolator import TgInterpolator
|
|
11
11
|
|
|
12
|
-
# TODO: save the config paramters (error and scaling factors) in the thermcon h5 file that now only stores the results
|
|
13
|
-
|
|
14
12
|
|
|
15
13
|
class ThermalConductivityCalculator:
|
|
16
14
|
"""
|
|
@@ -259,6 +257,7 @@ class ProcessLithologyToThermalConductivity:
|
|
|
259
257
|
|
|
260
258
|
def __init__(
|
|
261
259
|
self,
|
|
260
|
+
lithology_properties_df: pd.DataFrame,
|
|
262
261
|
borehole_df: pd.DataFrame,
|
|
263
262
|
Tg: float,
|
|
264
263
|
Tgrad: float,
|
|
@@ -272,8 +271,7 @@ class ProcessLithologyToThermalConductivity:
|
|
|
272
271
|
out_table: str,
|
|
273
272
|
read_from_table: bool,
|
|
274
273
|
) -> None:
|
|
275
|
-
|
|
276
|
-
self.lithology_props_df = pd.read_excel(lithology_properties_xlsx)
|
|
274
|
+
self.lithology_props_df = lithology_properties_df
|
|
277
275
|
|
|
278
276
|
self.borehole_df = borehole_df
|
|
279
277
|
self.lithology_props_dict = self.create_lithology_props_dict()
|
|
@@ -387,12 +385,22 @@ class ProcessLithologyToThermalConductivity:
|
|
|
387
385
|
Initialized instance.
|
|
388
386
|
"""
|
|
389
387
|
|
|
390
|
-
|
|
388
|
+
# Read borehole lithology table (Excel)
|
|
391
389
|
borehole_df = pd.read_excel(
|
|
392
|
-
|
|
390
|
+
config.borehole_lithology_path, sheet_name=config.borehole_lithology_sheetname
|
|
393
391
|
)
|
|
392
|
+
# Read lithology properties reference table (Excel)
|
|
393
|
+
if config.lithology_properties_path is not None:
|
|
394
|
+
lithology_properties_df = pd.read_excel(
|
|
395
|
+
config.lithology_properties_path
|
|
396
|
+
)
|
|
397
|
+
else:
|
|
398
|
+
lithology_properties_df = pd.read_excel(
|
|
399
|
+
files("geoloop.lithology.resources").joinpath("lithology_properties.xlsx")
|
|
400
|
+
)
|
|
394
401
|
|
|
395
402
|
return cls(
|
|
403
|
+
lithology_properties_df=lithology_properties_df,
|
|
396
404
|
borehole_df=borehole_df,
|
|
397
405
|
Tg=config.Tg,
|
|
398
406
|
Tgrad=config.Tgrad,
|
|
@@ -199,7 +199,7 @@ class PlotResults:
|
|
|
199
199
|
-------
|
|
200
200
|
None
|
|
201
201
|
"""
|
|
202
|
-
out_path_prefix = out_path.with_name(out_path.name + "
|
|
202
|
+
out_path_prefix = out_path.with_name(out_path.name + "_timeplot")
|
|
203
203
|
|
|
204
204
|
# Ensure results_dfs is a list of dataframes
|
|
205
205
|
if isinstance(results_dfs, pd.DataFrame):
|
|
@@ -237,12 +237,7 @@ class PlotResults:
|
|
|
237
237
|
and "Q_b" in df.columns
|
|
238
238
|
and "qloop" in df.columns
|
|
239
239
|
):
|
|
240
|
-
|
|
241
|
-
mean_q = df["qloop"].mean()
|
|
242
|
-
mean_COP = mean_Q / mean_q
|
|
243
|
-
df["COP"] = mean_COP # abs(df['Q_b'] / df['qloop'])
|
|
244
|
-
# df['COP'] = abs(df['Q_b']) / df['qloop']
|
|
245
|
-
# print(df["COP"].min())
|
|
240
|
+
df['COP'] = abs(df['Q_b']) / df['qloop']
|
|
246
241
|
if (
|
|
247
242
|
"Delta_T" in plot_parameters
|
|
248
243
|
and "T_fi" in df.columns
|
|
@@ -253,7 +248,7 @@ class PlotResults:
|
|
|
253
248
|
plots = [
|
|
254
249
|
("Q_b", "Heat Load [W]", "Q_b", None, None),
|
|
255
250
|
("flowrate", "Flowrate [kg/s]", "flowrate", None, None),
|
|
256
|
-
("COP", "Coefficient of Performance", "COP", None, None)
|
|
251
|
+
("COP", "Coefficient of Performance", "COP", None, None)
|
|
257
252
|
]
|
|
258
253
|
|
|
259
254
|
plotted_params = []
|
|
@@ -281,11 +276,12 @@ class PlotResults:
|
|
|
281
276
|
|
|
282
277
|
ax.legend(loc=(-0.07, -0.35))
|
|
283
278
|
|
|
284
|
-
ax_twin = ax.twinx()
|
|
285
|
-
ax_twin.set_ylabel("Pump Power [W]")
|
|
286
|
-
|
|
287
279
|
for idx, df in enumerate(results_dfs):
|
|
288
280
|
if "qloop" in plot_parameters and "qloop" in df.columns:
|
|
281
|
+
|
|
282
|
+
ax_twin = ax.twinx()
|
|
283
|
+
ax_twin.set_ylabel("Pump Power [W]")
|
|
284
|
+
|
|
289
285
|
color = next(color_iter)
|
|
290
286
|
|
|
291
287
|
# Plot the line
|
|
@@ -319,7 +315,7 @@ class PlotResults:
|
|
|
319
315
|
ax_twin.grid(axis="both")
|
|
320
316
|
|
|
321
317
|
file_name = out_path.with_name(
|
|
322
|
-
out_path.name + f"
|
|
318
|
+
out_path.name + f"_timeplot_{'_'.join(sorted(set(plotted_params)))}.png"
|
|
323
319
|
)
|
|
324
320
|
|
|
325
321
|
fig.tight_layout()
|
|
@@ -440,7 +436,7 @@ class PlotResults:
|
|
|
440
436
|
|
|
441
437
|
file_name = out_path.with_name(
|
|
442
438
|
out_path.name
|
|
443
|
-
+ "
|
|
439
|
+
+ "_timeplot_"
|
|
444
440
|
+ "_".join(sorted(set(plotted_params)))
|
|
445
441
|
+ ".png"
|
|
446
442
|
)
|
|
@@ -473,6 +469,15 @@ class PlotResults:
|
|
|
473
469
|
label=labels[idx][param],
|
|
474
470
|
color=next(color_iter),
|
|
475
471
|
)
|
|
472
|
+
if param=="COP":
|
|
473
|
+
if param == "COP":
|
|
474
|
+
ax.text(
|
|
475
|
+
0.7, 0.9, # 2% from left and bottom of the axes
|
|
476
|
+
f"mean COP: {df['COP'].mean():.2f}",
|
|
477
|
+
transform=ax.transAxes,
|
|
478
|
+
bbox=dict(boxstyle="round,pad=0.3", facecolor="white", alpha=0.7),
|
|
479
|
+
fontsize=12
|
|
480
|
+
)
|
|
476
481
|
|
|
477
482
|
ax.legend(loc=(-0.07, -0.17 - (0.08 * len(results_dfs))))
|
|
478
483
|
ax.grid()
|
|
@@ -984,7 +989,7 @@ class PlotResults:
|
|
|
984
989
|
bbox_to_anchor=(0, -0.1), loc="upper left"
|
|
985
990
|
) # Adjust legend position if needed
|
|
986
991
|
|
|
987
|
-
save_path = outpath.with_name(outpath.name + f"
|
|
992
|
+
save_path = outpath.with_name(outpath.name + f"_sensitivity_{y_variable}")
|
|
988
993
|
plt.savefig(save_path, bbox_inches="tight")
|
|
989
994
|
plt.close()
|
|
990
995
|
else:
|
|
File without changes
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: geoloop
|
|
3
|
-
Version: 1.0.
|
|
4
|
-
Summary: This is a Python package for simulation of (deep) Borehole Heat Exchanger (BHE) systems
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: This is a Python package for simulation of (deep) vertical Borehole Heat Exchanger (BHE) systems
|
|
5
5
|
Author-email: Zanne Korevaar <zanne.korevaar@tno.nl>, Jan-Diederik van Wees <jan_diederik.vanwees@tno.nl>
|
|
6
|
-
License: Apache
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
7
|
Keywords: borehole heat exchanger,BHE,geothermal,ground-source heat pump,deep borehole heat exchanger
|
|
8
8
|
Requires-Python: <3.14,>=3.12
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
@@ -33,20 +33,22 @@ Dynamic: license-file
|
|
|
33
33
|
|
|
34
34
|
## What is **Geoloop**?
|
|
35
35
|
|
|
36
|
-
**Geoloop** is a Python package for simulating borehole heat exchanger (BHE) systems,
|
|
37
|
-
with a focus on
|
|
36
|
+
**Geoloop** is a Python package for simulating vertical borehole heat exchanger (BHE) systems,
|
|
37
|
+
with a focus on the impact of depth-dependent thermal properties and geothermal gradient and their impact on system performance.
|
|
38
38
|
|
|
39
39
|
**Geoloop** incorporates (uncertainty in) depth-variations in subsurface thermal conductivity, subsurface temperature,
|
|
40
40
|
BHE design and diverse operational boundary conditions such as seasonal load variations or
|
|
41
|
-
minimum fluid temperatures
|
|
42
|
-
for optimization of the system design and operation. This makes Geoloop
|
|
41
|
+
minimum fluid temperatures. It allows for deterministic or stochastic performance analyses with the opportunity
|
|
42
|
+
for optimization of the system design and operation. This makes Geoloop well suited for scenario analyses and sensitivity
|
|
43
43
|
studies in both research and practical applications.
|
|
44
44
|
|
|
45
|
-
**Geoloop**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
**Geoloop** provides a novel depth-dependent approach for thermal response calculations.
|
|
46
|
+
A detailed description and benchmark of this depth-dependent semi-analytical method is provided in Korevaar et al. (2026).
|
|
47
|
+
**Geoloop** uses the *pygfunction* package, developed by Cimmino & Cook (2022), including its implementation
|
|
48
|
+
of *g*-functions, time aggregation schemes for varying loads, borehole and fluid thermal properties, and various visualization capabilities
|
|
49
|
+
|
|
50
|
+
**Geoloop's** generic framework allows for easy switching between simulation methods, including the
|
|
51
|
+
depth-dependent model, the depth-uniform implementation of g-functions as implemented in *pygfunction* and a numerical
|
|
50
52
|
finite volume approach.
|
|
51
53
|
|
|
52
54
|
---
|
|
@@ -66,7 +68,7 @@ see the [Installation Guide](https://geoloop-8f7a36.ci.tno.nl/installation/insta
|
|
|
66
68
|
|
|
67
69
|
## Requirements
|
|
68
70
|
|
|
69
|
-
Geoloop requires **Python 3.12
|
|
71
|
+
Geoloop requires **Python version >=3.12,<3.14**.
|
|
70
72
|
|
|
71
73
|
Core dependencies include:
|
|
72
74
|
- pygfunction
|
|
@@ -105,8 +107,14 @@ See the [LICENSE.md](LICENSE.md) file for details.
|
|
|
105
107
|
|
|
106
108
|
## Acknowledgments
|
|
107
109
|
|
|
108
|
-
Developed with the support of the
|
|
110
|
+
Developed with the support of the **Netherlands Enterprise Agency (RVO)**, in a consortium project with grant nr. MOOI322009.
|
|
109
111
|
|
|
110
112
|
---
|
|
111
113
|
|
|
112
114
|
|
|
115
|
+
## References
|
|
116
|
+
|
|
117
|
+
- Cimmino, M. and Cook, J.: pygfunction 2.2: New features and improvements in accuracy and computational efficiency,
|
|
118
|
+
in: Proceedings of the IGSHPA Research Track 2022, International Ground Source Heat Pump Association,
|
|
119
|
+
https://doi.org/10.22488/okstate.22.000015, 2022.
|
|
120
|
+
- Korevaar, Z., Brett, H., Lourens, A. and Van Wees, J.D.: Geoloop (v1.0) – a stochastic, depth-dependent borehole heat exchanger model, Geoscientific Model Development (in prep), 2026
|
|
@@ -38,6 +38,7 @@ src/geoloop/geoloopcore/strat_interpolator.py
|
|
|
38
38
|
src/geoloop/lithology/__init__.py
|
|
39
39
|
src/geoloop/lithology/plot_lithology.py
|
|
40
40
|
src/geoloop/lithology/process_lithology.py
|
|
41
|
+
src/geoloop/lithology/resources/__init__.py
|
|
41
42
|
src/geoloop/loadflowdata/__init__.py
|
|
42
43
|
src/geoloop/loadflowdata/flow_data.py
|
|
43
44
|
src/geoloop/loadflowdata/loadprofile.py
|
|
@@ -4,10 +4,11 @@ from pathlib import Path
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
import xarray as xr
|
|
6
6
|
|
|
7
|
+
from paths import test_dir, tests_input_path
|
|
8
|
+
|
|
7
9
|
from geoloop.configuration import SingleRunConfig, LithologyConfig, load_nested_config
|
|
8
10
|
from geoloop.utils.helpers import save_singlerun_results
|
|
9
11
|
from geoloop.bin.SingleRunSim import SingleRun
|
|
10
|
-
from geoloop.constants import test_dir, tests_input_path
|
|
11
12
|
from geoloop.geoloopcore.b2g import B2G
|
|
12
13
|
from geoloop.lithology.process_lithology import ProcessLithologyToThermalConductivity
|
|
13
14
|
|
|
@@ -4,6 +4,8 @@ from pathlib import Path
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
import xarray as xr
|
|
6
6
|
|
|
7
|
+
from paths import test_dir, tests_input_path
|
|
8
|
+
|
|
7
9
|
from geoloop.configuration import SingleRunConfig, load_nested_config, LithologyConfig, StochasticRunConfig
|
|
8
10
|
from geoloop.utils.helpers import (
|
|
9
11
|
save_MCrun_results,
|
|
@@ -11,7 +13,6 @@ from geoloop.utils.helpers import (
|
|
|
11
13
|
)
|
|
12
14
|
from geoloop.utils.RunManager import run_models
|
|
13
15
|
from geoloop.bin.SingleRunSim import SingleRun
|
|
14
|
-
from geoloop.constants import test_dir, tests_input_path
|
|
15
16
|
from geoloop.geoloopcore.b2g_ana import B2G_ana
|
|
16
17
|
from geoloop.lithology.process_lithology import ProcessLithologyToThermalConductivity
|
|
17
18
|
|
|
@@ -4,10 +4,11 @@ from pathlib import Path
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
import xarray as xr
|
|
6
6
|
|
|
7
|
+
from paths import test_dir, tests_input_path
|
|
8
|
+
|
|
7
9
|
from geoloop.configuration import load_nested_config, SingleRunConfig, LithologyConfig
|
|
8
10
|
from geoloop.utils.helpers import save_singlerun_results
|
|
9
11
|
from geoloop.bin.SingleRunSim import SingleRun
|
|
10
|
-
from geoloop.constants import test_dir, tests_input_path
|
|
11
12
|
from geoloop.lithology.process_lithology import ProcessLithologyToThermalConductivity
|
|
12
13
|
|
|
13
14
|
|
|
@@ -2,7 +2,8 @@ import unittest
|
|
|
2
2
|
|
|
3
3
|
import xarray as xr
|
|
4
4
|
|
|
5
|
-
from
|
|
5
|
+
from paths import tests_input_path, test_output_path
|
|
6
|
+
|
|
6
7
|
from geoloop.configuration import LithologyConfig, load_single_config
|
|
7
8
|
from geoloop.lithology.process_lithology import ProcessLithologyToThermalConductivity
|
|
8
9
|
|
|
@@ -2,9 +2,10 @@ import unittest
|
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
|
|
5
|
+
from paths import tests_input_path, test_output_path
|
|
6
|
+
|
|
5
7
|
from geoloop.configuration import LoadProfileConfig, FlowDataConfig, load_single_config
|
|
6
8
|
from geoloop.utils.helpers import apply_smoothing
|
|
7
|
-
from geoloop.constants import tests_input_path, test_output_path
|
|
8
9
|
from geoloop.loadflowdata.flow_data import FlowData
|
|
9
10
|
from geoloop.loadflowdata.loadprofile import LoadProfile
|
|
10
11
|
|
|
@@ -7,9 +7,10 @@ import matplotlib.pyplot as plt
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
import xarray as xr
|
|
9
9
|
|
|
10
|
+
from paths import test_dir, tests_input_path
|
|
11
|
+
|
|
10
12
|
from geoloop.configuration import PlotInputConfig, load_single_config
|
|
11
13
|
from geoloop.bin.Plotmain import DataSelection, DataTotal, PlotInput
|
|
12
|
-
from geoloop.constants import test_dir, tests_input_path
|
|
13
14
|
from geoloop.plotting.create_plots import PlotResults
|
|
14
15
|
|
|
15
16
|
|
|
@@ -4,10 +4,11 @@ from pathlib import Path
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
import xarray as xr
|
|
6
6
|
|
|
7
|
+
from paths import test_dir, tests_input_path
|
|
8
|
+
|
|
7
9
|
from geoloop.configuration import load_nested_config, SingleRunConfig, LithologyConfig
|
|
8
10
|
from geoloop.utils.helpers import save_singlerun_results
|
|
9
11
|
from geoloop.bin.SingleRunSim import SingleRun
|
|
10
|
-
from geoloop.constants import test_dir, tests_input_path
|
|
11
12
|
from geoloop.geoloopcore.pyg_ana import PYG_ana
|
|
12
13
|
from geoloop.lithology.process_lithology import ProcessLithologyToThermalConductivity
|
|
13
14
|
|
|
@@ -2,9 +2,10 @@ import unittest
|
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
|
|
5
|
+
from paths import tests_input_path
|
|
6
|
+
|
|
5
7
|
from geoloop.configuration import load_nested_config, SingleRunConfig, LithologyConfig
|
|
6
8
|
from geoloop.bin.SingleRunSim import SingleRun
|
|
7
|
-
from geoloop.constants import tests_input_path
|
|
8
9
|
from geoloop.geoloopcore.pygfield_ana import (
|
|
9
10
|
PYGFIELD_ana,
|
|
10
11
|
create_curved_borehole,
|
geoloop-1.0.0b1/README.md
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# Geoloop: A BHE Calculator for Python
|
|
2
|
-
|
|
3
|
-
[](https://pypi.org/project/geoloop/)
|
|
4
|
-
[](https://geoloop-8f7a36.ci.tno.nl/)
|
|
5
|
-
|
|
6
|
-
## What is **Geoloop**?
|
|
7
|
-
|
|
8
|
-
**Geoloop** is a Python package for simulating borehole heat exchanger (BHE) systems,
|
|
9
|
-
with a focus on optimal implementation of subsurface thermal properties and their impact on system performance.
|
|
10
|
-
|
|
11
|
-
**Geoloop** incorporates (uncertainty in) depth-variations in subsurface thermal conductivity, subsurface temperature,
|
|
12
|
-
BHE design and diverse operational boundary conditions such as seasonal load variations or
|
|
13
|
-
minimum fluid temperatures, in a tool for deterministic or stochastic performance analyses with the opportunity
|
|
14
|
-
for optimization of the system design and operation. This makes Geoloop ideal for scenario analyses and sensitivity
|
|
15
|
-
studies in both research and practical applications.
|
|
16
|
-
|
|
17
|
-
**Geoloop** uses thermal response factors (*g*-functions) calculated using the analytical Finite Line Source model from
|
|
18
|
-
the *pygfunction* package. This setup is extended into a stacked approach for depth-dependent thermal response calculations.
|
|
19
|
-
A detailed description and benchmark of this depth-dependent semi-analytical method is provided in Korevaar & Van Wees (in prep.).
|
|
20
|
-
**Geoloop's** generic framework allows for easy switching between simulation methods, including the innovative depth-dependent
|
|
21
|
-
semi-analytical approach, the depth-uniform implementation of g-functions as implemented in *pygfunction* and a numerical
|
|
22
|
-
finite volume approach.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Installation
|
|
27
|
-
|
|
28
|
-
Install from PyPI using:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
pip install geoloop
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
For detailed setup instructions (including uv-based environments and development setup),
|
|
35
|
-
see the [Installation Guide](https://geoloop-8f7a36.ci.tno.nl/installation/install/).
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Requirements
|
|
40
|
-
|
|
41
|
-
Geoloop requires **Python 3.12 or higher**.
|
|
42
|
-
|
|
43
|
-
Core dependencies include:
|
|
44
|
-
- pygfunction
|
|
45
|
-
- matplotlib
|
|
46
|
-
- numpy
|
|
47
|
-
- scipy
|
|
48
|
-
- h5py
|
|
49
|
-
- xarray
|
|
50
|
-
- pandas
|
|
51
|
-
- seaborn
|
|
52
|
-
- tqdm
|
|
53
|
-
- netCDF4
|
|
54
|
-
- SecondaryCoolantProps
|
|
55
|
-
- openpyxl
|
|
56
|
-
- h5netcdf
|
|
57
|
-
- pathlib
|
|
58
|
-
- pydantic
|
|
59
|
-
- typer
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
## Quick Start
|
|
64
|
-
|
|
65
|
-
Explore the [Examples](docs/examples/) folder to get started quickly with Geoloop.
|
|
66
|
-
|
|
67
|
-
Read the full documenation [here](https://geoloop-8f7a36.ci.tno.nl/).
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## License
|
|
72
|
-
|
|
73
|
-
This project is licensed under the Apache 2.0 License.
|
|
74
|
-
See the [LICENSE.md](LICENSE.md) file for details.
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Acknowledgments
|
|
79
|
-
|
|
80
|
-
Developed with the support of the Dutch funding agency **RVO**, in a consortium project with grant nr. MOOI322009.
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{geoloop-1.0.0b1/src/geoloop/utils → geoloop-1.0.2/src/geoloop/lithology/resources}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|