sciforge 0.0.3

A comprehensive scientific computing library in pure Rust with zero dependencies
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
//! Dispatch handler for PDE solver functions.

use super::super::params::*;
use crate::hub::domain::common::errors::{HubError, HubResult};
use crate::hub::domain::maths;
use crate::hub::engine::experience::runner::RunOutput;

pub(super) fn dispatch(func: &str, p: &Params) -> HubResult<RunOutput> {
    match func {
        "heat_equation_1d_explicit" => Ok(RunOutput::Vector(
            maths::pde::diffusion::heat_equation_1d_explicit(
                get_v(p, "u")?,
                get_f(p, "dx")?,
                get_f(p, "dt")?,
                get_f(p, "alpha")?,
            ),
        )),
        "heat_equation_1d_implicit" => Ok(RunOutput::Vector(
            maths::pde::diffusion::heat_equation_1d_implicit(
                get_v(p, "u")?,
                get_f(p, "dx")?,
                get_f(p, "dt")?,
                get_f(p, "alpha")?,
            ),
        )),
        "heat_equation_1d_crank_nicolson" => Ok(RunOutput::Vector(
            maths::pde::diffusion::heat_equation_1d_crank_nicolson(
                get_v(p, "u")?,
                get_f(p, "dx")?,
                get_f(p, "dt")?,
                get_f(p, "alpha")?,
            ),
        )),
        "diffusion_2d_explicit" => Ok(RunOutput::Matrix(
            maths::pde::diffusion::diffusion_2d_explicit(
                get_m(p, "u")?,
                get_f(p, "dx")?,
                get_f(p, "dy")?,
                get_f(p, "dt")?,
                get_f(p, "alpha")?,
            ),
        )),
        "stability_criterion_explicit" => Ok(RunOutput::Scalar(
            maths::pde::diffusion::stability_criterion_explicit(
                get_f(p, "dx")?,
                get_f(p, "alpha")?,
            ),
        )),
        "diffusion_green_function" => Ok(RunOutput::Scalar(
            maths::pde::diffusion::diffusion_green_function(
                get_f(p, "x")?,
                get_f(p, "t")?,
                get_f(p, "alpha")?,
            ),
        )),
        "advection_diffusion_1d" => Ok(RunOutput::Vector(
            maths::pde::diffusion::advection_diffusion_1d(
                get_v(p, "u")?,
                get_f(p, "dx")?,
                get_f(p, "dt")?,
                get_f(p, "alpha")?,
                get_f(p, "velocity")?,
            ),
        )),
        "diffusion_reaction_1d" => Ok(RunOutput::Vector(
            maths::pde::diffusion::diffusion_reaction_1d(
                get_v(p, "u")?,
                get_f(p, "dx")?,
                get_f(p, "dt")?,
                get_f(p, "alpha")?,
                get_f(p, "reaction_rate")?,
            ),
        )),
        "fisher_kpp_step" => Ok(RunOutput::Vector(maths::pde::diffusion::fisher_kpp_step(
            get_v(p, "u")?,
            get_f(p, "dx")?,
            get_f(p, "dt")?,
            get_f(p, "d")?,
            get_f(p, "r")?,
        ))),
        "nonlinear_diffusion_1d" => Ok(RunOutput::Vector(
            maths::pde::diffusion::nonlinear_diffusion_1d(
                get_v(p, "u")?,
                get_f(p, "dx")?,
                get_f(p, "dt")?,
                get_f(p, "m")?,
            ),
        )),
        "diffusion_2d_adi" => Ok(RunOutput::Matrix(maths::pde::diffusion::diffusion_2d_adi(
            get_m(p, "u")?,
            get_f(p, "dx")?,
            get_f(p, "dy")?,
            get_f(p, "dt")?,
            get_f(p, "alpha")?,
        ))),
        "stability_criterion_2d" => Ok(RunOutput::Scalar(
            maths::pde::diffusion::stability_criterion_2d(
                get_f(p, "dx")?,
                get_f(p, "dy")?,
                get_f(p, "alpha")?,
            ),
        )),
        "peclet_number" => Ok(RunOutput::Scalar(maths::pde::diffusion::peclet_number(
            get_f(p, "velocity")?,
            get_f(p, "length")?,
            get_f(p, "diffusivity")?,
        ))),
        "diffusion_steady_state_1d" => Ok(RunOutput::Vector(
            maths::pde::diffusion::diffusion_steady_state_1d(
                get_u(p, "n")?,
                get_f(p, "left_bc")?,
                get_f(p, "right_bc")?,
            ),
        )),
        "diffusion_analytical_finite" => Ok(RunOutput::Scalar(
            maths::pde::diffusion::diffusion_analytical_finite(
                get_f(p, "x")?,
                get_f(p, "t")?,
                get_f(p, "alpha")?,
                get_f(p, "length")?,
                get_u(p, "terms")?,
            ),
        )),
        "mass_conservation_check" => Ok(RunOutput::Scalar(
            maths::pde::diffusion::mass_conservation_check(get_v(p, "u")?, get_f(p, "dx")?),
        )),
        "diffusion_coefficient_from_msd" => Ok(RunOutput::Scalar(
            maths::pde::diffusion::diffusion_coefficient_from_msd(
                get_f(p, "msd")?,
                get_f(p, "time")?,
                get_i(p, "dimensions")? as u32,
            ),
        )),

        "wave_equation_1d" => Ok(RunOutput::Vector(maths::pde::wave::wave_equation_1d(
            get_v(p, "u")?,
            get_v(p, "u_prev")?,
            get_f(p, "dx")?,
            get_f(p, "dt")?,
            get_f(p, "c")?,
        ))),
        "wave_initial_step" => Ok(RunOutput::Vector(maths::pde::wave::wave_initial_step(
            get_v(p, "u")?,
            get_v(p, "v0")?,
            get_f(p, "dx")?,
            get_f(p, "dt")?,
            get_f(p, "c")?,
        ))),
        "wave_equation_2d" => Ok(RunOutput::Matrix(maths::pde::wave::wave_equation_2d(
            get_m(p, "u")?,
            get_m(p, "u_prev")?,
            get_f(p, "dx")?,
            get_f(p, "dy")?,
            get_f(p, "dt")?,
            get_f(p, "c")?,
        ))),
        "courant_number" => Ok(RunOutput::Scalar(maths::pde::wave::courant_number(
            get_f(p, "c")?,
            get_f(p, "dt")?,
            get_f(p, "dx")?,
        ))),
        "wave_energy_density" => Ok(RunOutput::Vector(maths::pde::wave::wave_energy_density(
            get_v(p, "u")?,
            get_v(p, "u_prev")?,
            get_f(p, "dx")?,
            get_f(p, "dt")?,
            get_f(p, "c")?,
            get_f(p, "rho")?,
        ))),
        "absorbing_boundary" => {
            let mut u = get_v(p, "u")?.to_vec();
            maths::pde::wave::absorbing_boundary(
                &mut u,
                get_v(p, "u_prev")?,
                get_f(p, "dx")?,
                get_f(p, "dt")?,
                get_f(p, "c")?,
            );
            Ok(RunOutput::Vector(u))
        }
        "string_vibration_mode" => Ok(RunOutput::Scalar(maths::pde::wave::string_vibration_mode(
            get_f(p, "x")?,
            get_f(p, "length")?,
            get_i(p, "mode")? as u32,
        ))),
        "wave_equation_1d_implicit" => Ok(RunOutput::Vector(
            maths::pde::wave::wave_equation_1d_implicit(
                get_v(p, "u")?,
                get_v(p, "u_prev")?,
                get_f(p, "dx")?,
                get_f(p, "dt")?,
                get_f(p, "c")?,
            ),
        )),
        "cfl_check" => Ok(RunOutput::Boolean(maths::pde::wave::cfl_check(
            get_f(p, "c")?,
            get_f(p, "dt")?,
            get_f(p, "dx")?,
        ))),
        "wave_reflection_coefficient" => Ok(RunOutput::Scalar(
            maths::pde::wave::wave_reflection_coefficient(get_f(p, "z1")?, get_f(p, "z2")?),
        )),
        "wave_transmission_coefficient" => Ok(RunOutput::Scalar(
            maths::pde::wave::wave_transmission_coefficient(get_f(p, "z1")?, get_f(p, "z2")?),
        )),
        "standing_wave" => Ok(RunOutput::Scalar(maths::pde::wave::standing_wave(
            get_f(p, "x")?,
            get_f(p, "t")?,
            get_f(p, "k")?,
            get_f(p, "omega")?,
            get_f(p, "amplitude")?,
        ))),
        "wave_phase_velocity" => Ok(RunOutput::Scalar(maths::pde::wave::wave_phase_velocity(
            get_f(p, "omega")?,
            get_f(p, "k")?,
        ))),
        "wave_group_velocity" => Ok(RunOutput::Scalar(maths::pde::wave::wave_group_velocity(
            get_f(p, "domega")?,
            get_f(p, "dk")?,
        ))),
        "wave_total_energy" => Ok(RunOutput::Scalar(maths::pde::wave::wave_total_energy(
            get_v(p, "u")?,
            get_v(p, "u_prev")?,
            get_f(p, "dx")?,
            get_f(p, "dt")?,
            get_f(p, "c")?,
            get_f(p, "rho")?,
        ))),
        "spherical_wave_amplitude" => Ok(RunOutput::Scalar(
            maths::pde::wave::spherical_wave_amplitude(
                get_f(p, "r")?,
                get_f(p, "amplitude_0")?,
                get_f(p, "r0")?,
            ),
        )),
        "wave_packet_gaussian" => Ok(RunOutput::Scalar(maths::pde::wave::wave_packet_gaussian(
            get_f(p, "x")?,
            get_f(p, "t")?,
            get_f(p, "k0")?,
            get_f(p, "sigma")?,
            get_f(p, "omega")?,
        ))),
        "wave_superposition" => Ok(RunOutput::Scalar(maths::pde::wave::wave_superposition(
            get_f(p, "x")?,
            get_f(p, "t")?,
            get_v(p, "amplitudes")?,
            get_v(p, "frequencies")?,
            get_v(p, "wave_numbers")?,
        ))),
        "wave_impedance" => Ok(RunOutput::Scalar(maths::pde::wave::wave_impedance(
            get_f(p, "density")?,
            get_f(p, "velocity")?,
        ))),

        "laplace_jacobi" => Ok(RunOutput::Matrix(maths::pde::laplace::laplace_jacobi(
            get_m(p, "u")?,
            get_u(p, "max_iter")?,
            get_f(p, "tol")?,
        ))),
        "laplace_gauss_seidel" => Ok(RunOutput::Matrix(
            maths::pde::laplace::laplace_gauss_seidel(
                get_m(p, "u")?,
                get_u(p, "max_iter")?,
                get_f(p, "tol")?,
            ),
        )),
        "laplace_sor" => Ok(RunOutput::Matrix(maths::pde::laplace::laplace_sor(
            get_m(p, "u")?,
            get_f(p, "omega")?,
            get_u(p, "max_iter")?,
            get_f(p, "tol")?,
        ))),
        "optimal_sor_omega" => Ok(RunOutput::Scalar(maths::pde::laplace::optimal_sor_omega(
            get_u(p, "nx")?,
            get_u(p, "ny")?,
        ))),
        "poisson_jacobi" => Ok(RunOutput::Matrix(maths::pde::laplace::poisson_jacobi(
            get_m(p, "u")?,
            get_m(p, "f_rhs")?,
            get_f(p, "dx")?,
            get_f(p, "dy")?,
            get_u(p, "max_iter")?,
            get_f(p, "tol")?,
        ))),
        "pde_residual_norm" => Ok(RunOutput::Scalar(maths::pde::laplace::residual_norm(
            get_m(p, "u")?,
            get_m(p, "f_rhs")?,
            get_f(p, "dx")?,
            get_f(p, "dy")?,
        ))),
        "harmonic_function_disk" => Ok(RunOutput::Scalar(
            maths::pde::laplace::harmonic_function_disk(
                get_f(p, "r")?,
                get_f(p, "theta")?,
                get_v(p, "a")?,
                get_v(p, "b")?,
                get_f(p, "radius")?,
            ),
        )),
        "poisson_gauss_seidel" => Ok(RunOutput::Matrix(
            maths::pde::laplace::poisson_gauss_seidel(
                get_m(p, "u")?,
                get_m(p, "f_rhs")?,
                get_f(p, "dx")?,
                get_f(p, "dy")?,
                get_u(p, "max_iter")?,
                get_f(p, "tol")?,
            ),
        )),
        "poisson_sor" => Ok(RunOutput::Matrix(maths::pde::laplace::poisson_sor(
            get_m(p, "u")?,
            get_m(p, "f_rhs")?,
            get_f(p, "dx")?,
            get_f(p, "dy")?,
            get_f(p, "omega")?,
            get_u(p, "max_iter")?,
            get_f(p, "tol")?,
        ))),
        "max_principle_check" => Ok(RunOutput::Boolean(
            maths::pde::laplace::max_principle_check(get_m(p, "phi")?),
        )),
        "greens_function_2d_free" => Ok(RunOutput::Scalar(
            maths::pde::laplace::greens_function_2d_free(
                get_f(p, "x")?,
                get_f(p, "y")?,
                get_f(p, "xs")?,
                get_f(p, "ys")?,
            ),
        )),
        "mean_value_property" => Ok(RunOutput::Scalar(maths::pde::laplace::mean_value_property(
            get_m(p, "phi")?,
            get_u(p, "ci")?,
            get_u(p, "cj")?,
            get_u(p, "radius")?,
        ))),
        "laplace_3d_jacobi" => {
            let u3d: Vec<Vec<Vec<f64>>> = get_m(p, "u")?
                .iter()
                .map(|layer| vec![layer.clone()])
                .collect();
            let r = maths::pde::laplace::laplace_3d_jacobi(
                &u3d,
                get_u(p, "max_iter")?,
                get_f(p, "tol")?,
            );
            Ok(RunOutput::Matrix(r.into_iter().flatten().collect()))
        }
        "dirichlet_energy" => Ok(RunOutput::Scalar(maths::pde::laplace::dirichlet_energy(
            get_m(p, "phi")?,
            get_f(p, "dx")?,
            get_f(p, "dy")?,
        ))),
        "laplace_iteration_count" => Ok(RunOutput::Integer(
            maths::pde::laplace::laplace_iteration_count(
                get_m(p, "u")?,
                get_u(p, "max_iter")?,
                get_f(p, "tol")?,
            ) as i64,
        )),

        "first_derivative" => Ok(RunOutput::Vector(
            maths::pde::finite_diff::first_derivative(get_v(p, "f")?, get_f(p, "dx")?),
        )),
        "second_derivative" => Ok(RunOutput::Vector(
            maths::pde::finite_diff::second_derivative(get_v(p, "f")?, get_f(p, "dx")?),
        )),
        "fourth_order_first_derivative" => Ok(RunOutput::Vector(
            maths::pde::finite_diff::fourth_order_first_derivative(get_v(p, "f")?, get_f(p, "dx")?),
        )),
        "laplacian_2d" => Ok(RunOutput::Matrix(maths::pde::finite_diff::laplacian_2d(
            get_m(p, "u")?,
            get_f(p, "dx")?,
            get_f(p, "dy")?,
        ))),
        "gradient_2d" => {
            let (gx, gy) = maths::pde::finite_diff::gradient_2d(
                get_m(p, "u")?,
                get_f(p, "dx")?,
                get_f(p, "dy")?,
            );
            Ok(RunOutput::Matrix(vec![
                gx.into_iter().flatten().collect(),
                gy.into_iter().flatten().collect(),
            ]))
        }
        "divergence_2d" => Ok(RunOutput::Matrix(maths::pde::finite_diff::divergence_2d(
            get_m(p, "fx")?,
            get_m(p, "fy")?,
            get_f(p, "dx")?,
            get_f(p, "dy")?,
        ))),
        "curl_2d" => Ok(RunOutput::Matrix(maths::pde::finite_diff::curl_2d(
            get_m(p, "fx")?,
            get_m(p, "fy")?,
            get_f(p, "dx")?,
            get_f(p, "dy")?,
        ))),
        "upwind_advection" => Ok(RunOutput::Vector(
            maths::pde::finite_diff::upwind_advection(
                get_v(p, "u")?,
                get_f(p, "v")?,
                get_f(p, "dx")?,
                get_f(p, "dt")?,
            ),
        )),
        "lax_wendroff" => Ok(RunOutput::Vector(maths::pde::finite_diff::lax_wendroff(
            get_v(p, "u")?,
            get_f(p, "c")?,
            get_f(p, "dx")?,
            get_f(p, "dt")?,
        ))),
        "third_derivative" => Ok(RunOutput::Vector(
            maths::pde::finite_diff::third_derivative(get_v(p, "f")?, get_f(p, "dx")?),
        )),
        "mixed_partial_xy" => Ok(RunOutput::Matrix(
            maths::pde::finite_diff::mixed_partial_xy(
                get_m(p, "u")?,
                get_f(p, "dx")?,
                get_f(p, "dy")?,
            ),
        )),
        "compact_fourth_order" => Ok(RunOutput::Vector(
            maths::pde::finite_diff::compact_fourth_order(get_v(p, "f")?, get_f(p, "dx")?),
        )),
        "von_neumann_stability" => Ok(RunOutput::Boolean(
            maths::pde::finite_diff::von_neumann_stability(get_f(p, "amplification_factor")?),
        )),
        "boundary_ghost_extrapolate" => Ok(RunOutput::Vector(
            maths::pde::finite_diff::boundary_ghost_extrapolate(get_v(p, "u")?),
        )),
        "hessian_2d" => {
            let h = maths::pde::finite_diff::hessian_2d(
                get_m(p, "u")?,
                get_f(p, "dx")?,
                get_f(p, "dy")?,
                get_u(p, "i")?,
                get_u(p, "j")?,
            );
            Ok(RunOutput::Matrix(vec![
                vec![h[0][0], h[0][1]],
                vec![h[1][0], h[1][1]],
            ]))
        }
        "biharmonic_2d" => Ok(RunOutput::Matrix(maths::pde::finite_diff::biharmonic_2d(
            get_m(p, "u")?,
            get_f(p, "dx")?,
            get_f(p, "dy")?,
        ))),
        "lax_friedrichs" => Ok(RunOutput::Vector(maths::pde::finite_diff::lax_friedrichs(
            get_v(p, "u")?,
            get_f(p, "c")?,
            get_f(p, "dx")?,
            get_f(p, "dt")?,
        ))),
        "maccormack" => Ok(RunOutput::Vector(maths::pde::finite_diff::maccormack(
            get_v(p, "u")?,
            get_f(p, "c")?,
            get_f(p, "dx")?,
            get_f(p, "dt")?,
        ))),

        _ => Err(HubError::InvalidInput(format!("unknown function: {func}"))),
    }
}