2 个版本
0.2.1 | 2022年6月19日 |
---|---|
0.2.0 | 2022年4月7日 |
#278 在 科学
485KB
9K SLoC
经典晶格量子场论模拟和工具。
这个库提供了一个在晶格上模拟纯规范 SU(3) 理论的工具。它旨在提供通用的工具,以便可以使用多种不同的模拟或方法。您可以轻松选择蒙特卡洛算法,您可以实现自己的哈密顿量等。它还提供了一种在 1 到 usize::MAX
维度之间进行模拟的简单方法。因此,这个库不仅限于 d = 3 或 d = 4。
查看我的其他仓库 plaquette,这是我在研究中使用的模拟二进制文件集。
功能:
- 通用维度;
- 可配置的蒙特卡洛算法;
- 多平台;
- 可配置的哈密顿量;
- Serde 支持;
- 原生 Rust;
- 一些统计工具;
尚未实现的功能:
- 更多的统计工具;
- 费米子支持;
- SU(N) 支持;
- 配置文件;
- C 兼容的 API / ABI;
使用方法
将 lattice_qcd_rs = { version = "0.2.1", git = "https://github.com/ABouttefeux/lattice_qcd_rs" }
添加到您的 cargo.toml
。默认启用的功能集包括
serde-serialize
允许在结构中使用 serde;no-overflow-test
用于禁用覆盖范围的溢出测试。
目前它不在 crates.io 上。也许我会添加它。但到目前为止,它仍在开发中。请注意,您可能需要指定特定的提交,因为现在我可能会引入破坏性变更。然而,一旦我准备好发布版本 0.2.0
,我将致力于更高的稳定性。
首先,让我们看看如何在10x10x10x10的晶格上使用beta = 1进行模拟。我们想要计算在经过一定步数后所有面砖迹线的 1/3 <Re(Tr(P_{ij}))>
。在我们的例子中,Beta值较小,所以我们选择了100,000步。
extern crate lattice_qcd_rs as lq;
extern crate rand_xoshiro;
use lq::prelude::*;
# use std::error::Error;
# fn main() -> Result<(), Box<dyn Error>> {
let mut rng = rand_xoshiro::Xoshiro256PlusPlus::from_entropy();
let size = 1000_f64;
let number_of_pts = 10;
let beta = 1_f64;
let mut simulation =
LatticeStateDefault::<4>::new_determinist(size, beta, number_of_pts, &mut rng)?;
let spread_parameter = 0.1_f64;
let mut mc = MetropolisHastingsDeltaDiagnostic::new(spread_parameter, rng)?;
for _ in 0..100 {
for _ in 0..1_000 {
simulation = simulation.monte_carlo_step(&mut mc)?;
}
// the more we advance te more the link matrices
// will deviate form SU(3), so we reprojet to SU(3)
// every 1_000 steps.
simulation.normalize_link_matrices();
}
let average = simulation.average_trace_plaquette().ok_or(ImplementationError::Unreachable)?.real() / 3_f64;
# Ok(())
# }
这个库使用rayon作为并行计算的一种方式。但是并不是所有事情都可以并行化。如果您想要进行多次类似的模拟(例如,您想对Beta = 1、1.1、1.2等进行模拟),请使用rayon。为了进行多次并行模拟。
需要更具体的例子吗?请查看我的其他仓库 plaquette。它包含了我用于研究的二进制文件。
我想做自己的事情。
我想使用自己的哈密顿量
实现 LatticeState
特性。
如果您想使用 hybride Monte Carlo 使用您自己的状态,您将需要为 LatticeStateEFSyncDefault<YourState>
实现 LatticeStateWithEField
。
我想使用自己的蒙特卡罗算法。
我提供了两种算法: Metropolis Hastings 和 hybride Monte Carlo。
查看 MonteCarlo
特性,或者也可以查看 MonteCarloDefault
。
MonteCarloDefault
可以更容易实现,但请注意,每次我们为之前和新的状态进行步骤时,都会重新计算整个哈密顿量,这可能会导致计算增量哈密顿量较慢。
要使用 MonteCarloDefault
作为 MonteCarlo
,有一个包装器: MCWrapper
。
为什么?
这是一些用于我博士论文的代码。主要我使用 arXiv:0707.2458、arXiv:0902.28568 和 arXiv:2010.07316 作为基础。
目标
目标是提供一个易于使用、快速且安全的库,用于进行经典晶格模拟。
关于随机数生成器(RNGs)的讨论
此库在任何需要随机数生成器时都会使用特性 rand::RngCore
。RNG的选择由库的用户决定。然而,需要考虑一些权衡。
让我们将不同的生成器分为几类。更多详情请参阅 https://rust-random.github.io/book/guide-gen.html。
一些可能的选择
- 推荐
rand_xoshiro::Xoshiro256PlusPlus
非密码学。它具有良好的性能和统计质量,可重放,并且具有有用的jump
函数。它是推荐的 PRNG。 rand::rngs::ThreadRng
是一个 CSPRNG。数据不可重放,并且经常重新播种。然而,它的速度较慢。rand::rngs::StdRng
是加密安全的,可以播种。它是确定性的,但不同平台之间不可重放。然而,它的速度较慢。rand_jitter::JitterRng
是真正的 RNG,但速度非常慢。
此外,ranlux 也是一个不错的选择。但是,据我所知,没有本地的 Rust 实现它(除了我的,但速度非常慢)。
其他示例
use lattice_qcd_rs::{
error::ImplementationError,
ComplexField,
simulation::monte_carlo::MetropolisHastingsDeltaDiagnostic,
simulation::state::{LatticeState, LatticeStateDefault},
};
# use std::error::Error;
# fn main() -> Result<(), Box<dyn Error>> {
let mut rng = rand::thread_rng();
let size = 1_000_f64;
let number_of_pts = 4;
let beta = 2_f64;
let mut simulation =
LatticeStateDefault::<4>::new_determinist(size, beta, number_of_pts, &mut rng)?;
let spread_parameter = 1E-5_f64;
let mut mc = MetropolisHastingsDeltaDiagnostic::new(spread_parameter, rng)
.ok_or(ImplementationError::OptionWithUnexpectedNone)?;
let number_of_sims = 100;
for _ in 0..number_of_sims / 10 {
for _ in 0..10 {
simulation = simulation.monte_carlo_step(&mut mc)?;
}
simulation.normalize_link_matrices(); // we renormalize all matrices back to SU(3);
}
let average = simulation.average_trace_plaquette()
.ok_or(ImplementationError::OptionWithUnexpectedNone)?
.real();
# Ok(())
# }
或者可以使用其他蒙特卡洛算法,例如
use lattice_qcd_rs::{
error::ImplementationError,
simulation::monte_carlo::{McWrapper, MetropolisHastingsDiagnostic},
simulation::state::{LatticeState, LatticeStateDefault},
};
# use std::error::Error;
# fn main() -> Result<(), Box<dyn Error>> {
let mut rng = rand::thread_rng();
let size = 1_000_f64;
let number_of_pts = 4;
let beta = 2_f64;
let mut simulation =
LatticeStateDefault::<3>::new_determinist(size, beta, number_of_pts, &mut rng)?;
let number_of_rand = 20;
let spread_parameter = 1E-5_f64;
let mut mc = McWrapper::new(
MetropolisHastingsDiagnostic::new(number_of_rand, spread_parameter)
.ok_or(ImplementationError::OptionWithUnexpectedNone)?,
rng,
);
simulation = simulation.monte_carlo_step(&mut mc)?;
simulation.normalize_link_matrices();
# Ok(())
# }
或者
use lattice_qcd_rs::{
integrator::SymplecticEulerRayon,
simulation::monte_carlo::HybridMonteCarloDiagnostic,
simulation::state::{LatticeState, LatticeStateDefault},
};
# use std::error::Error;
# fn main() -> Result<(), Box<dyn Error>> {
let mut rng = rand::thread_rng();
let size = 1_000_f64;
let number_of_pts = 4;
let beta = 2_f64;
let mut simulation =
LatticeStateDefault::<3>::new_determinist(size, beta, number_of_pts, &mut rng)?;
let delta_t = 1E-3_f64;
let number_of_step = 10;
let mut mc =
HybridMonteCarloDiagnostic::new(delta_t, number_of_step, SymplecticEulerRayon::new(), rng);
simulation = simulation.monte_carlo_step(&mut mc)?;
simulation.normalize_link_matrices();
# Ok(())
# }
依赖项
~6MB
~125K SLoC