Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • Sparse
  • WallLaw
  • improved_comm
  • master
  • release/0.2.1
  • release/0.2.10
  • release/0.2.11
  • release/0.2.12
  • release/0.2.13
  • release/0.2.14
  • release/0.2.15
  • release/0.2.2
  • release/0.2.3
  • release/0.2.4
  • release/0.2.5
  • release/0.2.6
  • release/0.2.7
  • release/0.2.8
  • release/0.2.9
  • release/0.3.0
  • release/0.3.1
  • release/0.3.2
  • release/0.3.3
  • release/0.3.4
  • release/0.4.0
  • release/0.4.1
  • release/0.4.2
  • release/0.4.3
  • release/0.4.4
  • release/1.0
  • release/1.0.1
  • release/1.1
  • release/1.1.1
  • release/1.2
  • release/1.3
  • release/1.3.1
  • release/1.3.2
  • release/1.3.3
  • release/1.3.4
  • release/1.3.5
  • release/1.3.6
  • release/1.3.7
42 results

Target

Select target project
  • ravi.k.ayyala/lbmpy
  • brendan-waters/lbmpy
  • anirudh.jonnalagadda/lbmpy
  • jbadwaik/lbmpy
  • alexander.reinauer/lbmpy
  • itischler/lbmpy
  • he66coqe/lbmpy
  • ev81oxyl/lbmpy
  • Bindgen/lbmpy
  • da15siwa/lbmpy
  • holzer/lbmpy
  • RudolfWeeber/lbmpy
  • pycodegen/lbmpy
13 results
Select Git revision
  • GetterSetterAPI
  • HRR
  • HydroPressure
  • InplaceConfig
  • Outflow
  • PhaseField
  • Sparse
  • UBBVelocity
  • UpdateAPISparse
  • WallLaw
  • WetNodeBoundaries
  • csebug
  • feature/sparse
  • feature/try
  • improved_comm
  • install_requires
  • master
  • phaseField
  • relaxationrates
  • test_martin
  • release/0.2.1
  • release/0.2.10
  • release/0.2.11
  • release/0.2.12
  • release/0.2.13
  • release/0.2.14
  • release/0.2.15
  • release/0.2.2
  • release/0.2.3
  • release/0.2.4
  • release/0.2.5
  • release/0.2.6
  • release/0.2.7
  • release/0.2.8
  • release/0.2.9
  • release/0.3.0
  • release/0.3.1
  • release/0.3.2
  • release/0.3.3
  • release/0.3.4
  • release/0.4.0
  • release/0.4.1
  • release/0.4.2
  • release/0.4.3
  • release/0.4.4
  • release/1.0
  • release/1.0.1
  • release/1.1
  • release/1.1.1
  • release/1.2
  • release/1.3
  • release/1.3.1
  • release/1.3.2
  • release/1.3.3
  • release/1.3.4
  • release/1.3.5
  • release/1.3.6
57 results
Show changes
Commits on Source (90)
Showing
with 1274 additions and 296 deletions
[flake8]
max-line-length=120
exclude=lbmpy/plot.py
lbmpy/session.py
ignore = W293 W503 W291 E741
exclude=src/lbmpy/plot.py
src/lbmpy/session.py
ignore = W293 W503 W291 C901 E741
lbmpy/_version.py export-subst
src/lbmpy/_version.py export-subst
__pycache__
.ipynb_checkpoints
.coverage
.coverage*
*.pyc
*.vti
/build
/html_doc
/dist
/*.egg-info
*.egg-info
.cache
_build
/.idea
......@@ -15,14 +15,18 @@ _local_tmp
**/pylintrc
*.bak
*.tmp
/lbmpy_tests/db
/tests/db
doc/bibtex.json
/db
/lbmpy/phasefield/simplex_projection.*.so
/lbmpy/phasefield/simplex_projection.c
/src/lbmpy/phasefield/simplex_projection.*.so
/src/lbmpy/phasefield/simplex_projection.c
test-report
report.xml
# macOS
**/.DS_Store
*.uuid
# benchmark database
/lbmpy_tests/benchmark/db
\ No newline at end of file
/tests/benchmark/db
\ No newline at end of file
stages:
- pretest
- test
- "Code Quality"
- "Tests"
- "Prerelease-Tests"
- integration
- nightly
- docs
- deploy
# -------------------------- Code Quality --------------------------------------------------------------------------------
# -------------------------- Pre Tests --------------------------------------------------------------------------------
# Linter for code formatting
flake8-lint:
stage: "Code Quality"
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/nox:alpine
script:
- nox -s lint
tags:
- docker
# -------------------------- Tests --------------------------------------------------------------------------------
# Normal test - runs on every commit all but "long run" tests
tests-and-coverage:
stage: pretest
except:
variables:
- $ENABLE_NIGHTLY_BUILDS
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full
testsuite-cuda-py3.10:
stage: "Tests"
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/nox:ubuntu24.04-cuda12.6
needs: []
script:
# - pip install sympy --upgrade
- export NUM_CORES=$(nproc --all)
- mkdir -p ~/.config/matplotlib
- echo "backend:template" > ~/.config/matplotlib/matplotlibrc
- mkdir public
- pip install git+https://gitlab-ci-token:${CI_JOB_TOKEN}@i10git.cs.fau.de/pycodegen/pystencils.git@master#egg=pystencils
- env
- pip list
- py.test -v -n $NUM_CORES --cov-report html --cov-report term --cov=. -m "not longrun" --junitxml=report.xml
- python3 -m coverage xml
- nox -s "testsuite_gpu-3.10(cupy12)"
tags:
- docker
- cuda11
- cuda
- cudaComputeCapability6.1
- AVX
coverage: /Total coverage:\s\d+.\d+\%/
artifacts:
when: always
paths:
- coverage_report
- test-report
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
junit: report.xml
testsuite-cpu-py3.13:
stage: "Tests"
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/nox:alpine
needs: []
script:
- mkdir -p ~/.config/matplotlib
- echo "backend:template" > ~/.config/matplotlib/matplotlibrc
- nox -s "testsuite_cpu-3.13"
tags:
- docker
- AVX
artifacts:
when: always
paths:
- test-report
reports:
junit: report.xml
# Normal test with longruns
tests-and-coverage-with-longrun:
stage: test
stage: "Tests"
when: manual
allow_failure: true
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full
......@@ -57,161 +86,120 @@ tests-and-coverage-with-longrun:
- py.test -v -n $NUM_CORES
tags:
- docker
- cuda11
- cuda
- cudaComputeCapability6.1
- AVX
minimal-conda:
stage: pretest
except:
variables:
- $ENABLE_NIGHTLY_BUILDS
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/minimal_conda
script:
- pip install git+https://gitlab-ci-token:${CI_JOB_TOKEN}@i10git.cs.fau.de/pycodegen/pystencils.git@master#egg=pystencils
- python setup.py quicktest
tags:
- docker
# -------------------------- Nightly and Pre-Release Tests --------------------------------------------------------------------------------
# Linter for code formatting
flake8-lint:
stage: pretest
except:
variables:
- $ENABLE_NIGHTLY_BUILDS
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full
script:
- flake8 lbmpy
tags:
- docker
- cuda11
# -------------------------- Tests -------------------------------------------------------------------------------------
# pipeline with latest python version
latest-python:
stage: test
except:
variables:
- $ENABLE_NIGHTLY_BUILDS
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/latest_python
before_script:
- pip install git+https://gitlab-ci-token:${CI_JOB_TOKEN}@i10git.cs.fau.de/pycodegen/pystencils.git@master#egg=pystencils
# Test against latest pystencils 2.0 development version
pystencils-2.0dev:
stage: "Prerelease-Tests"
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/nox:ubuntu24.04-cuda12.6
allow_failure: true
needs: []
script:
- env
- pip list
- export NUM_CORES=$(nproc --all)
- mkdir -p ~/.config/matplotlib
- echo "backend:template" > ~/.config/matplotlib/matplotlibrc
- mkdir public
- py.test -v -n $NUM_CORES -m "not longrun" --junitxml=report.xml
- nox -s "testsuite_pystencils2(cupy12)"
tags:
- docker
- AVX
- cuda
- cudaComputeCapability6.1
artifacts:
when: always
paths:
- test-report
reports:
junit: report.xml
# Minimal tests in windows environment
minimal-windows:
stage: test
except:
variables:
- $ENABLE_NIGHTLY_BUILDS
tags:
- win
script:
- export NUM_CORES=$(nproc --all)
- export MPLBACKEND=Agg
- source /cygdrive/c/Users/build/Miniconda3/Scripts/activate
- source activate pystencils
- pip install git+https://gitlab-ci-token:${CI_JOB_TOKEN}@i10git.cs.fau.de/pycodegen/pystencils.git@master#egg=pystencils
- python -c "import numpy"
- pip install sympy==1.9
- py.test -v -m "not (notebook or longrun)"
minimal-sympy-master:
stage: test
except:
variables:
- $ENABLE_NIGHTLY_BUILDS
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/minimal_conda
stage: "Prerelease-Tests"
needs: []
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/nox:alpine
script:
- pip install git+https://gitlab-ci-token:${CI_JOB_TOKEN}@i10git.cs.fau.de/pycodegen/pystencils.git@master#egg=pystencils
- python -m pip install --upgrade git+https://github.com/sympy/sympy.git
- pip list
- python setup.py quicktest
- nox -s quicktest -P 3.13 -- --sympy-master
allow_failure: true
tags:
- docker
- cuda
ubuntu:
stage: test
except:
variables:
- $ENABLE_NIGHTLY_BUILDS
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/ubuntu
# pycodegen-integration:
# image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full
# stage: integration
# when: manual
# allow_failure: true
# script:
# - env
# - pip list
# - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@i10git.cs.fau.de/pycodegen/pycodegen.git
# - cd pycodegen
# - git submodule sync --recursive
# - git submodule update --init --recursive
# - git submodule foreach git fetch origin # compare the latest master version!
# - git submodule foreach git reset --hard origin/master
# - cd lbmpy
# - git remote add test $CI_REPOSITORY_URL
# - git fetch test
# - git reset --hard $CI_COMMIT_SHA
# - cd ..
# - pip install -e pystencils/
# - pip install -e lbmpy/
# - ./install_walberla.sh
# # build all integration tests
# - cd walberla/build/
# - make -j $NUM_CORES MicroBenchmarkGpuLbm LbCodeGenerationExample
# - cd apps/benchmarks/UniformGridGPU
# - make -j $NUM_CORES
# - cd ../UniformGridCPU
# - make -j $NUM_CORES
# tags:
# - docker
# - cuda
# - cudaComputeCapability6.1
# - AVX
# -------------------- Scheduled Tasks --------------------------------------------------------------------------
nightly-sympy:
stage: nightly
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/latest_python
before_script:
# - apt-get -y remove python3-sympy
- ln -s /usr/include/locale.h /usr/include/xlocale.h
# - pip3 install `grep -Eo 'sympy[>=]+[0-9\.]+' setup.py | sed 's/>/=/g'`
- pip3 install git+https://gitlab-ci-token:${CI_JOB_TOKEN}@i10git.cs.fau.de/pycodegen/pystencils.git@master#egg=pystencils
- pip install -e .
- pip install git+https://gitlab-ci-token:${CI_JOB_TOKEN}@i10git.cs.fau.de/pycodegen/pystencils.git@master#egg=pystencils
- pip install --upgrade --pre sympy
script:
- env
- pip list
- export NUM_CORES=$(nproc --all)
- mkdir -p ~/.config/matplotlib
- echo "backend:template" > ~/.config/matplotlib/matplotlibrc
- env
- pip3 list
- pytest-3 -v -n $NUM_CORES -m "not longrun" --junitxml=report.xml
- mkdir public
- pytest -v -n $NUM_CORES -m "not longrun" --junitxml=report.xml
tags:
- docker
- cuda11
- AVX
- cuda
- cudaComputeCapability6.1
artifacts:
when: always
reports:
junit: report.xml
pycodegen-integration:
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full
stage: test
when: manual
allow_failure: true
script:
- env
- pip list
- git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@i10git.cs.fau.de/pycodegen/pycodegen.git
- cd pycodegen
- git submodule sync --recursive
- git submodule update --init --recursive
- git submodule foreach git fetch origin # compare the latest master version!
- git submodule foreach git reset --hard origin/master
- cd lbmpy
- git remote add test $CI_REPOSITORY_URL
- git fetch test
- git reset --hard $CI_COMMIT_SHA
- cd ..
- pip install -e pystencils/
- pip install -e lbmpy/
- ./install_walberla.sh
# build all integration tests
- cd walberla/build/
- make -j $NUM_CORES MicroBenchmarkGpuLbm LbCodeGenerationExample
- cd apps/benchmarks/UniformGridGPU
- make -j $NUM_CORES
- cd ../UniformGridCPU
- make -j $NUM_CORES
tags:
- docker
- cuda11
- AVX
# -------------------- Documentation and deploy ------------------------------------------------------------------------
build-documentation:
stage: test
stage: docs
needs: []
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/documentation
before_script:
- pip install -e .
script:
- export PYTHONPATH=`pwd`
- pip install git+https://gitlab-ci-token:${CI_JOB_TOKEN}@i10git.cs.fau.de/pycodegen/pystencils.git@master#egg=pystencils
......@@ -219,7 +207,8 @@ build-documentation:
- sphinx-build -W -b html doc html_doc
tags:
- docker
- cuda11
- cuda
- cudaComputeCapability6.1
artifacts:
paths:
- html_doc
......@@ -227,7 +216,10 @@ build-documentation:
pages:
image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full
rules:
- if: '$CI_PIPELINE_SOURCE != "schedule" && $CI_PROJECT_PATH == "pycodegen/lbmpy" && $CI_COMMIT_BRANCH == "master"'
stage: deploy
needs: ["testsuite-cuda-py3.10", "build-documentation"]
script:
- ls -l
- mv coverage_report html_doc
......@@ -237,5 +229,3 @@ pages:
- public
tags:
- docker
only:
- master@pycodegen/lbmpy
......@@ -11,3 +11,4 @@ Contributors:
- Rudolf Weeber <weeber@icp.uni-stuttgart.de>
- Christian Godenschwager <christian.godenschwager@fau.de>
- Jan Hönig <jan.hoenig@fau.de>
- Philipp Suffa <philipp.suffa@fau.de>
------------------------ Important ---------------------------------
lbmpy is under the following GNU AGPLv3 license.
This license holds for the sources of lbmpy itself as well
as for all kernels generated with lbmpy i.e.
the output of lbmpy is also protected by the GNU AGPLv3 license.
----------------------------------------------------------------------
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
......
include README.md
include COPYING.txt
include AUTHORS.txt
include CONTRIBUTING.md
global-include *.pyx
include versioneer.py
include lbmpy/_version.py
include CHANGELOG.md
......@@ -71,6 +71,7 @@ Many thanks go to the [contributors](https://i10git.cs.fau.de/pycodegen/lbmpy/-/
If you use lbmpy in a publication, please cite the following articles:
Overview:
- F. Hennig et al, Advanced Automatic Code Generation for Multiple Relaxation-Time Lattice Boltzmann Methods. SIAM Journal on Scientific Computing, 2023. https://doi.org/10.1137/22M1531348 ([Preprint](https://arxiv.org/abs/2211.02435))
- M. Bauer et al, lbmpy: Automatic code generation for efficient parallel lattice Boltzmann methods. Journal of Computational Science, 2021. https://doi.org/10.1016/j.jocs.2020.101269 ([Preprint](https://arxiv.org/abs/2001.11806))
Multiphase:
......
......@@ -7,7 +7,7 @@
# conda env create -f conda_environment_user.yml
# . activate pystencils
#
# If you have CUDA installed and want to use your GPU, uncomment the last line to install pycuda
# If you have CUDA or ROCm installed and want to use your GPU, uncomment the last line to install cupy
#
# ----------------------------------------------------------------------------------------------------------------------
......@@ -33,4 +33,4 @@ dependencies:
- pyevtk # VTK output for serial simulations
- blitzdb # file-based No-SQL database to store simulation results
- pystencils
#- pycuda # add this if you have CUDA installed
#- cupy # add this if you have CUDA or ROCm installed
......@@ -5,13 +5,18 @@ import runpy
import sys
import warnings
import platform
import pathlib
import nbformat
from nbconvert import PythonExporter
import nbconvert
import sympy
from lbmpy._compat import IS_PYSTENCILS_2
# Trigger config file reading / creation once - to avoid race conditions when multiple instances are creating it
# at the same time
from pystencils.cpu import cpujit
if not IS_PYSTENCILS_2:
from pystencils.cpu import cpujit
# trigger cython imports - there seems to be a problem when multiple processes try to compile the same cython file
# at the same time
......@@ -19,9 +24,9 @@ try:
import pyximport
pyximport.install(language_level=3)
from lbmpy.phasefield.simplex_projection import simplex_projection_2d # NOQA
except ImportError:
pass
from lbmpy.phasefield.simplex_projection import simplex_projection_2d # NOQA
SCRIPT_FOLDER = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, os.path.abspath('lbmpy'))
......@@ -42,33 +47,42 @@ def add_path_to_ignore(path):
collect_ignore = [os.path.join(SCRIPT_FOLDER, "doc", "conf.py"),
os.path.join(SCRIPT_FOLDER, "doc", "img", "mb_discretization", "maxwell_boltzmann_stencil_plot.py")]
add_path_to_ignore('pystencils_tests/benchmark')
add_path_to_ignore('_local_tmp')
if IS_PYSTENCILS_2:
# TODO: Fix these step-by-step
collect_ignore += [
os.path.join(SCRIPT_FOLDER, "doc", "notebooks", "10_tutorial_conservative_allen_cahn_two_phase.ipynb"),
os.path.join(SCRIPT_FOLDER, "tests", "test_compiled_in_boundaries.ipynb")
]
try:
import pycuda
import cupy
except ImportError:
collect_ignore += [os.path.join(SCRIPT_FOLDER, "lbmpy_tests/test_cpu_gpu_equivalence.py")]
collect_ignore += [os.path.join(SCRIPT_FOLDER, "tests/test_cpu_gpu_equivalence.py")]
try:
import waLBerla
except ImportError:
collect_ignore += [os.path.join(SCRIPT_FOLDER, "lbmpy_tests/test_datahandling_parallel.py")]
collect_ignore += [os.path.join(SCRIPT_FOLDER, "tests/test_datahandling_parallel.py")]
try:
import blitzdb
except ImportError:
collect_ignore += [os.path.join(SCRIPT_FOLDER, "lbmpy_tests/benchmark"),
collect_ignore += [os.path.join(SCRIPT_FOLDER, "tests/benchmark"),
os.path.join(SCRIPT_FOLDER,
"lbmpy_tests/full_scenarios/kida_vortex_flow/scenario_kida_vortex_flow.py")]
"tests/full_scenarios/kida_vortex_flow/scenario_kida_vortex_flow.py"),
os.path.join(SCRIPT_FOLDER, "tests/full_scenarios/shear_wave/scenario_shear_wave.py"),
os.path.join(SCRIPT_FOLDER, "tests/test_json_serializer.py"),
os.path.join(SCRIPT_FOLDER, "src/lbmpy/db.py")]
if platform.system().lower() == 'windows':
collect_ignore += [os.path.join(SCRIPT_FOLDER, "lbmpy_tests/test_quicktests.py")]
collect_ignore += [os.path.join(SCRIPT_FOLDER, "tests/test_quicktests.py")]
sver = sympy.__version__.split(".")
if int(sver[0]) == 1 and int(sver[1]) < 2:
add_path_to_ignore('lbmpy_tests/phasefield')
collect_ignore += [os.path.join(SCRIPT_FOLDER, "lbmpy_tests/test_n_phase_boyer_noncoupled.ipynb")]
add_path_to_ignore('tests/phasefield')
collect_ignore += [os.path.join(SCRIPT_FOLDER, "tests/test_n_phase_boyer_noncoupled.ipynb")]
collect_ignore += [os.path.join(SCRIPT_FOLDER, 'setup.py')]
......@@ -104,22 +118,29 @@ class IPyNbTest(pytest.Item):
# disable matplotlib output
exec("import matplotlib.pyplot as p; "
"p.close('all'); "
"p.switch_backend('Template')", global_dict)
# in notebooks there is an implicit plt.show() - if this is not called a warning is shown when the next
# plot is created. This warning is suppressed here
# Also animations cannot be shown, which also leads to a warning.
exec("import warnings;"
"warnings.filterwarnings('ignore', 'Adding an axes using the same arguments as a previous.*');",
"warnings.filterwarnings('ignore', 'Adding an axes using the same arguments as a previous.*');"
"warnings.filterwarnings('ignore', 'Animation was deleted without rendering anything.*');",
global_dict)
with tempfile.NamedTemporaryFile() as f:
f.write(self.code.encode())
f.flush()
runpy.run_path(f.name, init_globals=global_dict, run_name=self.name)
# Close any open figures
exec("import matplotlib.pyplot as p; "
"p.close('all')", global_dict)
class IPyNbFile(pytest.File):
def collect(self):
exporter = PythonExporter()
exporter = nbconvert.PythonExporter()
exporter.exclude_markdown = True
exporter.exclude_input_prompt = True
......@@ -138,10 +159,19 @@ class IPyNbFile(pytest.File):
pass
def pytest_collect_file(path, parent):
glob_exprs = ["*demo*.ipynb", "*tutorial*.ipynb", "test_*.ipynb"]
if any(path.fnmatch(g) for g in glob_exprs):
if pytest_version >= 50403:
return IPyNbFile.from_parent(fspath=path, parent=parent)
else:
return IPyNbFile(path, parent)
if pytest_version >= 70000:
# Since pytest 7.0, usage of `py.path.local` is deprecated and `pathlib.Path` should be used instead
import pathlib
def pytest_collect_file(file_path: pathlib.Path, parent):
glob_exprs = ["*demo*.ipynb", "*tutorial*.ipynb", "test_*.ipynb"]
if any(file_path.match(g) for g in glob_exprs):
return IPyNbFile.from_parent(path=file_path, parent=parent)
else:
def pytest_collect_file(path, parent):
glob_exprs = ["*demo*.ipynb", "*tutorial*.ipynb", "test_*.ipynb"]
if any(path.fnmatch(g) for g in glob_exprs):
if pytest_version >= 50403:
return IPyNbFile.from_parent(fspath=path, parent=parent)
else:
return IPyNbFile(path, parent)
......@@ -33,7 +33,7 @@ version = re.sub(r'(\d+\.\d+)\.\d+(.*)', r'\1\2', lbmpy.__version__)
version = re.sub(r'(\.dev\d+).*?$', r'\1', version)
# The full version, including alpha/beta/rc tags.
release = lbmpy.__version__
language = None
language = 'en'
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '**.ipynb_checkpoints']
default_role = 'any'
pygments_style = 'sphinx'
......
File added
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="190.286" height="190.833" viewBox="0 0 190.286 190.833">
<defs>
<g>
<g id="glyph-0-0">
</g>
<g id="glyph-0-1">
<path d="M 3.5 1.71875 L 3.359375 1.71875 C 3.015625 1.71875 2.828125 1.625 2.84375 1.453125 C 2.84375 1.421875 2.859375 1.390625 2.859375 1.359375 L 4.328125 -3.828125 L 3.671875 -3.828125 L 3.546875 -3.40625 C 3.40625 -3.8125 3.21875 -3.953125 2.859375 -3.953125 C 1.671875 -3.953125 0.21875 -2.3125 0.21875 -0.9375 C 0.21875 -0.3125 0.578125 0.09375 1.140625 0.09375 C 1.78125 0.09375 2.1875 -0.234375 2.984375 -1.375 L 2.1875 1.25 C 2.078125 1.609375 1.921875 1.6875 1.34375 1.734375 L 1.34375 1.875 L 3.5 1.875 Z M 2.875 -3.765625 C 3.171875 -3.765625 3.40625 -3.515625 3.40625 -3.203125 C 3.40625 -2.46875 2.796875 -1.1875 2.1875 -0.6875 C 1.953125 -0.484375 1.71875 -0.375 1.5 -0.375 C 1.1875 -0.375 1 -0.640625 1 -1.0625 C 1 -1.734375 1.46875 -2.71875 2.046875 -3.3125 C 2.328125 -3.59375 2.625 -3.765625 2.875 -3.765625 Z M 2.875 -3.765625 "/>
</g>
<g id="glyph-1-0">
</g>
<g id="glyph-1-1">
<path d="M 3.59375 -1.109375 C 3.234375 -0.65625 3.140625 -0.578125 2.984375 -0.578125 C 2.8125 -0.578125 2.71875 -0.703125 2.65625 -1.046875 L 2.375 -2.453125 C 2.390625 -2.484375 2.40625 -2.5 2.453125 -2.5625 C 2.765625 -3.078125 2.984375 -3.296875 3.1875 -3.296875 C 3.25 -3.296875 3.3125 -3.28125 3.421875 -3.21875 C 3.546875 -3.140625 3.609375 -3.125 3.703125 -3.125 C 3.96875 -3.125 4.203125 -3.34375 4.203125 -3.59375 C 4.203125 -3.890625 3.953125 -4.140625 3.6875 -4.140625 C 3.265625 -4.140625 2.984375 -3.90625 2.265625 -2.90625 C 2.109375 -3.671875 2.03125 -3.890625 1.859375 -4.140625 L 0.375 -3.921875 L 0.375 -3.6875 C 0.5625 -3.703125 0.59375 -3.703125 0.6875 -3.703125 C 0.96875 -3.703125 1.09375 -3.546875 1.1875 -3.109375 L 1.453125 -1.71875 L 1.0625 -1.09375 C 0.875 -0.8125 0.78125 -0.71875 0.625 -0.71875 C 0.578125 -0.71875 0.53125 -0.75 0.4375 -0.796875 C 0.296875 -0.875 0.1875 -0.921875 0.078125 -0.921875 C -0.203125 -0.921875 -0.40625 -0.6875 -0.40625 -0.40625 C -0.40625 -0.09375 -0.171875 0.109375 0.15625 0.109375 C 0.609375 0.109375 0.8125 -0.0625 1.34375 -0.921875 L 1.546875 -1.28125 C 1.6875 -0.59375 1.765625 -0.375 1.953125 -0.109375 C 2.0625 0.03125 2.25 0.109375 2.421875 0.109375 C 2.859375 0.109375 3.234375 -0.1875 3.78125 -0.984375 Z M 3.59375 -1.109375 "/>
</g>
<g id="glyph-1-2">
<path d="M 2.859375 -1.265625 C 2.421875 -0.65625 2.140625 -0.453125 1.765625 -0.453125 C 1.375 -0.453125 1.109375 -0.78125 1.109375 -1.265625 C 1.109375 -1.828125 1.34375 -2.625 1.65625 -3.203125 C 1.890625 -3.625 2.15625 -3.84375 2.4375 -3.84375 C 2.53125 -3.84375 2.625 -3.78125 2.625 -3.6875 C 2.625 -3.65625 2.609375 -3.609375 2.5625 -3.53125 C 2.46875 -3.375 2.4375 -3.28125 2.4375 -3.171875 C 2.4375 -2.90625 2.65625 -2.703125 2.953125 -2.703125 C 3.28125 -2.703125 3.515625 -2.96875 3.515625 -3.34375 C 3.515625 -3.8125 3.109375 -4.140625 2.515625 -4.140625 C 1.25 -4.140625 -0.046875 -2.671875 -0.046875 -1.234375 C -0.046875 -0.4375 0.515625 0.109375 1.328125 0.109375 C 1.71875 0.109375 2.109375 -0.03125 2.40625 -0.28125 C 2.640625 -0.484375 2.796875 -0.65625 3.109375 -1.109375 Z M 2.859375 -1.265625 "/>
</g>
<g id="glyph-2-0">
</g>
<g id="glyph-2-1">
<path d="M 3.859375 -3.90625 L 0.875 -3.90625 L 0.875 -3.8125 C 1.265625 -3.78125 1.34375 -3.734375 1.34375 -3.5625 C 1.34375 -3.484375 1.3125 -3.328125 1.28125 -3.1875 L 0.53125 -0.53125 C 0.4375 -0.171875 0.390625 -0.140625 0.046875 -0.09375 L 0.046875 0 L 1.5625 0 L 1.5625 -0.09375 C 1.203125 -0.109375 1.09375 -0.171875 1.09375 -0.359375 C 1.09375 -0.40625 1.125 -0.5 1.15625 -0.625 L 1.53125 -1.96875 C 1.75 -1.953125 1.875 -1.9375 2.015625 -1.9375 C 2.25 -1.9375 2.28125 -1.9375 2.34375 -1.921875 C 2.421875 -1.859375 2.46875 -1.796875 2.46875 -1.671875 C 2.46875 -1.578125 2.453125 -1.5 2.421875 -1.3125 L 2.53125 -1.28125 L 2.984375 -2.6875 L 2.875 -2.71875 C 2.609375 -2.171875 2.578125 -2.171875 1.578125 -2.15625 L 1.96875 -3.546875 C 2.015625 -3.671875 2.09375 -3.703125 2.34375 -3.703125 C 3.34375 -3.703125 3.5625 -3.625 3.5625 -3.265625 C 3.5625 -3.21875 3.5625 -3.203125 3.546875 -3.125 C 3.546875 -3.078125 3.546875 -3.078125 3.546875 -3 L 3.671875 -2.984375 Z M 3.859375 -3.90625 "/>
</g>
<g id="glyph-2-2">
<path d="M 0.65625 -3.84375 C 1.015625 -3.84375 1.046875 -3.8125 1.046875 -3.6875 C 1.046875 -3.625 1.03125 -3.5625 1 -3.421875 C 0.984375 -3.390625 0.96875 -3.34375 0.96875 -3.3125 L 0.953125 -3.265625 L 0.140625 -0.28125 L 0.140625 -0.25 C 0.140625 -0.109375 0.59375 0.0625 0.9375 0.0625 C 1.84375 0.0625 2.828125 -0.984375 2.828125 -1.921875 C 2.828125 -2.34375 2.53125 -2.640625 2.140625 -2.640625 C 1.71875 -2.640625 1.40625 -2.390625 0.984375 -1.734375 C 1.296875 -2.875 1.328125 -3.03125 1.609375 -4.0625 L 1.578125 -4.09375 C 1.28125 -4.03125 1.0625 -4 0.65625 -3.953125 Z M 1.90625 -2.34375 C 2.15625 -2.34375 2.328125 -2.140625 2.328125 -1.828125 C 2.328125 -1.4375 2.015625 -0.796875 1.65625 -0.421875 C 1.4375 -0.203125 1.1875 -0.078125 0.921875 -0.078125 C 0.734375 -0.078125 0.65625 -0.140625 0.65625 -0.28125 C 0.65625 -0.640625 0.828125 -1.21875 1.078125 -1.65625 C 1.34375 -2.125 1.609375 -2.34375 1.90625 -2.34375 Z M 1.90625 -2.34375 "/>
</g>
<g id="glyph-2-3">
<path d="M 5.421875 -3.90625 L 4.3125 -3.90625 L 4.3125 -3.8125 C 4.640625 -3.78125 4.703125 -3.734375 4.703125 -3.578125 C 4.703125 -3.484375 4.65625 -3.328125 4.578125 -3.171875 L 3.453125 -0.96875 L 3.21875 -3.375 L 3.21875 -3.453125 C 3.21875 -3.703125 3.296875 -3.78125 3.625 -3.8125 L 3.625 -3.90625 L 2.203125 -3.90625 L 2.203125 -3.8125 C 2.546875 -3.796875 2.609375 -3.765625 2.640625 -3.46875 L 2.703125 -3.046875 L 1.671875 -0.96875 L 1.40625 -3.40625 C 1.40625 -3.421875 1.40625 -3.46875 1.40625 -3.484375 C 1.40625 -3.71875 1.46875 -3.765625 1.84375 -3.8125 L 1.84375 -3.90625 L 0.421875 -3.90625 L 0.421875 -3.8125 C 0.625 -3.78125 0.671875 -3.765625 0.734375 -3.71875 C 0.796875 -3.65625 0.828125 -3.53125 0.890625 -2.984375 L 1.265625 0.109375 L 1.375 0.109375 L 2.703125 -2.609375 L 2.734375 -2.609375 L 3.046875 0.109375 L 3.15625 0.109375 L 4.96875 -3.375 C 5.140625 -3.6875 5.1875 -3.734375 5.421875 -3.8125 Z M 5.421875 -3.90625 "/>
</g>
<g id="glyph-3-0">
</g>
<g id="glyph-3-1">
<path d="M 1.90625 -0.84375 C 1.609375 -0.4375 1.4375 -0.3125 1.171875 -0.3125 C 0.921875 -0.3125 0.734375 -0.515625 0.734375 -0.84375 C 0.734375 -1.21875 0.890625 -1.75 1.109375 -2.140625 C 1.265625 -2.421875 1.4375 -2.5625 1.625 -2.5625 C 1.6875 -2.5625 1.75 -2.53125 1.75 -2.46875 C 1.75 -2.4375 1.734375 -2.40625 1.703125 -2.359375 C 1.65625 -2.25 1.625 -2.1875 1.625 -2.125 C 1.625 -1.9375 1.78125 -1.8125 1.96875 -1.8125 C 2.1875 -1.8125 2.34375 -1.984375 2.34375 -2.21875 C 2.34375 -2.546875 2.078125 -2.765625 1.671875 -2.765625 C 0.828125 -2.765625 -0.03125 -1.78125 -0.03125 -0.828125 C -0.03125 -0.296875 0.34375 0.078125 0.890625 0.078125 C 1.15625 0.078125 1.40625 -0.015625 1.609375 -0.1875 C 1.765625 -0.328125 1.859375 -0.4375 2.078125 -0.734375 Z M 1.90625 -0.84375 "/>
</g>
<g id="glyph-3-2">
<path d="M 1.296875 -0.84375 L 1.203125 -0.71875 C 1.046875 -0.484375 0.921875 -0.359375 0.828125 -0.359375 C 0.78125 -0.359375 0.734375 -0.40625 0.734375 -0.453125 C 0.734375 -0.484375 0.765625 -0.6875 0.796875 -0.765625 L 1.328125 -2.765625 C 1.015625 -2.6875 0.59375 -2.640625 0.125 -2.59375 L 0.125 -2.4375 C 0.390625 -2.4375 0.484375 -2.390625 0.484375 -2.265625 C 0.484375 -2.21875 0.453125 -2.125 0.4375 -2.015625 L 0.09375 -0.734375 C 0.046875 -0.5625 0.015625 -0.40625 0.015625 -0.328125 C 0.015625 -0.109375 0.171875 0.046875 0.421875 0.046875 C 0.78125 0.046875 1 -0.125 1.421875 -0.765625 Z M 1.15625 -4.09375 C 0.953125 -4.09375 0.765625 -3.90625 0.765625 -3.703125 C 0.765625 -3.46875 0.9375 -3.296875 1.15625 -3.296875 C 1.390625 -3.296875 1.578125 -3.46875 1.578125 -3.6875 C 1.578125 -3.90625 1.375 -4.09375 1.15625 -4.09375 Z M 1.15625 -4.09375 "/>
</g>
<g id="glyph-4-0">
</g>
<g id="glyph-4-1">
<path d="M 1.078125 -0.703125 L 1 -0.609375 C 0.875 -0.40625 0.765625 -0.296875 0.6875 -0.296875 C 0.640625 -0.296875 0.609375 -0.34375 0.609375 -0.375 C 0.609375 -0.40625 0.640625 -0.578125 0.65625 -0.640625 L 1.109375 -2.296875 C 0.84375 -2.25 0.5 -2.1875 0.109375 -2.15625 L 0.109375 -2.03125 C 0.3125 -2.03125 0.40625 -1.984375 0.40625 -1.890625 C 0.40625 -1.84375 0.390625 -1.765625 0.359375 -1.6875 L 0.078125 -0.609375 C 0.03125 -0.46875 0.015625 -0.328125 0.015625 -0.265625 C 0.015625 -0.078125 0.15625 0.046875 0.359375 0.046875 C 0.65625 0.046875 0.84375 -0.109375 1.1875 -0.640625 Z M 0.96875 -3.421875 C 0.796875 -3.421875 0.640625 -3.265625 0.640625 -3.078125 C 0.640625 -2.890625 0.78125 -2.734375 0.96875 -2.734375 C 1.15625 -2.734375 1.3125 -2.890625 1.3125 -3.078125 C 1.3125 -3.265625 1.15625 -3.421875 0.96875 -3.421875 Z M 0.96875 -3.421875 "/>
</g>
<g id="glyph-5-0">
</g>
<g id="glyph-5-1">
<path d="M 1.65625 -3.171875 L 0 -3.171875 L 0 -2.8125 L 1.65625 -2.8125 Z M 1.65625 -3.171875 "/>
</g>
</g>
<clipPath id="clip-0">
<path clip-rule="nonzero" d="M 59 32 L 190.285156 32 L 190.285156 190.832031 L 59 190.832031 Z M 59 32 "/>
</clipPath>
</defs>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -9.962062 -0.00015625 L 159.405125 -0.00015625 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -9.962062 49.812344 L 159.405125 49.812344 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -9.962062 99.62875 L 159.405125 99.62875 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -9.962062 149.44125 L 159.405125 149.44125 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M -0.001125 -9.961094 L -0.001125 159.406094 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 49.815281 -9.961094 L 49.815281 159.406094 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 99.627781 -9.961094 L 99.627781 159.406094 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 149.440281 -9.961094 L 149.440281 159.406094 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0.390625%, 45.097351%, 69.802856%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 4.698094 -0.00015625 C 4.698094 2.593594 2.592625 4.695156 -0.001125 4.695156 C -2.594875 4.695156 -4.696437 2.593594 -4.696437 -0.00015625 C -4.696437 -2.593906 -2.594875 -4.695469 -0.001125 -4.695469 C 2.592625 -4.695469 4.698094 -2.593906 4.698094 -0.00015625 Z M 4.698094 -0.00015625 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0.390625%, 45.097351%, 69.802856%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 4.698094 49.812344 C 4.698094 52.406094 2.592625 54.511562 -0.001125 54.511562 C -2.594875 54.511562 -4.696437 52.406094 -4.696437 49.812344 C -4.696437 47.218594 -2.594875 45.117031 -0.001125 45.117031 C 2.592625 45.117031 4.698094 47.218594 4.698094 49.812344 Z M 4.698094 49.812344 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0.390625%, 45.097351%, 69.802856%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 4.698094 99.62875 C 4.698094 102.2225 2.592625 104.324062 -0.001125 104.324062 C -2.594875 104.324062 -4.696437 102.2225 -4.696437 99.62875 C -4.696437 97.035 -2.594875 94.929531 -0.001125 94.929531 C 2.592625 94.929531 4.698094 97.035 4.698094 99.62875 Z M 4.698094 99.62875 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0.390625%, 45.097351%, 69.802856%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 4.698094 149.44125 C 4.698094 152.035 2.592625 154.136562 -0.001125 154.136562 C -2.594875 154.136562 -4.696437 152.035 -4.696437 149.44125 C -4.696437 146.8475 -2.594875 144.745937 -0.001125 144.745937 C 2.592625 144.745937 4.698094 146.8475 4.698094 149.44125 Z M 4.698094 149.44125 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(87.057495%, 56.077576%, 1.959229%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 54.510594 -0.00015625 C 54.510594 2.593594 52.409031 4.695156 49.815281 4.695156 C 47.221531 4.695156 45.116062 2.593594 45.116062 -0.00015625 C 45.116062 -2.593906 47.221531 -4.695469 49.815281 -4.695469 C 52.409031 -4.695469 54.510594 -2.593906 54.510594 -0.00015625 Z M 54.510594 -0.00015625 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(87.057495%, 56.077576%, 1.959229%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 54.510594 49.812344 C 54.510594 52.406094 52.409031 54.511562 49.815281 54.511562 C 47.221531 54.511562 45.116062 52.406094 45.116062 49.812344 C 45.116062 47.218594 47.221531 45.117031 49.815281 45.117031 C 52.409031 45.117031 54.510594 47.218594 54.510594 49.812344 Z M 54.510594 49.812344 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(87.057495%, 56.077576%, 1.959229%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 54.510594 99.62875 C 54.510594 102.2225 52.409031 104.324062 49.815281 104.324062 C 47.221531 104.324062 45.116062 102.2225 45.116062 99.62875 C 45.116062 97.035 47.221531 94.929531 49.815281 94.929531 C 52.409031 94.929531 54.510594 97.035 54.510594 99.62875 Z M 54.510594 99.62875 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0.390625%, 45.097351%, 69.802856%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 54.510594 149.44125 C 54.510594 152.035 52.409031 154.136562 49.815281 154.136562 C 47.221531 154.136562 45.116062 152.035 45.116062 149.44125 C 45.116062 146.8475 47.221531 144.745937 49.815281 144.745937 C 52.409031 144.745937 54.510594 146.8475 54.510594 149.44125 Z M 54.510594 149.44125 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0.782776%, 61.959839%, 45.097351%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 104.323094 -0.00015625 C 104.323094 2.593594 102.221531 4.695156 99.627781 4.695156 C 97.034031 4.695156 94.932469 2.593594 94.932469 -0.00015625 C 94.932469 -2.593906 97.034031 -4.695469 99.627781 -4.695469 C 102.221531 -4.695469 104.323094 -2.593906 104.323094 -0.00015625 Z M 104.323094 -0.00015625 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0.782776%, 61.959839%, 45.097351%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 104.323094 49.812344 C 104.323094 52.406094 102.221531 54.511562 99.627781 54.511562 C 97.034031 54.511562 94.932469 52.406094 94.932469 49.812344 C 94.932469 47.218594 97.034031 45.117031 99.627781 45.117031 C 102.221531 45.117031 104.323094 47.218594 104.323094 49.812344 Z M 104.323094 49.812344 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(87.057495%, 56.077576%, 1.959229%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 104.323094 99.62875 C 104.323094 102.2225 102.221531 104.324062 99.627781 104.324062 C 97.034031 104.324062 94.932469 102.2225 94.932469 99.62875 C 94.932469 97.035 97.034031 94.929531 99.627781 94.929531 C 102.221531 94.929531 104.323094 97.035 104.323094 99.62875 Z M 104.323094 99.62875 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(87.057495%, 56.077576%, 1.959229%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 104.323094 149.44125 C 104.323094 152.035 102.221531 154.136562 99.627781 154.136562 C 97.034031 154.136562 94.932469 152.035 94.932469 149.44125 C 94.932469 146.8475 97.034031 144.745937 99.627781 144.745937 C 102.221531 144.745937 104.323094 146.8475 104.323094 149.44125 Z M 104.323094 149.44125 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0.782776%, 61.959839%, 45.097351%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 154.1395 -0.00015625 C 154.1395 2.593594 152.034031 4.695156 149.440281 4.695156 C 146.846531 4.695156 144.744969 2.593594 144.744969 -0.00015625 C 144.744969 -2.593906 146.846531 -4.695469 149.440281 -4.695469 C 152.034031 -4.695469 154.1395 -2.593906 154.1395 -0.00015625 Z M 154.1395 -0.00015625 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0.782776%, 61.959839%, 45.097351%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 154.1395 49.812344 C 154.1395 52.406094 152.034031 54.511562 149.440281 54.511562 C 146.846531 54.511562 144.744969 52.406094 144.744969 49.812344 C 144.744969 47.218594 146.846531 45.117031 149.440281 45.117031 C 152.034031 45.117031 154.1395 47.218594 154.1395 49.812344 Z M 154.1395 49.812344 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0.782776%, 61.959839%, 45.097351%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 154.1395 99.62875 C 154.1395 102.2225 152.034031 104.324062 149.440281 104.324062 C 146.846531 104.324062 144.744969 102.2225 144.744969 99.62875 C 144.744969 97.035 146.846531 94.929531 149.440281 94.929531 C 152.034031 94.929531 154.1395 97.035 154.1395 99.62875 Z M 154.1395 99.62875 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(87.057495%, 56.077576%, 1.959229%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 154.1395 149.44125 C 154.1395 152.035 152.034031 154.136562 149.440281 154.136562 C 146.846531 154.136562 144.744969 152.035 144.744969 149.44125 C 144.744969 146.8475 146.846531 144.745937 149.440281 144.745937 C 152.034031 144.745937 154.1395 146.8475 154.1395 149.44125 Z M 154.1395 149.44125 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0%, 0%, 0%)" fill-opacity="1" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 88.381687 65.75375 C 88.381687 68.3475 86.280125 70.449062 83.686375 70.449062 C 81.092625 70.449062 78.991062 68.3475 78.991062 65.75375 C 78.991062 63.16 81.092625 61.058437 83.686375 61.058437 C 86.280125 61.058437 88.381687 63.16 88.381687 65.75375 Z M 88.381687 65.75375 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<g clip-path="url(#clip-0)">
<path fill="none" stroke-width="1.99255" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 149.440281 109.589687 C 95.252781 100.035 59.073094 48.363125 68.627781 -5.824375 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
</g>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-dasharray="2.98883 2.98883" stroke-miterlimit="10" d="M 4.98325 144.460781 L 44.830906 104.609219 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-dasharray="2.98883 2.98883" stroke-miterlimit="10" d="M 54.79575 94.644375 L 94.647312 54.796719 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 55.842625 96.589687 L 79.702 72.726406 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0%, 0%, 0%)" fill-opacity="1" d="M 74.222656 71.777344 L 75.855469 76.683594 L 76.265625 73.820312 L 79.125 73.414062 "/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 53.799656 92.652187 L 77.659031 68.792812 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0%, 0%, 0%)" fill-opacity="1" d="M 100.125 103.660156 L 98.492188 98.757812 L 98.082031 101.617188 L 95.222656 102.023438 "/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 7.026219 145.406094 L 44.830906 107.5975 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0%, 0%, 0%)" fill-opacity="1" d="M 25.40625 22.960938 L 27.039062 27.863281 L 27.449219 25.003906 L 30.308594 24.59375 "/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-dasharray="2.98883 2.98883" stroke-miterlimit="10" d="M 19.924656 65.75375 L 83.686375 65.75375 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill="none" stroke-width="0.99628" stroke-linecap="butt" stroke-linejoin="miter" stroke="rgb(0%, 0%, 0%)" stroke-opacity="1" stroke-miterlimit="10" d="M 24.905125 68.644375 L 24.905125 96.738125 " transform="matrix(1, 0, 0, -1, 20.423, 170.41)"/>
<path fill-rule="nonzero" fill="rgb(0%, 0%, 0%)" fill-opacity="1" d="M 45.328125 104.65625 L 47.640625 100.03125 L 45.328125 101.765625 L 43.019531 100.03125 "/>
<path fill-rule="nonzero" fill="rgb(0%, 0%, 0%)" fill-opacity="1" d="M 45.328125 70.78125 L 43.019531 75.40625 L 45.328125 73.671875 L 47.640625 75.40625 "/>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-1" x="39.103" y="89.761"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-1" x="24.961" y="17.349"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-2-1" x="29.594" y="18.694"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-2-1" x="33.748432" y="18.694"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-1" x="76.852" y="67.163"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-2-1" x="81.484" y="68.507"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-1" x="127.248" y="116.953"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-2-2" x="131.731" y="118.298"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-1" x="110.094" y="105.968"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-2-3" x="114.577" y="107.312"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-1" x="90.172" y="85.461"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-3-1" x="94.954" y="86.806"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-4-1" x="97.733" y="87.934"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-0-1" x="75.228" y="91.006"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-3-1" x="80.01" y="92.351"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-5-1" x="82.639" y="93.298"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-4-1" x="82.789" y="94.344"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-1-2" x="42.409" y="37.257"/>
</g>
<g fill="rgb(0%, 0%, 0%)" fill-opacity="1">
<use xlink:href="#glyph-3-2" x="46.539" y="38.602"/>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="53.913788mm"
height="53.913788mm"
viewBox="0 0 53.913788 53.913788"
version="1.1"
id="svg834"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="lbmpy-logo.svg"
inkscape:export-filename="/local/bauer/code/lbmpy/lbmpy/doc/img/logo.png"
inkscape:export-xdpi="70.669998"
inkscape:export-ydpi="70.669998"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs828">
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1421"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-7"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-7"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-6-9"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-7-4"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-7-5"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-2"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-3"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-2-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-2-5"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-3-7"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-2-6-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-2-5-9"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-3-7-4"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-2-6-3-0"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-2-5-9-6"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#c6c6c6;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-3-7-4-0"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-2-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-2-8"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-3-4"
is_visible="true"
lpeversion="0" />
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4608">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4610" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4612" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4614" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4616" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4618" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4632">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4634" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4636" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4638" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4640" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4642" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4620">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4622" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4624" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4626" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4628" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4630" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4596">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4598" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4600" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4602" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4604" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4606" />
</filter>
<inkscape:path-effect
effect="spiro"
id="path-effect4188-5"
is_visible="true"
lpeversion="0" />
<inkscape:path-effect
effect="spiro"
id="path-effect4188"
is_visible="true"
lpeversion="0" />
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4608-0">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4610-2" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4612-5" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4614-7" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4616-6" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4618-9" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4632-1">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4634-9" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4636-8" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4638-7" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4640-6" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4642-5" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4620-1">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4622-1" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4624-4" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4626-8" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4628-5" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4630-7" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4596-6">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4598-6" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4600-9" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4602-1" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4604-4" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4606-3" />
</filter>
<inkscape:path-effect
effect="spiro"
id="path-effect4188-5-6"
is_visible="true"
lpeversion="0" />
<inkscape:path-effect
effect="spiro"
id="path-effect4188-7"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-3"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1421-6"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-75"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-5"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-6"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-6-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-7-9"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-7-1"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-2-27"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-2-0"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-3-9"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-2-6-36"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-2-5-0"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-3-7-6"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-2-6-3-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-2-5-9-61"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-3-7-4-8"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-2-2-7"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-2-8-9"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-3-4-2"
is_visible="true"
lpeversion="0" />
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-8-6-9-0"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1421-2-7-4-2"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#dddddd;fill-opacity:1;fill-rule:evenodd;stroke:#dddddd;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<inkscape:path-effect
effect="spiro"
id="path-effect1404-7-7-5-3"
is_visible="true"
lpeversion="0" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="158.57143"
inkscape:cy="78.571429"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1664"
inkscape:window-height="1113"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:showpageshadow="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid1886"
originx="-9.840785"
originy="-227.28709"
spacingy="1"
spacingx="1"
units="mm" />
</sodipodi:namedview>
<metadata
id="metadata831">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-9.8407853,-15.799119)">
<rect
style="opacity:1;fill:#646ecb;fill-opacity:1;stroke:#d2d2d2;stroke-width:0.509157;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect1396"
width="53.404633"
height="53.404633"
x="10.095364"
y="16.053698"
ry="3.0735996"
inkscape:export-xdpi="188.45"
inkscape:export-ydpi="188.45" />
<path
style="font-weight:bold;font-size:16.9333px;line-height:125%;font-family:'Latin Modern Mono Light';-inkscape-font-specification:'Latin Modern Mono Light, Bold';letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583px"
d="m 21.505785,62.578241 c 0,-0.626532 -0.474132,-0.643466 -0.795865,-0.643466 h -2.015062 v -8.26345 c 0,-0.609599 -0.118533,-0.812798 -0.795865,-0.812798 h -2.607729 c -0.321732,0 -0.812798,0.01693 -0.812798,0.643465 0,0.609599 0.507999,0.626532 0.795865,0.626532 h 2.015063 v 7.806251 h -1.99813 c -0.321732,0 -0.812798,0.01693 -0.812798,0.643466 0,0.609599 0.507999,0.626532 0.795865,0.626532 h 5.435589 c 0.3048,0 0.795865,-0.01693 0.795865,-0.626532 z m 9.228643,-3.064927 c 0,-2.116663 -1.54093,-3.776126 -3.352793,-3.776126 -0.728132,0 -1.405464,0.237066 -1.964263,0.643465 v -2.709328 c 0,-0.609599 -0.118533,-0.812798 -0.795865,-0.812798 h -1.202265 c -0.321732,0 -0.812798,0.01693 -0.812798,0.643465 0,0.609599 0.507999,0.626532 0.795865,0.626532 h 0.609599 v 8.263451 c 0,0.406399 0.01693,0.812798 0.711198,0.812798 0.524933,0 0.660399,-0.237066 0.677332,-0.575732 0.643466,0.541865 1.303865,0.677332 1.79493,0.677332 1.862663,0 3.53906,-1.625597 3.53906,-3.793059 z m -1.388531,0 c 0,1.49013 -1.083731,2.523061 -2.184395,2.523061 -1.202265,0 -1.727197,-1.371597 -1.727197,-2.116662 v -1.202265 c 0,-0.914398 0.897465,-1.710263 1.862663,-1.710263 1.151464,0 2.048929,1.151465 2.048929,2.506129 z m 10.820373,3.064927 c 0,-0.558799 -0.321733,-0.643466 -0.931331,-0.643466 v -3.860792 c 0,-0.355599 -0.03387,-2.336795 -1.608664,-2.336795 -0.474132,0 -1.117598,0.186266 -1.608663,0.745065 -0.287867,-0.491066 -0.745066,-0.745065 -1.269998,-0.745065 -0.491066,0 -0.948265,0.169333 -1.337731,0.474132 -0.118533,-0.372533 -0.440265,-0.389466 -0.745065,-0.389466 h -0.524932 c -0.3048,0 -0.812799,0.03387 -0.812799,0.626532 0,0.558799 0.321733,0.643466 0.931332,0.643466 v 4.842923 c -0.609599,0 -0.931332,0.08467 -0.931332,0.643466 0,0.609599 0.524933,0.626532 0.812799,0.626532 h 1.43933 c 0.3048,0 0.761999,-0.01693 0.761999,-0.626532 0,-0.558799 -0.270933,-0.643466 -0.880532,-0.643466 v -2.827861 c 0,-1.354664 0.575732,-2.099729 1.219198,-2.099729 0.321733,0 0.474132,0.270933 0.474132,1.219198 v 3.708392 c -0.355599,0.01693 -0.677332,0.1016 -0.677332,0.643466 0,0.609599 0.474133,0.626532 0.761999,0.626532 h 1.236131 c 0.304799,0 0.761998,-0.01693 0.761998,-0.626532 0,-0.558799 -0.287866,-0.643466 -0.897465,-0.643466 v -2.827861 c 0,-1.354664 0.592666,-2.099729 1.219198,-2.099729 0.338666,0 0.474132,0.270933 0.474132,1.219198 v 3.708392 c -0.338666,0.01693 -0.660398,0.1016 -0.660398,0.643466 0,0.609599 0.474132,0.626532 0.745065,0.626532 h 1.236131 c 0.304799,0 0.812798,-0.01693 0.812798,-0.626532 z m 9.829776,-3.064927 c 0,-2.116663 -1.540931,-3.776126 -3.352794,-3.776126 -0.728132,0 -1.422397,0.237066 -1.981196,0.660398 -0.01693,-0.389466 -0.169333,-0.575732 -0.778932,-0.575732 H 42.68086 c -0.321733,0 -0.812798,0.03387 -0.812798,0.643466 0,0.609598 0.507999,0.626532 0.795865,0.626532 h 0.609598 v 8.500516 H 42.68086 c -0.321733,0 -0.812798,0.01693 -0.812798,0.643466 0,0.609598 0.507999,0.626532 0.795865,0.626532 h 2.624661 c 0.287866,0 0.795865,-0.01693 0.795865,-0.626532 0,-0.626532 -0.491065,-0.643466 -0.812798,-0.643466 h -0.592666 v -2.963327 c 0.643466,0.558799 1.286931,0.677332 1.777997,0.677332 1.862663,0 3.53906,-1.625597 3.53906,-3.793059 z m -1.388531,0 c 0,1.49013 -1.083731,2.523061 -2.184396,2.523061 -1.202264,0 -1.727196,-1.371597 -1.727196,-2.116662 v -1.202265 c 0,-0.914398 0.897465,-1.710263 1.862663,-1.710263 1.151464,0 2.048929,1.151465 2.048929,2.506129 z M 59.08922,56.46532 c 0,-0.626533 -0.474133,-0.643466 -0.795865,-0.643466 h -1.930397 c -0.304799,0 -0.795865,0.03387 -0.795865,0.626532 0,0.626532 0.474133,0.643466 0.795865,0.643466 h 0.270933 l -1.456264,4.419591 -1.676396,-4.419591 h 0.220133 c 0.304799,0 0.795865,-0.01693 0.795865,-0.626532 0,-0.626533 -0.474133,-0.643466 -0.795865,-0.643466 h -1.930397 c -0.321732,0 -0.795865,0.01693 -0.795865,0.643466 0,0.609598 0.491066,0.626532 0.795865,0.626532 H 52.2143 l 2.370662,5.977455 c -0.06773,0.186266 -0.423333,1.371597 -0.609599,1.744129 -0.338666,0.643466 -0.863598,1.032932 -1.185331,1.032932 0.01693,-0.06773 0.186266,-0.118533 0.186266,-0.372533 0,-0.491066 -0.355599,-0.846665 -0.846665,-0.846665 -0.524932,0 -0.846665,0.355599 -0.846665,0.846665 0,0.761999 0.609599,1.490131 1.490131,1.490131 1.69333,0 2.523062,-2.252129 2.590795,-2.438396 l 2.523061,-7.433718 h 0.4064 c 0.304799,0 0.795865,-0.01693 0.795865,-0.626532 z"
id="text1392"
aria-label="lbm py" />
<path
style="fill:none;fill-rule:evenodd;stroke:#dddddd;stroke-width:0.845195;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-8-6-9)"
d="M 36.797679,33.475 H 23.568513"
id="path1402-8-0-4"
inkscape:connector-curvature="0"
inkscape:path-effect="#path-effect1404-7-7-5"
inkscape:original-d="m 36.797679,33.475 c -4.259608,0.03317 -8.970011,-0.03362 -13.229166,0"
sodipodi:nodetypes="cc"
inkscape:export-xdpi="188.45"
inkscape:export-ydpi="188.45" />
<g
id="g9842"
inkscape:export-xdpi="188.45"
inkscape:export-ydpi="188.45">
<path
sodipodi:nodetypes="cc"
inkscape:original-d="m 36.797679,33.475 c 2.23e-4,-4.259735 2.23e-4,-8.969879 0,-13.229167"
inkscape:path-effect="#path-effect1404"
inkscape:connector-curvature="0"
id="path1402"
d="M 36.797679,33.475 V 20.245833"
style="fill:none;fill-rule:evenodd;stroke:#dddddd;stroke-width:0.845195;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send)" />
<path
sodipodi:nodetypes="cc"
inkscape:original-d="m 36.797679,33.475 c 4.259736,2.23e-4 8.969879,2.23e-4 13.229167,0"
inkscape:path-effect="#path-effect1404-7"
inkscape:connector-curvature="0"
id="path1402-8"
d="M 36.797679,33.475 H 50.026846"
style="fill:none;fill-rule:evenodd;stroke:#dddddd;stroke-width:0.845195;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-8)" />
<path
sodipodi:nodetypes="cc"
inkscape:original-d="m 36.797679,33.475 c 0.03317,4.259607 -0.03362,8.97001 0,13.229166"
inkscape:path-effect="#path-effect1404-7-7"
inkscape:connector-curvature="0"
id="path1402-8-0"
d="M 36.797679,33.475 V 46.704166"
style="fill:none;fill-rule:evenodd;stroke:#dddddd;stroke-width:0.845195;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-8-6)" />
<path
sodipodi:nodetypes="cc"
inkscape:original-d="m 36.797679,33.475 c 4.259736,2.23e-4 8.13389,-13.228083 12.393178,-13.228306"
inkscape:path-effect="#path-effect1404-7-3"
inkscape:connector-curvature="0"
id="path1402-8-9"
d="M 36.797679,33.475 49.190857,20.246694"
style="fill:none;fill-rule:evenodd;stroke:#dddddd;stroke-width:0.845195;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-8-2)" />
<path
sodipodi:nodetypes="cc"
inkscape:original-d="M 36.797679,33.475 C 32.537943,33.475223 27.827801,20.246056 23.568513,20.245833"
inkscape:path-effect="#path-effect1404-7-3-7"
inkscape:connector-curvature="0"
id="path1402-8-9-4"
d="M 36.797679,33.475 23.568513,20.245833"
style="fill:none;fill-rule:evenodd;stroke:#dddddd;stroke-width:0.845195;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-8-2-6)" />
<path
sodipodi:nodetypes="cc"
inkscape:original-d="M 36.797679,33.475 C 32.537943,33.474776 27.827801,46.703943 23.568513,46.704166"
inkscape:path-effect="#path-effect1404-7-3-7-4"
inkscape:connector-curvature="0"
id="path1402-8-9-4-4"
d="M 36.797679,33.475 23.568513,46.704166"
style="fill:none;fill-rule:evenodd;stroke:#dddddd;stroke-width:0.845195;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-8-2-6-3)" />
<path
sodipodi:nodetypes="cc"
inkscape:original-d="m 36.797679,33.475 c 4.259736,-2.23e-4 7.646962,13.228943 11.90625,13.229166"
inkscape:path-effect="#path-effect1404-7-3-4"
inkscape:connector-curvature="0"
id="path1402-8-9-3"
d="m 36.797679,33.475 11.90625,13.229166"
style="fill:none;fill-rule:evenodd;stroke:#dddddd;stroke-width:0.845195;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-8-2-2)" />
</g>
</g>
</svg>
......@@ -2,23 +2,23 @@
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="53.913788mm"
height="53.913788mm"
viewBox="0 0 53.913788 53.913788"
version="1.1"
id="svg834"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="logo.svg"
inkscape:export-filename="/local/bauer/code/lbmpy/lbmpy/doc/img/logo.png"
inkscape:export-xdpi="70.669998"
inkscape:export-ydpi="70.669998">
inkscape:export-ydpi="70.669998"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs828">
<marker
......@@ -641,25 +641,31 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="158.26067"
inkscape:cy="-4.9825309"
inkscape:cx="158.21429"
inkscape:cy="251.78571"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1214"
inkscape:window-height="1052"
inkscape:window-x="1482"
inkscape:window-y="524"
inkscape:window-width="1557"
inkscape:window-height="1122"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0">
fit-margin-bottom="0"
inkscape:showpageshadow="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid1886"
originx="-9.8407853"
originy="-227.28709" />
originy="-227.28709"
spacingy="1"
spacingx="1"
units="mm" />
</sodipodi:namedview>
<metadata
id="metadata831">
......@@ -688,21 +694,11 @@
ry="3.0735996"
inkscape:export-xdpi="188.45"
inkscape:export-ydpi="188.45" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11666656px;line-height:125%;font-family:'Latin Modern Mono Light';-inkscape-font-specification:'Latin Modern Mono Light, ';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="13.547134"
y="63.204773"
<path
style="font-weight:bold;font-size:16.9333px;line-height:125%;font-family:'Latin Modern Mono Light';-inkscape-font-specification:'Latin Modern Mono Light, Bold';letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.264583px"
d="m 21.505785,62.578241 c 0,-0.626532 -0.474132,-0.643466 -0.795865,-0.643466 h -2.015062 v -8.26345 c 0,-0.609599 -0.118533,-0.812798 -0.795865,-0.812798 h -2.607729 c -0.321732,0 -0.812798,0.01693 -0.812798,0.643465 0,0.609599 0.507999,0.626532 0.795865,0.626532 h 2.015063 v 7.806251 h -1.99813 c -0.321732,0 -0.812798,0.01693 -0.812798,0.643466 0,0.609599 0.507999,0.626532 0.795865,0.626532 h 5.435589 c 0.3048,0 0.795865,-0.01693 0.795865,-0.626532 z m 9.228643,-3.064927 c 0,-2.116663 -1.54093,-3.776126 -3.352793,-3.776126 -0.728132,0 -1.405464,0.237066 -1.964263,0.643465 v -2.709328 c 0,-0.609599 -0.118533,-0.812798 -0.795865,-0.812798 h -1.202265 c -0.321732,0 -0.812798,0.01693 -0.812798,0.643465 0,0.609599 0.507999,0.626532 0.795865,0.626532 h 0.609599 v 8.263451 c 0,0.406399 0.01693,0.812798 0.711198,0.812798 0.524933,0 0.660399,-0.237066 0.677332,-0.575732 0.643466,0.541865 1.303865,0.677332 1.79493,0.677332 1.862663,0 3.53906,-1.625597 3.53906,-3.793059 z m -1.388531,0 c 0,1.49013 -1.083731,2.523061 -2.184395,2.523061 -1.202265,0 -1.727197,-1.371597 -1.727197,-2.116662 v -1.202265 c 0,-0.914398 0.897465,-1.710263 1.862663,-1.710263 1.151464,0 2.048929,1.151465 2.048929,2.506129 z m 10.820373,3.064927 c 0,-0.558799 -0.321733,-0.643466 -0.931331,-0.643466 v -3.860792 c 0,-0.355599 -0.03387,-2.336795 -1.608664,-2.336795 -0.474132,0 -1.117598,0.186266 -1.608663,0.745065 -0.287867,-0.491066 -0.745066,-0.745065 -1.269998,-0.745065 -0.491066,0 -0.948265,0.169333 -1.337731,0.474132 -0.118533,-0.372533 -0.440265,-0.389466 -0.745065,-0.389466 h -0.524932 c -0.3048,0 -0.812799,0.03387 -0.812799,0.626532 0,0.558799 0.321733,0.643466 0.931332,0.643466 v 4.842923 c -0.609599,0 -0.931332,0.08467 -0.931332,0.643466 0,0.609599 0.524933,0.626532 0.812799,0.626532 h 1.43933 c 0.3048,0 0.761999,-0.01693 0.761999,-0.626532 0,-0.558799 -0.270933,-0.643466 -0.880532,-0.643466 v -2.827861 c 0,-1.354664 0.575732,-2.099729 1.219198,-2.099729 0.321733,0 0.474132,0.270933 0.474132,1.219198 v 3.708392 c -0.355599,0.01693 -0.677332,0.1016 -0.677332,0.643466 0,0.609599 0.474133,0.626532 0.761999,0.626532 h 1.236131 c 0.304799,0 0.761998,-0.01693 0.761998,-0.626532 0,-0.558799 -0.287866,-0.643466 -0.897465,-0.643466 v -2.827861 c 0,-1.354664 0.592666,-2.099729 1.219198,-2.099729 0.338666,0 0.474132,0.270933 0.474132,1.219198 v 3.708392 c -0.338666,0.01693 -0.660398,0.1016 -0.660398,0.643466 0,0.609599 0.474132,0.626532 0.745065,0.626532 h 1.236131 c 0.304799,0 0.812798,-0.01693 0.812798,-0.626532 z m 9.829776,-3.064927 c 0,-2.116663 -1.540931,-3.776126 -3.352794,-3.776126 -0.728132,0 -1.422397,0.237066 -1.981196,0.660398 -0.01693,-0.389466 -0.169333,-0.575732 -0.778932,-0.575732 H 42.68086 c -0.321733,0 -0.812798,0.03387 -0.812798,0.643466 0,0.609598 0.507999,0.626532 0.795865,0.626532 h 0.609598 v 8.500516 H 42.68086 c -0.321733,0 -0.812798,0.01693 -0.812798,0.643466 0,0.609598 0.507999,0.626532 0.795865,0.626532 h 2.624661 c 0.287866,0 0.795865,-0.01693 0.795865,-0.626532 0,-0.626532 -0.491065,-0.643466 -0.812798,-0.643466 h -0.592666 v -2.963327 c 0.643466,0.558799 1.286931,0.677332 1.777997,0.677332 1.862663,0 3.53906,-1.625597 3.53906,-3.793059 z m -1.388531,0 c 0,1.49013 -1.083731,2.523061 -2.184396,2.523061 -1.202264,0 -1.727196,-1.371597 -1.727196,-2.116662 v -1.202265 c 0,-0.914398 0.897465,-1.710263 1.862663,-1.710263 1.151464,0 2.048929,1.151465 2.048929,2.506129 z M 59.08922,56.46532 c 0,-0.626533 -0.474133,-0.643466 -0.795865,-0.643466 h -1.930397 c -0.304799,0 -0.795865,0.03387 -0.795865,0.626532 0,0.626532 0.474133,0.643466 0.795865,0.643466 h 0.270933 l -1.456264,4.419591 -1.676396,-4.419591 h 0.220133 c 0.304799,0 0.795865,-0.01693 0.795865,-0.626532 0,-0.626533 -0.474133,-0.643466 -0.795865,-0.643466 h -1.930397 c -0.321732,0 -0.795865,0.01693 -0.795865,0.643466 0,0.609598 0.491066,0.626532 0.795865,0.626532 H 52.2143 l 2.370662,5.977455 c -0.06773,0.186266 -0.423333,1.371597 -0.609599,1.744129 -0.338666,0.643466 -0.863598,1.032932 -1.185331,1.032932 0.01693,-0.06773 0.186266,-0.118533 0.186266,-0.372533 0,-0.491066 -0.355599,-0.846665 -0.846665,-0.846665 -0.524932,0 -0.846665,0.355599 -0.846665,0.846665 0,0.761999 0.609599,1.490131 1.490131,1.490131 1.69333,0 2.523062,-2.252129 2.590795,-2.438396 l 2.523061,-7.433718 h 0.4064 c 0.304799,0 0.795865,-0.01693 0.795865,-0.626532 z"
id="text1392"
inkscape:export-xdpi="188.45"
inkscape:export-ydpi="188.45"><tspan
sodipodi:role="line"
id="tspan1390"
x="13.547134"
y="63.204773"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16.93333244px;font-family:'Latin Modern Mono Light';-inkscape-font-specification:'Latin Modern Mono Light, Bold';fill:#ffffff;stroke-width:0.26458332px">lbm<tspan
style="font-size:2.82222223px"
id="tspan1398"> </tspan>py</tspan></text>
aria-label="lbm py" />
<path
style="fill:none;fill-rule:evenodd;stroke:#dddddd;stroke-width:0.84519458;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-8-6-9)"
d="M 36.797679,33.475 H 23.568513"
......
......@@ -6,6 +6,9 @@ lbmpy
:maxdepth: 2
sphinx/tutorials.rst
sphinx/methods.rst
sphinx/boundary_conditions.rst
sphinx/forcemodels.rst
sphinx/api.rst
......
Source diff could not be displayed: it is too large. Options to address this: view the blob.
%% Cell type:code id: tags:
 
``` python
import pytest
pytest.importorskip('pycuda')
pytest.importorskip('cupy')
```
 
%% Output
 
<module 'pycuda' from '/home/markus/miniconda3/envs/pystencils/lib/python3.8/site-packages/pycuda/__init__.py'>
<module 'cupy' from '/home/markus/.local/lib/python3.11/site-packages/cupy/__init__.py'>
 
%% Cell type:code id: tags:
 
``` python
from lbmpy.session import *
from pystencils import Target
```
 
%% Cell type:markdown id: tags:
 
# Tutorial 01: Running pre-defined scenarios
 
 
*lbmpy* is a module to do Lattice Boltzmann simulations in Python.
 
In this tutorial you will get a broad overview of *lbmpy*'s features. We will run some of the included scenarios that come with *lbmpy*, like a channel flow and a lid driven cavity. This tutorial uses the simple, high-level API of *lbmpy*, while the following tutorials go into the low-level details.
 
The only prerequisite for this tutorial is basic Python and [numpy](http://www.numpy.org/) knowledge.
 
 
> #### What's special about *lbmpy* ?
> The LBM kernels (i.e. the functions that do all the computations) are not written in Python. Instead *lbmpy* generates optimized C or CUDA code for these kernels and compiles it using the *pystencils* module. In that way we get very fast LBM kernels, a lot faster than pure Python implementations and probably also faster than handwritten C kernels. This sounds complicated, but we don't have to care about all this background work, since all compiled kernels are available as Python functions again. Thus *lbmpy* can be used just like any other Python package.
 
 
## Lid Driven Cavity
 
We start by simulating a fluid in a rectangular box, where one wall (the lid) is moving. This is called a 'lid driven cavity'. At the stationary walls *no-slip* boundary conditions are set, which enforce zero velocity at the wall. At the lid there is a *velocity bounce back (UBB)* boundary condition, which sets zero normal velocity and a prescribed tangential velocity.
 
We don't have to set up all these boundary conditions manually since there is a function ``create_lid_driven_cavity`` that does all the work for us. This function takes the tangential velocity of the lid, which drives the flow. It is given in lattice units and to get a stable simulation it should be smaller than 0.1. The `relaxation_rate` determines the viscosity of the fluid: Small relaxation rates correspond to high viscosity. The `relaxation_rate` has to be between 0 and 2.
 
%% Cell type:code id: tags:
 
``` python
ldc_scenario = create_lid_driven_cavity(domain_size=(80,50), lid_velocity=0.01, relaxation_rate=1.95)
ldc_scenario.method
```
 
%% Output
 
<lbmpy.methods.momentbased.momentbasedmethod.MomentBasedLbMethod at 0x7fe7a8828d30>
 
%% Cell type:markdown id: tags:
 
The *run* method of the scenario runs the specified amount of time steps. When you run the next cell, 2000 time steps are executed and the velocity field is plotted. You can run the cell multiple times to see a time evolution.
 
%% Cell type:code id: tags:
 
``` python
ldc_scenario.run(2000)
plt.figure(dpi=200)
plt.vector_field(ldc_scenario.velocity_slice(), step=2);
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
### Variations to experiment with:
- simulate with a higher ``relaxation_rate`` (i.e. higher [Reynolds number](https://en.wikipedia.org/wiki/Reynolds_number)), keep in mind that the ``relaxation_rate`` has to be smaller than 2. You might have to increase (``domain_size``) to keep the simulation stable and run more time steps to get to the stationary solution. You also might want to increase the ``step`` parameter for the plot, to reduce the number of arrows.
- run a 3D simulation by adding a third dimension size to ``domain_size``. The ``velocity`` property of the scenario is now a 3D field that has to be sliced before it can be plotted, e.g. ``ldc_scenario.velocity[:, :, 10, 0:2]`` generates a slice at ``z=10`` and plot the ``x`` and ``y`` component of the velocity.
 
%% Cell type:markdown id: tags:
 
## Fully periodic flow
 
Another simple scenario is a box with periodic boundary conditions in all directions. We initialize a non-zero initial velocity field, which is decaying over time due to viscous effects and the absence of driving forces or boundary conditions. In this example we initialize a shear flow where in one stripe the fluid is moving to the left, and everywhere else to the right. We perturbe this initial velocity field with random noise to get an instable shear layer.
 
%% Cell type:code id: tags:
 
``` python
width, height = 200, 60
velocity_magnitude = 0.05
init_vel = np.zeros((width,height,2))
# fluid moving to the right everywhere...
init_vel[:, :, 0] = velocity_magnitude
# ...except at a stripe in the middle, where it moves left
init_vel[:, height//3 : height//3*2, 0] = -velocity_magnitude
# small random y velocity component
init_vel[:, :, 1] = 0.1 * velocity_magnitude * np.random.rand(width,height)
 
plt.figure(dpi=200)
plt.vector_field(init_vel, step=4);
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
With this initial velocity field we create a simulation scenario:
 
%% Cell type:code id: tags:
 
``` python
shear_flow_scenario = create_fully_periodic_flow(initial_velocity=init_vel, relaxation_rate=1.97)
```
 
%% Cell type:code id: tags:
 
``` python
shear_flow_scenario.run(500)
plt.figure(dpi=200)
plt.vector_field(shear_flow_scenario.velocity[:, :])
```
 
%% Output
 
<matplotlib.quiver.Quiver at 0x7fe7a80e2bb0>
 
 
%% Cell type:markdown id: tags:
 
Instead of plotting a single point in time we create an animation. For this we first have to
define an update function that runs a few time steps and returns the field to plot.
This function is called ``iterations`` times, then the animation stops.
To cancel the animation while it is running, hit the stop button in the IPython menu bar.
 
%% Cell type:code id: tags:
 
``` python
# def next_frame():
# shear_flow_scenario.run(50)
# return shear_flow_scenario.velocity[:, :]
# plt.figure(dpi=200)
# display_animation(plt.vector_field_animation(next_frame, step=2), iterations=50)
```
 
%% Cell type:markdown id: tags:
 
Vortices are created between the two layers. This phenomenon is called [Kelvin-Helmholz Instability](https://en.wikipedia.org/wiki/Kelvin%E2%80%93Helmholtz_instability). For a better visualization of the vortices we can plot the [vorticity](https://en.wikipedia.org/wiki/Vorticity) of velocity field:
 
%% Cell type:code id: tags:
 
``` python
plt.figure(dpi=200)
plt.scalar_field(vorticity_2d(shear_flow_scenario.velocity[:, :]));
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
### Variations to experiment with:
- make an animation of the vorticity
- increase the ``relaxation_rate``. What is the maximum relaxation rate you can get before the simulation gets unstable?
- use an entropic method to get to higher relaxation rates:
 
```
entropic_shear_flow_scenario = create_fully_periodic_flow(initial_velocity=init_vel, method='trt-kbc-n4',
entropic=True, compressible=True)
entropic_shear_flow_scenario.kernel_params['omega_0'] = 1.999
```
 
%% Cell type:markdown id: tags:
 
## Channel
 
In the last part of this tutorial you learn how to modify the boundary handling of scenarios.
Therefor we set up a channel flow and place some objects into it.
 
The channel will be driven by a constant body force e.g. gravity which acts in x direction. Along the flow direction periodic boundary conditions are used whereas the walls are modeled with a *noslip* boundary condition.
 
%% Cell type:code id: tags:
 
``` python
channel_scenario = create_channel(domain_size=(300, 100), force=1e-7, initial_velocity=(0.025, 0),
relaxation_rate=1.97,
config=CreateKernelConfig(target=Target.GPU))
```
 
%% Cell type:code id: tags:
 
``` python
channel_scenario._lbmKernels[0].ast
```
 
%% Output
 
KernelFunction kernel([_data_force_driven_channel_pdfSrc, _data_force_driven_channel_pdfTmp])
 
%% Cell type:markdown id: tags:
 
As in the last scenario, we specify an initial velocity here. Instead of passing a velocity value for every cell we specify here a constant for the complete domain.
 
%% Cell type:code id: tags:
 
``` python
channel_scenario.run(10000)
plt.figure(dpi=200)
plt.vector_field(channel_scenario.velocity[:, :], step=4);
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
This is a 2D [Poiseuille flow](https://en.wikipedia.org/wiki/Hagen%E2%80%93Poiseuille_equation) where a parabolic profile of the x velocity is expected for the stationary case.
 
%% Cell type:code id: tags:
 
``` python
vel_profile = channel_scenario.velocity[0.5, :, 0]
plt.figure(dpi=200)
plt.plot(vel_profile);
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
The stationary state is not yet reached, you can run more time steps and see how the profile gets closer to a parabola.
 
 
### Modifying boundaries
 
Lets first view the current boundary configuration:
 
%% Cell type:code id: tags:
 
``` python
def draw_boundary_setup():
fig = plt.figure(figsize=(10.0, 3.0), dpi=200)
plt.boundary_handling(channel_scenario.boundary_handling)
plt.axis('off');
 
draw_boundary_setup()
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
In above plot you can see that the *no-slip* boundaries at the top and bottom of the channel, otherwise the channel is empty.
 
Since an empty channel is pretty boring, lets put an obstacle in it. We start with the simplest option: a rectangular, solid block. The rectangle is specified as a slice, similar to advanced *numpy* indexing. The ``make_slice`` function can also take ``float`` as indices for specifying the slice relative to the domain size. The following cell puts an obstacle into the domain that has one third of the channel height.
Additionally we have to pass a function that defines what should happen at the boundary (here ``noSlip``).
By default, the name of the function is also the boundary name.
 
%% Cell type:code id: tags:
 
``` python
from lbmpy.boundaries import NoSlip
 
wall = NoSlip()
channel_scenario.boundary_handling.set_boundary(wall, make_slice[0.2:0.25, 0:0.333])
```
 
%% Output
 
2
 
%% Cell type:markdown id: tags:
 
When plotting the boundary handling again, we see the rectangular obstacle:
 
%% Cell type:code id: tags:
 
``` python
draw_boundary_setup()
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
When setting and plotting boundaries the domain is actually 2 cells larger than originally specified. These so called 'ghost layer' slices are one cell thick and are automatically added at each domain boundary. They can be used to set boundaries and are also used for communication when running distributed memory parallel simulations.
When specifying the slice, keep in mind that the domain is actually slightly larger. When plotting the simulation results the ghost layers are automatically removed.
 
To convert a cell back to ``domain``, the same method can be used. To demonstrate this, we cut a piece out of the obstacle:
 
%% Cell type:code id: tags:
 
``` python
channel_scenario.boundary_handling.set_boundary('domain', make_slice[0.2:0.235, 0.0333:0.3])
fig = plt.figure(figsize=(10.0, 3.0), dpi=200)
plt.boundary_handling(channel_scenario.boundary_handling)
plt.axis('off');
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
To add non-rectangular obstacles one can also pass a mask array, which is ``True`` for cells where the boundary should be set. This is demonstrated in the next cell, where a sphere is placed in the channel.
 
%% Cell type:code id: tags:
 
``` python
def set_sphere(x, y):
shape = channel_scenario.domain_size
mid = (0.5 * shape[0], 0.5 * shape[1])
radius = 13
return (x-mid[0])**2 + (y-mid[1])**2 < radius**2
 
channel_scenario.boundary_handling.set_boundary(wall, mask_callback=set_sphere)
draw_boundary_setup()
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
Now, we run the simulation to see the flow aroung the obstacles:
 
%% Cell type:code id: tags:
 
``` python
channel_scenario.run(10000)
plt.figure(dpi=200)
plt.vector_field_magnitude(channel_scenario.velocity[:,:]);
```
 
%% Output
 
 
%% Cell type:markdown id: tags:
 
### Variations to experiment with:
 
- increase the Reynolds number. You might also have to increase the resolution, and/or use a more advanced method like cumulant or entropic stabilization
Source diff could not be displayed: it is too large. Options to address this: view the blob.
......@@ -673,7 +673,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
......@@ -687,7 +687,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.2"
"version": "3.11.4"
},
"vscode": {
"interpreter": {