OpenSimula 0.8.8__tar.gz → 0.8.10__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.
- {opensimula-0.8.8/src/opensimula.egg-info → opensimula-0.8.10}/PKG-INFO +9 -3
- {opensimula-0.8.8 → opensimula-0.8.10}/README.md +6 -2
- {opensimula-0.8.8 → opensimula-0.8.10}/pyproject.toml +7 -1
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/Component.py +117 -7
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/Iterative_process.py +43 -8
- opensimula-0.8.10/src/opensimula/Message.py +35 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/Parameter_container.py +46 -7
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/Parameters.py +125 -2
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/Project.py +84 -20
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/Simulation.py +44 -10
- opensimula-0.8.10/src/opensimula/Variable.py +67 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Building_surface.py +37 -6
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/DX_unit.py +90 -4
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/File_met.py +9 -3
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/HVAC_MZW_system.py +29 -4
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/HVAC_SZW_system.py +26 -6
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Opening.py +15 -3
- {opensimula-0.8.8 → opensimula-0.8.10/src/opensimula.egg-info}/PKG-INFO +9 -3
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_Case_600FF.py +3 -3
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_Case_610.py +4 -4
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_HVAC_DX_Equipment.py +21 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_HVAC_DX_system.py +12 -12
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_HVAC_FAN_COIL_water_system.py +10 -10
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_Project.py +66 -0
- opensimula-0.8.8/src/opensimula/Message.py +0 -19
- opensimula-0.8.8/src/opensimula/Variable.py +0 -41
- {opensimula-0.8.8 → opensimula-0.8.10}/LICENSE +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/setup.cfg +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/Child.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/__init__.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Building.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Calculator.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Chiller_heat_pump.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Construction.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Day_schedule.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Fan.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/File_data.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Frame.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Glazing.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/HVAC_DX_system.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/HVAC_perfect_system.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/HVAC_water_system.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Material.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Opening_type.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Pump.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Solar_surface.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Space.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Space_type.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Surface.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Test_component.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Water_coil.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Week_schedule.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/Year_schedule.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/components/__init__.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/editor/__init__.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/editor/schema.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/editor/static/editor.css +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/editor/static/editor.js +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/editor/validation.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/editor/widget.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/visual_3D/Environment_3D.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula/visual_3D/Polygon_3D.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula.egg-info/SOURCES.txt +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula.egg-info/dependency_links.txt +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula.egg-info/requires.txt +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/src/opensimula.egg-info/top_level.txt +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_Calculator.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_Construction.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_File_data.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_File_met.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_HVAC_water_system_process.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_Iterative_process.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_Schedules.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_editor_schema.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_editor_widget.py +0 -0
- {opensimula-0.8.8 → opensimula-0.8.10}/test/test_underground_repeated_simulation.py +0 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opensimula
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.10
|
|
4
4
|
Summary: Component-based time simulation environment in Python
|
|
5
|
+
Author: Luis Pérez-Lombard, Ismael R. Maestre
|
|
5
6
|
Author-email: "Juan F. Coronel" <jfc@us.es>
|
|
7
|
+
Maintainer-email: "Juan F. Coronel" <jfc@us.es>
|
|
6
8
|
Requires-Python: >=3.12
|
|
7
9
|
Description-Content-Type: text/markdown
|
|
8
10
|
License-File: LICENSE
|
|
@@ -179,9 +181,13 @@ the latest version (each version also has its own DOI, listed on
|
|
|
179
181
|
[CITATION.cff](https://github.com/jfCoronel/OpenSimula/blob/main/CITATION.cff) (GitHub's "Cite this repository" button generates APA and BibTeX
|
|
180
182
|
entries from it).
|
|
181
183
|
|
|
182
|
-
##
|
|
184
|
+
## Authors
|
|
183
185
|
|
|
184
|
-
* [Juan F. Coronel](http://jfc.us.es), Universidad de Sevilla
|
|
186
|
+
* [Juan F. Coronel](http://jfc.us.es), Universidad de Sevilla — creator, lead developer and maintainer
|
|
187
|
+
* Luis Pérez-Lombard, Universidad de Sevilla — reviewer and advisor on the HVAC models, tester
|
|
188
|
+
and co-author of the validation test cases
|
|
189
|
+
* Ismael R. Maestre, Universidad de Cádiz — reviewer and advisor on the building envelope
|
|
190
|
+
models, tester and co-author of the validation test cases
|
|
185
191
|
|
|
186
192
|
## License
|
|
187
193
|
|
|
@@ -157,9 +157,13 @@ the latest version (each version also has its own DOI, listed on
|
|
|
157
157
|
[CITATION.cff](https://github.com/jfCoronel/OpenSimula/blob/main/CITATION.cff) (GitHub's "Cite this repository" button generates APA and BibTeX
|
|
158
158
|
entries from it).
|
|
159
159
|
|
|
160
|
-
##
|
|
160
|
+
## Authors
|
|
161
161
|
|
|
162
|
-
* [Juan F. Coronel](http://jfc.us.es), Universidad de Sevilla
|
|
162
|
+
* [Juan F. Coronel](http://jfc.us.es), Universidad de Sevilla — creator, lead developer and maintainer
|
|
163
|
+
* Luis Pérez-Lombard, Universidad de Sevilla — reviewer and advisor on the HVAC models, tester
|
|
164
|
+
and co-author of the validation test cases
|
|
165
|
+
* Ismael R. Maestre, Universidad de Cádiz — reviewer and advisor on the building envelope
|
|
166
|
+
models, tester and co-author of the validation test cases
|
|
163
167
|
|
|
164
168
|
## License
|
|
165
169
|
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "opensimula"
|
|
3
|
-
version = "0.8.
|
|
3
|
+
version = "0.8.10"
|
|
4
4
|
requires-python = ">=3.12"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name="Juan F. Coronel", email="jfc@us.es" },
|
|
7
|
+
{ name="Luis Pérez-Lombard" },
|
|
8
|
+
{ name="Ismael R. Maestre" },
|
|
9
|
+
]
|
|
10
|
+
maintainers = [
|
|
11
|
+
{ name="Juan F. Coronel", email="jfc@us.es" },
|
|
7
12
|
]
|
|
8
13
|
description = "Component-based time simulation environment in Python"
|
|
9
14
|
readme = "README.md"
|
|
@@ -28,6 +33,7 @@ dev = [
|
|
|
28
33
|
"mkdocs>=1.6.1",
|
|
29
34
|
"pytest>=8.4.2",
|
|
30
35
|
"marimo>=0.19.0",
|
|
36
|
+
"mkdocstrings[python]>=1.0.8",
|
|
31
37
|
]
|
|
32
38
|
|
|
33
39
|
[tool.setuptools]
|
|
@@ -5,9 +5,26 @@ from opensimula.Variable import Variable
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class Component(Parameter_container):
|
|
8
|
-
"""Base Class for all the components
|
|
8
|
+
"""Base Class for all the components
|
|
9
|
+
|
|
10
|
+
A component has parameters (inherited from Parameter_container, with `name`,
|
|
11
|
+
`description` and `type`) and variables (time series filled during the simulation).
|
|
12
|
+
Components are created by the project (`Project.new_component()`, `read_dict()`,
|
|
13
|
+
`read_json()`), not directly.
|
|
14
|
+
|
|
15
|
+
New component types inherit from this class: they add their parameters and variables
|
|
16
|
+
in `__init__()`, validate them in `check()` and override the simulation methods
|
|
17
|
+
(`pre_simulation()`, `pre_iteration()`, `iteration()`, `post_iteration()`,
|
|
18
|
+
`post_simulation()`) that the project calls in this order. See the developer guide.
|
|
19
|
+
"""
|
|
9
20
|
|
|
10
21
|
def __init__(self, name, proj):
|
|
22
|
+
"""Create new component
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
name (str): name of the component
|
|
26
|
+
proj (Project): project the component belongs to
|
|
27
|
+
"""
|
|
11
28
|
Parameter_container.__init__(self, proj._sim_)
|
|
12
29
|
self._variables_ = {}
|
|
13
30
|
self.add_parameter(Parameter_string("type", "Component"))
|
|
@@ -16,35 +33,62 @@ class Component(Parameter_container):
|
|
|
16
33
|
self._project_ = proj
|
|
17
34
|
|
|
18
35
|
def project(self):
|
|
36
|
+
"""Project the component belongs to
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Project: parent project
|
|
40
|
+
"""
|
|
19
41
|
return self._project_
|
|
20
42
|
|
|
21
43
|
def add_variable(self, variable):
|
|
22
|
-
"""
|
|
44
|
+
"""Add a new variable to the component
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
variable (Variable): variable to add, replaces any variable with the same key
|
|
48
|
+
"""
|
|
23
49
|
variable.parent = self
|
|
24
50
|
variable._sim_ = self._sim_
|
|
25
51
|
self._variables_[variable.key] = variable
|
|
26
52
|
|
|
27
53
|
def del_variable(self, variable):
|
|
54
|
+
"""Remove a variable from the component
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
variable (Variable): variable to remove
|
|
58
|
+
"""
|
|
28
59
|
self._variables_.pop(variable.key,None)
|
|
29
60
|
|
|
30
61
|
def variable(self, key):
|
|
62
|
+
"""Find and return a variable using its key
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
key (str): key of the variable, e.g. "temperature"
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Variable: the variable (KeyError if it does not exist)
|
|
69
|
+
"""
|
|
31
70
|
return self._variables_[key]
|
|
32
71
|
|
|
33
72
|
def variable_dict(self):
|
|
73
|
+
"""Variables of the component
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
dict: {key: Variable}
|
|
77
|
+
"""
|
|
34
78
|
return self._variables_
|
|
35
79
|
|
|
36
80
|
def variable_dataframe(self, units=False, frequency=None, value="mean", interval=None, pos_neg_columns=[]):
|
|
37
|
-
"""
|
|
81
|
+
"""Variables of the component as a table
|
|
38
82
|
|
|
39
83
|
Args:
|
|
40
|
-
units (bool, optional): Includes unit in the name of the variable. Defaults to
|
|
84
|
+
units (bool, optional): Includes unit in the name of the variable. Defaults to False.
|
|
41
85
|
frequency (None or str, optional): frequency of the values: None, "hourly", "daily", "monthly", "yearly". Defaults to None.
|
|
42
86
|
value (str, optional): "mean", "sum", "sum_pos", "sum_neg", "max" or "min". Defaults to "mean".
|
|
43
87
|
interval (None or list of two dates): List with the start and end dates of the period to be included in the dataframe, if the value is None all values are included.
|
|
44
88
|
pos_neg_columns (list of str, optional): List of variables that will be included in separate columns positive and negative values. Defaults to [].
|
|
45
89
|
|
|
46
90
|
Returns:
|
|
47
|
-
pandas
|
|
91
|
+
pandas.DataFrame: column "date" and one column per variable
|
|
48
92
|
"""
|
|
49
93
|
series = {}
|
|
50
94
|
series["date"] = self.project().dates()
|
|
@@ -92,7 +136,7 @@ class Component(Parameter_container):
|
|
|
92
136
|
been the walk follows it until the stack runs out.
|
|
93
137
|
|
|
94
138
|
Returns:
|
|
95
|
-
|
|
139
|
+
list of Component: referenced components and, last, the component itself
|
|
96
140
|
"""
|
|
97
141
|
if _seen is None:
|
|
98
142
|
_seen = set()
|
|
@@ -125,8 +169,12 @@ class Component(Parameter_container):
|
|
|
125
169
|
def check(self):
|
|
126
170
|
"""Check if all is correct
|
|
127
171
|
|
|
172
|
+
Checks every parameter and creates the variables of the `Parameter_variable` and
|
|
173
|
+
`Parameter_variable_list` parameters. Components that override it call this one
|
|
174
|
+
first and add their own checks.
|
|
175
|
+
|
|
128
176
|
Returns:
|
|
129
|
-
|
|
177
|
+
list of Message: errors found
|
|
130
178
|
"""
|
|
131
179
|
errors = []
|
|
132
180
|
# Parameter errors
|
|
@@ -152,6 +200,16 @@ class Component(Parameter_container):
|
|
|
152
200
|
return errors
|
|
153
201
|
|
|
154
202
|
def get_parameter_variable_dictionary(self,time_index):
|
|
203
|
+
"""Values of the variables taken from `Parameter_variable` parameters at a time step
|
|
204
|
+
|
|
205
|
+
Used to evaluate `Parameter_math_exp` expressions.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
time_index (int): index of the time step
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
dict: {symbol: value}
|
|
212
|
+
"""
|
|
155
213
|
# variables dictonary
|
|
156
214
|
var_dic = {}
|
|
157
215
|
for i in range(len(self._var_from_parameter_symbol)):
|
|
@@ -159,6 +217,15 @@ class Component(Parameter_container):
|
|
|
159
217
|
return var_dic
|
|
160
218
|
|
|
161
219
|
def pre_simulation(self, n_time_steps, delta_t):
|
|
220
|
+
"""Prepare the component before the time loop of the simulation
|
|
221
|
+
|
|
222
|
+
The base method sets up the variables of the `Parameter_variable` parameters and
|
|
223
|
+
initialises every variable to zeros. Overriding methods call it first.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
n_time_steps (int): number of time steps of the simulation
|
|
227
|
+
delta_t (int): time step (s)
|
|
228
|
+
"""
|
|
162
229
|
# Create variables from paramater "Parameter_variable" and "Parameter_variable_list"
|
|
163
230
|
self._var_from_parameter_symbol = []
|
|
164
231
|
self._var_from_parameter_variable = []
|
|
@@ -176,9 +243,20 @@ class Component(Parameter_container):
|
|
|
176
243
|
var.initialise(n_time_steps)
|
|
177
244
|
|
|
178
245
|
def post_simulation(self):
|
|
246
|
+
"""Finish the component after the time loop of the simulation"""
|
|
179
247
|
pass
|
|
180
248
|
|
|
181
249
|
def pre_iteration(self, time_index, date, daylight_saving):
|
|
250
|
+
"""Prepare the time step, before its iterations
|
|
251
|
+
|
|
252
|
+
The base method copies the values of the `Parameter_variable` parameters at the
|
|
253
|
+
time step. Overriding methods call it first.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
time_index (int): index of the time step
|
|
257
|
+
date (datetime): date of the time step (center of the interval)
|
|
258
|
+
daylight_saving (bool): daylight saving time is in effect
|
|
259
|
+
"""
|
|
182
260
|
# Initilise all variables to 0
|
|
183
261
|
for key, value in self.parameter_dict().items():
|
|
184
262
|
# Copy variables in paramater_variable
|
|
@@ -193,9 +271,31 @@ class Component(Parameter_container):
|
|
|
193
271
|
value.symbol[i]).values[time_index] = value.variable[i].values[time_index]
|
|
194
272
|
|
|
195
273
|
def iteration(self, time_index, date, daylight_saving, n_iter):
|
|
274
|
+
"""Calculate one iteration of the time step
|
|
275
|
+
|
|
276
|
+
The project repeats the iterations of every component until all of them return
|
|
277
|
+
True or the maximum number of iterations is reached.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
time_index (int): index of the time step
|
|
281
|
+
date (datetime): date of the time step (center of the interval)
|
|
282
|
+
daylight_saving (bool): daylight saving time is in effect
|
|
283
|
+
n_iter (int): number of the iteration in the time step, from 0
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
bool: the component has converged
|
|
287
|
+
"""
|
|
196
288
|
return True
|
|
197
289
|
|
|
198
290
|
def post_iteration(self, time_index, date, daylight_saving, converged):
|
|
291
|
+
"""Finish the time step, after its iterations
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
time_index (int): index of the time step
|
|
295
|
+
date (datetime): date of the time step (center of the interval)
|
|
296
|
+
daylight_saving (bool): daylight saving time is in effect
|
|
297
|
+
converged (bool): every component converged in the time step
|
|
298
|
+
"""
|
|
199
299
|
pass
|
|
200
300
|
|
|
201
301
|
def _repr_html_(self):
|
|
@@ -208,6 +308,11 @@ class Component(Parameter_container):
|
|
|
208
308
|
return html
|
|
209
309
|
|
|
210
310
|
def variable_html(self):
|
|
311
|
+
"""Key, description and unit of the variables as an HTML table
|
|
312
|
+
|
|
313
|
+
Returns:
|
|
314
|
+
str: HTML table
|
|
315
|
+
"""
|
|
211
316
|
keys = []
|
|
212
317
|
descriptions = []
|
|
213
318
|
units = []
|
|
@@ -222,5 +327,10 @@ class Component(Parameter_container):
|
|
|
222
327
|
return data.to_html()
|
|
223
328
|
|
|
224
329
|
def function_html(self):
|
|
330
|
+
"""Short HTML help of the component's table methods
|
|
331
|
+
|
|
332
|
+
Returns:
|
|
333
|
+
str: HTML text
|
|
334
|
+
"""
|
|
225
335
|
html = "<p><strong>parameter_dataframe():</strong> Return pandas DataFrame with the component parametes.</p>"
|
|
226
336
|
html += "<p><strong>variable_dataframe():</strong> Return pandas DataFrame with the component variables.</p>"
|
|
@@ -1,15 +1,32 @@
|
|
|
1
1
|
import math
|
|
2
2
|
|
|
3
3
|
class Iterative_process:
|
|
4
|
+
"""Iterative process using the fixed-point method with adaptive relaxation coefficient
|
|
5
|
+
|
|
6
|
+
Used by the components to converge a value coupled with other components (e.g. the
|
|
7
|
+
temperature or humidity of a space) within the iterations of a time step:
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
it = Iterative_process(x_0, tol=0.01)
|
|
11
|
+
# in each iteration, with the value proposed by the component's equations
|
|
12
|
+
x = it.estimate_next_x(proposed_x)
|
|
13
|
+
converged = it.converged()
|
|
14
|
+
```
|
|
15
|
+
"""
|
|
16
|
+
|
|
4
17
|
def __init__(self, x_0, tol = 1e-5, lambda_min=0.1, lambda_max=1.0, n_ini_relax=2,rel_vel = 0.9):
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
18
|
+
"""Create new iterative process
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
x_0 (float): Initial value
|
|
22
|
+
tol (float, optional): convergence tolerance of the residual. Defaults to 1e-5.
|
|
23
|
+
lambda_min (float, optional): minimum relaxation coefficient. Defaults to 0.1.
|
|
24
|
+
lambda_max (float, optional): maximum (and initial) relaxation coefficient.
|
|
25
|
+
Defaults to 1.0.
|
|
26
|
+
n_ini_relax (int, optional): Number of iterations in which adaptive relaxation
|
|
27
|
+
is initiated, must be greater than 1. Defaults to 2.
|
|
28
|
+
rel_vel (float, optional): factor that reduces (or, divided, recovers) the
|
|
29
|
+
relaxation coefficient. Defaults to 0.9.
|
|
13
30
|
"""
|
|
14
31
|
self.x = [x_0]
|
|
15
32
|
self.tol = tol
|
|
@@ -21,12 +38,25 @@ class Iterative_process:
|
|
|
21
38
|
self.residual = None # |proposed_x - x| of the last iteration
|
|
22
39
|
|
|
23
40
|
def converged(self):
|
|
41
|
+
"""The residual of the last iteration is below the tolerance
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
bool: converged
|
|
45
|
+
"""
|
|
24
46
|
# Fixed-point residual, not the relaxed step: with relaxation lambda the step is only
|
|
25
47
|
# lambda * residual, so testing the step stopped with residuals up to tol / lambda_min
|
|
26
48
|
# (10 x tol), e.g. zones far from their moisture balance in steady state
|
|
27
49
|
return self.residual is not None and self.residual < self.tol
|
|
28
50
|
|
|
29
51
|
def estimate_next_x(self, proposed_x):
|
|
52
|
+
"""Relaxed next value from the value proposed by the fixed-point equation
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
proposed_x (float): value given by the equations from the last value
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
float: next value, `(1 - lambda) * x + lambda * proposed_x`
|
|
59
|
+
"""
|
|
30
60
|
residual = proposed_x - self.x[-1]
|
|
31
61
|
x_next = (1 - self.lambda_i) * self.x[-1] + self.lambda_i * proposed_x
|
|
32
62
|
|
|
@@ -46,5 +76,10 @@ class Iterative_process:
|
|
|
46
76
|
return x_next
|
|
47
77
|
|
|
48
78
|
def set_next_x(self, next_x):
|
|
79
|
+
"""Set the next value directly, without relaxation
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
next_x (float): next value
|
|
83
|
+
"""
|
|
49
84
|
self.x.append(next_x)
|
|
50
85
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class Message:
|
|
2
|
+
"""Message of the simulation environment (error, warning or information)
|
|
3
|
+
|
|
4
|
+
Messages are added with `Simulation.message()` and listed with
|
|
5
|
+
`Simulation.message_list()`.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
def __init__(self, text, level="ERROR"):
|
|
9
|
+
"""Create new message
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
text (str): text of the message
|
|
13
|
+
level (str, optional): "ERROR", "WARNING", "INFO" or "CONSOLE". Defaults to
|
|
14
|
+
"ERROR".
|
|
15
|
+
"""
|
|
16
|
+
self._text_ = text
|
|
17
|
+
self._level_ = level # ERROR, WARNING, INFO, CONSOLE
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def text(self):
|
|
21
|
+
"""str: text of the message"""
|
|
22
|
+
return self._text_
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def level(self):
|
|
26
|
+
"""str: "ERROR", "WARNING", "INFO" or "CONSOLE" """
|
|
27
|
+
return self._level_
|
|
28
|
+
|
|
29
|
+
def print(self):
|
|
30
|
+
"""Print the message, preceded by its level unless it is "CONSOLE" """
|
|
31
|
+
if self.level == "CONSOLE":
|
|
32
|
+
print(self.text)
|
|
33
|
+
else:
|
|
34
|
+
print(self.level + ": " + self.text)
|
|
35
|
+
|
|
@@ -3,40 +3,71 @@ from opensimula.Parameters import Parameter_string
|
|
|
3
3
|
from opensimula.Message import Message
|
|
4
4
|
|
|
5
5
|
class Parameter_container:
|
|
6
|
-
"""Class to manage a list of
|
|
6
|
+
"""Class to manage a list of Parameters
|
|
7
7
|
|
|
8
8
|
Superclass for Projects and Components
|
|
9
9
|
|
|
10
10
|
Default parameters included:
|
|
11
|
+
|
|
11
12
|
- name (string)
|
|
12
13
|
- description (string)
|
|
13
|
-
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
def __init__(self, sim):
|
|
17
|
+
"""Create the container with the parameters name and description
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
sim (Simulation): simulation environment, used to report messages
|
|
21
|
+
"""
|
|
17
22
|
self._sim_ = sim
|
|
18
23
|
self._parameters_ = {}
|
|
19
24
|
self.add_parameter(Parameter_string("name", "Name"))
|
|
20
25
|
self.add_parameter(Parameter_string("description", "Description"))
|
|
21
26
|
|
|
22
27
|
def add_parameter(self, param):
|
|
23
|
-
"""
|
|
28
|
+
"""Add a parameter
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
param (Parameter): parameter to add, replaces any parameter with the same key
|
|
32
|
+
"""
|
|
24
33
|
param.parent = self
|
|
25
34
|
param._sim_ = self._sim_
|
|
26
35
|
self._parameters_[param.key] = param
|
|
27
36
|
|
|
28
37
|
def del_parameter(self, param):
|
|
29
|
-
"""
|
|
30
|
-
|
|
38
|
+
"""Delete a parameter
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
param (Parameter): parameter to delete
|
|
42
|
+
"""
|
|
43
|
+
self._parameters_.pop(param.key, None)
|
|
31
44
|
|
|
32
45
|
def parameter(self, key):
|
|
46
|
+
"""Find and return a parameter using its key
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
key (str): key of the parameter, e.g. "name"
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Parameter: the parameter (KeyError if it does not exist); read or change its
|
|
53
|
+
value with `.value`
|
|
54
|
+
"""
|
|
33
55
|
return self._parameters_[key]
|
|
34
56
|
|
|
35
57
|
def parameter_dict(self):
|
|
58
|
+
"""Parameters of the container
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
dict: {key: Parameter}
|
|
62
|
+
"""
|
|
36
63
|
return self._parameters_
|
|
37
64
|
|
|
38
65
|
def set_parameters(self, dictonary):
|
|
39
|
-
"""
|
|
66
|
+
"""Set parameter values from a dictionary
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
dictonary (dict): {key: value}; unknown keys are reported as errors
|
|
70
|
+
"""
|
|
40
71
|
for key, value in dictonary.items():
|
|
41
72
|
if key in self._parameters_:
|
|
42
73
|
self.parameter(key).value = value
|
|
@@ -44,6 +75,14 @@ class Parameter_container:
|
|
|
44
75
|
self._sim_.message(Message("Component parameter " + key + " does not exist","ERROR"))
|
|
45
76
|
|
|
46
77
|
def parameter_dataframe(self, string_format=False):
|
|
78
|
+
"""Parameters as a table
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
string_format (bool, optional): Convert every value to string. Defaults to False.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
pandas.DataFrame: key, type, value and unit of each parameter
|
|
85
|
+
"""
|
|
47
86
|
keys = []
|
|
48
87
|
values = []
|
|
49
88
|
types = []
|
|
@@ -69,7 +108,7 @@ class Parameter_container:
|
|
|
69
108
|
"""Check if all is correct
|
|
70
109
|
|
|
71
110
|
Returns:
|
|
72
|
-
|
|
111
|
+
list of Message: errors found
|
|
73
112
|
"""
|
|
74
113
|
errors = []
|
|
75
114
|
for key, value in self._parameters_.items():
|