10 个不稳定版本 (3 个破坏性更新)
0.4.0 | 2022年4月12日 |
---|---|
0.3.1 | 2022年3月28日 |
0.2.3 | 2021年10月28日 |
0.2.2 | 2021年9月1日 |
0.1.2 | 2021年7月30日 |
#661 在 算法
每月33次下载
325KB
6.5K SLoC
funspace
Funspace
函数空间集合。基础
名称 | 变换类型 | 正交 | 边界条件 | 链接 |
---|---|---|---|---|
Chebyshev |
R2r | 是 | 无 | [chebyshev() ] |
ChebDirichlet |
R2r | 否 | u(-1) = u(1) = 0 | [cheb_dirichlet() ] |
ChebNeumann |
R2r | 否 | u'(-1) = u'(1) = 0 | [cheb_neumann() ] |
ChebDirichletNeumann |
R2r | 否 | u(-1) = u'(1) = 0 | [cheb_dirichlet_neumann() ] |
ChebBiHarmonicA |
R2r | 否 | u(-1) = u'(-1) = u(1)= u'(1) = 0 | [cheb_biharmonic_a() ] |
ChebBiHarmonicB |
R2r | 否 | u(-1) = u''(-1) = u(1)= u''(1) = 0 | [cheb_biharmonic_b() ] |
FourierR2c |
R2c | 是 | 周期性 | [fourier_r2c() ] |
FourierC2c |
C2c | 是 | 周期性 | [fourier_c2c() ] |
变换
变换描述了从物理值到频谱系数的转换,反之亦然。例如,函数的傅里叶变换给出了代表正弦函数的复值系数。切比雪夫变换给出了实值频谱系数,代表切比雪夫多项式。变换是通过 BaseTransform
特性实现的。
示例
在 cheb_dirichlet
空间中应用一维数组的正向变换
use funspace::traits::BaseTransform;
use funspace::cheb_dirichlet;
use ndarray::{Array1, array};
let mut cd = cheb_dirichlet::<f64>(5);
let input = array![1., 2., 3., 4., 5.];
let output: Array1<f64> = cd.forward(&input, 0);
微分
光谱空间的微分通常既高效又非常准确。傅里叶空间的微分成为谱系数与波数向量的简单乘法。切比雪夫空间的微分通过递推关系进行,几乎与傅里叶空间一样快。每个基都实现了一种微分方法,该方法应用于系数数组。这由BaseGradient
特质定义。
示例
微分
use funspace::fourier_r2c;
use funspace::traits::{BaseTransform, BaseElements, BaseGradient};
use ndarray::Array1;
use num_complex::Complex;
// Define base
let mut fo = fourier_r2c(8);
// Get coordinates in physical space
let x: Vec<f64> = fo.coords().clone();
let v: Array1<f64> = x
.iter()
.map(|x| (2. * x).sin())
.collect::<Vec<f64>>()
.into();
// Transform to physical space
let vhat: Array1<Complex<f64>> = fo.forward(&v, 0);
// Apply differentiation twice along first axis
let dvhat = fo.gradient(&vhat, 2, 0);
// Transform back to spectral space
let dv: Array1<f64> = fo.backward(&dvhat, 0);
// Compare with correct derivative
for (exp, ist) in x
.iter()
.map(|x| -4. * (2. * x).sin())
.collect::<Vec<f64>>()
.iter()
.zip(dv.iter())
{
assert!((exp - ist).abs() < 1e-5);
}
正交和组合基
傅里叶多项式或切比雪夫多项式的函数空间被认为是正交的,即其集中每个多项式与其他任何多项式的点积为零。在这种情况下,质量矩阵是一个纯对角矩阵。然而,可以通过正交基函数的线性组合构造其他函数空间,即它们是组合基。通过这种方式,可以构造满足某些边界条件(如Dirichlet(u(x0) = 0)或Neumann(u'(x0) = 0))的函数空间。这用于求解偏微分方程(参见加里金方法)。
要将其组合形式切换到正交形式,每个基都实现了一个BaseFromOrtho
特质,该特质定义了转换to_ortho
和from_ortho
。如果基已经是正交的,则返回输入,否则它从组合空间转换到正交空间(to_ortho
),反之亦然(from_ortho
)。请注意,组合空间的大小m通常小于其正交对应物n,即光谱表示的系数更少。换句话说,组合空间是正交空间的低维子空间。
示例
将组合空间cheb_dirichlet
转换为它的正交对应物chebyshev
。请注意,cheb_dirichlet
有6个谱系数,而chebyshev
基有8个。
use funspace::traits::{BaseTransform, BaseElements, BaseFromOrtho};
use funspace::{cheb_dirichlet, chebyshev};
use std::f64::consts::PI;
use ndarray::prelude::*;
use ndarray::Array1;
use num_complex::Complex;
// Define base
let ch = chebyshev(8);
let cd = cheb_dirichlet(8);
// Get coordinates
let x: Vec<f64> = ch.coords().clone();
let v: Array1<f64> = x
.iter()
.map(|x| (PI / 2. * x).cos())
.collect::<Vec<f64>>()
.into();
// Transform to spectral space
let ch_vhat: Array1<f64> = ch.forward(&v, 0);
let cd_vhat: Array1<f64> = cd.forward(&v, 0);
// Send array to orthogonal space (cheb_dirichlet -> chebyshev)
let cd_vhat_ortho = cd.to_ortho(&cd_vhat, 0);
// Both arrays are equal, because field was
// initialized with dirichlet boundary conditions.
for (exp, ist) in ch_vhat.iter().zip(cd_vhat_ortho.iter()) {
assert!((exp - ist).abs() < 1e-5);
}
// However, if the function values do not satisfy
// dirichlet boundary conditions, they will
// be enforced by the transform to the cheb_dirichlet function
// space, thus the transformed values will deviate
// from a pure chebyshev transform (which does not
// enfore the boundary conditions).
let mut v: Array1<f64> = x
.iter()
.map(|x| (PI / 2. * x).sin())
.collect::<Vec<f64>>()
.into();
let ch_vhat: Array1<f64> = ch.forward(&v, 0);
let cd_vhat: Array1<f64> = cd.forward(&v, 0);
let cd_vhat_ortho = cd.to_ortho(&cd_vhat, 0);
// They will deviate
println!("chebyshev : {:?}", ch_vhat);
println!("cheb_dirichlet: {:?}", cd_vhat_ortho);
MPI支持(功能)
Funspace
附带有限的mpi支持。目前这仅限于2D空间。底层它使用rust mpi库的一个分支 https://github.com/rsmpi/rsmpi,该库需要现有的MPI实现和libclang
。
在您的Cargo.toml
中激活此功能
funspace = {version = "0.4", features = ["mpi"]}
示例
examples/space_mpi.rs
安装cargo mpirun
,然后
cargo mpirun --np 2 --example space_mpi --features="mpi"
版本
- v0.4.0: 主要API更改 + 新方法
- v0.3.0: 主要API更改 + 性能改进
许可证:MIT
依赖关系
~6.5MB
~127K SLoC