1 个不稳定版本
0.1.0 | 2021年7月16日 |
---|
#199 在 模拟 中
17KB
190 行
SSSF - 超级简单的模拟框架
这是一个允许您编写 Rust 物理模拟而无需繁琐和重复样板代码的 crate。我因为大学课程需要编写大量的物理模拟而创建了它,现在我想分享,因为它非常优雅,可能对类似情况的人有用。它非常适合小型物理模拟,但我认为它也适用于大型项目,尽管在大型项目中,为您的特定问题创建一个定制的解决方案可能是一个好主意。
使用方法
假设您想构建一个在 x-y 平面上以恒定速度移动的身体的模拟。那么您需要创建一个结构体,它为每个时间步长保存有关该身体的信息
BodyParameters{
t: f32 // time,
x: f32,
y: f32,
v_x: f32,
v_y: f32,
}
这些参数将在每个时间步长之后存储为历史记录,这就是为什么我们在 BodyParameters
中添加了 t
字段来跟踪位置(x、
y
)和速度(V_x、
v_y
)随时间变化的历史记录。现在我们已经处理了我们想要保存历史记录的参数,我们可以转向那些在整个模拟过程中保持不变的参数,或者我们不需要/想要保存历史记录的参数——例如,我们不会想为每个时间步长保存康威生命游戏的整个网格——我们将在没有历史记录的参数中保存它。所以回到移动身体的例子。我们可以把这些参数视为我们不想跟踪的环境。
EnvironmentParameters{
dt: f32
}
为了这个示例,我们不需要存储任何复杂的内容,所以让我们只存储 dt
- 时间增量。之后,我们可以开始模拟,提供 BodyParameters、
EnvironmentParameters 和模拟的步函数,如下所示
let mut simulation = SimManger::new(
BodyParameters { t: 0., x: 0., y:0., v_x:1., v_y:1. }, // Initial parameters for the body
EnvironmentParameters { dt: 0.1 },
|body_parameteres, environment_parameters| BodyParameters { // Defining step function
t: body_parameters.t + environment_parameters.dt,
x: body_parameters.x + environment_parameters.dt * body_parameters.v_x,
y: body_parameters.y + environment_parameters.dt * body_parameters.v_y,
v_x: body_parameters.v_x,
v_y: body_parameters.v_y,
},
);
如上图所示,您需要提供 step_fn: FnMut(&BodyParameters, &mut EnvironmentParameters) ->BodyParameters
函数,它在此模拟步骤后必须返回 BodyParameters
,它们将被自动保存。现在,为了运行模拟,您需要调用 .run(stop_fn)
,其中 stop_fn: Fn(&DynamicParameters, &EnvironmentParameters) -> bool
是一个简单的函数,在每个时间步之后进行检查。如果为真,则模拟停止。例如。
如果您想在 t = 5 s
时停止模拟,请调用
模拟.运行(|body_parameters, _environment_parameters| body_parameters.t== 5.);
如果您想在 x = 20 m
时停止模拟,请调用
模拟.运行(|body_parameters, _environment_parameters| body_parameters.x== 20.);
写入文件
将模拟历史记录保存到文件以便进一步分析,制作一些漂亮的图表等非常有用。在这种情况下,您希望为 BodyParameters
实现 ToCSV
特性。我不想使用 serde
进行序列化,因为我希望这个框架非常轻量级,并且实际上并不需要。您可以像这样实现 ToCSV
impl ToCSV for BodyParameters {
fn get_header() -> String {
String::from("t,x,y") // Header for .csv file (don't contain "\n" in this string, it's added automatically)
}
fn get_row(&self) -> String {
format!("{},{},{}", self.t, self.x, self.y) // Contents of .csv file (don't contain "\n" in this string, it's added automatically)
}
}
然后,您不能像调用 .run(stop_fn)
一样调用,而是需要这样调用
simulation.to_file(PathBuf::from(r"output.csv"))
.run_with_save(stop_fn);
依赖项
~8KB