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.
Files changed (69) hide show
  1. engforge/__init__.py +26 -0
  2. engforge/_testing_components.py +864 -0
  3. engforge/analysis.py +257 -0
  4. engforge/attr_dynamics.py +222 -0
  5. engforge/attr_plotting.py +811 -0
  6. engforge/attr_signals.py +116 -0
  7. engforge/attr_slots.py +211 -0
  8. engforge/attr_solver.py +443 -0
  9. engforge/attributes.py +326 -0
  10. engforge/common.py +76 -0
  11. engforge/component_collections.py +276 -0
  12. engforge/components.py +55 -0
  13. engforge/configuration.py +673 -0
  14. engforge/dataframe.py +185 -0
  15. engforge/datastores/__init__.py +116 -0
  16. engforge/datastores/data.py +519 -0
  17. engforge/datastores/gdocs.py +2650 -0
  18. engforge/datastores/reporting.py +935 -0
  19. engforge/datastores/secrets.py +549 -0
  20. engforge/dynamics.py +662 -0
  21. engforge/eng/__init__.py +0 -0
  22. engforge/eng/costs.py +1459 -0
  23. engforge/eng/fluid_material.py +279 -0
  24. engforge/eng/geometry.py +1060 -0
  25. engforge/eng/pipes.py +1211 -0
  26. engforge/eng/prediction.py +366 -0
  27. engforge/eng/solid_materials.py +445 -0
  28. engforge/eng/structure.py +2228 -0
  29. engforge/eng/structure_beams.py +821 -0
  30. engforge/eng/thermodynamics.py +271 -0
  31. engforge/engforge_attributes.py +380 -0
  32. engforge/env_var.py +214 -0
  33. engforge/locations.py +18 -0
  34. engforge/logging.py +290 -0
  35. engforge/patterns.py +449 -0
  36. engforge/problem_context.py +2251 -0
  37. engforge/properties.py +501 -0
  38. engforge/reporting.py +595 -0
  39. engforge/solveable.py +964 -0
  40. engforge/solver.py +316 -0
  41. engforge/solver_utils.py +726 -0
  42. engforge/system.py +143 -0
  43. engforge/system_reference.py +299 -0
  44. engforge/tabulation.py +288 -0
  45. engforge/test/__init__.py +2 -0
  46. engforge/test/_pre_test_structures.py +221 -0
  47. engforge/test/report_testing.py +158 -0
  48. engforge/test/test_airfilter.py +91 -0
  49. engforge/test/test_analysis.py +3 -0
  50. engforge/test/test_comp_iter.py +196 -0
  51. engforge/test/test_composition.py +139 -0
  52. engforge/test/test_costs.py +338 -0
  53. engforge/test/test_dynamics.py +109 -0
  54. engforge/test/test_dynamics_spaces.py +39 -0
  55. engforge/test/test_four_bar.py +97 -0
  56. engforge/test/test_modules.py +72 -0
  57. engforge/test/test_performance.py +93 -0
  58. engforge/test/test_pipes.py +49 -0
  59. engforge/test/test_problem.py +411 -0
  60. engforge/test/test_problem_deepscoping.py +68 -0
  61. engforge/test/test_slider_crank.py +51 -0
  62. engforge/test/test_solver.py +343 -0
  63. engforge/test/test_tabulation.py +233 -0
  64. engforge/typing.py +92 -0
  65. engforge-0.3.0.dist-info/METADATA +392 -0
  66. engforge-0.3.0.dist-info/RECORD +69 -0
  67. engforge-0.3.0.dist-info/WHEEL +5 -0
  68. engforge-0.3.0.dist-info/licenses/LICENSE +7 -0
  69. 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()