funspace
Funspace
Bases
Implemented bases:
Chebyshev
(Orthogonal), see [chebyshev()
]ChebDirichlet
(Composite), see [cheb_dirichlet()
]ChebNeumann
(Composite), see [cheb_neumann()
]ChebDirichletNeumann
(Composite), see [cheb_dirichlet_neumann()
]FourierC2c
(Orthogonal), see [fourier_c2c()
]FourierR2c
(Orthogonal), see [fourier_r2c()
]
Transform
A transformation describes a change from physical space to functional space.
For example, a Fourier transform transforms a function
on a equispaced grid into coefficients of sine/cosine polynomials.
This is analogous to other function spaces. The transformations are
implemented by the [FunspaceElemental
] trait.
Example
Apply forward transform of 1d array in cheb_dirichlet
space
use FunspaceElemental;
use cheb_dirichlet;
use ;
let mut cd = ;
let input = array!;
let output: = cd.forward;
Differentiation
An essential advantage of the representation of a function with coefficients in
the function space is its ease of differentiation. Differentiation in
Fourier space becomes multiplication with the wavenumber vector.
Differentiation in Chebyshev space is done by a recurrence
relation and almost as fast as in Fourier space.
Each base implements a differentiation method, which is applied to
an array of coefficents. This is defined by the [FunspaceElemental
] trait.
Example
Apply differentiation
use fourier_r2c;
use ;
use Array1;
use Complex;
// Define base
let mut fo = fourier_r2c;
// Get coordinates in physical space
let x: = fo.get_nodes.clone;
let v: = x
.iter
.map
.
.into;
// Transform to physical space
let vhat: = fo.forward;
// Apply differentiation twice along first axis
let dvhat = fo.differentiate;
// Transform back to spectral space
let dv: = fo.backward;
// Compare with correct derivative
for in x
.iter
.map
.
.iter
.zip
Composite Bases
Function spaces such as those of Fourier polynomials or Chebyshev polynomials are are considered orthogonal, i.e. the dot product of every single polynomial with any other polynomial in its set vanishes. In this cases the mass matrix is a purely diagonal matrix. However, other function spaces can be constructed by a linear combination of the orthogonal basis functions. In this way, bases can be constructed that satisfy certain boundary conditions such as Dirichlet (zero at the ends) or Neumann (zero derivative at the ends). This is useful for solving partial differential equations (see Galerkin method), since calculation in these bases automatically satisfy the boundary conditions.
To switch from its composite form to the orthogonal form, each base implements
a [FunspaceElemental
] trait, which defines the transform to_ortho
and from_ortho
.
If the base is already orthogonal, the input will be returned, otherwise it
is transformed from the composite space to the orthogonal space (to_ortho
), or vice versa
(from_ortho
).
Note that the size of the composite space is usually
less than its orthogonal counterpart. In other words, the composite space is
usually a lower dimensional subspace of the orthogonal space. Therefore the number of coefficients
between orthogonal and composite space is different.
Example
Transform composite space cheb_dirichlet
to its orthogonal counterpart
chebyshev
. Note that cheb_dirichlet
has 6 spectral coefficients,
while the chebyshev
bases has 8.
use ;
use ;
use PI;
use *;
use Array1;
use Complex;
// Define base
let mut ch = chebyshev;
let mut cd = cheb_dirichlet;
// Get coordinates in physical space
let x: = ch.get_nodes.clone;
let v: = x
.iter
.map
.
.into;
// Transform to physical space
let ch_vhat: = ch.forward;
let cd_vhat: = cd.forward;
// Send array to orthogonal space (cheb_dirichlet
// to chebyshev in this case)
let cd_vhat_ortho = cd.to_ortho;
// Both arrays are equal, because field was
// initialized with correct boundary conditions,
// i.e. dirichlet ones
for in ch_vhat.iter.zip
// However, if the physical field values do not
// satisfy dirichlet boundary conditions, they
// will be enforced by the transform to cheb_dirichle
// and ultimately the transformed values will deviate
// from a pure chebyshev transform (which does not)
// enfore the boundary conditions.
let mut v: = x
.iter
.map
.
.into;
let ch_vhat: = ch.forward;
let cd_vhat: = cd.forward;
let cd_vhat_ortho = cd.to_ortho;
// They will deviate
println!;
println!;
MPI Support (Feature)
Funspace
comes with limited mpi support. Currently this is restricted
to 2D spaces. Under the hood it uses a fork of the rust mpi libary
https://github.com/rsmpi/rsmpi which requires an existing MPI implementation
and libclang
.
Activate the feature in your ``Cargo.toml`
funspace = {version = "0.3", features = ["mpi"]}`
Examples
examples/space_mpi.rs
Install cargo mpirun
, for example, and run
cargo mpirun --np 2 --example space_mpi --features="mpi"
Versions
- v0.3.0: Major API changes + Performance improvements
License: MIT