engforge 0.3.0__py3-none-any.whl
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.
- engforge/__init__.py +26 -0
- engforge/_testing_components.py +864 -0
- engforge/analysis.py +257 -0
- engforge/attr_dynamics.py +222 -0
- engforge/attr_plotting.py +811 -0
- engforge/attr_signals.py +116 -0
- engforge/attr_slots.py +211 -0
- engforge/attr_solver.py +443 -0
- engforge/attributes.py +326 -0
- engforge/common.py +76 -0
- engforge/component_collections.py +276 -0
- engforge/components.py +55 -0
- engforge/configuration.py +673 -0
- engforge/dataframe.py +185 -0
- engforge/datastores/__init__.py +116 -0
- engforge/datastores/data.py +519 -0
- engforge/datastores/gdocs.py +2650 -0
- engforge/datastores/reporting.py +935 -0
- engforge/datastores/secrets.py +549 -0
- engforge/dynamics.py +662 -0
- engforge/eng/__init__.py +0 -0
- engforge/eng/costs.py +1459 -0
- engforge/eng/fluid_material.py +279 -0
- engforge/eng/geometry.py +1060 -0
- engforge/eng/pipes.py +1211 -0
- engforge/eng/prediction.py +366 -0
- engforge/eng/solid_materials.py +445 -0
- engforge/eng/structure.py +2228 -0
- engforge/eng/structure_beams.py +821 -0
- engforge/eng/thermodynamics.py +271 -0
- engforge/engforge_attributes.py +380 -0
- engforge/env_var.py +214 -0
- engforge/locations.py +18 -0
- engforge/logging.py +290 -0
- engforge/patterns.py +449 -0
- engforge/problem_context.py +2251 -0
- engforge/properties.py +501 -0
- engforge/reporting.py +595 -0
- engforge/solveable.py +964 -0
- engforge/solver.py +316 -0
- engforge/solver_utils.py +726 -0
- engforge/system.py +143 -0
- engforge/system_reference.py +299 -0
- engforge/tabulation.py +288 -0
- engforge/test/__init__.py +2 -0
- engforge/test/_pre_test_structures.py +221 -0
- engforge/test/report_testing.py +158 -0
- engforge/test/test_airfilter.py +91 -0
- engforge/test/test_analysis.py +3 -0
- engforge/test/test_comp_iter.py +196 -0
- engforge/test/test_composition.py +139 -0
- engforge/test/test_costs.py +338 -0
- engforge/test/test_dynamics.py +109 -0
- engforge/test/test_dynamics_spaces.py +39 -0
- engforge/test/test_four_bar.py +97 -0
- engforge/test/test_modules.py +72 -0
- engforge/test/test_performance.py +93 -0
- engforge/test/test_pipes.py +49 -0
- engforge/test/test_problem.py +411 -0
- engforge/test/test_problem_deepscoping.py +68 -0
- engforge/test/test_slider_crank.py +51 -0
- engforge/test/test_solver.py +343 -0
- engforge/test/test_tabulation.py +233 -0
- engforge/typing.py +92 -0
- engforge-0.3.0.dist-info/METADATA +392 -0
- engforge-0.3.0.dist-info/RECORD +69 -0
- engforge-0.3.0.dist-info/WHEEL +5 -0
- engforge-0.3.0.dist-info/licenses/LICENSE +7 -0
- engforge-0.3.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
from engforge.configuration import Configuration, forge
|
|
2
|
+
from engforge.components import Component, system_property, forge
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
import matplotlib
|
|
6
|
+
import random
|
|
7
|
+
import attr, attrs
|
|
8
|
+
import numpy
|
|
9
|
+
import inspect
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
import CoolProp
|
|
13
|
+
from CoolProp.CoolProp import PropsSI
|
|
14
|
+
import fluids
|
|
15
|
+
import abc
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# TODO: add a exact fluid state (T,P) / (Q,P) in the concept of processes for each thermodynamic operation (isothermal,isobaric,heating...ect)
|
|
19
|
+
|
|
20
|
+
STD_PRESSURE = 1e5 # pa
|
|
21
|
+
STD_TEMP = 273 + 15
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@forge
|
|
25
|
+
class FluidMaterial(Component):
|
|
26
|
+
"""Placeholder for pressure dependent material, defaults to ideal water"""
|
|
27
|
+
|
|
28
|
+
P = attrs.field(default=STD_PRESSURE, type=float)
|
|
29
|
+
T = attrs.field(default=STD_TEMP, type=float)
|
|
30
|
+
|
|
31
|
+
@abc.abstractproperty
|
|
32
|
+
def density(self):
|
|
33
|
+
"""default functionality, assumed gas with eq-state= gas constant"""
|
|
34
|
+
return 1000.0
|
|
35
|
+
|
|
36
|
+
@abc.abstractproperty
|
|
37
|
+
def viscosity(self):
|
|
38
|
+
"""ideal fluid has no viscosity"""
|
|
39
|
+
return 1e-10
|
|
40
|
+
|
|
41
|
+
@abc.abstractproperty
|
|
42
|
+
def surface_tension(self):
|
|
43
|
+
return 1e-10
|
|
44
|
+
|
|
45
|
+
# TODO: enthalpy
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@forge
|
|
49
|
+
class IdealGas(FluidMaterial):
|
|
50
|
+
"""Material Defaults To Gas Properties, so eq_of_state is just Rgas, no viscosity, defaults to air"""
|
|
51
|
+
|
|
52
|
+
gas_constant = attrs.field(default=287.0, type=float)
|
|
53
|
+
|
|
54
|
+
@system_property
|
|
55
|
+
def density(self) -> float:
|
|
56
|
+
"""default functionality, assumed gas with eq-state= gas constant"""
|
|
57
|
+
return self.P / (self.gas_constant * self.T)
|
|
58
|
+
|
|
59
|
+
@system_property
|
|
60
|
+
def viscosity(self) -> float:
|
|
61
|
+
"""ideal fluid has no viscosity"""
|
|
62
|
+
return 1e-10
|
|
63
|
+
|
|
64
|
+
# @system_property
|
|
65
|
+
# def surface_tension(self):
|
|
66
|
+
# return 0.0
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
IdealAir = type("IdealAir", (IdealGas,), {"gas_constant": 287.0})
|
|
70
|
+
IdealH2 = type("IdealH2", (IdealGas,), {"gas_constant": 4124.2})
|
|
71
|
+
IdealOxygen = type("IdealOxygen", (IdealGas,), {"gas_constant": 259.8})
|
|
72
|
+
IdealSteam = type("IdealSteam", (IdealGas,), {"gas_constant": 461.5})
|
|
73
|
+
|
|
74
|
+
# @forge
|
|
75
|
+
# class PerfectGas(FluidMaterial):
|
|
76
|
+
# '''A Calorically Perfect gas with viscosity'''
|
|
77
|
+
# eq_of_state = attrs.field()
|
|
78
|
+
# P = attrs.field(default=STD_PRESSURE, type=float)
|
|
79
|
+
|
|
80
|
+
# @system_property
|
|
81
|
+
# def density(self):
|
|
82
|
+
# '''default functionality, assumed gas with eq-state= gas constant'''
|
|
83
|
+
# return self.eq_of_state.density(T=self.T,P=self.P)
|
|
84
|
+
|
|
85
|
+
# @system_property
|
|
86
|
+
# def viscosity(self):
|
|
87
|
+
# '''ideal fluid has no viscosity'''
|
|
88
|
+
# return self.eq_of_state.viscosity(T=self.T,P=self.P)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@forge
|
|
92
|
+
class CoolPropMaterial(FluidMaterial):
|
|
93
|
+
"""Uses coolprop equation of state"""
|
|
94
|
+
|
|
95
|
+
material: str
|
|
96
|
+
|
|
97
|
+
# TODO: handle phase changes with internal _quality that you can add heat to
|
|
98
|
+
_surf_tension_K = None
|
|
99
|
+
_surf_tension_Nm = None
|
|
100
|
+
_state = None
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def state(self):
|
|
104
|
+
if hasattr(self, "_force_state"):
|
|
105
|
+
return self._force_state
|
|
106
|
+
if self._state and not self.anything_changed:
|
|
107
|
+
return self._state
|
|
108
|
+
else:
|
|
109
|
+
tsat = self.Tsat
|
|
110
|
+
if abs(self.T - tsat) < 1e-4:
|
|
111
|
+
self._state = ("Q", 0, "P", self.P, self.material)
|
|
112
|
+
elif self.T > tsat:
|
|
113
|
+
self._state = ("T|gas", self.T, "P", self.P, self.material)
|
|
114
|
+
else:
|
|
115
|
+
self._state = ("T|liquid", self.T, "P", self.P, self.material)
|
|
116
|
+
|
|
117
|
+
return self._state
|
|
118
|
+
|
|
119
|
+
@system_property
|
|
120
|
+
def density(self) -> float:
|
|
121
|
+
"""default functionality, assumed gas with eq-state= gas constant"""
|
|
122
|
+
return PropsSI("D", *self.state)
|
|
123
|
+
|
|
124
|
+
@system_property
|
|
125
|
+
def enthalpy(self) -> float:
|
|
126
|
+
return PropsSI("H", *self.state)
|
|
127
|
+
|
|
128
|
+
@system_property
|
|
129
|
+
def viscosity(self) -> float:
|
|
130
|
+
return PropsSI("V", *self.state)
|
|
131
|
+
|
|
132
|
+
@system_property
|
|
133
|
+
def surface_tension(self) -> float:
|
|
134
|
+
"""returns liquid surface tension"""
|
|
135
|
+
if self._surf_tension_K and self._surf_tension_Nm:
|
|
136
|
+
X = self._surf_tension_K
|
|
137
|
+
Y = self._surf_tension_Nm
|
|
138
|
+
l = Y[0]
|
|
139
|
+
r = Y[-1]
|
|
140
|
+
return numpy.interp(self.T, xp=X, fp=Y, left=l, right=r)
|
|
141
|
+
|
|
142
|
+
self.debug("no surface tension model! returning 0")
|
|
143
|
+
return 0.0
|
|
144
|
+
|
|
145
|
+
@system_property
|
|
146
|
+
def thermal_conductivity(self) -> float:
|
|
147
|
+
"""returns liquid thermal conductivity"""
|
|
148
|
+
return PropsSI("CONDUCTIVITY", *self.state)
|
|
149
|
+
|
|
150
|
+
@system_property
|
|
151
|
+
def specific_heat(self) -> float:
|
|
152
|
+
"""returns liquid thermal conductivity"""
|
|
153
|
+
return PropsSI("C", *self.state)
|
|
154
|
+
|
|
155
|
+
@system_property
|
|
156
|
+
def Tsat(self) -> float:
|
|
157
|
+
return PropsSI("T", "Q", 0, "P", self.P, self.material)
|
|
158
|
+
|
|
159
|
+
@system_property
|
|
160
|
+
def Psat(self) -> float:
|
|
161
|
+
try:
|
|
162
|
+
return PropsSI("P", "Q", 0, "T", self.T, self.material)
|
|
163
|
+
except:
|
|
164
|
+
return numpy.nan
|
|
165
|
+
|
|
166
|
+
def __call__(self, *args, **kwargs):
|
|
167
|
+
"""calls coolprop module with args adding the material"""
|
|
168
|
+
args = (*args, self.material)
|
|
169
|
+
return PropsSI(*args)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# TODO: add water suface tenstion
|
|
173
|
+
T_K = [
|
|
174
|
+
273.15,
|
|
175
|
+
278.15,
|
|
176
|
+
283.15,
|
|
177
|
+
293.15,
|
|
178
|
+
303.15,
|
|
179
|
+
313.15,
|
|
180
|
+
323.15,
|
|
181
|
+
333.15,
|
|
182
|
+
343.15,
|
|
183
|
+
353.15,
|
|
184
|
+
363.15,
|
|
185
|
+
373.15,
|
|
186
|
+
423.15,
|
|
187
|
+
473.15,
|
|
188
|
+
523.15,
|
|
189
|
+
573.15,
|
|
190
|
+
623.15,
|
|
191
|
+
647.25,
|
|
192
|
+
]
|
|
193
|
+
ST_NM = [
|
|
194
|
+
0.0756,
|
|
195
|
+
0.0749,
|
|
196
|
+
0.0742,
|
|
197
|
+
0.0728,
|
|
198
|
+
0.0712,
|
|
199
|
+
0.0696,
|
|
200
|
+
0.0679,
|
|
201
|
+
0.0662,
|
|
202
|
+
0.0644,
|
|
203
|
+
0.0626,
|
|
204
|
+
0.0608,
|
|
205
|
+
0.0589,
|
|
206
|
+
0.0482,
|
|
207
|
+
0.0376,
|
|
208
|
+
0.0264,
|
|
209
|
+
0.0147,
|
|
210
|
+
0.0037,
|
|
211
|
+
0.0,
|
|
212
|
+
]
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
Water = type(
|
|
216
|
+
"Water",
|
|
217
|
+
(CoolPropMaterial,),
|
|
218
|
+
{"material": "Water", "_surf_tension_K": T_K, "_surf_tension_Nm": ST_NM},
|
|
219
|
+
)
|
|
220
|
+
Air = type("Air", (CoolPropMaterial,), {"material": "Air"})
|
|
221
|
+
Oxygen = type("Oxygen", (CoolPropMaterial,), {"material": "Oxygen"})
|
|
222
|
+
Hydrogen = type("Hydrogen", (CoolPropMaterial,), {"material": "Hydrogen"})
|
|
223
|
+
Steam = type(
|
|
224
|
+
"Steam",
|
|
225
|
+
(CoolPropMaterial,),
|
|
226
|
+
{
|
|
227
|
+
"material": "IF97:Water",
|
|
228
|
+
"_surf_tension_K": T_K,
|
|
229
|
+
"_surf_tension_Nm": ST_NM,
|
|
230
|
+
},
|
|
231
|
+
)
|
|
232
|
+
SeaWater = type(
|
|
233
|
+
"SeaWater",
|
|
234
|
+
(CoolPropMaterial,),
|
|
235
|
+
{"material": "MITSW", "_surf_tension_K": T_K, "_surf_tension_Nm": ST_NM},
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
# Create some useful mixed models
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
@forge
|
|
242
|
+
class CoolPropMixture(CoolPropMaterial):
|
|
243
|
+
"""coolprop mixture of two elements... can only use T/Q, P/Q, T/P calls to coolprop"""
|
|
244
|
+
|
|
245
|
+
material1 = "Air"
|
|
246
|
+
materail2 = "Water"
|
|
247
|
+
_X = 1.0 # 1.0 > mole fraction of material > 0
|
|
248
|
+
|
|
249
|
+
@system_property
|
|
250
|
+
def material(self) -> str:
|
|
251
|
+
Xm = self._X
|
|
252
|
+
return f"{self.material1}[{Xm}]&{self.materail2}[{1.0-Xm}]"
|
|
253
|
+
|
|
254
|
+
@classmethod
|
|
255
|
+
def setup(cls):
|
|
256
|
+
try:
|
|
257
|
+
CoolProp.apply_simple_mixing_rule(cls.material, cls.material2, "linear")
|
|
258
|
+
except Exception as e:
|
|
259
|
+
pass
|
|
260
|
+
# self.error(e,'issue setting mixing rule, but continuting.')
|
|
261
|
+
|
|
262
|
+
@system_property
|
|
263
|
+
def Mmass1(self) -> float:
|
|
264
|
+
return PropsSI("M", "T", self.T, "P", self.P, self.material1)
|
|
265
|
+
|
|
266
|
+
@system_property
|
|
267
|
+
def Mmass2(self) -> float:
|
|
268
|
+
return PropsSI("M", "T", self.T, "P", self.P, self.material2)
|
|
269
|
+
|
|
270
|
+
def update_mass_ratios(self, m1, m2):
|
|
271
|
+
"""add masses or massrates and molar ratio will be updated"""
|
|
272
|
+
x1 = m1 / self.Mmass1
|
|
273
|
+
x2 = m2 / self.Mmass2
|
|
274
|
+
xtot = x1 + x2
|
|
275
|
+
self._X = x1 / xtot
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
AirWaterMix = type("AirWaterMix", (CoolPropMixture,), {})
|
|
279
|
+
AirWaterMix.setup()
|