8686//! }
8787//! ```
8888
89- use anyhow:: { bail, Result } ;
9089use crate :: fuga:: ConvToMat ;
90+ use crate :: traits:: math:: { InnerProduct , Norm , Normed , Vector } ;
9191use crate :: util:: non_macro:: eye;
92- use crate :: traits :: math :: { Norm , Normed , InnerProduct , Vector } ;
92+ use anyhow :: { bail , Result } ;
9393
9494/// Trait for defining an ODE problem.
9595///
@@ -367,7 +367,10 @@ impl<BU: ButcherTableau> ODEIntegrator for BU {
367367/// In MATLAB, it is called `ode3`.
368368#[ derive( Debug , Clone , Copy , Default ) ]
369369#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
370- #[ cfg_attr( feature = "rkyv" , derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize ) ) ]
370+ #[ cfg_attr(
371+ feature = "rkyv" ,
372+ derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize )
373+ ) ]
371374pub struct RALS3 ;
372375
373376impl ButcherTableau for RALS3 {
@@ -383,7 +386,10 @@ impl ButcherTableau for RALS3 {
383386/// It calculates four intermediate values (k1, k2, k3, k4) to estimate the next step solution.
384387#[ derive( Debug , Clone , Copy , Default ) ]
385388#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
386- #[ cfg_attr( feature = "rkyv" , derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize ) ) ]
389+ #[ cfg_attr(
390+ feature = "rkyv" ,
391+ derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize )
392+ ) ]
387393pub struct RK4 ;
388394
389395impl ButcherTableau for RK4 {
@@ -398,7 +404,10 @@ impl ButcherTableau for RK4 {
398404/// This fourth order method is known as minimum truncation error RK4.
399405#[ derive( Debug , Clone , Copy , Default ) ]
400406#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
401- #[ cfg_attr( feature = "rkyv" , derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize ) ) ]
407+ #[ cfg_attr(
408+ feature = "rkyv" ,
409+ derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize )
410+ ) ]
402411pub struct RALS4 ;
403412
404413impl ButcherTableau for RALS4 {
@@ -418,7 +427,10 @@ impl ButcherTableau for RALS4 {
418427/// This integrator uses the 5th order Runge-Kutta method to numerically integrate the ODE system.
419428#[ derive( Debug , Clone , Copy , Default ) ]
420429#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
421- #[ cfg_attr( feature = "rkyv" , derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize ) ) ]
430+ #[ cfg_attr(
431+ feature = "rkyv" ,
432+ derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize )
433+ ) ]
422434pub struct RK5 ;
423435
424436impl ButcherTableau for RK5 {
@@ -478,7 +490,10 @@ impl ButcherTableau for RK5 {
478490/// - `max_step_iter`: The maximum number of iterations per step.
479491#[ derive( Debug , Clone , Copy ) ]
480492#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
481- #[ cfg_attr( feature = "rkyv" , derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize ) ) ]
493+ #[ cfg_attr(
494+ feature = "rkyv" ,
495+ derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize )
496+ ) ]
482497pub struct BS23 {
483498 pub tol : f64 ,
484499 pub safety_factor : f64 ,
@@ -560,7 +575,10 @@ impl ButcherTableau for BS23 {
560575/// - `max_step_iter`: The maximum number of iterations per step.
561576#[ derive( Debug , Clone , Copy ) ]
562577#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
563- #[ cfg_attr( feature = "rkyv" , derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize ) ) ]
578+ #[ cfg_attr(
579+ feature = "rkyv" ,
580+ derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize )
581+ ) ]
564582pub struct RKF45 {
565583 pub tol : f64 ,
566584 pub safety_factor : f64 ,
@@ -663,7 +681,10 @@ impl ButcherTableau for RKF45 {
663681/// - `max_step_iter`: The maximum number of iterations per step.
664682#[ derive( Debug , Clone , Copy ) ]
665683#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
666- #[ cfg_attr( feature = "rkyv" , derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize ) ) ]
684+ #[ cfg_attr(
685+ feature = "rkyv" ,
686+ derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize )
687+ ) ]
667688pub struct DP45 {
668689 pub tol : f64 ,
669690 pub safety_factor : f64 ,
@@ -785,7 +806,10 @@ impl ButcherTableau for DP45 {
785806/// - Ch. Tsitouras, Comput. Math. Appl. 62 (2011) 770-780.
786807#[ derive( Debug , Clone , Copy ) ]
787808#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
788- #[ cfg_attr( feature = "rkyv" , derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize ) ) ]
809+ #[ cfg_attr(
810+ feature = "rkyv" ,
811+ derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize )
812+ ) ]
789813pub struct TSIT45 {
790814 pub tol : f64 ,
791815 pub safety_factor : f64 ,
@@ -916,7 +940,10 @@ impl ButcherTableau for TSIT45 {
916940/// - Meysam Mahooti (2025). [Runge-Kutta-Fehlberg (RKF78)](https://www.mathworks.com/matlabcentral/fileexchange/61130-runge-kutta-fehlberg-rkf78), MATLAB Central File Exchange.
917941#[ derive( Debug , Clone , Copy ) ]
918942#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
919- #[ cfg_attr( feature = "rkyv" , derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize ) ) ]
943+ #[ cfg_attr(
944+ feature = "rkyv" ,
945+ derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize )
946+ ) ]
920947pub struct RKF78 {
921948 pub tol : f64 ,
922949 pub safety_factor : f64 ,
@@ -986,11 +1013,35 @@ impl ButcherTableau for RKF78 {
9861013 // k6
9871014 & [ 1.0 / 20.0 , 0.0 , 0.0 , 5.0 / 20.0 , 4.0 / 20.0 ] ,
9881015 // k7
989- & [ -25.0 / 108.0 , 0.0 , 0.0 , 125.0 / 108.0 , -260.0 / 108.0 , 250.0 / 108.0 ] ,
1016+ & [
1017+ -25.0 / 108.0 ,
1018+ 0.0 ,
1019+ 0.0 ,
1020+ 125.0 / 108.0 ,
1021+ -260.0 / 108.0 ,
1022+ 250.0 / 108.0 ,
1023+ ] ,
9901024 // k8
991- & [ 31.0 / 300.0 , 0.0 , 0.0 , 0.0 , 61.0 / 225.0 , -2.0 / 9.0 , 13.0 / 900.0 ] ,
1025+ & [
1026+ 31.0 / 300.0 ,
1027+ 0.0 ,
1028+ 0.0 ,
1029+ 0.0 ,
1030+ 61.0 / 225.0 ,
1031+ -2.0 / 9.0 ,
1032+ 13.0 / 900.0 ,
1033+ ] ,
9921034 // k9
993- & [ 2.0 , 0.0 , 0.0 , -53.0 / 6.0 , 704.0 / 45.0 , -107.0 / 9.0 , 67.0 / 90.0 , 3.0 ] ,
1035+ & [
1036+ 2.0 ,
1037+ 0.0 ,
1038+ 0.0 ,
1039+ -53.0 / 6.0 ,
1040+ 704.0 / 45.0 ,
1041+ -107.0 / 9.0 ,
1042+ 67.0 / 90.0 ,
1043+ 3.0 ,
1044+ ] ,
9941045 // k10
9951046 & [
9961047 -91.0 / 108.0 ,
@@ -1051,7 +1102,7 @@ impl ButcherTableau for RKF78 {
10511102 // BU_i = BE_i (8th order) - ErrorCoeff_i
10521103 // ErrorCoeff_i = [-41/840, 0, ..., 0, -41/840 (for k11), 41/840 (for k12), 41/840 (for k13)]
10531104 const BU : & ' static [ f64 ] = & [
1054- 41.0 / 420.0 , // 41/840 - (-41/840)
1105+ 41.0 / 420.0 , // 41/840 - (-41/840)
10551106 0.0 ,
10561107 0.0 ,
10571108 0.0 ,
@@ -1110,7 +1161,10 @@ impl ButcherTableau for RKF78 {
11101161/// Currently, there are two options: fixed-point iteration and Broyden's method.
11111162#[ derive( Debug , Clone , Copy ) ]
11121163#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
1113- #[ cfg_attr( feature = "rkyv" , derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize ) ) ]
1164+ #[ cfg_attr(
1165+ feature = "rkyv" ,
1166+ derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize )
1167+ ) ]
11141168pub enum ImplicitSolver {
11151169 FixedPoint ,
11161170 Broyden ,
@@ -1130,7 +1184,10 @@ pub enum ImplicitSolver {
11301184/// - `max_step_iter`: The maximum number of iterations for the implicit solver per step.
11311185#[ derive( Debug , Clone , Copy ) ]
11321186#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
1133- #[ cfg_attr( feature = "rkyv" , derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize ) ) ]
1187+ #[ cfg_attr(
1188+ feature = "rkyv" ,
1189+ derive( rkyv:: Archive , rkyv:: Serialize , rkyv:: Deserialize )
1190+ ) ]
11341191pub struct GL4 {
11351192 pub solver : ImplicitSolver ,
11361193 pub tol : f64 ,
@@ -1203,7 +1260,7 @@ impl ODEIntegrator for GL4 {
12031260 break ;
12041261 }
12051262 }
1206- } ,
1263+ }
12071264 ImplicitSolver :: Broyden => {
12081265 let m = 2 * n;
12091266 let mut U = vec ! [ 0.0 ; m] ;
@@ -1219,7 +1276,7 @@ impl ODEIntegrator for GL4 {
12191276 y2. copy_from_slice ( y) ;
12201277 problem. rhs ( t + c * dt, & y1, & mut k1) ?;
12211278 problem. rhs ( t + d * dt, & y2, & mut k2) ?;
1222- for i in 0 .. n {
1279+ for i in 0 .. n {
12231280 U [ i] = k1[ i] ;
12241281 U [ n + i] = k2[ i] ;
12251282 }
@@ -1233,12 +1290,14 @@ impl ODEIntegrator for GL4 {
12331290 let mut J_inv = eye ( m) ;
12341291
12351292 // Repeat Broyden's method
1236- for _ in 0 .. self . max_step_iter {
1293+ for _ in 0 .. self . max_step_iter {
12371294 // delta = - J_inv * F_vec
12381295 let mut delta = ( & J_inv * & F_vec ) . mul_scalar ( -1.0 ) ;
12391296
12401297 // U <- U + delta
1241- U . iter_mut ( ) . zip ( delta. iter_mut ( ) ) . for_each ( |( u, d) | * u += * d) ;
1298+ U . iter_mut ( )
1299+ . zip ( delta. iter_mut ( ) )
1300+ . for_each ( |( u, d) | * u += * d) ;
12421301
12431302 let mut F_new = vec ! [ 0.0 ; m] ;
12441303 compute_F ( problem, t, y, dt, c, d, sqrt3, & U , & mut F_new ) ?;
@@ -1268,11 +1327,11 @@ impl ODEIntegrator for GL4 {
12681327 }
12691328
12701329 // Extract k1 and k2
1271- for i in 0 .. n {
1330+ for i in 0 .. n {
12721331 k1[ i] = U [ i] ;
12731332 k2[ i] = U [ n + i] ;
12741333 }
1275- } ,
1334+ }
12761335 }
12771336
12781337 for i in 0 ..n {
0 commit comments