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
// Copyright (c) 2020-2022 David Sorokin <davsor@mail.ru>, based in Yoshkar-Ola, Russia
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use crate::simulation::generator::GeneratorType;
/// It represents the simulation specs.
#[derive(Clone)]
pub struct Specs {
/// The start simulation time.
pub start_time: f64,
/// The final simulation time.
pub stop_time: f64,
/// The integration time step.
pub dt: f64,
/// The type of random number generator.
pub generator_type: GeneratorType
}
impl Specs {
/// Return the indexed time value in the grid by the specified index and size,
/// where the index changes within `[0, size)`. Index 0 corresponds to the start time,
/// but the index with value `size-1` corresponds to the stop time.
#[inline]
pub fn grid_time(&self, index: usize, size: usize) -> f64 {
let t0 = self.start_time;
let t2 = self.stop_time;
let n2 = if size <= 1 { 1 } else { size - 1 };
let dt2 = (t2 - t0) / (n2 as f64);
if index == 0 { t0 } else {
if index == n2 { t2 } else {
t0 + (index as f64) * dt2
}
}
}
/// Return the grid index that would correspond the specified modeling time.
#[inline]
pub fn grid_index(&self, t: f64, size: usize) -> usize {
let t0 = self.start_time;
let t2 = self.stop_time;
let n2 = if size <= 1 { 1 } else { size - 1 };
if t == t0 {
0
} else if t == t2 {
n2
} else {
let dt = (t2 - t0) / (n2 as f64);
((t - t0) / dt).floor() as usize
}
}
}
/// It represents the simulation specs representation.
#[repr(C)]
pub struct SpecsRepr {
/// The start simulation time.
pub start_time: f64,
/// The final simulation time.
pub stop_time: f64,
/// The integration time step.
pub dt: f64
}
impl From<Specs> for SpecsRepr {
fn from(specs: Specs) -> Self {
SpecsRepr {
start_time: specs.start_time,
stop_time: specs.stop_time,
dt: specs.dt
}
}
}
impl SpecsRepr {
/// Return the indexed time value in the grid by the specified index and size,
/// where the index changes within `[0, size)`. Index 0 corresponds to the start time,
/// but the index with value `size-1` corresponds to the stop time.
#[inline]
pub fn grid_time(&self, index: usize, size: usize) -> f64 {
let t0 = self.start_time;
let t2 = self.stop_time;
let n2 = if size <= 1 { 1 } else { size - 1 };
let dt2 = (t2 - t0) / (n2 as f64);
if index == 0 { t0 } else {
if index == n2 { t2 } else {
t0 + (index as f64) * dt2
}
}
}
/// Return the grid index that would correspond the specified modeling time.
#[inline]
pub fn grid_index(&self, t: f64, size: usize) -> usize {
let t0 = self.start_time;
let t2 = self.stop_time;
let n2 = if size <= 1 { 1 } else { size - 1 };
if t == t0 {
0
} else if t == t2 {
n2
} else {
let dt = (t2 - t0) / (n2 as f64);
((t - t0) / dt).floor() as usize
}
}
}