Git Product home page Git Product logo

cpmech / russell Goto Github PK

View Code? Open in Web Editor NEW
93.0 9.0 8.0 7.16 MB

Rust Scientific Libary. ODE and DAE (Runge-Kutta) solvers. Special functions (Bessel, Elliptic, Beta, Gamma, Erf). Linear algebra. Sparse solvers (MUMPS, UMFPACK). Probability distributions. Tensor calculus.

License: MIT License

Rust 97.31% Shell 0.44% C 1.80% Python 0.33% Makefile 0.05% BitBake 0.05% M 0.03%
eigenvalues eigenvectors sparse-matrix mathematics linear-algebra rust differential-equations scientific-computing special-functions interpolation

russell's Introduction

Russell - Rust Scientific Library

Russell

Numerical mathematics, ordinary differential equations, special math functions, high-performance (sparse) linear algebra


codecov Track Awesome List


Test & Coverage Test with local libs Test with Intel MKL Test on Arch Linux Test on Rocky Linux Test on macOS


documentation: lab documentation: ode documentation: sparse documentation: stat documentation: tensor


Contents

Introduction

Russell (Rust Scientific Library) assists in developing high-performance computations involving linear algebra, sparse linear systems, differential equations, statistics, and continuum mechanics using the Rust programming language. The applications built with Russell revolve around the computational mechanics discipline; however, since Russell deals with fundamental mathematics and numerics, it is also helpful for other disciplines.

Russell aims to deliver efficient, reliable, and easy-to-maintain code. Thus, Russell implements several unit and integration tests and requires test coverage to be over 95%. For the sake of code maintenance, Russell avoids overcomplicated Rust constructions. Nonetheless, Russell considers a good range of Rust concepts, such as generics and traits, and convenient/powerful constructs, such as enums, options, and results. Another goal of Russell is to publish examples of all computations in the documentation to assist the user/developer.

Available libraries:

  • Crates.io russell_lab Scientific laboratory with special math functions, linear algebra, interpolation, quadrature, numerical derivation, and more
  • Crates.io russell_ode Solvers for ordinary differential equations (ODEs) and differential algebraic equations (DAEs)
  • Crates.io russell_sparse Solvers for large sparse linear systems (wraps MUMPS and UMFPACK)
  • Crates.io russell_stat Statistics calculations and (engineering) probability distributions
  • Crates.io russell_tensor Tensor analysis, calculus, and functions for continuum mechanics

๐Ÿ‘† Check the crate version and update your Cargo.toml accordingly. Examples:

[dependencies]
russell_lab = "*"
russell_sparse = "*"
russell_ode = "*"
russell_stat = "*"
russell_tensor = "*"

All crates have an option to use Intel MKL instead of the default OpenBLAS. For instance, the features keyword may be configured as follows:

[dependencies]
russell_lab = { version = "*", features = ["intel_mkl"] }
russell_sparse = { version = "*", features = ["intel_mkl"] }
russell_ode = { version = "*", features = ["intel_mkl"] }
russell_stat = { version = "*", features = ["intel_mkl"] }
russell_tensor = { version = "*", features = ["intel_mkl"] }

External associated and recommended crates:

  • plotpy Plotting tools using Python3/Matplotlib as an engine (for quality graphics)
  • tritet Triangle and tetrahedron mesh generators (with Triangle and Tetgen)
  • gemlab Geometry, meshes, and numerical integration for finite element analyses

Installation

Russell requires some non-Rust libraries (e.g., OpenBLAS, Intel MKL, MUMPS, SuiteSparse) to achieve the max performance. These libraries can be installed as explained in each subsection next.

After installing the dependencies, you may add each crate using:

cargo add russell_lab
cargo add russell_sparse # etc.

Debian/Ubuntu Linux

Required libraries:

# install libraries for russell
sudo apt-get install -y --no-install-recommends \
    liblapacke-dev \
    libopenblas-dev \
    libsuitesparse-dev

Rocky Linux

Required libraries:

# initialize
dnf update -y
dnf install epel-release -y
crb enable

# install libraries for russell
dnf install -y \
  lapack-devel \
  openblas-devel \
  suitesparse-devel

Arch Linux

Required libraries:

# install libraries for russell
yay -Y --gendb --noconfirm && yay -Y --devel --save
yay -Syu blas-openblas --noconfirm
yay -Syu suitesparse --noconfirm

macOS

First, install Homebrew. Then, run:

# install libraries for russell
brew install lapack openblas suite-sparse

Optional feature "local_suitesparse"

russell_sparse allows the use of a locally compiled SuiteSparse, installed in /usr/local/include/suitesparse and /usr/local/lib/suitesparse. This option is defined by the local_suitesparse feature. The compile-and-install-suitesparse script may be used in this case:

bash zscripts/compile-and-install-suitesparse.bash

Optional feature "with_mumps"

russell_sparse has an optional feature named with_mumps which enables the MUMPS solver. To use this feature, MUMPS needs to be locally compiled first. The compile-and-install-mumps script may be used in this case:

bash zscripts/compile-and-install-mumps.bash

Optional feature "intel_mkl"

To enable Intel MKL (and disable OpenBLAS), the optional intel_mkl feature may be used. In this case SuiteSparse (and MUMPS) must be locally compiled (with Intel MKL). This step can be easily accomplished by the compile-and-install-suitesparse and compile-and-install-mumps scripts, called with the mkl argument. For example:

bash zscripts/compile-and-install-suitesparse.bash mkl
bash zscripts/compile-and-install-mumps.bash mkl

Number of threads

By default, OpenBLAS will use all available threads, including Hyper-Threads that may worsen the performance. Thus, it is recommended to set the following environment variable:

export OPENBLAS_NUM_THREADS=<real-core-number>

Substitute <real-core-number> with the correct value from your system.

Furthermore, if working on a multi-threaded application where the solver should not be multi-threaded on its own (e.g., running parallel calculations in an optimization tool), you may set:

export OPENBLAS_NUM_THREADS=1

๐ŸŒŸ Examples

See also:

(lab) Numerical integration (quadrature)

The code below approximates the area of a semicircle of unitary radius.

use russell_lab::math::PI;
use russell_lab::{approx_eq, Quadrature, StrError};

fn main() -> Result<(), StrError> {
    let mut quad = Quadrature::new();
    let args = &mut 0;
    let (a, b) = (-1.0, 1.0);
    let (area, stats) = quad.integrate(a, b, args, |x, _| Ok(f64::sqrt(1.0 - x * x)))?;
    println!("\narea = {}", area);
    println!("\n{}", stats);
    approx_eq(area, PI / 2.0, 1e-13);
    Ok(())
}

(lab) Solution of PDEs using spectral collocation

This example illustrates the solution of a 1D PDE using the spectral collocation method. It employs the InterpLagrange struct.

dยฒu     du          x
โ€”โ€”โ€” - 4 โ€”โ€” + 4 u = e  + C
dxยฒ     dx

    -4 e
C = โ€”โ€”โ€”โ€”โ€”โ€”
    1 + eยฒ

x โˆˆ [-1, 1]

Boundary conditions:

u(-1) = 0  and  u(1) = 0

Reference solution:

        x   sinh(1)  2x   C
u(x) = e  - โ€”โ€”โ€”โ€”โ€”โ€”โ€” e   + โ€”
            sinh(2)       4

See the code

Results:

algo_lorene_1d_pde_spectral_collocation

(lab) Matrix visualization

We can use the fantastic tool named vismatrix to visualize the pattern of non-zero values of a matrix. With vismatrix, we can click on each circle and investigate the numeric values as well.

The function mat_write_vismatrix writes the input data file for vismatrix.

See the code

After generating the "dot-smat" file, run the following command:

vismatrix /tmp/russell_lab/matrix_visualization.smat

Output:

Matrix visualization

(lab) Singular value decomposition

use russell_lab::{mat_svd, Matrix, Vector, StrError};

fn main() -> Result<(), StrError> {
    // set matrix
    let mut a = Matrix::from(&[
        [2.0, 4.0],
        [1.0, 3.0],
        [0.0, 0.0],
        [0.0, 0.0],
    ]);

    // allocate output structures
    let (m, n) = a.dims();
    let min_mn = if m < n { m } else { n };
    let mut s = Vector::new(min_mn);
    let mut u = Matrix::new(m, m);
    let mut vt = Matrix::new(n, n);

    // perform SVD
    mat_svd(&mut s, &mut u, &mut vt, &mut a)?;

    // check S
    let s_correct = "โ”Œ      โ”\n\
                     โ”‚ 5.46 โ”‚\n\
                     โ”‚ 0.37 โ”‚\n\
                     โ””      โ”˜";
    assert_eq!(format!("{:.2}", s), s_correct);

    // check SVD: a == u * s * vt
    let mut usv = Matrix::new(m, n);
    for i in 0..m {
        for j in 0..n {
            for k in 0..min_mn {
                usv.add(i, j, u.get(i, k) * s[k] * vt.get(k, j));
            }
        }
    }
    let usv_correct = "โ”Œ                   โ”\n\
                       โ”‚ 2.000000 4.000000 โ”‚\n\
                       โ”‚ 1.000000 3.000000 โ”‚\n\
                       โ”‚ 0.000000 0.000000 โ”‚\n\
                       โ”‚ 0.000000 0.000000 โ”‚\n\
                       โ””                   โ”˜";
    assert_eq!(format!("{:.6}", usv), usv_correct);
    Ok(())
}

(lab) Cholesky factorization

use russell_lab::*;

fn main() -> Result<(), StrError> {
    // set matrix (full)
    #[rustfmt::skip]
    let a_full = Matrix::from(&[
        [ 3.0, 0.0,-3.0, 0.0],
        [ 0.0, 3.0, 1.0, 2.0],
        [-3.0, 1.0, 4.0, 1.0],
        [ 0.0, 2.0, 1.0, 3.0],
    ]);

    // set matrix (lower)
    #[rustfmt::skip]
    let mut a_lower = Matrix::from(&[
        [ 3.0, 0.0, 0.0, 0.0],
        [ 0.0, 3.0, 0.0, 0.0],
        [-3.0, 1.0, 4.0, 0.0],
        [ 0.0, 2.0, 1.0, 3.0],
    ]);

    // set matrix (upper)
    #[rustfmt::skip]
    let mut a_upper = Matrix::from(&[
        [3.0, 0.0,-3.0, 0.0],
        [0.0, 3.0, 1.0, 2.0],
        [0.0, 0.0, 4.0, 1.0],
        [0.0, 0.0, 0.0, 3.0],
    ]);

    // perform Cholesky factorization (lower)
    mat_cholesky(&mut a_lower, false)?;
    let l = &a_lower;

    // perform Cholesky factorization (upper)
    mat_cholesky(&mut a_upper, true)?;
    let u = &a_upper;

    // check:  l โ‹… lแต€ = a
    let m = a_full.nrow();
    let mut l_lt = Matrix::new(m, m);
    for i in 0..m {
        for j in 0..m {
            for k in 0..m {
                l_lt.add(i, j, l.get(i, k) * l.get(j, k));
            }
        }
    }
    mat_approx_eq(&l_lt, &a_full, 1e-14);

    // check:   uแต€ โ‹… u = a
    let mut ut_u = Matrix::new(m, m);
    for i in 0..m {
        for j in 0..m {
            for k in 0..m {
                ut_u.add(i, j, u.get(k, i) * u.get(k, j));
            }
        }
    }
    mat_approx_eq(&ut_u, &a_full, 1e-14);
    Ok(())
}

(lab) Solution of a (dense) linear system

use russell_lab::{solve_lin_sys, Matrix, Vector, StrError};

fn main() -> Result<(), StrError> {
    // set matrix and right-hand side
    let mut a = Matrix::from(&[
        [1.0,  3.0, -2.0],
        [3.0,  5.0,  6.0],
        [2.0,  4.0,  3.0],
    ]);
    let mut b = Vector::from(&[5.0, 7.0, 8.0]);

    // solve linear system b := aโปยนโ‹…b
    solve_lin_sys(&mut b, &mut a)?;

    // check
    let x_correct = "โ”Œ         โ”\n\
                     โ”‚ -15.000 โ”‚\n\
                     โ”‚   8.000 โ”‚\n\
                     โ”‚   2.000 โ”‚\n\
                     โ””         โ”˜";
    assert_eq!(format!("{:.3}", b), x_correct);
    Ok(())
}

(lab) Reading table-formatted data files

The goal is to read the following file (clay-data.txt):

# Fujinomori clay test results

     sr        ea        er   # header
1.00000  -6.00000   0.10000   
2.00000   7.00000   0.20000   
3.00000   8.00000   0.20000   # << look at this line

# comments plus new lines are OK

4.00000   9.00000   0.40000   
5.00000  10.00000   0.50000   

# bye

The code below illustrates how to do it.

Each column (sr, ea, er) is accessible via the get method of the [HashMap].

use russell_lab::{read_table, StrError};
use std::collections::HashMap;
use std::env;
use std::path::PathBuf;

fn main() -> Result<(), StrError> {
    // get the asset's full path
    let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
    let full_path = root.join("data/tables/clay-data.txt");

    // read the file
    let labels = &["sr", "ea", "er"];
    let table: HashMap<String, Vec<f64>> = read_table(&full_path, Some(labels))?;

    // check the columns
    assert_eq!(table.get("sr").unwrap(), &[1.0, 2.0, 3.0, 4.0, 5.0]);
    assert_eq!(table.get("ea").unwrap(), &[-6.0, 7.0, 8.0, 9.0, 10.0]);
    assert_eq!(table.get("er").unwrap(), &[0.1, 0.2, 0.2, 0.4, 0.5]);
    Ok(())
}

(sparse) Solution of a sparse linear system

use russell_lab::*;
use russell_sparse::prelude::*;
use russell_sparse::StrError;

fn main() -> Result<(), StrError> {
    // constants
    let ndim = 5; // number of rows = number of columns
    let nnz = 13; // number of non-zero values, including duplicates

    // allocate solver
    let mut umfpack = SolverUMFPACK::new()?;

    // allocate the coefficient matrix
    //  2  3  .  .  .
    //  3  .  4  .  6
    //  . -1 -3  2  .
    //  .  .  1  .  .
    //  .  4  2  .  1
    let mut coo = SparseMatrix::new_coo(ndim, ndim, nnz, Sym::No)?;
    coo.put(0, 0, 1.0)?; // << (0, 0, a00/2) duplicate
    coo.put(0, 0, 1.0)?; // << (0, 0, a00/2) duplicate
    coo.put(1, 0, 3.0)?;
    coo.put(0, 1, 3.0)?;
    coo.put(2, 1, -1.0)?;
    coo.put(4, 1, 4.0)?;
    coo.put(1, 2, 4.0)?;
    coo.put(2, 2, -3.0)?;
    coo.put(3, 2, 1.0)?;
    coo.put(4, 2, 2.0)?;
    coo.put(2, 3, 2.0)?;
    coo.put(1, 4, 6.0)?;
    coo.put(4, 4, 1.0)?;

    // parameters
    let mut params = LinSolParams::new();
    params.verbose = false;
    params.compute_determinant = true;

    // call factorize
    umfpack.factorize(&mut coo, Some(params))?;

    // allocate x and rhs
    let mut x = Vector::new(ndim);
    let rhs = Vector::from(&[8.0, 45.0, -3.0, 3.0, 19.0]);

    // calculate the solution
    umfpack.solve(&mut x, &coo, &rhs, false)?;
    println!("x =\n{}", x);

    // check the results
    let correct = vec![1.0, 2.0, 3.0, 4.0, 5.0];
    vec_approx_eq(&x, &correct, 1e-14);

    // analysis
    let mut stats = StatsLinSol::new();
    umfpack.update_stats(&mut stats);
    let (mx, ex) = (stats.determinant.mantissa_real, stats.determinant.exponent);
    println!("det(a) = {:?}", mx * f64::powf(10.0, ex));
    println!("rcond  = {:?}", stats.output.umfpack_rcond_estimate);
    Ok(())
}

(ode) Solution of the Brusselator ODE

The system is:

y0' = 1 - 4 y0 + y0ยฒ y1
y1' = 3 y0 - y0ยฒ y1

with  y0(x=0) = 3/2  and  y1(x=0) = 3

Solving with DoPri8 -- 8(5,3):

use russell_lab::StrError;
use russell_ode::prelude::*;

fn main() -> Result<(), StrError> {
    // get the ODE system
    let (system, x0, mut y0, mut args, y_ref) = Samples::brusselator_ode();

    // final x
    let x1 = 20.0;

    // solver
    let params = Params::new(Method::DoPri8);
    let mut solver = OdeSolver::new(params, system)?;

    // enable dense output
    let h_out = 0.01;
    let selected_y_components = &[0, 1];
    solver.enable_output().set_dense_recording(true, h_out, selected_y_components)?;

    // solve the problem
    solver.solve(&mut y0, x0, x1, None, Some(&mut out), &mut args)?;

    // print the results and stats
    println!("y_russell     = {:?}", y0.as_data());
    println!("y_mathematica = {:?}", y_ref.as_data());
    println!("{}", solver.stats());
    Ok(())
}

A plot of the (dense) solution is shown below:

Brusselator results: DoPri8

(ode) Solution of the Brusselator PDE

This example solves the Brusselator PDE described in (Hairer E, Wanner G (2002) Solving Ordinary Differential Equations II Stiff and Differential-Algebraic Problems. Second Revised Edition. Corrected 2nd printing 2002. Springer Series in Computational Mathematics, 614p).

See the code brusselator_pde_radau5_2nd.rs.

The results are shown below for the U field:

brusselator_pde_radau5_2nd_u.jpg

And below for the V field:

brusselator_pde_radau5_2nd_v.jpg

The code brusselator_pde_2nd_comparison.rs compares russell results with Mathematica results.

The figure below shows the russell (black dashed lines) and Mathematica (red solid lines) results for the U field:

comparison U

The figure below shows the russell (black dashed lines) and Mathematica (red solid lines) results for the V field:

comparison V

(stat) Generate the Frechet distribution

Code:

use russell_stat::*;

fn main() -> Result<(), StrError> {
    // generate samples
    let mut rng = get_rng();
    let dist = DistributionFrechet::new(0.0, 1.0, 1.0)?;
    let nsamples = 10_000;
    let mut data = vec![0.0; nsamples];
    for i in 0..nsamples {
        data[i] = dist.sample(&mut rng);
    }
    println!("{}", statistics(&data));

    // text-plot
    let stations = (0..20).map(|i| (i as f64) * 0.5).collect::<Vec<f64>>();
    let mut hist = Histogram::new(&stations)?;
    hist.count(&data);
    println!("{}", hist);
    Ok(())
}

Sample output:

min = 0.11845731988882305
max = 26248.036672205748
mean = 12.268212841918867
std_dev = 312.7131690782321

[  0,0.5) | 1370 ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ
[0.5,  1) | 2313 ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ
[  1,1.5) | 1451 ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ
[1.5,  2) |  971 ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ
[  2,2.5) |  659 ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ
[2.5,  3) |  460 ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ
[  3,3.5) |  345 ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ
[3.5,  4) |  244 ๐ŸŸฆ๐ŸŸฆ๐ŸŸฆ
[  4,4.5) |  216 ๐ŸŸฆ๐ŸŸฆ
[4.5,  5) |  184 ๐ŸŸฆ๐ŸŸฆ
[  5,5.5) |  133 ๐ŸŸฆ
[5.5,  6) |  130 ๐ŸŸฆ
[  6,6.5) |  115 ๐ŸŸฆ
[6.5,  7) |  108 ๐ŸŸฆ
[  7,7.5) |   70 
[7.5,  8) |   75 
[  8,8.5) |   57 
[8.5,  9) |   48 
[  9,9.5) |   59 
      sum = 9008

(tensor) Allocate second-order tensors

use russell_tensor::*;

fn main() -> Result<(), StrError> {
    // general
    let a = Tensor2::from_matrix(
        &[
            [1.0, SQRT_2 * 2.0, SQRT_2 * 3.0],
            [SQRT_2 * 4.0, 5.0, SQRT_2 * 6.0],
            [SQRT_2 * 7.0, SQRT_2 * 8.0, 9.0],
        ],
        Mandel::General,
    )?;
    assert_eq!(
        format!("{:.1}", a.vec),
        "โ”Œ      โ”\n\
         โ”‚  1.0 โ”‚\n\
         โ”‚  5.0 โ”‚\n\
         โ”‚  9.0 โ”‚\n\
         โ”‚  6.0 โ”‚\n\
         โ”‚ 14.0 โ”‚\n\
         โ”‚ 10.0 โ”‚\n\
         โ”‚ -2.0 โ”‚\n\
         โ”‚ -2.0 โ”‚\n\
         โ”‚ -4.0 โ”‚\n\
         โ””      โ”˜"
    );

    // symmetric-3D
    let b = Tensor2::from_matrix(
        &[
            [1.0, 4.0 / SQRT_2, 6.0 / SQRT_2],
            [4.0 / SQRT_2, 2.0, 5.0 / SQRT_2],
            [6.0 / SQRT_2, 5.0 / SQRT_2, 3.0],
        ],
        Mandel::Symmetric,
    )?;
    assert_eq!(
        format!("{:.1}", b.vec),
        "โ”Œ     โ”\n\
         โ”‚ 1.0 โ”‚\n\
         โ”‚ 2.0 โ”‚\n\
         โ”‚ 3.0 โ”‚\n\
         โ”‚ 4.0 โ”‚\n\
         โ”‚ 5.0 โ”‚\n\
         โ”‚ 6.0 โ”‚\n\
         โ””     โ”˜"
    );

    // symmetric-2D
    let c = Tensor2::from_matrix(
        &[[1.0, 4.0 / SQRT_2, 0.0], [4.0 / SQRT_2, 2.0, 0.0], [0.0, 0.0, 3.0]],
        Mandel::Symmetric2D,
    )?;
    assert_eq!(
        format!("{:.1}", c.vec),
        "โ”Œ     โ”\n\
         โ”‚ 1.0 โ”‚\n\
         โ”‚ 2.0 โ”‚\n\
         โ”‚ 3.0 โ”‚\n\
         โ”‚ 4.0 โ”‚\n\
         โ””     โ”˜"
    );
    Ok(())
}

Roadmap

  • Improve russell_lab
    • Implement more integration tests for linear algebra
    • Implement more examples
    • Implement more benchmarks
    • Wrap more BLAS/LAPACK functions
      • Implement dggev, zggev, zheev, and zgeev
    • Wrap Intel MKL (option for OpenBLAS)
    • Add more complex number functions
    • Add fundamental functions to russell_lab
      • Implement the Bessel functions
      • Implement the modified Bessel functions
      • Implement the elliptical integral functions
      • Implement Beta, Gamma and Erf functions (and associated)
      • Implement orthogonal polynomial functions
    • Implement some numerical methods in russell_lab
      • Implement Brent's solver
      • Implement a solver for the cubic equation
      • Implement numerical derivation
      • Implement numerical Jacobian function
      • Implement line search
      • Implement Newton's method for nonlinear systems
      • Implement numerical quadrature
      • Implement multidimensional data interpolation
    • Add interpolation and polynomials to russell_lab
      • Implement Chebyshev polynomials
      • Implement Chebyshev interpolation
      • Implement Orthogonal polynomials
      • Implement Lagrange interpolation
      • Implement Fourier interpolation
  • Improve russell_sparse
    • Wrap the KLU solver (in addition to MUMPS and UMFPACK)
    • Implement the Compressed Sparse Column format (CSC)
    • Implement the Compressed Sparse Row format (CSC)
    • Improve the C-interface to UMFPACK and MUMPS
    • Write the conversion from COO to CSC in Rust
  • Improve russell_ode
    • Implement explicit Runge-Kutta solvers
    • Implement Radau5 for DAEs
    • Implement extrapolation methods
    • Implement multi-step methods
    • Implement general linear methods
  • Improve russell_stat
    • Add probability distribution functions
    • Implement drawing of ASCII histograms
    • Implement FORM (first-order reliability method)
    • Add more examples
  • Improve russell_tensor
    • Implement functions to calculate invariants
    • Implement first and second-order derivatives of invariants
    • Implement some high-order derivatives
    • Implement standard continuum mechanics tensors
  • General improvements
    • Compile on macOS
    • Study the possibility to install Russell on Windows

russell's People

Contributors

cpmech avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

russell's Issues

Build error on Rocky 9

System: Rocky 9
Version: 1.2.0 and 1.2.1

I tried the examples/pde_laplace_equation.rs but failed at building. The rust-analyzer sayed that I missed zmumps_c.h, but I have this file at /usr/include/MUMPS/. The full information is like below:

error: failed to run custom build command for `russell_sparse v1.2.0`
...
  cargo:warning=c_code/interface_complex_mumps.c:6:10: ่‡ดๅ‘ฝ้”™่ฏฏ๏ผšzmumps_c.h๏ผšๆฒกๆœ‰้‚ฃไธชๆ–‡ไปถๆˆ–็›ฎๅฝ•
  cargo:warning=    6 | #include "zmumps_c.h"
  cargo:warning=      |          ^~~~~~~~~~~~
  cargo:warning=็ผ–่ฏ‘ไธญๆ–ญใ€‚
...
error occurred: Command "/usr/bin/gcc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-4" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-o" "/run/media/ML/MD/Supernova/test/russel/target/debug/build/russell_sparse-8877400e9f10e264/out/be5a010cd526d178-interface_complex_mumps.o" "-c" "c_code/interface_complex_mumps.c" with args gcc did not execute successfully (status code exit status: 1).

Does the program have a search to /usr/include/MUMPS? I found a similar issue #75 focusing the build.rs file, but I did not find the MUMPS option inside.

I also built a symbolic link to /usr/local/include/MUMPS but still the same error.

(Generalized) eigenvalues for complex matrices

Hi,

Thank you for creating this library! It will be very useful for me in my attempts at rewriting some old FORTRAN codes to Rust.

For my specific purpose, I need generalized eigenvalue solvers (i.e. dggev) and complex matrix eigenvalue solvers (zggev, zheev, zgeev). Are there currently plans to add these?

Thanks!

Build Error

I added russell_sparse = "*" to Cargo.toml to build.

However I have the following error message:

error: failed to run custom build command for `russell_lab v1.0.0`

Caused by:
  process didn't exit successfully: `...\target\debug\build\russell_lab-fa25270958244ff7\build-script-build` (exit code: 1)
  --- stderr


  error occurred: Command "...\\VisualStudio\\VisualStudio\\VC\\Tools\\MSVC\\14.32.31326\\bin\\HostX64\\x64\\cl.exe" "-nologo" "-MD" "-Z7" "-Brepro" "-W4" "-Fo...\\Proj\\FluidSimCrate-master\\target\\debug\\build\\russell_lab-19d28318bc43dd4e\\out\\be5a010cd526d178-interface_fftw.o" "-c" "c_code/interface_fftw.c" with args "cl.exe" did not execute successfully (status code exit code: 2).

I am developing on Windows. Thanks in advance for any help.

Need to have acces to Element in SparseTriplet

Hi,
First , thanks for the amazing library!

I am using SparseTriplet to solve a sparse Ax =b;

I am using A.put(i, j, 1000.0)? and it works great, but sometimes, I need to update the value as (i,j) but I dont see a SparseTriplet.get(i,j) function.

How should I do this?

Thanks

russell_lab blas build

Hello, nice library!

On my archlinux system, I have openblas installed, and it's headers are at /usr/include/openblas/cblas.h; for whatever reason, when building I get this error:

  running: "cc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-4" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-o" "/home/m4b/git/russell/target/debug/build/russell_lab-8efc726f530eb1fc/out/c_code/interface_blas.o" "-c" "c_code/interface_blas.c"
  cargo:warning=c_code/interface_blas.c:18:10: fatal error: cblas.h: No such file or directory

  cargo:warning=   18 | #include "cblas.h"

  cargo:warning=      |          ^~~~~~~~~

  cargo:warning=compilation terminated.

  exit status: 1

  --- stderr

In attempting to debug, I discovered I can pass:

RUSSELL_LAB_USE_INTEL_MKL=1

However, more rustish would (probably) be to use a feature flag to opt into using the intel api.

Regardless I think finding the headers should succeed, it looks like this else branch in the build.rs needs slightly better handling:

        // OpenBLAS
        cc::Build::new()
            .file("c_code/interface_blas.c")
            .compile("c_code_interface_blas");
        println!("cargo:rustc-link-lib=dylib=openblas");
        println!("cargo:rustc-link-lib=dylib=lapack");

There is also pkgconf which people usually use for this purpose to find headers, etc., e.g.:

pkgconf --cflags-only-I cblas
-I/usr/include/openblas

returns the correct path (and there is a rust crate to use at build time for this).

Lastly, and this is only partially related, the only function I'm using here is: https://docs.rs/russell_lab/0.7.2/russell_lab/matrix/fn.mat_pseudo_inverse.html

which works perfectly for me (thank you, it's results are identical in my test cases to the matlab and octave pinv), and it would be more ideal if this were pure rust and I could opt out of the blas linkage, but that is probably infeasible, and anyway, another issue entirely :)

Anyway, thanks for the great library!

Make solvers clonable for caching purposes

Hi,

First of all, thanks for creating this library! It has been a joy to use for my project.

In my project, I would like to precompute some sparse matrices and their factorization to reuse them later to solve for different bs. In turn, something I would like to do something like this at the beginning of my program:

let mut mat = self.create_sparse_diffusion_laplacian(params);

let mut solver = SolverUMFPACK::new().unwrap();
solver.factorize(&mut mat, None).unwrap();

// same to some cache
CACHE.push((solver, mat))

And then later, in some other function with access to cache, load the factorized solver:

let mut solver = CACHE.get(i).clone(); // this currently doesn't work --- SolverUMFPACK doesn't implement Clone trait

let mut b = populate_b();
let mut x = Vector::new(params.n_dev_cells);

solver.solve(&mut x, &mat, &b, false).unwrap();

However, at the moment I cannot clone the solver as the Clone trait is not implemented. I am not too familiar with Rust yet, or its FFI, but would it be possible to support this kind of behaviour? Or is there some other way to achieve this?

Thanks in advance!

Examples of russell to solve 3D Poisson equations

I want to solve the 3D Poisson-Boltzmann equation like $$\nabla^2 \phi - \kappa^2 \phi = 4 \pi \rho_f / \epsilon$$ with the boundary contitions $$\phi (\infty) = 0$$ could the russell handle this problem? I saw that the PDE example was for 2D Laplace equation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.