Giter Club home page Giter Club logo

samurai's Introduction


Project license Codacy Badge

Pull Requests welcome code with love by hpc-maths

The use of mesh adaptation methods in numerical simulation allows to drastically reduce the memory footprint and the computational costs. There are different kinds of methods: AMR patch-based, AMR cell-based, multiresolution cell-based or point-based, ...

Different open source software is available to the community to manage mesh adaptation: AMReX for patch-based AMR, p4est and pablo for cell-based adaptation.

The strength of samurai is that it allows to implement all the above mentioned mesh adaptation methods from the same data structure. The mesh is represented as intervals and a set algebra allows to efficiently search for subsets among these intervals. Samurai also offers a flexible and pleasant interface to easily implement numerical methods.

Table of Contents

Get started

In this section, we propose two examples: the first one solves a 2D advection equation with mesh adaptation using multiresolution, the second one shows the use of set algebra on intervals.

The advection equation

We want to solve the 2D advection equation given by

$$ \partial_t u + a \cdot \nabla u = 0 \; \text{in} \; [0, 1]\times [0, 1] $$

with homogeneous Dirichlet boundary conditions and $a = (1, 1)$. The initial solution is given by

$$ u_0(x, y) = \left\{ \begin{align*} 1 & \; \text{in} \; [0.4, 0.6]\times [0.4, 0.6], \\ 0 & \; \text{elsewhere}. \end{align*} \right. $$

To solve this equation, we use the well known upwind scheme.

The following steps describe how to solve this problem with samurai. It is important to note that these steps are generally the same whatever the equations we want to solve.

  • Define the configuration of the problem

    constexpr size_t dim = 2;
    using Config = samurai::MRConfig<dim>;
    std::size_t min_level = 2, max_level = 8;
  • Create the Cartesian mesh

    const samurai::Box<double, dim> box({0., 0.}, {1., 1.});
    samurai::MRMesh<Config> mesh(box, min_level, max_level);
  • Create the field on this mesh

    auto u = samurai::make_field<double, 1>("u", mesh);
    samurai::make_bc<samurai::Dirichlet<1>>(u, 0.);
  • Initialization of this field

    samurai::for_each_cell(mesh, [&](const auto& cell)
    {
        double length = 0.2;
        if (xt::all(xt::abs(cell.center() - 0.5) <= 0.5*length))
        {
            u[cell] = 1;
        }
    });
  • Create the adaptation method

    auto MRadaptation = samurai::make_MRAdapt(u);
  • Time loop

    double dx = samurai::cell_length(max_level);
    double dt = 0.5*dx;
    auto unp1 = samurai::make_field<double, 1>("u", mesh);
    
    // Time loop
    for (std::size_t nite = 0; nite < 50; ++nite)
    {
        // adapt u
        MRadaptation(1e-4, 2);
    
        // update the ghosts used by the upwind scheme
        samurai::update_ghost_mr(u);
    
        // upwind scheme
        samurai::for_each_interval(mesh, [&](std::size_t level, const auto& i, const auto& index)
        {
            double dx = samurai::cell_length(level);
            auto j = index[0];
    
            unp1(level, i, j) = u(level, i, j) - dt / dx * (u(level, i, j) - u(level, i - 1, j)
                                                          + u(level, i, j) - u(level, i, j - 1));
        });
    
        std::swap(unp1.array(), u.array());
    }

The whole example can be found here.

The projection operator

When manipulating grids of different resolution levels, it is often necessary to transmit the solution of a level $l$ to a level $l+1$ and vice versa. We are interested here in the projection operator defined by

$$ u(l, i, j) = \frac{1}{4}\sum_{k_i=0}^1\sum_{k_j=0}^1 u(l+1, 2i + k_i, 2j + k_j) $$

This operator allows to compute the cell-average value of the solution at a grid node at level $l$ from cell-average values of the solution known on children-nodes at grid level $l + 1$ for a 2D problem.

We assume that we already have a samurai mesh with several level defined in the variable mesh. To access to a level, we use the operator mesh[level]. We also assume that we created a field on this mesh using the make_field and initialized it.

The following steps describe how to implement the projection operator with samurai.

  • Create a subset of the mesh using set algebra
auto set = samurai::intersection(mesh[level], mesh[level+1]).on(level);
  • Apply an operator on this subset
set([&](const auto& i, const auto index)
{
    auto j = index[0];
    u(level, i, j) = 0.25*(u(level+1, 2*i, 2*j)
                         + u(level+1, 2*i+1, 2*j)
                         + u(level+1, 2*i, 2*j+1)
                         + u(level+1, 2*i+1, 2*j+1));
});

The multi dimensional projection operator can be found here.

There's more

If you want to learn more about samurai skills by looking at examples, we encourage you to browse the demos directory.

The tutorial directory is a good first step followed by the FiniteVolume directory.

Features

  • Facilitate data manipulation by using the formalism on a uniform Cartesian grid
  • Facilitate the implementation of complex operators between grid levels
  • High memory compression of an adapted mesh
  • Complex mesh creation using a set of meshes
  • Finite volume methods using flux construction
  • Lattice Boltzmann methods examples
  • Finite difference methods
  • Discontinuous Galerkin methods
  • Matrix assembling of the discrete operators using PETSc
  • AMR cell-based methods
  • AMR patch-based and block-based methods
  • MRA cell-based methods
  • MRA point-based methods
  • HDF5 ouput format support
  • MPI implementation

Installation

From conda

mamba install samurai

If you want to compile your scripts, you also have to install a C++ compiler and cmake.

mamba install cxx-compiler cmake

And finally, if you have to use PETSc to assemble the matrix of your problem, you need to install it

mamba install petsc pkg-config

From Conan Center

If you want to install samurai from Conan, you can use the following command:

conan install --requires=samurai/0.13.0

From source

Run the cmake configuration

  • With mamba or conda

    First, you need to create the environment with all the dependencies installed

    mamba env create --file conda/environment.yml
    mamba activate samurai-env
    cmake . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_DEMOS=ON
  • With vcpkg

    cmake . -B ./build -DENABLE_VCPKG=ON -DBUILD_DEMOS=ON
  • With conan

    cmake . -B ./build -DCMAKE_BUILD_TYPE=Release -DENABLE_CONAN_OPTION=ON -DBUILD_DEMOS=ON

Build the demos

cmake --build ./build --config Release

Get help

For a better understanding of all the components of samurai, you can consult the documentation https://hpc-math-samurai.readthedocs.io.

If you have any question or remark, you can write a message on github discussions and we will be happy do help you or to discuss with you.

Project assistance

If you want to say thank you or/and support active development of samurai:

  • Add a GitHub Star to the project.
  • Tweet about samurai.
  • Write interesting articles about the project on Dev.to, Medium or your personal blog.

Together, we can make samurai better!

Contributing

First off, thanks for taking the time to contribute! Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make will benefit everybody else and are greatly appreciated.

Please read our contribution guidelines, and thank you for being involved!

License

This project is licensed under the BSD license.

See LICENSE for more information.

samurai's People

Contributors

github-actions[bot] avatar gouarin avatar grenier avatar kivvix avatar pmatalon avatar rolanddenis avatar tbellotti avatar uilianries 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

Watchers

 avatar  avatar  avatar  avatar

samurai's Issues

[Feat]: XDMF files time-aware

What do you want?

XDMF files can carry time information (under Time node).
This feature can help Paraview to synchronize files with different time recording.

A possible usage

No response

A possible implementation

The following lines can be added to lines 657 and 688 of hdf5.hpp:

auto time                      = grid.append_child("Time");
time.append_attribute("Value") = t;

The question is: how to pass time value t with respect to other arguments (optional or not) of save_field?

Other informations

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

`update_ghost` performance

By default, the function update_ghost updates all the ghosts defined in the mesh (AMR or MRA). When you compute the new solution using a time scheme, for example, only the ghosts used by the spatial scheme need to be updated. The ghosts used to adapt the mesh are not needed.

Then, the cost can be considerably reduced if you only update the right ghosts.

Improve BC

When we add a boundary condition using for example

auto u = samurai::make_field<double, 4>("u", mesh);
samurai::make_bc<samurai::dirichlet>(u, 0., 0., 0., 0.);

we defined the boundary condition for all components of the field.

But sometimes, we don't want to split our field and we want to have several boundary conditions depending of the field component.

The BCclass must then be updated to take this case into account.

Fix use of fmt 0.8

The fmt version was fixed to 0.7 in the conda environment because the CI failed with the 0.8 on Mac Os.

[Feat]: Periodic boundaries with MPI

What do you want?

Extension of periodic boundary to support MPI run. For the moment, this boundary condition is only supported on sequential run. The function update_ghost_periodic in update.hpp file needs to be extended to handle MPI ghost cells.

The new feature can be easily tested with the linear convection demo with only 2 MPI processes.

periodic conditions

The periodic boundary conditions are defined in the mesh. But is it what we want?

Shouldn't periodic boundary conditions be a boundary condition like any other?

[Bug]: `INIT_BC` does not correctly capture field type

What happened?

It's not possible to name a template parameter as I want when I use INIT_BC macro.

Input code

template <class Field_t>
struct Dirichlet : public Bc<Field_t>
{
    INIT_BC(Dirichlet)

    void apply(Field_t& f, const cell_t& cell_out, const cell_t& cell_in,
               const value_t& value) const override
    {
        f[cell_out] = 2 * value - f[cell_in];
    }
};

What expected?

Give template parameter Field (or Field_t in this example) to INIT_BC macro.

#define INIT_BC(NAME, FIELD)                              \
    using base_t  = samurai::Bc<FIELD>;            \
    using cell_t  = typename base_t::cell_t;       \
    using value_t = typename base_t::value_t;      \
    using base_t::Bc;                              \
                                                   \
    std::unique_ptr<base_t> clone() const override \
    {                                              \
        return std::make_unique<NAME>(*this);      \
    }
INIT_BC(Dirichlet, Field_t)

What is your operating system?

Mac OS

How did you install our software?

from source

Software version

0.x.x

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Fix cppcheck error

cppcheck gives some errors that are disabled in samurai. To find them, you can search the keyword cppcheck-suppress.

You have to check if these errors are false positives or not.

[Bug]: update_bc and UniformMesh

What happened?

IT's not possible to use update_bc function with UniformMeshsince the periodicity is not implemented for this kind of mesh.

Input code

static constexpr std::size_t dim = 1;
using config                     = UniformConfig<dim>;
auto mesh                        = UniformMesh<config>({{0}, {1}}, 4);
auto u                           = make_field<double, 1>("u", mesh);

make_bc<Dirichlet>(u);
update_bc(u);

What expected?

Have the same behaviour of MRMesh

What is your operating system?

Mac OS

How did you install our software?

from source

Software version

No response

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

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.