DiffSL
Thus far we have used Rust code to specify the problem we want to solve. This is fine if you are using DiffSol from Rust, but what if you want to use DiffSol from a higher-level language like Python or R? For this usecase we have designed a Domain Specific Language (DSL) called DiffSL that can be used to specify the problem. DiffSL is not a general purpose language but is tightly constrained to the specification of a system of ordinary differential equations. It features a relativly simple syntax that consists of writing a series of tensors (dense or sparse) that represent the equations of the system. For more detail on the syntax of DiffSL see the DiffSL book. This section will focus on how to use DiffSL to specify a problem in DiffSol.
DiffSL Context
The main struct that is used to specify a problem in DiffSL is the DiffSlContext
struct. Creating this struct
Just-In-Time (JIT) compiles your DiffSL code into a form that can be executed efficiently by DiffSol.
fn main() { use diffsol::{DiffSl, CraneliftModule}; type M = nalgebra::DMatrix<f64>; type CG = CraneliftModule; let eqn = DiffSl::<M, CG>::compile(" in = [r, k] r { 1.0 } k { 1.0 } u { 0.1 } F { r * u * (1.0 - u / k) } out { u } ").unwrap(); }
Once you have created the DiffSlContext
struct you can use it to create a problem using the build_diffsl
method on the OdeBuilder
struct.
fn main() { use diffsol::{DiffSl, CraneliftModule}; use diffsol::{OdeBuilder, Bdf, OdeSolverMethod, OdeSolverState}; type M = nalgebra::DMatrix<f64>; type CG = CraneliftModule; let eqn = DiffSl::<M, CG>::compile(" in = [r, k] r { 1.0 } k { 1.0 } u { 0.1 } F { r * u * (1.0 - u / k) } out { u } ").unwrap(); let problem = OdeBuilder::new() .rtol(1e-6) .p([1.0, 10.0]) .build_from_eqn(eqn).unwrap(); let mut solver = Bdf::default(); let t = 0.4; let state = OdeSolverState::new(&problem, &solver).unwrap(); let _soln = solver.solve(&problem, state, t).unwrap(); }