phaxor 1.0.0__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.
- phaxor-1.0.0/LICENSE +21 -0
- phaxor-1.0.0/PKG-INFO +168 -0
- phaxor-1.0.0/README.md +125 -0
- phaxor-1.0.0/phaxor/__init__.py +188 -0
- phaxor-1.0.0/phaxor/display.py +60 -0
- phaxor-1.0.0/phaxor/engines/__init__.py +1 -0
- phaxor-1.0.0/phaxor/engines/apf.py +56 -0
- phaxor-1.0.0/phaxor/engines/arrhenius.py +46 -0
- phaxor-1.0.0/phaxor/engines/battery_ups.py +54 -0
- phaxor-1.0.0/phaxor/engines/beam.py +109 -0
- phaxor-1.0.0/phaxor/engines/beam_deflection.py +151 -0
- phaxor-1.0.0/phaxor/engines/bearing_capacity.py +89 -0
- phaxor-1.0.0/phaxor/engines/bearing_life.py +55 -0
- phaxor-1.0.0/phaxor/engines/belt_drive.py +102 -0
- phaxor-1.0.0/phaxor/engines/bolt_analysis.py +112 -0
- phaxor-1.0.0/phaxor/engines/cable_sizing.py +87 -0
- phaxor-1.0.0/phaxor/engines/chem_equilibrium.py +86 -0
- phaxor-1.0.0/phaxor/engines/circuit_breaker.py +77 -0
- phaxor-1.0.0/phaxor/engines/column_buckling.py +83 -0
- phaxor-1.0.0/phaxor/engines/concrete_volume.py +92 -0
- phaxor-1.0.0/phaxor/engines/cop.py +51 -0
- phaxor-1.0.0/phaxor/engines/corrosion.py +55 -0
- phaxor-1.0.0/phaxor/engines/cstr.py +74 -0
- phaxor-1.0.0/phaxor/engines/dc_motor.py +48 -0
- phaxor-1.0.0/phaxor/engines/development_length.py +42 -0
- phaxor-1.0.0/phaxor/engines/distillation.py +97 -0
- phaxor-1.0.0/phaxor/engines/earth_pressure.py +101 -0
- phaxor-1.0.0/phaxor/engines/earthing.py +67 -0
- phaxor-1.0.0/phaxor/engines/electrical_efficiency.py +56 -0
- phaxor-1.0.0/phaxor/engines/energy_consumption.py +46 -0
- phaxor-1.0.0/phaxor/engines/failure_theory.py +103 -0
- phaxor-1.0.0/phaxor/engines/fatigue_life.py +45 -0
- phaxor-1.0.0/phaxor/engines/flywheel.py +94 -0
- phaxor-1.0.0/phaxor/engines/gear_ratio.py +67 -0
- phaxor-1.0.0/phaxor/engines/geometry.py +61 -0
- phaxor-1.0.0/phaxor/engines/gibbs.py +56 -0
- phaxor-1.0.0/phaxor/engines/hardness_conv.py +59 -0
- phaxor-1.0.0/phaxor/engines/hardness_conversion.py +52 -0
- phaxor-1.0.0/phaxor/engines/heat_exchanger.py +110 -0
- phaxor-1.0.0/phaxor/engines/heat_transfer.py +106 -0
- phaxor-1.0.0/phaxor/engines/ideal_gas.py +67 -0
- phaxor-1.0.0/phaxor/engines/impedance.py +79 -0
- phaxor-1.0.0/phaxor/engines/induction_motor.py +60 -0
- phaxor-1.0.0/phaxor/engines/isolated_footing.py +91 -0
- phaxor-1.0.0/phaxor/engines/matrix.py +80 -0
- phaxor-1.0.0/phaxor/engines/mohrs_circle.py +45 -0
- phaxor-1.0.0/phaxor/engines/ohms_law.py +45 -0
- phaxor-1.0.0/phaxor/engines/open_channel.py +90 -0
- phaxor-1.0.0/phaxor/engines/packed_bed.py +60 -0
- phaxor-1.0.0/phaxor/engines/pavement_thickness.py +88 -0
- phaxor-1.0.0/phaxor/engines/pf_correction.py +50 -0
- phaxor-1.0.0/phaxor/engines/pfr.py +84 -0
- phaxor-1.0.0/phaxor/engines/pipe_flow.py +284 -0
- phaxor-1.0.0/phaxor/engines/power.py +42 -0
- phaxor-1.0.0/phaxor/engines/pressure_force.py +71 -0
- phaxor-1.0.0/phaxor/engines/pump_power.py +78 -0
- phaxor-1.0.0/phaxor/engines/rankine_cycle.py +83 -0
- phaxor-1.0.0/phaxor/engines/rcc_beam.py +101 -0
- phaxor-1.0.0/phaxor/engines/rcc_column.py +85 -0
- phaxor-1.0.0/phaxor/engines/rcc_slab.py +132 -0
- phaxor-1.0.0/phaxor/engines/rectifier.py +93 -0
- phaxor-1.0.0/phaxor/engines/reinforcement_qty.py +78 -0
- phaxor-1.0.0/phaxor/engines/resonance.py +65 -0
- phaxor-1.0.0/phaxor/engines/rule_of_mixtures.py +42 -0
- phaxor-1.0.0/phaxor/engines/settlement.py +58 -0
- phaxor-1.0.0/phaxor/engines/shaft_design.py +104 -0
- phaxor-1.0.0/phaxor/engines/short_circuit.py +64 -0
- phaxor-1.0.0/phaxor/engines/sight_distance.py +61 -0
- phaxor-1.0.0/phaxor/engines/soil_properties.py +52 -0
- phaxor-1.0.0/phaxor/engines/solar_sizing.py +88 -0
- phaxor-1.0.0/phaxor/engines/spring_design.py +149 -0
- phaxor-1.0.0/phaxor/engines/steel_weight.py +108 -0
- phaxor-1.0.0/phaxor/engines/stoichiometry.py +99 -0
- phaxor-1.0.0/phaxor/engines/stress_strain.py +69 -0
- phaxor-1.0.0/phaxor/engines/torque_power.py +73 -0
- phaxor-1.0.0/phaxor/engines/transformer.py +54 -0
- phaxor-1.0.0/phaxor/engines/unit_converter.py +97 -0
- phaxor-1.0.0/phaxor/engines/vibration.py +68 -0
- phaxor-1.0.0/phaxor/engines/vle.py +79 -0
- phaxor-1.0.0/phaxor/engines/weir_orifice.py +50 -0
- phaxor-1.0.0/phaxor/engines/weld_strength.py +82 -0
- phaxor-1.0.0/phaxor.egg-info/PKG-INFO +168 -0
- phaxor-1.0.0/phaxor.egg-info/SOURCES.txt +86 -0
- phaxor-1.0.0/phaxor.egg-info/dependency_links.txt +1 -0
- phaxor-1.0.0/phaxor.egg-info/requires.txt +3 -0
- phaxor-1.0.0/phaxor.egg-info/top_level.txt +1 -0
- phaxor-1.0.0/pyproject.toml +27 -0
- phaxor-1.0.0/setup.cfg +4 -0
phaxor-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Phaxor Team
|
|
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.
|
phaxor-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: phaxor
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Engineering Calculator Library — Ideal Gas, Ohm's Law, Mohr's Circle, Beam Analysis, and more with rich Jupyter output
|
|
5
|
+
Author: Phaxor Team
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Phaxor Team
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Keywords: engineering,calculator,physics,mechanical,electrical,structural,jupyter
|
|
29
|
+
Classifier: Development Status :: 4 - Beta
|
|
30
|
+
Classifier: Intended Audience :: Education
|
|
31
|
+
Classifier: Intended Audience :: Science/Research
|
|
32
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
33
|
+
Classifier: Programming Language :: Python :: 3
|
|
34
|
+
Classifier: Topic :: Scientific/Engineering
|
|
35
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
36
|
+
Classifier: Framework :: Jupyter
|
|
37
|
+
Requires-Python: >=3.8
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
License-File: LICENSE
|
|
40
|
+
Provides-Extra: jupyter
|
|
41
|
+
Requires-Dist: ipython>=7.0; extra == "jupyter"
|
|
42
|
+
Dynamic: license-file
|
|
43
|
+
|
|
44
|
+
# 🔬 Phaxor — Engineering Calculator Library
|
|
45
|
+
|
|
46
|
+
**Embeddable engineering calculations for JavaScript and Python.**
|
|
47
|
+
|
|
48
|
+
## Install
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install phaxor
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Quick Start
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
import phaxor
|
|
58
|
+
|
|
59
|
+
# Ideal Gas Law
|
|
60
|
+
result = phaxor.compute('ideal-gas', {
|
|
61
|
+
'solveFor': 'pressure',
|
|
62
|
+
'volume': 0.02241,
|
|
63
|
+
'moles': 1,
|
|
64
|
+
'temperature': 273.15,
|
|
65
|
+
'gas': 'air'
|
|
66
|
+
})
|
|
67
|
+
print(f"Pressure = {result['P']:.0f} Pa") # 101325 Pa
|
|
68
|
+
|
|
69
|
+
# Ohm's Law
|
|
70
|
+
result = phaxor.compute('ohms-law', {
|
|
71
|
+
'solveFor': 'I',
|
|
72
|
+
'voltage': 12,
|
|
73
|
+
'resistance': 100
|
|
74
|
+
})
|
|
75
|
+
print(f"Current = {result['I']} A") # 0.12 A
|
|
76
|
+
|
|
77
|
+
# Unit Conversion
|
|
78
|
+
km = phaxor.convert('length', 1, 'mi', 'km')
|
|
79
|
+
print(f"1 mile = {km:.6f} km") # 1.609344 km
|
|
80
|
+
|
|
81
|
+
# Mohr's Circle
|
|
82
|
+
result = phaxor.compute('mohrs-circle', {
|
|
83
|
+
'sigmaX': 80,
|
|
84
|
+
'sigmaY': -40,
|
|
85
|
+
'tauXY': 30,
|
|
86
|
+
'theta': 25
|
|
87
|
+
})
|
|
88
|
+
print(f"σ₁ = {result['sigma1']:.1f} MPa")
|
|
89
|
+
|
|
90
|
+
# List all calculators
|
|
91
|
+
for calc in phaxor.list_calculators():
|
|
92
|
+
print(f" {calc['id']:20s} {calc['name']}")
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Available Calculators
|
|
96
|
+
|
|
97
|
+
| ID | Name | Category |
|
|
98
|
+
|----|------|----------|
|
|
99
|
+
| `ideal-gas` | Ideal Gas Law | Thermodynamics |
|
|
100
|
+
| `ohms-law` | Ohm's Law | Electrical |
|
|
101
|
+
| `mohrs-circle` | Mohr's Circle | Structural |
|
|
102
|
+
| `gear-ratio` | Gear Ratio | Mechanical |
|
|
103
|
+
| `heat-transfer` | Heat Transfer | Thermodynamics |
|
|
104
|
+
| `column-buckling` | Column Buckling | Structural |
|
|
105
|
+
| `stress-strain` | Stress & Strain | Structural |
|
|
106
|
+
| `beam` | Beam Analysis | Structural |
|
|
107
|
+
| `pipe-flow` | Pipe Flow | Fluid Mechanics |
|
|
108
|
+
| `unit-converter` | Unit Converter | General |
|
|
109
|
+
|
|
110
|
+
## Pipe Flow (Detailed Model)
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
import phaxor
|
|
114
|
+
|
|
115
|
+
# Pressure-driven solve using NPS + Schedule diameter lookup
|
|
116
|
+
result = phaxor.compute('pipe-flow', {
|
|
117
|
+
'solveMode': 'known-pressures',
|
|
118
|
+
'nps': '4',
|
|
119
|
+
'schedule': '40',
|
|
120
|
+
'length': 120,
|
|
121
|
+
'roughness': 0.000045,
|
|
122
|
+
'minorLossK': 6.5,
|
|
123
|
+
'elevationChange': 5,
|
|
124
|
+
'inletPressure': 220, # kPa gauge
|
|
125
|
+
'outletPressure': 0, # kPa gauge
|
|
126
|
+
'density': 998,
|
|
127
|
+
'viscosity': 0.001002
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
print(f"Q = {result['flowRate']*3600:.2f} m3/h")
|
|
131
|
+
print(f"ID source = {result['diameterSource']}")
|
|
132
|
+
print(f"Delta P = {result['pressureDeltaKPa']:.2f} kPa")
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The `pipe-flow` engine now supports:
|
|
136
|
+
- `known-flow` and `known-pressures` boundary modes
|
|
137
|
+
- Flow input by volumetric flow, mass flow, or velocity
|
|
138
|
+
- Minor loss (`K`) and elevation/pump head terms
|
|
139
|
+
- Pipe sizing by direct diameter or `nps + schedule`
|
|
140
|
+
- Extended outputs (major/minor loss split, power estimates, turbulence initialization fields)
|
|
141
|
+
|
|
142
|
+
## Jupyter Notebooks
|
|
143
|
+
|
|
144
|
+
In Jupyter, calling `phaxor.compute()` automatically renders a styled HTML table:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
import phaxor
|
|
148
|
+
|
|
149
|
+
# This renders a beautiful HTML table in Jupyter!
|
|
150
|
+
phaxor.compute('ideal-gas', {
|
|
151
|
+
'solveFor': 'pressure',
|
|
152
|
+
'volume': 0.02241,
|
|
153
|
+
'moles': 1,
|
|
154
|
+
'temperature': 273.15,
|
|
155
|
+
})
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## API
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
phaxor.compute(calculator_type, inputs) # Run any calculator
|
|
162
|
+
phaxor.convert(category, value, from_unit, to_unit) # Unit conversion
|
|
163
|
+
phaxor.list_calculators() # List all available calculators
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## License
|
|
167
|
+
|
|
168
|
+
MIT
|
phaxor-1.0.0/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# 🔬 Phaxor — Engineering Calculator Library
|
|
2
|
+
|
|
3
|
+
**Embeddable engineering calculations for JavaScript and Python.**
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install phaxor
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import phaxor
|
|
15
|
+
|
|
16
|
+
# Ideal Gas Law
|
|
17
|
+
result = phaxor.compute('ideal-gas', {
|
|
18
|
+
'solveFor': 'pressure',
|
|
19
|
+
'volume': 0.02241,
|
|
20
|
+
'moles': 1,
|
|
21
|
+
'temperature': 273.15,
|
|
22
|
+
'gas': 'air'
|
|
23
|
+
})
|
|
24
|
+
print(f"Pressure = {result['P']:.0f} Pa") # 101325 Pa
|
|
25
|
+
|
|
26
|
+
# Ohm's Law
|
|
27
|
+
result = phaxor.compute('ohms-law', {
|
|
28
|
+
'solveFor': 'I',
|
|
29
|
+
'voltage': 12,
|
|
30
|
+
'resistance': 100
|
|
31
|
+
})
|
|
32
|
+
print(f"Current = {result['I']} A") # 0.12 A
|
|
33
|
+
|
|
34
|
+
# Unit Conversion
|
|
35
|
+
km = phaxor.convert('length', 1, 'mi', 'km')
|
|
36
|
+
print(f"1 mile = {km:.6f} km") # 1.609344 km
|
|
37
|
+
|
|
38
|
+
# Mohr's Circle
|
|
39
|
+
result = phaxor.compute('mohrs-circle', {
|
|
40
|
+
'sigmaX': 80,
|
|
41
|
+
'sigmaY': -40,
|
|
42
|
+
'tauXY': 30,
|
|
43
|
+
'theta': 25
|
|
44
|
+
})
|
|
45
|
+
print(f"σ₁ = {result['sigma1']:.1f} MPa")
|
|
46
|
+
|
|
47
|
+
# List all calculators
|
|
48
|
+
for calc in phaxor.list_calculators():
|
|
49
|
+
print(f" {calc['id']:20s} {calc['name']}")
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Available Calculators
|
|
53
|
+
|
|
54
|
+
| ID | Name | Category |
|
|
55
|
+
|----|------|----------|
|
|
56
|
+
| `ideal-gas` | Ideal Gas Law | Thermodynamics |
|
|
57
|
+
| `ohms-law` | Ohm's Law | Electrical |
|
|
58
|
+
| `mohrs-circle` | Mohr's Circle | Structural |
|
|
59
|
+
| `gear-ratio` | Gear Ratio | Mechanical |
|
|
60
|
+
| `heat-transfer` | Heat Transfer | Thermodynamics |
|
|
61
|
+
| `column-buckling` | Column Buckling | Structural |
|
|
62
|
+
| `stress-strain` | Stress & Strain | Structural |
|
|
63
|
+
| `beam` | Beam Analysis | Structural |
|
|
64
|
+
| `pipe-flow` | Pipe Flow | Fluid Mechanics |
|
|
65
|
+
| `unit-converter` | Unit Converter | General |
|
|
66
|
+
|
|
67
|
+
## Pipe Flow (Detailed Model)
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
import phaxor
|
|
71
|
+
|
|
72
|
+
# Pressure-driven solve using NPS + Schedule diameter lookup
|
|
73
|
+
result = phaxor.compute('pipe-flow', {
|
|
74
|
+
'solveMode': 'known-pressures',
|
|
75
|
+
'nps': '4',
|
|
76
|
+
'schedule': '40',
|
|
77
|
+
'length': 120,
|
|
78
|
+
'roughness': 0.000045,
|
|
79
|
+
'minorLossK': 6.5,
|
|
80
|
+
'elevationChange': 5,
|
|
81
|
+
'inletPressure': 220, # kPa gauge
|
|
82
|
+
'outletPressure': 0, # kPa gauge
|
|
83
|
+
'density': 998,
|
|
84
|
+
'viscosity': 0.001002
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
print(f"Q = {result['flowRate']*3600:.2f} m3/h")
|
|
88
|
+
print(f"ID source = {result['diameterSource']}")
|
|
89
|
+
print(f"Delta P = {result['pressureDeltaKPa']:.2f} kPa")
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The `pipe-flow` engine now supports:
|
|
93
|
+
- `known-flow` and `known-pressures` boundary modes
|
|
94
|
+
- Flow input by volumetric flow, mass flow, or velocity
|
|
95
|
+
- Minor loss (`K`) and elevation/pump head terms
|
|
96
|
+
- Pipe sizing by direct diameter or `nps + schedule`
|
|
97
|
+
- Extended outputs (major/minor loss split, power estimates, turbulence initialization fields)
|
|
98
|
+
|
|
99
|
+
## Jupyter Notebooks
|
|
100
|
+
|
|
101
|
+
In Jupyter, calling `phaxor.compute()` automatically renders a styled HTML table:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
import phaxor
|
|
105
|
+
|
|
106
|
+
# This renders a beautiful HTML table in Jupyter!
|
|
107
|
+
phaxor.compute('ideal-gas', {
|
|
108
|
+
'solveFor': 'pressure',
|
|
109
|
+
'volume': 0.02241,
|
|
110
|
+
'moles': 1,
|
|
111
|
+
'temperature': 273.15,
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## API
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
phaxor.compute(calculator_type, inputs) # Run any calculator
|
|
119
|
+
phaxor.convert(category, value, from_unit, to_unit) # Unit conversion
|
|
120
|
+
phaxor.list_calculators() # List all available calculators
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
MIT
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"""Phaxor Engineering Calculator Library for Python."""
|
|
2
|
+
|
|
3
|
+
__version__ = "1.0.0"
|
|
4
|
+
|
|
5
|
+
from .engines.arrhenius import solve_arrhenius
|
|
6
|
+
from .engines.cstr import solve_cstr
|
|
7
|
+
from .engines.chem_equilibrium import solve_chem_equilibrium
|
|
8
|
+
from .engines.distillation import solve_distillation
|
|
9
|
+
from .engines.gibbs import solve_gibbs
|
|
10
|
+
from .engines.pfr import solve_pfr
|
|
11
|
+
from .engines.packed_bed import solve_packed_bed
|
|
12
|
+
from .engines.stoichiometry import solve_stoichiometry
|
|
13
|
+
from .engines.vle import solve_vle
|
|
14
|
+
from .engines.battery_ups import solve_battery_ups
|
|
15
|
+
from .engines.cable_sizing import solve_cable_sizing
|
|
16
|
+
from .engines.circuit_breaker import solve_circuit_breaker
|
|
17
|
+
from .engines.dc_motor import solve_dc_motor
|
|
18
|
+
from .engines.earthing import solve_earthing
|
|
19
|
+
from .engines.electrical_efficiency import solve_electrical_efficiency
|
|
20
|
+
from .engines.energy_consumption import solve_energy_consumption
|
|
21
|
+
from .engines.impedance import solve_impedance
|
|
22
|
+
from .engines.induction_motor import solve_induction_motor
|
|
23
|
+
from .engines.ohms_law import solve_ohms_law
|
|
24
|
+
from .engines.power import solve_ac_power
|
|
25
|
+
from .engines.pf_correction import solve_pf_correction
|
|
26
|
+
from .engines.rectifier import solve_rectifier
|
|
27
|
+
from .engines.resonance import solve_resonance
|
|
28
|
+
from .engines.short_circuit import solve_short_circuit
|
|
29
|
+
from .engines.solar_sizing import solve_solar_sizing
|
|
30
|
+
from .engines.transformer import solve_transformer
|
|
31
|
+
from .engines.geometry import solve_geometry
|
|
32
|
+
from .engines.matrix import solve_matrix
|
|
33
|
+
from .engines.unit_converter import convert_unit, get_categories, get_units
|
|
34
|
+
from .engines.open_channel import solve_open_channel
|
|
35
|
+
from .engines.pavement_thickness import solve_pavement_thickness
|
|
36
|
+
from .engines.sight_distance import solve_sight_distance
|
|
37
|
+
from .engines.weir_orifice import solve_weir_orifice
|
|
38
|
+
from .engines.apf import solve_apf
|
|
39
|
+
from .engines.corrosion import solve_corrosion
|
|
40
|
+
from .engines.fatigue_life import solve_fatigue_life
|
|
41
|
+
from .engines.hardness_conversion import solve_hardness_conversion
|
|
42
|
+
from .engines.rule_of_mixtures import solve_rule_of_mixtures
|
|
43
|
+
from .engines.beam import solve_beam
|
|
44
|
+
from .engines.bearing_life import solve_bearing_life
|
|
45
|
+
from .engines.belt_drive import solve_belt_drive
|
|
46
|
+
from .engines.bolt_analysis import solve_bolt_analysis
|
|
47
|
+
from .engines.cop import solve_cop
|
|
48
|
+
from .engines.flywheel import solve_flywheel
|
|
49
|
+
from .engines.gear_ratio import solve_gear_ratio
|
|
50
|
+
from .engines.heat_exchanger import solve_heat_exchanger
|
|
51
|
+
from .engines.heat_transfer import solve_heat_transfer
|
|
52
|
+
from .engines.ideal_gas import solve_ideal_gas, GASES, R_UNIVERSAL
|
|
53
|
+
from .engines.pipe_flow import solve_pipe_flow
|
|
54
|
+
from .engines.pressure_force import solve_pressure_force
|
|
55
|
+
from .engines.pump_power import solve_pump_power
|
|
56
|
+
from .engines.rankine_cycle import solve_rankine_cycle
|
|
57
|
+
from .engines.shaft_design import solve_shaft_design
|
|
58
|
+
from .engines.spring_design import solve_spring_design
|
|
59
|
+
from .engines.torque_power import solve_torque_power
|
|
60
|
+
from .engines.vibration import solve_vibration
|
|
61
|
+
from .engines.weld_strength import solve_weld_strength
|
|
62
|
+
from .engines.beam_deflection import solve_beam_deflection
|
|
63
|
+
from .engines.bearing_capacity import solve_bearing_capacity
|
|
64
|
+
from .engines.column_buckling import solve_column_buckling, calc_column_section
|
|
65
|
+
from .engines.concrete_volume import solve_concrete_volume
|
|
66
|
+
from .engines.development_length import solve_development_length
|
|
67
|
+
from .engines.earth_pressure import solve_earth_pressure
|
|
68
|
+
from .engines.failure_theory import solve_failure_theory
|
|
69
|
+
from .engines.isolated_footing import solve_isolated_footing
|
|
70
|
+
from .engines.mohrs_circle import solve_mohrs_circle
|
|
71
|
+
from .engines.rcc_beam import solve_rcc_beam
|
|
72
|
+
from .engines.rcc_column import solve_rcc_column
|
|
73
|
+
from .engines.rcc_slab import solve_rcc_slab
|
|
74
|
+
from .engines.reinforcement_qty import solve_reinforcement_qty
|
|
75
|
+
from .engines.settlement import solve_settlement
|
|
76
|
+
from .engines.soil_properties import solve_soil_properties
|
|
77
|
+
from .engines.steel_weight import solve_steel_weight
|
|
78
|
+
from .engines.stress_strain import solve_stress_strain, calc_area, MATERIALS as STRESS_MATERIALS
|
|
79
|
+
from .display import display_result
|
|
80
|
+
|
|
81
|
+
CALCULATORS = {
|
|
82
|
+
'arrhenius': {'name': 'Arrhenius', 'category': 'Chemical', 'solver': solve_arrhenius},
|
|
83
|
+
'cstr': {'name': 'CSTR Design', 'category': 'Chemical', 'solver': solve_cstr},
|
|
84
|
+
'chem-equilibrium': {'name': 'Chem Equilibrium', 'category': 'Chemical', 'solver': solve_chem_equilibrium},
|
|
85
|
+
'distillation': {'name': 'Distillation', 'category': 'Chemical', 'solver': solve_distillation},
|
|
86
|
+
'gibbs': {'name': 'Gibbs', 'category': 'Chemical', 'solver': solve_gibbs},
|
|
87
|
+
'pfr': {'name': 'PFR Design', 'category': 'Chemical', 'solver': solve_pfr},
|
|
88
|
+
'packed-bed': {'name': 'Packed Bed', 'category': 'Chemical', 'solver': solve_packed_bed},
|
|
89
|
+
'stoichiometry': {'name': 'Stoichiometry', 'category': 'Chemical', 'solver': solve_stoichiometry},
|
|
90
|
+
'vle': {'name': 'VLE / Phase Equilibrium', 'category': 'Chemical', 'solver': solve_vle},
|
|
91
|
+
'battery-ups': {'name': 'Battery Ups', 'category': 'Electrical', 'solver': solve_battery_ups},
|
|
92
|
+
'cable-sizing': {'name': 'Cable Sizing', 'category': 'Electrical', 'solver': solve_cable_sizing},
|
|
93
|
+
'circuit-breaker': {'name': 'Circuit Breaker', 'category': 'Electrical', 'solver': solve_circuit_breaker},
|
|
94
|
+
'dc-motor': {'name': 'DC Motor', 'category': 'Electrical', 'solver': solve_dc_motor},
|
|
95
|
+
'earthing': {'name': 'Earthing', 'category': 'Electrical', 'solver': solve_earthing},
|
|
96
|
+
'electrical-efficiency': {'name': 'Electrical Efficiency', 'category': 'Electrical', 'solver': solve_electrical_efficiency},
|
|
97
|
+
'energy-consumption': {'name': 'Energy Consumption', 'category': 'Electrical', 'solver': solve_energy_consumption},
|
|
98
|
+
'impedance': {'name': 'Impedance', 'category': 'Electrical', 'solver': solve_impedance},
|
|
99
|
+
'induction-motor': {'name': 'Induction Motor', 'category': 'Electrical', 'solver': solve_induction_motor},
|
|
100
|
+
'ohms-law': {'name': 'Ohm\'s Law', 'category': 'Electrical', 'solver': solve_ohms_law},
|
|
101
|
+
'power': {'name': 'Power', 'category': 'Electrical', 'solver': solve_ac_power},
|
|
102
|
+
'pf-correction': {'name': 'Power Factor Correction', 'category': 'Electrical', 'solver': solve_pf_correction},
|
|
103
|
+
'rectifier': {'name': 'Rectifier', 'category': 'Electrical', 'solver': solve_rectifier},
|
|
104
|
+
'resonance': {'name': 'Resonance', 'category': 'Electrical', 'solver': solve_resonance},
|
|
105
|
+
'short-circuit': {'name': 'Short Circuit', 'category': 'Electrical', 'solver': solve_short_circuit},
|
|
106
|
+
'solar-sizing': {'name': 'Solar Sizing', 'category': 'Electrical', 'solver': solve_solar_sizing},
|
|
107
|
+
'transformer': {'name': 'Transformer', 'category': 'Electrical', 'solver': solve_transformer},
|
|
108
|
+
'geometry': {'name': 'Geometry', 'category': 'General', 'solver': solve_geometry},
|
|
109
|
+
'matrix': {'name': 'Matrix', 'category': 'General', 'solver': solve_matrix},
|
|
110
|
+
'unit-converter': {'name': 'Unit Converter', 'category': 'General', 'solver': convert_unit},
|
|
111
|
+
'open-channel': {'name': 'Open Channel Flow', 'category': 'Hydraulics', 'solver': solve_open_channel},
|
|
112
|
+
'pavement-thickness': {'name': 'Pavement Thickness', 'category': 'Hydraulics', 'solver': solve_pavement_thickness},
|
|
113
|
+
'sight-distance': {'name': 'Sight Distance', 'category': 'Hydraulics', 'solver': solve_sight_distance},
|
|
114
|
+
'weir-orifice': {'name': 'Weir & Orifice', 'category': 'Hydraulics', 'solver': solve_weir_orifice},
|
|
115
|
+
'apf': {'name': 'Atomic Packing Factor', 'category': 'Materials', 'solver': solve_apf},
|
|
116
|
+
'corrosion': {'name': 'Corrosion', 'category': 'Materials', 'solver': solve_corrosion},
|
|
117
|
+
'fatigue-life': {'name': 'Fatigue Life', 'category': 'Materials', 'solver': solve_fatigue_life},
|
|
118
|
+
'hardness-conversion': {'name': 'Hardness Conversion', 'category': 'Materials', 'solver': solve_hardness_conversion},
|
|
119
|
+
'rule-of-mixtures': {'name': 'Rule of Mixtures', 'category': 'Materials', 'solver': solve_rule_of_mixtures},
|
|
120
|
+
'beam': {'name': 'Beam', 'category': 'Mechanical', 'solver': solve_beam},
|
|
121
|
+
'bearing-life': {'name': 'Bearing Life', 'category': 'Mechanical', 'solver': solve_bearing_life},
|
|
122
|
+
'belt-drive': {'name': 'Belt Drive', 'category': 'Mechanical', 'solver': solve_belt_drive},
|
|
123
|
+
'bolt-analysis': {'name': 'Bolt Analysis', 'category': 'Mechanical', 'solver': solve_bolt_analysis},
|
|
124
|
+
'cop': {'name': 'Coefficient of Performance', 'category': 'Mechanical', 'solver': solve_cop},
|
|
125
|
+
'flywheel': {'name': 'Flywheel', 'category': 'Mechanical', 'solver': solve_flywheel},
|
|
126
|
+
'gear-ratio': {'name': 'Gear Ratio', 'category': 'Mechanical', 'solver': solve_gear_ratio},
|
|
127
|
+
'heat-exchanger': {'name': 'Heat Exchanger', 'category': 'Mechanical', 'solver': solve_heat_exchanger},
|
|
128
|
+
'heat-transfer': {'name': 'Heat Transfer', 'category': 'Mechanical', 'solver': solve_heat_transfer},
|
|
129
|
+
'ideal-gas': {'name': 'Ideal Gas Law', 'category': 'Mechanical', 'solver': solve_ideal_gas},
|
|
130
|
+
'pipe-flow': {'name': 'Pipe Flow', 'category': 'Mechanical', 'solver': solve_pipe_flow},
|
|
131
|
+
'pressure-force': {'name': 'Pressure Force', 'category': 'Mechanical', 'solver': solve_pressure_force},
|
|
132
|
+
'pump-power': {'name': 'Pump Power', 'category': 'Mechanical', 'solver': solve_pump_power},
|
|
133
|
+
'rankine-cycle': {'name': 'Rankine Cycle', 'category': 'Mechanical', 'solver': solve_rankine_cycle},
|
|
134
|
+
'shaft-design': {'name': 'Shaft Design', 'category': 'Mechanical', 'solver': solve_shaft_design},
|
|
135
|
+
'spring-design': {'name': 'Spring Design', 'category': 'Mechanical', 'solver': solve_spring_design},
|
|
136
|
+
'torque-power': {'name': 'Torque Power', 'category': 'Mechanical', 'solver': solve_torque_power},
|
|
137
|
+
'vibration': {'name': 'Vibration', 'category': 'Mechanical', 'solver': solve_vibration},
|
|
138
|
+
'weld-strength': {'name': 'Weld Strength', 'category': 'Mechanical', 'solver': solve_weld_strength},
|
|
139
|
+
'beam-deflection': {'name': 'Beam Deflection', 'category': 'Structural', 'solver': solve_beam_deflection},
|
|
140
|
+
'bearing-capacity': {'name': 'Bearing Capacity', 'category': 'Structural', 'solver': solve_bearing_capacity},
|
|
141
|
+
'column-buckling': {'name': 'Column Buckling', 'category': 'Structural', 'solver': solve_column_buckling},
|
|
142
|
+
'concrete-volume': {'name': 'Concrete Volume', 'category': 'Structural', 'solver': solve_concrete_volume},
|
|
143
|
+
'development-length': {'name': 'Development Length', 'category': 'Structural', 'solver': solve_development_length},
|
|
144
|
+
'earth-pressure': {'name': 'Earth Pressure', 'category': 'Structural', 'solver': solve_earth_pressure},
|
|
145
|
+
'failure-theory': {'name': 'Failure Theory', 'category': 'Structural', 'solver': solve_failure_theory},
|
|
146
|
+
'isolated-footing': {'name': 'Isolated Footing', 'category': 'Structural', 'solver': solve_isolated_footing},
|
|
147
|
+
'mohrs-circle': {'name': 'Mohr\'s Circle', 'category': 'Structural', 'solver': solve_mohrs_circle},
|
|
148
|
+
'rcc-beam': {'name': 'RCC Beam Design', 'category': 'Structural', 'solver': solve_rcc_beam},
|
|
149
|
+
'rcc-column': {'name': 'RCC Column Design', 'category': 'Structural', 'solver': solve_rcc_column},
|
|
150
|
+
'rcc-slab': {'name': 'RCC Slab Design', 'category': 'Structural', 'solver': solve_rcc_slab},
|
|
151
|
+
'reinforcement-qty': {'name': 'Reinforcement Qty', 'category': 'Structural', 'solver': solve_reinforcement_qty},
|
|
152
|
+
'settlement': {'name': 'Settlement', 'category': 'Structural', 'solver': solve_settlement},
|
|
153
|
+
'soil-properties': {'name': 'Soil Properties', 'category': 'Structural', 'solver': solve_soil_properties},
|
|
154
|
+
'steel-weight': {'name': 'Steel Weight', 'category': 'Structural', 'solver': solve_steel_weight},
|
|
155
|
+
'stress-strain': {'name': 'Stress Strain', 'category': 'Structural', 'solver': solve_stress_strain},
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
def compute(calculator_type: str, inputs: dict) -> dict:
|
|
159
|
+
"""Run a calculator engine and return results."""
|
|
160
|
+
calc = CALCULATORS.get(calculator_type)
|
|
161
|
+
if not calc:
|
|
162
|
+
available = ', '.join(CALCULATORS.keys())
|
|
163
|
+
raise ValueError(f"Unknown calculator: '{calculator_type}'. Available: {available}")
|
|
164
|
+
result = calc['solver'](inputs)
|
|
165
|
+
try:
|
|
166
|
+
display_result(calculator_type, calc['name'], inputs, result)
|
|
167
|
+
except Exception:
|
|
168
|
+
pass
|
|
169
|
+
return result
|
|
170
|
+
|
|
171
|
+
def convert(category: str, value: float, from_unit: str, to_unit: str) -> float:
|
|
172
|
+
"""Convert a value between units."""
|
|
173
|
+
result = convert_unit({
|
|
174
|
+
'category': category,
|
|
175
|
+
'value': value,
|
|
176
|
+
'fromUnit': from_unit,
|
|
177
|
+
'toUnit': to_unit,
|
|
178
|
+
})
|
|
179
|
+
if result is None:
|
|
180
|
+
raise ValueError(f"Cannot convert {from_unit} -> {to_unit} in category '{category}'")
|
|
181
|
+
return result['value']
|
|
182
|
+
|
|
183
|
+
def list_calculators() -> list:
|
|
184
|
+
"""List all available calculators."""
|
|
185
|
+
return [
|
|
186
|
+
{'id': k, 'name': v['name'], 'category': v['category']}
|
|
187
|
+
for k, v in CALCULATORS.items()
|
|
188
|
+
]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Phaxor — Rich Jupyter Notebook Display
|
|
3
|
+
Renders engineering results as styled HTML tables in Jupyter notebooks.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def display_result(calculator_type: str, name: str, inputs: dict, result: dict | None):
|
|
8
|
+
"""
|
|
9
|
+
Display a styled HTML table of results in Jupyter notebooks.
|
|
10
|
+
Falls back silently if not in a Jupyter environment.
|
|
11
|
+
"""
|
|
12
|
+
try:
|
|
13
|
+
from IPython.display import display, HTML
|
|
14
|
+
except ImportError:
|
|
15
|
+
return # Not in Jupyter
|
|
16
|
+
|
|
17
|
+
if result is None:
|
|
18
|
+
display(HTML(f"""
|
|
19
|
+
<div style="padding:16px;background:#1a1b26;border:1px solid #ef4444;border-radius:12px;
|
|
20
|
+
font-family:system-ui;color:#f87171;">
|
|
21
|
+
⚠️ <strong>{name}</strong> — Invalid inputs. Check your parameters.
|
|
22
|
+
</div>
|
|
23
|
+
"""))
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
# Filter out complex nested data for clean display
|
|
27
|
+
display_items = {}
|
|
28
|
+
for k, v in result.items():
|
|
29
|
+
if isinstance(v, (int, float)):
|
|
30
|
+
display_items[k] = f"{v:,.6g}"
|
|
31
|
+
elif isinstance(v, str):
|
|
32
|
+
display_items[k] = v
|
|
33
|
+
elif isinstance(v, bool):
|
|
34
|
+
display_items[k] = '✅ Yes' if v else '❌ No'
|
|
35
|
+
|
|
36
|
+
rows_html = ''.join(
|
|
37
|
+
f"""<tr>
|
|
38
|
+
<td style="padding:8px 12px;border-bottom:1px solid #2f334d;font-weight:600;color:#7aa2f7;
|
|
39
|
+
font-family:monospace;font-size:13px;">{k}</td>
|
|
40
|
+
<td style="padding:8px 12px;border-bottom:1px solid #2f334d;font-size:13px;">{v}</td>
|
|
41
|
+
</tr>"""
|
|
42
|
+
for k, v in display_items.items()
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
html = f"""
|
|
46
|
+
<div style="font-family:'Inter',system-ui,sans-serif;max-width:600px;margin:12px 0;">
|
|
47
|
+
<div style="background:#1a1b26;border:1px solid #2f334d;border-radius:12px;overflow:hidden;">
|
|
48
|
+
<div style="padding:14px 16px;background:linear-gradient(135deg,#22d3ee22,#a855f722);
|
|
49
|
+
display:flex;align-items:center;gap:8px;">
|
|
50
|
+
<div style="width:8px;height:8px;border-radius:50%;background:#22d3ee;"></div>
|
|
51
|
+
<strong style="color:#c0caf5;font-size:15px;">{name}</strong>
|
|
52
|
+
<span style="margin-left:auto;font-size:10px;color:#565f89;">Phaxor v1.0</span>
|
|
53
|
+
</div>
|
|
54
|
+
<table style="width:100%;border-collapse:collapse;color:#c0caf5;">
|
|
55
|
+
{rows_html}
|
|
56
|
+
</table>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
"""
|
|
60
|
+
display(HTML(html))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Engine sub-package."""
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Phaxor — Atomic Packing Factor Engine (Python port)"""
|
|
2
|
+
import math
|
|
3
|
+
|
|
4
|
+
def solve_apf(inputs: dict) -> dict | None:
|
|
5
|
+
"""APF Calculator."""
|
|
6
|
+
structure = inputs.get('structure', 'BCC')
|
|
7
|
+
radius = float(inputs.get('radius', 0))
|
|
8
|
+
molar_mass = float(inputs.get('molarMass', 0))
|
|
9
|
+
|
|
10
|
+
if radius <= 0 or molar_mass <= 0:
|
|
11
|
+
return None
|
|
12
|
+
|
|
13
|
+
na = 6.022e23
|
|
14
|
+
n = 0
|
|
15
|
+
apf = 0.0
|
|
16
|
+
a = 0.0
|
|
17
|
+
v_nm3 = 0.0
|
|
18
|
+
|
|
19
|
+
if structure == 'SC':
|
|
20
|
+
n = 1
|
|
21
|
+
apf = 0.5236
|
|
22
|
+
a = 2 * radius
|
|
23
|
+
v_nm3 = a ** 3
|
|
24
|
+
elif structure == 'BCC':
|
|
25
|
+
n = 2
|
|
26
|
+
apf = 0.6802
|
|
27
|
+
a = 4 * radius / math.sqrt(3)
|
|
28
|
+
v_nm3 = a ** 3
|
|
29
|
+
elif structure == 'FCC':
|
|
30
|
+
n = 4
|
|
31
|
+
apf = 0.7405
|
|
32
|
+
a = 2 * math.sqrt(2) * radius
|
|
33
|
+
v_nm3 = a ** 3
|
|
34
|
+
elif structure == 'HCP':
|
|
35
|
+
n = 6
|
|
36
|
+
apf = 0.7405
|
|
37
|
+
a = 2 * radius
|
|
38
|
+
v_nm3 = 3 * math.sqrt(2) * (a ** 3)
|
|
39
|
+
elif structure == 'Diamond':
|
|
40
|
+
n = 8
|
|
41
|
+
apf = 0.3401
|
|
42
|
+
a = 8 * radius / math.sqrt(3)
|
|
43
|
+
v_nm3 = a ** 3
|
|
44
|
+
|
|
45
|
+
v_cm3 = v_nm3 * 1e-21
|
|
46
|
+
rho = (n * molar_mass) / (na * v_cm3) if v_cm3 > 0 else 0
|
|
47
|
+
void_frac = 1.0 - apf
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
'apf': apf,
|
|
51
|
+
'a': float(f"{a:.4f}"),
|
|
52
|
+
'rho': float(f"{rho:.2f}"),
|
|
53
|
+
'V_nm3': float(f"{v_nm3:.4f}"),
|
|
54
|
+
'n': n,
|
|
55
|
+
'voidFrac': float(f"{void_frac:.3f}")
|
|
56
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Phaxor — Arrhenius Engine (Python port)"""
|
|
2
|
+
import math
|
|
3
|
+
|
|
4
|
+
R_GAS = 8.314
|
|
5
|
+
|
|
6
|
+
def solve_arrhenius(inputs: dict) -> dict | None:
|
|
7
|
+
"""Arrhenius Equation Calculator."""
|
|
8
|
+
a = float(inputs.get('A', 0))
|
|
9
|
+
ea = float(inputs.get('Ea', 0))
|
|
10
|
+
t1 = float(inputs.get('T1', 0))
|
|
11
|
+
t2 = float(inputs.get('T2', 0))
|
|
12
|
+
|
|
13
|
+
if a <= 0 or ea <= 0 or t1 <= 0:
|
|
14
|
+
return None
|
|
15
|
+
|
|
16
|
+
k1 = a * math.exp(-ea / (R_GAS * t1))
|
|
17
|
+
k2 = a * math.exp(-ea / (R_GAS * t2)) if t2 > 0 else 0
|
|
18
|
+
ratio = k2 / k1 if (k2 > 0 and k1 > 0) else 0
|
|
19
|
+
|
|
20
|
+
slope = -ea / R_GAS
|
|
21
|
+
half_life = math.log(2) / k1 if k1 > 0 else 0
|
|
22
|
+
|
|
23
|
+
plot_data = []
|
|
24
|
+
t_min = max(200, t1 - 200)
|
|
25
|
+
t_max = max(t2 + 200, t1 + 200) if t2 > 0 else t1 + 400
|
|
26
|
+
step = (t_max - t_min) / 50
|
|
27
|
+
|
|
28
|
+
curr_t = t_min
|
|
29
|
+
while curr_t <= t_max:
|
|
30
|
+
if curr_t > 0:
|
|
31
|
+
k_val = a * math.exp(-ea / (R_GAS * curr_t))
|
|
32
|
+
plot_data.append({
|
|
33
|
+
'invT': float(f"{1000/curr_t:.4f}"),
|
|
34
|
+
'lnk': float(f"{math.log(k_val):.3f}"),
|
|
35
|
+
'T': int(curr_t)
|
|
36
|
+
})
|
|
37
|
+
curr_t += step
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
'k1': k1,
|
|
41
|
+
'k2': k2,
|
|
42
|
+
'ratio': float(f"{ratio:.2f}"),
|
|
43
|
+
'slope': float(f"{slope:.2f}"),
|
|
44
|
+
'halfLife1st': half_life,
|
|
45
|
+
'plotData': plot_data
|
|
46
|
+
}
|