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次下载

MIT 许可证

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_orthofrom_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