R Integration¶
This example demonstrates how to use fluids from R.
Source Code¶
1
2# Install and load reticulate
3library(reticulate)
4
5# Function to run all tests
6test_fluids <- function() {
7 tryCatch({
8 # 1. Test import
9 fluids <- import("fluids")
10 print("✓ Successfully imported fluids")
11
12 # 2. Test version access
13 version <- py_get_attr(fluids, "__version__")
14 print(paste("✓ Fluids version:", version))
15
16 # 3. Test basic Reynolds number calculation
17 Re <- fluids$Reynolds(V=2.5, D=0.1, rho=1000, mu=0.001)
18 print(paste("✓ Reynolds number calculation successful:", Re))
19 stopifnot(Re > 0) # Basic sanity check
20
21 # 4. Test friction factor calculation
22 fd <- fluids$friction_factor(Re=1e5, eD=0.0001)
23 print(paste("✓ Friction factor calculation successful:", fd))
24 stopifnot(fd > 0 && fd < 1) # Basic range check
25
26 print("\nAll tests completed successfully!")
27
28 }, error = function(e) {
29 print(paste("Error occurred:", e$message))
30 stop("Test suite failed")
31 })
32}
33test_atmosphere <- function() {
34 tryCatch({
35 fluids <- import("fluids")
36 # Test ATMOSPHERE_1976 class
37 atm <- fluids$ATMOSPHERE_1976(Z=5000)
38
39 # Test basic properties
40 print("Testing atmosphere at 5000m elevation:")
41 print(paste("✓ Temperature:", round(atm$T, 4)))
42 print(paste("✓ Pressure:", round(atm$P, 4)))
43 print(paste("✓ Density:", round(atm$rho, 6)))
44
45 # Test derived properties
46 print(paste("✓ Gravity:", round(atm$g, 6)))
47 print(paste("✓ Viscosity:", formatC(atm$mu, format="e", digits=6)))
48 print(paste("✓ Thermal conductivity:", round(atm$k, 6)))
49 print(paste("✓ Sonic velocity:", round(atm$v_sonic, 4)))
50
51 # Test static methods
52 g_high <- fluids$ATMOSPHERE_1976$gravity(Z=1E5)
53 print(paste("✓ High altitude gravity:", round(g_high, 6)))
54
55 v_sonic <- fluids$ATMOSPHERE_1976$sonic_velocity(T=300)
56 print(paste("✓ Sonic velocity at 300K:", round(v_sonic, 4)))
57
58 mu_400 <- fluids$ATMOSPHERE_1976$viscosity(T=400)
59 print(paste("✓ Viscosity at 400K:", formatC(mu_400, format="e", digits=6)))
60
61 k_400 <- fluids$ATMOSPHERE_1976$thermal_conductivity(T=400)
62 print(paste("✓ Thermal conductivity at 400K:", round(k_400, 6)))
63 }, error = function(e) {
64 print(paste("Error in atmosphere tests:", e$message))
65 stop("Atmosphere test suite failed")
66 })
67}
68test_tank <- function() {
69 tryCatch({
70 fluids <- import("fluids")
71 # Test basic tank creation
72 T1 <- fluids$TANK(V=10, L_over_D=0.7, sideB='conical', horizontal=FALSE)
73 print("\nTesting tank calculations:")
74 print(paste("✓ Tank length:", round(T1$L, 6)))
75 print(paste("✓ Tank diameter:", round(T1$D, 6)))
76
77 # Test ellipsoidal tank
78 tank_ellip <- fluids$TANK(D=10, V=500, horizontal=FALSE,
79 sideA='ellipsoidal', sideB='ellipsoidal',
80 sideA_a=1, sideB_a=1)
81 print(paste("✓ Ellipsoidal tank L:", round(tank_ellip$L, 6)))
82
83 # Test torispherical tank
84 DIN <- fluids$TANK(L=3, D=5, horizontal=FALSE,
85 sideA='torispherical', sideB='torispherical',
86 sideA_f=1, sideA_k=0.1, sideB_f=1, sideB_k=0.1)
87 print(paste("✓ Tank representation:", capture.output(print(DIN))))
88 print(paste("✓ Tank max height:", round(DIN$h_max, 6)))
89 print(paste("✓ Height at V=40:", round(DIN$h_from_V(40), 6)))
90 print(paste("✓ Volume at h=4.1:", round(DIN$V_from_h(4.1), 5)))
91 print(paste("✓ Surface area at h=2.1:", round(DIN$SA_from_h(2.1), 5)))
92
93 }, error = function(e) {
94 print(paste("Error in tank tests:", e$message))
95 stop("Tank test suite failed")
96 })
97}
98# Test function for Reynolds number calculations
99test_reynolds <- function() {
100 tryCatch({
101 print("\nTesting Reynolds number calculations:")
102 fluids <- import("fluids")
103
104 # Test with density and viscosity
105 Re1 <- fluids$Reynolds(V=2.5, D=0.25, rho=1.1613, mu=1.9E-5)
106 print(paste("✓ Re (with rho, mu):", round(Re1, 4)))
107 stopifnot(abs(Re1 - 38200.6579) < 0.1)
108
109 # Test with kinematic viscosity
110 Re2 <- fluids$Reynolds(V=2.5, D=0.25, nu=1.636e-05)
111 print(paste("✓ Re (with nu):", round(Re2, 4)))
112 stopifnot(abs(Re2 - 38202.934) < 0.1)
113
114 }, error = function(e) {
115 print(paste("Error in Reynolds tests:", e$message))
116 stop("Reynolds test suite failed")
117 })
118}
119
120# Test function for particle size distributions
121test_psd <- function() {
122 tryCatch({
123 print("\nTesting particle size distribution functionality:")
124 fluids <- import("fluids")
125
126 # Create a discrete PSD
127 ds <- c(240, 360, 450, 562.5, 703, 878, 1097, 1371, 1713, 2141, 2676, 3345, 4181, 5226, 6532)
128 numbers <- c(65, 119, 232, 410, 629, 849, 990, 981, 825, 579, 297, 111, 21, 1)
129
130 psd <- fluids$particle_size_distribution$ParticleSizeDistribution(
131 ds=ds,
132 fractions=numbers,
133 order=0
134 )
135 print("✓ Created discrete PSD")
136
137 # Test mean sizes
138 d21 <- psd$mean_size(2, 1)
139 print(paste("✓ Size-weighted mean diameter:", round(d21, 4)))
140 stopifnot(abs(d21 - 1857.788) < 0.1)
141
142 d10 <- psd$mean_size(1, 0)
143 print(paste("✓ Arithmetic mean diameter:", round(d10, 4)))
144 stopifnot(abs(d10 - 1459.372) < 0.1)
145
146 # Test percentile calculations
147 d10_percentile <- psd$dn(0.1)
148 d90_percentile <- psd$dn(0.9)
149 print(paste("✓ D10:", round(d10_percentile, 4)))
150 print(paste("✓ D90:", round(d90_percentile, 4)))
151
152 # Test probability functions
153 pdf_val <- psd$pdf(1000)
154 cdf_val <- psd$cdf(5000)
155 print(paste("✓ PDF at 1000:", formatC(pdf_val, format="e", digits=4)))
156 print(paste("✓ CDF at 5000:", round(cdf_val, 6)))
157
158 # Test lognormal distribution
159 psd_log <- fluids$particle_size_distribution$PSDLognormal(s=0.5, d_characteristic=5E-6)
160 print("✓ Created lognormal PSD")
161
162 vssa <- psd_log$vssa
163 print(paste("✓ Volume specific surface area:", round(vssa, 2)))
164
165 span <- psd_log$dn(0.9) - psd_log$dn(0.1)
166 print(paste("✓ Span:", formatC(span, format="e", digits=4)))
167
168 ratio_7525 <- psd_log$dn(0.75)/psd_log$dn(0.25)
169 print(paste("✓ D75/D25 ratio:", round(ratio_7525, 6)))
170
171 }, error = function(e) {
172 print(paste("Error in PSD tests:", e$message))
173 stop("PSD test suite failed")
174 })
175}
176benchmark_fluids <- function() {
177 fluids <- import("fluids")
178 cat("\nRunning benchmarks:\n")
179
180 # Benchmark friction factor calculation
181 cat("\nBenchmarking friction_factor:\n")
182 t1 <- system.time({
183 for(i in 1:10000) {
184 fluids$friction_factor(Re=1e5, eD=0.0001)
185 }
186 })
187 cat(sprintf("Time for 10000 friction_factor calls: %.6f seconds\n", t1["elapsed"]))
188 cat(sprintf("Average time per call: %.6f seconds\n", t1["elapsed"]/10000))
189
190 # Benchmark tank creation
191 cat("\nBenchmarking TANK creation:\n")
192 t2 <- system.time({
193 for(i in 1:1000) {
194 fluids$TANK(L=3, D=5, horizontal=FALSE,
195 sideA="torispherical", sideB="torispherical",
196 sideA_f=1, sideA_k=0.1, sideB_f=1, sideB_k=0.1)
197 }
198 })
199 cat(sprintf("Time for 1000 TANK creations: %.6f seconds\n", t2["elapsed"]))
200 cat(sprintf("Average time per creation: %.6f seconds\n", t2["elapsed"]/1000))
201}
202
203# Run the tests
204test_fluids()
205test_atmosphere()
206test_tank()
207test_reynolds()
208test_psd()
209benchmark_fluids()
Requirements¶
Python with fluids installed
reticulate https://cran.r-project.org/web/packages/reticulate/index.html
Usage Notes¶
The example demonstrates basic integration with fluids
90 microsecond friction factor, 170 microsecond tank creation observed by author