scirs2_integrate/dae/
types.rs

1//! Types for DAE solver module
2//!
3//! This module defines the core types used by DAE solvers,
4//! including method enums, options, and results.
5
6use crate::common::IntegrateFloat;
7use crate::ode::ODEMethod;
8use scirs2_core::ndarray::Array1;
9
10/// DAE system type
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
12pub enum DAEType {
13    /// Semi-explicit index-1 DAE of the form:
14    /// x' = f(x, y, t)
15    /// 0 = g(x, y, t)
16    #[default]
17    SemiExplicit,
18
19    /// Fully implicit index-1 DAE of the form:
20    /// F(x', x, t) = 0
21    FullyImplicit,
22}
23
24/// DAE index classification
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
26pub enum DAEIndex {
27    /// Index-1 (differentiate once to get an ODE)
28    #[default]
29    Index1,
30    /// Index-2 (differentiate twice)
31    Index2,
32    /// Index-3 (differentiate three times)
33    Index3,
34    /// Higher-index (differentiate more than three times)
35    HigherIndex,
36}
37
38/// Options for controlling the behavior of DAE solvers
39#[derive(Debug, Clone)]
40pub struct DAEOptions<F: IntegrateFloat> {
41    /// The DAE system type
42    pub dae_type: DAEType,
43
44    /// The DAE index (classification)
45    pub index: DAEIndex,
46
47    /// The ODE solver method to use for the differential part
48    pub method: ODEMethod,
49
50    /// Relative tolerance for error control
51    pub rtol: F,
52
53    /// Absolute tolerance for error control
54    pub atol: F,
55
56    /// Initial step size (optional, if not provided, it will be estimated)
57    pub h0: Option<F>,
58
59    /// Maximum number of steps to take
60    pub max_steps: usize,
61
62    /// Maximum step size (optional)
63    pub max_step: Option<F>,
64
65    /// Minimum step size (optional)
66    pub min_step: Option<F>,
67
68    /// Maximum iterations for the nonlinear solver
69    pub max_newton_iterations: usize,
70
71    /// Tolerance for the nonlinear solver
72    pub newton_tol: F,
73
74    /// Maximum BDF order (optional, defaults to 5)
75    pub max_order: Option<usize>,
76}
77
78impl<F: IntegrateFloat> Default for DAEOptions<F> {
79    fn default() -> Self {
80        DAEOptions {
81            dae_type: DAEType::default(),
82            index: DAEIndex::default(),
83            method: ODEMethod::Radau, // Use Radau by default, as it's suitable for index-1 DAEs
84            rtol: F::from_f64(1e-3).unwrap(),
85            atol: F::from_f64(1e-6).unwrap(),
86            h0: None,
87            max_steps: 500,
88            max_step: None,
89            min_step: None,
90            max_newton_iterations: 10,
91            newton_tol: F::from_f64(1e-8).unwrap(),
92            max_order: None,
93        }
94    }
95}
96
97/// Result of DAE integration
98#[derive(Debug, Clone)]
99pub struct DAEResult<F: IntegrateFloat> {
100    /// Time points
101    pub t: Vec<F>,
102
103    /// Solution values for differential variables at time points
104    pub x: Vec<Array1<F>>,
105
106    /// Solution values for algebraic variables at time points
107    pub y: Vec<Array1<F>>,
108
109    /// Whether the integration was successful
110    pub success: bool,
111
112    /// Status message
113    pub message: Option<String>,
114
115    /// Number of function evaluations
116    pub n_eval: usize,
117
118    /// Number of constraint evaluations
119    pub n_constraint_eval: usize,
120
121    /// Number of steps taken
122    pub n_steps: usize,
123
124    /// Number of accepted steps
125    pub n_accepted: usize,
126
127    /// Number of rejected steps
128    pub n_rejected: usize,
129
130    /// Number of LU decompositions
131    pub n_lu: usize,
132
133    /// Number of Jacobian evaluations
134    pub n_jac: usize,
135
136    /// The solver method used
137    pub method: ODEMethod,
138
139    /// The DAE type
140    pub dae_type: DAEType,
141
142    /// The DAE index
143    pub index: DAEIndex,
144}