OpenSimula 0.5.1__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.5.1/LICENSE +21 -0
- opensimula-0.5.1/PKG-INFO +49 -0
- opensimula-0.5.1/README.md +25 -0
- opensimula-0.5.1/pyproject.toml +37 -0
- opensimula-0.5.1/setup.cfg +4 -0
- opensimula-0.5.1/src/opensimula/Child.py +19 -0
- opensimula-0.5.1/src/opensimula/Component.py +214 -0
- opensimula-0.5.1/src/opensimula/Iterative_process.py +47 -0
- opensimula-0.5.1/src/opensimula/Message.py +19 -0
- opensimula-0.5.1/src/opensimula/Parameter_container.py +80 -0
- opensimula-0.5.1/src/opensimula/Parameters.py +755 -0
- opensimula-0.5.1/src/opensimula/Project.py +674 -0
- opensimula-0.5.1/src/opensimula/Simulation.py +212 -0
- opensimula-0.5.1/src/opensimula/Variable.py +37 -0
- opensimula-0.5.1/src/opensimula/__init__.py +8 -0
- opensimula-0.5.1/src/opensimula/components/Building.py +511 -0
- opensimula-0.5.1/src/opensimula/components/Building_surface.py +318 -0
- opensimula-0.5.1/src/opensimula/components/Calculator.py +51 -0
- opensimula-0.5.1/src/opensimula/components/Construction.py +309 -0
- opensimula-0.5.1/src/opensimula/components/Day_schedule.py +64 -0
- opensimula-0.5.1/src/opensimula/components/File_data.py +117 -0
- opensimula-0.5.1/src/opensimula/components/File_met.py +1035 -0
- opensimula-0.5.1/src/opensimula/components/Frame.py +35 -0
- opensimula-0.5.1/src/opensimula/components/Glazing.py +122 -0
- opensimula-0.5.1/src/opensimula/components/HVAC_DX_equipment.py +210 -0
- opensimula-0.5.1/src/opensimula/components/HVAC_DX_system.py +254 -0
- opensimula-0.5.1/src/opensimula/components/HVAC_MZW_system.py +554 -0
- opensimula-0.5.1/src/opensimula/components/HVAC_SZW_system.py +338 -0
- opensimula-0.5.1/src/opensimula/components/HVAC_coil_equipment.py +206 -0
- opensimula-0.5.1/src/opensimula/components/HVAC_fan_equipment.py +44 -0
- opensimula-0.5.1/src/opensimula/components/HVAC_perfect_system.py +137 -0
- opensimula-0.5.1/src/opensimula/components/Material.py +14 -0
- opensimula-0.5.1/src/opensimula/components/Opening.py +409 -0
- opensimula-0.5.1/src/opensimula/components/Opening_type.py +90 -0
- opensimula-0.5.1/src/opensimula/components/Solar_surface.py +114 -0
- opensimula-0.5.1/src/opensimula/components/Space.py +388 -0
- opensimula-0.5.1/src/opensimula/components/Space_type.py +81 -0
- opensimula-0.5.1/src/opensimula/components/Surface.py +129 -0
- opensimula-0.5.1/src/opensimula/components/Test_component.py +76 -0
- opensimula-0.5.1/src/opensimula/components/Week_schedule.py +30 -0
- opensimula-0.5.1/src/opensimula/components/Year_schedule.py +65 -0
- opensimula-0.5.1/src/opensimula/components/__init__.py +40 -0
- opensimula-0.5.1/src/opensimula/visual_3D/Environment_3D.py +257 -0
- opensimula-0.5.1/src/opensimula/visual_3D/Polygon_3D.py +262 -0
- opensimula-0.5.1/src/opensimula.egg-info/PKG-INFO +49 -0
- opensimula-0.5.1/src/opensimula.egg-info/SOURCES.txt +58 -0
- opensimula-0.5.1/src/opensimula.egg-info/dependency_links.txt +1 -0
- opensimula-0.5.1/src/opensimula.egg-info/requires.txt +14 -0
- opensimula-0.5.1/src/opensimula.egg-info/top_level.txt +1 -0
- opensimula-0.5.1/test/test_Calculator.py +40 -0
- opensimula-0.5.1/test/test_Case_600FF.py +323 -0
- opensimula-0.5.1/test/test_Case_610.py +354 -0
- opensimula-0.5.1/test/test_Construction.py +129 -0
- opensimula-0.5.1/test/test_File_data.py +71 -0
- opensimula-0.5.1/test/test_File_met.py +99 -0
- opensimula-0.5.1/test/test_HVAC_DX_Equipment.py +49 -0
- opensimula-0.5.1/test/test_HVAC_DX_system.py +408 -0
- opensimula-0.5.1/test/test_Iterative_process.py +13 -0
- opensimula-0.5.1/test/test_Project.py +122 -0
- opensimula-0.5.1/test/test_Schedules.py +81 -0
opensimula-0.5.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Juan F. Coronel
|
|
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,49 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: opensimula
|
|
3
|
+
Version: 0.5.1
|
|
4
|
+
Summary: Component-based time simulation environment in Python
|
|
5
|
+
Author-email: "Juan F. Coronel" <jfc@us.es>
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: dash>=3.2.0
|
|
10
|
+
Requires-Dist: dash-ag-grid>=32.3.2
|
|
11
|
+
Requires-Dist: dash-bootstrap-components>=2.0.4
|
|
12
|
+
Requires-Dist: nbformat>=5.10.4
|
|
13
|
+
Requires-Dist: numpy>=2.3.3
|
|
14
|
+
Requires-Dist: openpyxl>=3.1.5
|
|
15
|
+
Requires-Dist: pandas>=2.3.2
|
|
16
|
+
Requires-Dist: plotly>=6.3.0
|
|
17
|
+
Requires-Dist: psychrolib>=2.5.0
|
|
18
|
+
Requires-Dist: scipy>=1.16.2
|
|
19
|
+
Requires-Dist: shapely>=2.1.1
|
|
20
|
+
Requires-Dist: tqdm>=4.67.1
|
|
21
|
+
Requires-Dist: triangle>=20250106
|
|
22
|
+
Requires-Dist: vedo>=2025.5.4
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+
Component-based time simulation environment in Python
|
|
27
|
+
|
|
28
|
+
[Documentation page](https://jfcoronel.github.io/opensimula/)
|
|
29
|
+
|
|
30
|
+
## Main Developers
|
|
31
|
+
|
|
32
|
+
* [Juan F. Coronel](http://jfc.us.es), Universidad de Sevilla
|
|
33
|
+
|
|
34
|
+
## Package dependencies
|
|
35
|
+
- numpy
|
|
36
|
+
- pandas
|
|
37
|
+
- scipy
|
|
38
|
+
- shapely
|
|
39
|
+
- psychrolib
|
|
40
|
+
- plotly
|
|
41
|
+
- dash
|
|
42
|
+
- dash_bootstrap_components
|
|
43
|
+
- dash_ag_grid
|
|
44
|
+
- pyvista
|
|
45
|
+
- trame
|
|
46
|
+
- trame-vtk
|
|
47
|
+
- trame-vuetify
|
|
48
|
+
- ipywidgets
|
|
49
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+

|
|
2
|
+
Component-based time simulation environment in Python
|
|
3
|
+
|
|
4
|
+
[Documentation page](https://jfcoronel.github.io/opensimula/)
|
|
5
|
+
|
|
6
|
+
## Main Developers
|
|
7
|
+
|
|
8
|
+
* [Juan F. Coronel](http://jfc.us.es), Universidad de Sevilla
|
|
9
|
+
|
|
10
|
+
## Package dependencies
|
|
11
|
+
- numpy
|
|
12
|
+
- pandas
|
|
13
|
+
- scipy
|
|
14
|
+
- shapely
|
|
15
|
+
- psychrolib
|
|
16
|
+
- plotly
|
|
17
|
+
- dash
|
|
18
|
+
- dash_bootstrap_components
|
|
19
|
+
- dash_ag_grid
|
|
20
|
+
- pyvista
|
|
21
|
+
- trame
|
|
22
|
+
- trame-vtk
|
|
23
|
+
- trame-vuetify
|
|
24
|
+
- ipywidgets
|
|
25
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "opensimula"
|
|
3
|
+
version = "0.5.1"
|
|
4
|
+
requires-python = ">=3.12"
|
|
5
|
+
authors = [
|
|
6
|
+
{ name="Juan F. Coronel", email="jfc@us.es" },
|
|
7
|
+
]
|
|
8
|
+
description = "Component-based time simulation environment in Python"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"dash>=3.2.0",
|
|
12
|
+
"dash-ag-grid>=32.3.2",
|
|
13
|
+
"dash-bootstrap-components>=2.0.4",
|
|
14
|
+
"nbformat>=5.10.4",
|
|
15
|
+
"numpy>=2.3.3",
|
|
16
|
+
"openpyxl>=3.1.5",
|
|
17
|
+
"pandas>=2.3.2",
|
|
18
|
+
"plotly>=6.3.0",
|
|
19
|
+
"psychrolib>=2.5.0",
|
|
20
|
+
"scipy>=1.16.2",
|
|
21
|
+
"shapely>=2.1.1",
|
|
22
|
+
"tqdm>=4.67.1",
|
|
23
|
+
"triangle>=20250106",
|
|
24
|
+
"vedo>=2025.5.4",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[dependency-groups]
|
|
28
|
+
dev = [
|
|
29
|
+
"ipykernel>=6.30.1",
|
|
30
|
+
"mkdocs>=1.6.1",
|
|
31
|
+
"pytest>=8.4.2",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[build-system]
|
|
35
|
+
requires = ["setuptools>=61.2", "wheel"]
|
|
36
|
+
|
|
37
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# ____________ Child ________________________
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Child():
|
|
5
|
+
"""Objects with parent
|
|
6
|
+
|
|
7
|
+
Superclass for Paramaters an Variables
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
def __init__(self, parent=None):
|
|
11
|
+
self._parent_ = parent
|
|
12
|
+
|
|
13
|
+
@property
|
|
14
|
+
def parent(self):
|
|
15
|
+
return self._parent_
|
|
16
|
+
|
|
17
|
+
@parent.setter
|
|
18
|
+
def parent(self, parent):
|
|
19
|
+
self._parent_ = parent
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from opensimula.Parameter_container import Parameter_container
|
|
3
|
+
from opensimula.Parameters import Parameter_string
|
|
4
|
+
from opensimula.Variable import Variable
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Component(Parameter_container):
|
|
8
|
+
"""Base Class for all the components"""
|
|
9
|
+
|
|
10
|
+
def __init__(self, name, proj):
|
|
11
|
+
Parameter_container.__init__(self, proj._sim_)
|
|
12
|
+
self._variables_ = {}
|
|
13
|
+
self.add_parameter(Parameter_string("type", "Component"))
|
|
14
|
+
self.parameter("name").value = name
|
|
15
|
+
self.parameter("description").value = "Description of the component"
|
|
16
|
+
self._project_ = proj
|
|
17
|
+
|
|
18
|
+
def project(self):
|
|
19
|
+
return self._project_
|
|
20
|
+
|
|
21
|
+
def add_variable(self, variable):
|
|
22
|
+
"""add new Variable"""
|
|
23
|
+
variable.parent = self
|
|
24
|
+
variable._sim_ = self._sim_
|
|
25
|
+
self._variables_[variable.key] = variable
|
|
26
|
+
|
|
27
|
+
def del_variable(self, variable):
|
|
28
|
+
self._variables_.pop(variable.key,None)
|
|
29
|
+
|
|
30
|
+
def variable(self, key):
|
|
31
|
+
return self._variables_[key]
|
|
32
|
+
|
|
33
|
+
def variable_dict(self):
|
|
34
|
+
return self._variables_
|
|
35
|
+
|
|
36
|
+
def variable_dataframe(self, units=False, frequency=None, value="mean", interval=None, pos_neg_columns=[]):
|
|
37
|
+
"""_summary_
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
units (bool, optional): Includes unit in the name of the variable. Defaults to True.
|
|
41
|
+
frequency (None or str, optional): frequency of the values: None, "H" Hour, "D" Day, "M" Month, "Y" Year . Defaults to None.
|
|
42
|
+
value (str, optional): "mean", "sum", "sum_pos", "sum_neg", "max" or "min". Defaults to "mean".
|
|
43
|
+
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
|
+
pos_neg_columns (list of str, optional): List of variables that will be included in separate columns positive and negative values. Defaults to [].
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
pandas DataFrame: Returns all the variables
|
|
48
|
+
"""
|
|
49
|
+
series = {}
|
|
50
|
+
series["date"] = self.project().dates()
|
|
51
|
+
for key, var in self._variables_.items():
|
|
52
|
+
if var.unit == "":
|
|
53
|
+
series[key] = var.values
|
|
54
|
+
else:
|
|
55
|
+
if units:
|
|
56
|
+
series[key + " [" + var.unit + "]"] = var.values
|
|
57
|
+
else:
|
|
58
|
+
series[key] = var.values
|
|
59
|
+
data = pd.DataFrame(series)
|
|
60
|
+
if pos_neg_columns != []:
|
|
61
|
+
for col in pos_neg_columns:
|
|
62
|
+
data[col + "_pos"] = data[col].apply(lambda x: x if x > 0 else 0)
|
|
63
|
+
data[col + "_neg"] = data[col].apply(lambda x: x if x < 0 else 0)
|
|
64
|
+
if frequency is not None:
|
|
65
|
+
if value == "mean":
|
|
66
|
+
data = data.resample(frequency, on='date').mean()
|
|
67
|
+
elif value == "sum":
|
|
68
|
+
data = data.resample(frequency, on='date').sum()
|
|
69
|
+
elif value == "max":
|
|
70
|
+
data = data.resample(frequency, on='date').max()
|
|
71
|
+
elif value == "min":
|
|
72
|
+
data = data.resample(frequency, on='date').min()
|
|
73
|
+
if interval is not None:
|
|
74
|
+
data = data[(data['date'] > interval[0]) &
|
|
75
|
+
(data['date'] < interval[1])]
|
|
76
|
+
return data
|
|
77
|
+
|
|
78
|
+
# ____________ Functions that must be overwriten for time simulation _________________
|
|
79
|
+
|
|
80
|
+
def get_all_referenced_components(self):
|
|
81
|
+
"""Get list of all referenced components, first itself. Look recursively at the referenced components
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
component_list (component[])
|
|
85
|
+
"""
|
|
86
|
+
comp_list = []
|
|
87
|
+
for key, value in self.parameter_dict().items():
|
|
88
|
+
if value.type == "Parameter_component":
|
|
89
|
+
if value.component is not None:
|
|
90
|
+
sublist = value.component.get_all_referenced_components()
|
|
91
|
+
for subcomp in sublist:
|
|
92
|
+
comp_list.append(subcomp)
|
|
93
|
+
elif value.type == "Parameter_component_list":
|
|
94
|
+
for comp in value.component:
|
|
95
|
+
if comp is not None:
|
|
96
|
+
sublist = comp.get_all_referenced_components()
|
|
97
|
+
for subcomp in sublist:
|
|
98
|
+
comp_list.append(subcomp)
|
|
99
|
+
if value.type == "Parameter_variable":
|
|
100
|
+
if value.variable is not None:
|
|
101
|
+
sublist = value.variable.parent.get_all_referenced_components()
|
|
102
|
+
for subcomp in sublist:
|
|
103
|
+
comp_list.append(subcomp)
|
|
104
|
+
elif value.type == "Parameter_variable_list":
|
|
105
|
+
for var in value.variable:
|
|
106
|
+
if var is not None:
|
|
107
|
+
sublist = var.parent.get_all_referenced_components()
|
|
108
|
+
for subcomp in sublist:
|
|
109
|
+
comp_list.append(subcomp)
|
|
110
|
+
comp_list.append(self)
|
|
111
|
+
return comp_list
|
|
112
|
+
|
|
113
|
+
def check(self):
|
|
114
|
+
"""Check if all is correct
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
errors (string list): List of errors
|
|
118
|
+
"""
|
|
119
|
+
errors = []
|
|
120
|
+
# Parameter errors
|
|
121
|
+
for key, value in self.parameter_dict().items():
|
|
122
|
+
param_error = value.check()
|
|
123
|
+
for e in param_error:
|
|
124
|
+
errors.append(e)
|
|
125
|
+
# Create variables in paramater_variable
|
|
126
|
+
if value.type == "Parameter_variable":
|
|
127
|
+
if value.variable is not None:
|
|
128
|
+
if (value.symbol in self._variables_): # Delete
|
|
129
|
+
self.del_variable(self.variable(value.symbol))
|
|
130
|
+
self.add_variable(
|
|
131
|
+
Variable(value.symbol, value.variable.unit))
|
|
132
|
+
if value.type == "Parameter_variable_list":
|
|
133
|
+
for i in range(len(value.variable)):
|
|
134
|
+
if value.variable[i] is not None:
|
|
135
|
+
if (value.symbol[i] in self._variables_): # Delete
|
|
136
|
+
self.del_variable(self.variable(value.symbol[i]))
|
|
137
|
+
self.add_variable(
|
|
138
|
+
Variable(value.symbol[i], value.variable[i].unit))
|
|
139
|
+
|
|
140
|
+
return errors
|
|
141
|
+
|
|
142
|
+
def get_parameter_variable_dictionary(self,time_index):
|
|
143
|
+
# variables dictonary
|
|
144
|
+
var_dic = {}
|
|
145
|
+
for i in range(len(self._var_from_parameter_symbol)):
|
|
146
|
+
var_dic[self._var_from_parameter_symbol[i]] = self._var_from_parameter_variable[i].values[time_index]
|
|
147
|
+
return var_dic
|
|
148
|
+
|
|
149
|
+
def pre_simulation(self, n_time_steps, delta_t):
|
|
150
|
+
# Create variables from paramater "Parameter_variable" and "Parameter_variable_list"
|
|
151
|
+
self._var_from_parameter_symbol = []
|
|
152
|
+
self._var_from_parameter_variable = []
|
|
153
|
+
for param in self.parameter_dict().values():
|
|
154
|
+
if param.type == "Parameter_variable":
|
|
155
|
+
self._var_from_parameter_symbol.append(param.symbol)
|
|
156
|
+
self._var_from_parameter_variable.append(param.variable)
|
|
157
|
+
elif param.type == "Parameter_variable_list":
|
|
158
|
+
for i in range(len(param.variable)):
|
|
159
|
+
self._var_from_parameter_symbol.append(param.symbol[i])
|
|
160
|
+
self._var_from_parameter_variable.append(param.variable[i])
|
|
161
|
+
|
|
162
|
+
# Initilise all variables to 0
|
|
163
|
+
for key, var in self._variables_.items():
|
|
164
|
+
var.initialise(n_time_steps)
|
|
165
|
+
|
|
166
|
+
def post_simulation(self):
|
|
167
|
+
pass
|
|
168
|
+
|
|
169
|
+
def pre_iteration(self, time_index, date, daylight_saving):
|
|
170
|
+
# Initilise all variables to 0
|
|
171
|
+
for key, value in self.parameter_dict().items():
|
|
172
|
+
# Copy variables in paramater_variable
|
|
173
|
+
if value.type == "Parameter_variable":
|
|
174
|
+
if value.variable is not None:
|
|
175
|
+
self.variable(
|
|
176
|
+
value.symbol).values[time_index] = value.variable.values[time_index]
|
|
177
|
+
if value.type == "Parameter_variable_list":
|
|
178
|
+
for i in range(len(value.variable)):
|
|
179
|
+
if value.variable[i] is not None:
|
|
180
|
+
self.variable(
|
|
181
|
+
value.symbol[i]).values[time_index] = value.variable[i].values[time_index]
|
|
182
|
+
|
|
183
|
+
def iteration(self, time_index, date, daylight_saving, n_iter):
|
|
184
|
+
return True
|
|
185
|
+
|
|
186
|
+
def post_iteration(self, time_index, date, daylight_saving, converged):
|
|
187
|
+
pass
|
|
188
|
+
|
|
189
|
+
def _repr_html_(self):
|
|
190
|
+
html = f"<h3>Component: {self.parameter('name').value}</h3><p><strong>Desciption: </strong>{self.parameter('description').value}</p>"
|
|
191
|
+
html += "<strong>Parameters:</strong>"
|
|
192
|
+
html += self.parameter_dataframe().to_html()
|
|
193
|
+
if (len(self._variables_) > 0):
|
|
194
|
+
html += "<br/><strong>Variables:</strong>"
|
|
195
|
+
html += self.variable_html()
|
|
196
|
+
return html
|
|
197
|
+
|
|
198
|
+
def variable_html(self):
|
|
199
|
+
keys = []
|
|
200
|
+
descriptions = []
|
|
201
|
+
units = []
|
|
202
|
+
for key, var in self._variables_.items():
|
|
203
|
+
keys.append(key)
|
|
204
|
+
descriptions.append(var.description)
|
|
205
|
+
units.append(var.unit)
|
|
206
|
+
|
|
207
|
+
data = pd.DataFrame(
|
|
208
|
+
{"key": keys, "description": descriptions, "unit": units}
|
|
209
|
+
)
|
|
210
|
+
return data.to_html()
|
|
211
|
+
|
|
212
|
+
def function_html(self):
|
|
213
|
+
html = "<p><strong>parameter_dataframe():</strong> Return pandas DataFrame with the component parametes.</p>"
|
|
214
|
+
html += "<p><strong>variable_dataframe():</strong> Return pandas DataFrame with the component variables.</p>"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
class Iterative_process:
|
|
4
|
+
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
|
+
Iterative process using the fixed-point method with adaptive relaxation coefficient
|
|
7
|
+
|
|
8
|
+
Parameters:
|
|
9
|
+
x_0: Initial value
|
|
10
|
+
tol: convergence tolerance
|
|
11
|
+
lambda_min, lambda_max: relaxation coefficient range
|
|
12
|
+
n_ini_relax: Number of iterations in which adaptive relaxation is initiated, must be greater than 1
|
|
13
|
+
"""
|
|
14
|
+
self.x = [x_0]
|
|
15
|
+
self.tol = tol
|
|
16
|
+
self.lambda_min = lambda_min
|
|
17
|
+
self.lambda_max = lambda_max
|
|
18
|
+
self.lambda_i = lambda_max
|
|
19
|
+
self.n_ini_relax = n_ini_relax
|
|
20
|
+
self.rel_vel = rel_vel
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def converged(self):
|
|
24
|
+
if len(self.x) == 1:
|
|
25
|
+
return False
|
|
26
|
+
else:
|
|
27
|
+
if abs(self.x[-1]-self.x[-2]) < self.tol:
|
|
28
|
+
return True
|
|
29
|
+
else:
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
def estimate_next_x(self, proposed_x):
|
|
33
|
+
x_next = (1 - self.lambda_i) * self.x[-1] + self.lambda_i * proposed_x
|
|
34
|
+
|
|
35
|
+
# Ajuste dinámico de lambda (reduce si hay oscilaciones)
|
|
36
|
+
if len(self.x)>self.n_ini_relax:
|
|
37
|
+
#if abs(x_next - self.x[-1]) > abs(self.x[-1]- self.x[-2]):
|
|
38
|
+
self.lambda_i = max(self.lambda_min, self.lambda_i * self.rel_vel) # Reducimos lambda
|
|
39
|
+
#else:
|
|
40
|
+
#self.lambda_i = min(self.lambda_max, self.lambda_i * 1/self.rel_vel) # Aumentamos lambda
|
|
41
|
+
|
|
42
|
+
self.x.append(x_next)
|
|
43
|
+
return x_next
|
|
44
|
+
|
|
45
|
+
def set_next_x(self, next_x):
|
|
46
|
+
self.x.append(next_x)
|
|
47
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class Message:
|
|
2
|
+
def __init__(self, text, level="ERROR"):
|
|
3
|
+
self._text_ = text
|
|
4
|
+
self._level_ = level # ERROR, WARNING, INFO, CONSOLE
|
|
5
|
+
|
|
6
|
+
@property
|
|
7
|
+
def text(self):
|
|
8
|
+
return self._text_
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def level(self):
|
|
12
|
+
return self._level_
|
|
13
|
+
|
|
14
|
+
def print(self):
|
|
15
|
+
if self.level == "CONSOLE":
|
|
16
|
+
print(self.text)
|
|
17
|
+
else:
|
|
18
|
+
print(self.level + ": " + self.text)
|
|
19
|
+
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from opensimula.Parameters import Parameter_string
|
|
3
|
+
from opensimula.Message import Message
|
|
4
|
+
|
|
5
|
+
class Parameter_container:
|
|
6
|
+
"""Class to manage a list of Paramaters
|
|
7
|
+
|
|
8
|
+
Superclass for Projects and Components
|
|
9
|
+
|
|
10
|
+
Default parameters included:
|
|
11
|
+
- name (string)
|
|
12
|
+
- description (string)
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, sim):
|
|
17
|
+
self._sim_ = sim
|
|
18
|
+
self._parameters_ = {}
|
|
19
|
+
self.add_parameter(Parameter_string("name", "Name"))
|
|
20
|
+
self.add_parameter(Parameter_string("description", "Description"))
|
|
21
|
+
|
|
22
|
+
def add_parameter(self, param):
|
|
23
|
+
"""add Parameter"""
|
|
24
|
+
param.parent = self
|
|
25
|
+
param._sim_ = self._sim_
|
|
26
|
+
self._parameters_[param.key] = param
|
|
27
|
+
|
|
28
|
+
def del_parameter(self, param):
|
|
29
|
+
"""Deletet parameter"""
|
|
30
|
+
self._parameters_.remove(param)
|
|
31
|
+
|
|
32
|
+
def parameter(self, key):
|
|
33
|
+
return self._parameters_[key]
|
|
34
|
+
|
|
35
|
+
def parameter_dict(self):
|
|
36
|
+
return self._parameters_
|
|
37
|
+
|
|
38
|
+
def set_parameters(self, dictonary):
|
|
39
|
+
"""Read parameters from dictonary"""
|
|
40
|
+
for key, value in dictonary.items():
|
|
41
|
+
if key in self._parameters_:
|
|
42
|
+
self.parameter(key).value = value
|
|
43
|
+
else:
|
|
44
|
+
self._sim_.message(Message("Component parameter " + key + " does not exist","ERROR"))
|
|
45
|
+
|
|
46
|
+
def parameter_dataframe(self, string_format=False):
|
|
47
|
+
keys = []
|
|
48
|
+
values = []
|
|
49
|
+
types = []
|
|
50
|
+
units = []
|
|
51
|
+
for key, par in self._parameters_.items():
|
|
52
|
+
keys.append(key)
|
|
53
|
+
if string_format:
|
|
54
|
+
values.append(str(par.value))
|
|
55
|
+
else:
|
|
56
|
+
values.append(par.value)
|
|
57
|
+
types.append(par.type)
|
|
58
|
+
if hasattr(par, "unit"):
|
|
59
|
+
units.append(par.unit)
|
|
60
|
+
else:
|
|
61
|
+
units.append("")
|
|
62
|
+
|
|
63
|
+
data = pd.DataFrame(
|
|
64
|
+
{"key": keys, "type": types, "value": values, "unit": units}
|
|
65
|
+
)
|
|
66
|
+
return data
|
|
67
|
+
|
|
68
|
+
def check_parameters(self):
|
|
69
|
+
"""Check if all is correct
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
errors (string list): List of errors
|
|
73
|
+
"""
|
|
74
|
+
errors = []
|
|
75
|
+
for key, value in self._parameters_.items():
|
|
76
|
+
param_error = value.check()
|
|
77
|
+
if len(param_error) > 1:
|
|
78
|
+
for e in param_error:
|
|
79
|
+
errors.append(e)
|
|
80
|
+
return errors
|