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
  • mr_refactor_wfb
  • suffa/cumulantfourth_order_correction_with_psm
  • 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
44 results

Target

Select target project
No results found
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 39

83 files
+ 4101
1265
Compare changes
  • Side-by-side
  • Inline

Files

+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@ doc/bibtex.json
/src/lbmpy/phasefield/simplex_projection.*.so
/src/lbmpy/phasefield/simplex_projection.c

test-report
report.xml

# macOS
**/.DS_Store
*.uuid
+127 −142
Original line number Diff line number Diff line
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 xml --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,163 +86,117 @@ 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
    - pip install -e .
    - python quicktest.py
  tags:
    - docker

# Linter for code formatting
flake8-lint:
  stage: pretest
  except:
    variables:
      - $ENABLE_NIGHTLY_BUILDS
  image: i10git.cs.fau.de:5005/pycodegen/pycodegen/full
  script:
    - flake8 src/lbmpy
  tags:
    - docker
    - cuda11
# --------------------------  Nightly and Pre-Release Tests --------------------------------------------------------------------------------

# -------------------------- 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
  before_script:
    - pip install -e .
  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 quicktest.py
    - 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
    - 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 .
@@ -224,7 +207,8 @@ build-documentation:
    - sphinx-build -W -b html doc html_doc
  tags:
    - docker
    - cuda11
    - cuda
    - cudaComputeCapability6.1
  artifacts:
    paths:
      - html_doc
@@ -232,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
@@ -242,5 +229,3 @@ pages:
      - public
  tags:
    - docker
  only:
    - master@pycodegen/lbmpy
+1 −0
Original line number Diff line number Diff line
@@ -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>
+0 −12
Original line number Diff line number Diff line
------------------------   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

+40 −12
Original line number Diff line number Diff line
@@ -5,12 +5,17 @@ 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
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
@@ -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'))
@@ -44,6 +49,13 @@ 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('_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 cupy
except ImportError:
@@ -106,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

@@ -140,6 +159,15 @@ class IPyNbFile(pytest.File):
        pass


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):

doc/img/lbmpy-logo.svg

0 → 100644
+794 −0

File added.

Preview size limit exceeded, changes collapsed.

+27 −31
Original line number Diff line number Diff line
@@ -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"
Original line number Diff line number Diff line
%% Cell type:markdown id: tags:

# Shan-Chen Two-Phase Single-Component Lattice Boltzmann

%% Cell type:code id: tags:

``` python
from lbmpy.session import *
from lbmpy.updatekernels import create_stream_pull_with_output_kernel
from lbmpy.macroscopic_value_kernels import macroscopic_values_getter, macroscopic_values_setter
from lbmpy.maxwellian_equilibrium import get_weights
```

%% Cell type:markdown id: tags:

This is based on section 9.3.2 of Krüger et al.'s "The Lattice Boltzmann Method", Springer 2017 (http://www.lbmbook.com).
Sample code is available at [https://github.com/lbm-principles-practice/code/](https://github.com/lbm-principles-practice/code/blob/master/chapter9/shanchen.cpp).

%% Cell type:markdown id: tags:

## Parameters

%% Cell type:code id: tags:

``` python
N = 64
omega_a = 1.
g_aa = -4.7
rho0 = 1.

stencil = LBStencil(Stencil.D2Q9)
weights = get_weights(stencil, c_s_sq=sp.Rational(1,3))
weights = get_weights(stencil)
```

%% Cell type:markdown id: tags:

## Data structures

%% Cell type:code id: tags:

``` python
dh = ps.create_data_handling((N,) * stencil.D, periodicity=True, default_target=ps.Target.CPU)

src = dh.add_array('src', values_per_cell=stencil.Q)
dst = dh.add_array_like('dst', 'src')

ρ = dh.add_array('rho')
```

%% Cell type:markdown id: tags:

## Force & combined velocity

%% Cell type:markdown id: tags:

The force on the fluid is
$\vec{F}_A(\vec{x})=-\psi(\rho_A(\vec{x}))g_{AA}\sum\limits_{i=1}^{q}w_i\psi(\rho_A(\vec{x}+\vec{c}_i))\vec{c}_i$
with
$\psi(\rho)=\rho_0\left[1-\exp(-\rho/\rho_0)\right]$.

%% Cell type:code id: tags:

``` python
def psi(dens):
    return rho0 * (1. - sp.exp(-dens / rho0));
```

%% Cell type:code id: tags:

``` python
zero_vec = sp.Matrix([0] * stencil.D)

force = sum((psi(ρ[d]) * w_d * sp.Matrix(d)
            for d, w_d in zip(stencil, weights)), zero_vec) * psi(ρ.center) * -1 * g_aa
```

%% Cell type:markdown id: tags:

## Kernels

%% Cell type:code id: tags:

``` python
lbm_config = LBMConfig(stencil=stencil, relaxation_rate=omega_a, compressible=True,
                       force_model=ForceModel.GUO, force=force, kernel_type='collide_only')

collision = create_lb_update_rule(lbm_config=lbm_config,
                                  optimization={'symbolic_field': src})

stream = create_stream_pull_with_output_kernel(collision.method, src, dst, {'density': ρ})


config = ps.CreateKernelConfig(target=dh.default_target, cpu_openmp=False)

stream_kernel = ps.create_kernel(stream, config=config).compile()
collision_kernel = ps.create_kernel(collision, config=config).compile()
```

%% Cell type:markdown id: tags:

## Initialization

%% Cell type:code id: tags:

``` python
method_without_force = create_lb_method(LBMConfig(stencil=stencil, relaxation_rate=omega_a, compressible=True))
init_assignments = macroscopic_values_setter(method_without_force, velocity=(0, 0),
                                             pdfs=src.center_vector, density=ρ.center)


init_kernel = ps.create_kernel(init_assignments, ghost_layers=0, config=config).compile()
```

%% Cell type:code id: tags:

``` python
def init():
    for x in range(N):
        for y in range(N):
            if (x-N/2)**2 + (y-N/2)**2 <= 15**2:
                dh.fill(ρ.name, 2.1, slice_obj=[x,y])
            else:
                dh.fill(ρ.name, 0.15, slice_obj=[x,y])

    dh.run_kernel(init_kernel)
```

%% Cell type:markdown id: tags:

## Timeloop

%% Cell type:code id: tags:

``` python
sync_pdfs = dh.synchronization_function([src.name])
sync_ρs = dh.synchronization_function([ρ.name])

def time_loop(steps):
    dh.all_to_gpu()
    for i in range(steps):
        sync_ρs()
        dh.run_kernel(collision_kernel)

        sync_pdfs()
        dh.run_kernel(stream_kernel)

        dh.swap(src.name, dst.name)
    dh.all_to_cpu()
```

%% Cell type:code id: tags:

``` python
def plot_ρs():
    plt.figure(dpi=200)
    plt.title("$\\rho$")
    plt.scalar_field(dh.gather_array(ρ.name), vmin=0, vmax=2.5)
    plt.colorbar()
```

%% Cell type:markdown id: tags:

## Run the simulation
### Initial state

%% Cell type:code id: tags:

``` python
init()
plot_ρs()
```

%% Output

img src="data:image/png;base64,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">

%% Cell type:markdown id: tags:

### Run the simulation until converged

%% Cell type:code id: tags:

``` python
init()
time_loop(1000)
plot_ρs()
```

%% Output

img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAACQcAAAQKCAYAAAD3zl6bAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAewgAAHsIBbtB1PgAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8li6FKAAAgAElEQVR4nOzdfZDtd10f8Pdn7+Ym4flJTEiw8mQDijYUKOpI6hPVilUYddQWRUClD0zrdCqZgoVqO63WzmhTqlApKGNrBaTQlmCx1ogIJXRaawsRi6IJAUKgQCDJvbnnfPrHntt7env3npvf7tmzv9++XjNn9vs7v+/DZ8/ZvRkO7/1+q7sDAAAAAAAAAABMz9amCwAAAAAAAAAAANZDOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAA4FKrqflX1kqp6V1XdVlUnFo8PVdWrq+qLN10jAAAAAIxNdfemawAAAACOuKr6xiT/PMkV5+l2d5LndPcbDqYqAAAAABg/4SAAAABgo6rq5UletvTU7ye5McmJJF+a5E8v3bszyZO6+/cOrEAAAAAAGDHhIAAAAGBjqurvJPm7i8tbknx/d7/trD7PTPKGJBcvnnptd3/fwVUJAAAAAOMlHAQAAABsRFV9TZJfS1JJ/jjJV3T3h3fp+yNJfnRxeUeSB3X3/EAKBQAAAIAREw4CAAAADlxVHUvyviRflKSzEwx693n6X5nk5qWnrnK0GAAAAACstrXpAgAAAIAj6TuyEwxKkn99vmBQknT3LUk+s/TUA9dVGAAAAABMiXAQAAAAsAnft9R+xQWOuWepbStkAAAAALgAjhUDAAAADlRV3T/J/05yLMntSR7eKz6gqKrtJHcl2V48dXl3f3SthQIAAADABNg5CAAAADhoX5GdYFCS/NaqYNDCY3MmGHRHko+tozAAAAAAmBrhIAAAAOCg/Zml9vsvcMxXLbV/8wIDRQAAAABw5AkHAQAAAAft6qX2bRc45llL7V/dx1oAAAAAYNKEgwAAAICDthwOumhV56p6bJI/t7i8O8kvrqMoAAAAAJgi4SAAAADgwFTVQ5L8iaWnnnABw/5xznyG8Zru/uS+FwYAAAAAEyUcBAAAABykq8+6flZVPXi3zlV1bZK/sLj8ZJIfWVdhAAAAADBFwkEAAADAQVoOB51M8sAkv1RVD1ruVFUPrKpXJPkHi6dmSZ7T3Z84mDIBAAAAYBq2N10AAAAAcKQsh4NekuQfJnlGkj+qqv+Y5PYkVya5Jsl9Fv1mSV7Y3W89yEIBAAAAYAqquzddAwAAAHBEVNX7kjx+cfnI7BwZdl123934liTf391vO4DyAAAAAGByhIMAAACAA1FV90nymSTHknyyux+6eP4rk/z1JE9NcnmSTyd5X5I3Jnl1d9+5mYoBAAAAYPwcKwYAAAAclC/LTjAoSX7n9JPd/c4k79xIRQAAAAAwcbtt2Q0AAACw365eav+3jVUBAAAAAEeIcBAAAABwUJbDQb+zay8AAAAAYN8IBwEAAAAHRTgIAAAAAA5YdfemawAAAAAmrqq2k3w2ycVJ7klyv+4+udmqAAAAAGD67BwEAAAAHIQnZCcYlCQ3CQYBAAAAwMEQDgIAAAAOgiPFAAAAAGADHCsGAAAAAAAAAMCRUFVPSvINSb4qyZckeXiSe5LcmuS3k7y6u9+xD+u8PMnLLrD7V3f3b+x1zd1sr2tiAAAAAAAAAAA4LKrqhiRPP8et40ket3h8b1W9LskLuvvkQda3LsJBAAAAAAAAAAAcBVcsvt6a5PVJ3pHkj5McS/LlSf7mos9zspOp+e59WveJK+7/4T6tc06OFQMAAAAAAAAAYPKq6t8l+YUkb+zu2TnuPyzJO5N80eKppw89Ymz5WLHurkEF75OtTS4OAAAAAAAAAAAHobuf2d2/fK5g0OL+7dnZPei0bzuYytZLOAgAAAAAAAAAAHb8xlL7MZsqYj8JBwEAAAAAAAAAwI7jS+35xqrYR8JBAAAAAAAAAACw45ql9k37MWFVvb2qPlFVJ6vqtqr6jaq6tqoevB/zr1y/uw9inVGrqouTPHFx+fEk5zx7DgAAAAAAAAAOuWNJPm/R/t3uPrHJYlivqtpOctmm6xjoslxARqO7b9mvBatqK8m7kjx18dRTuvu9A+d6eZKXrej2qSTP7e43D1njQm2vc/IJeWKSGzddBAAAAAAAAADso6ckGRR8YDQuS3LzpotYs9rHuX4oZ4JBbxoaDFryu0n+TZL3JLk1yUVJ/mSSv5jkGUkelOSNVfXN3X39HtfalZ2DLkBVPTnCQQAAAAAAAABMy+BdURiHqroyEw8Hdfe+hIOq6pokv5adjXZuS/Kl3f2xPcz3oO7+1Hnu/2CSn11c3prksd1919D1zsfOQRfm46cb73nPe3L55ZdvshYAYKKe8+Qf2XQJAAxR+/mHSXDI+KMygI163Xt/bNMlAAAT9JGPfCRPferpjVHO/H/hTN+7r39kLn/4sU2XsdJHbpvlad/4f/NMT0ny0XWvWVVfnORN2cnRnEjyHXsJBiXJ+YJBi/uvXGxW84Ikj0jy7CS/uJc1dyMcdGH+7/l1l19+ea688spN1gIATNQlx+636RIAGGJra9MVwPrM55uuAOBI81k0AHAAZqu7MBWXP/xYrnzERZsu4976aHffss4FqupRSf5Dkgdn53fiu7r7hnWuueSV2QkHJck1WVM4yCeYAAAAAAAAAAAcOVX1iOwcJfaIJJ3ked39pgMs4X1L7SvWtYidgwAAAAAAAAAAJm6ezjyHf5fgeQ7mmPOqeliStyd59OKpF3X3LxzI4ktlHMQidg4CAAAAAAAAAODIqKoHJvnVJE9YPHVtd79iA6U8Yal967oWEQ4CAAAAAAAAAOBIqKr7JPn3SZ60eOrvd/ePb6icH1xq37CuRRwrBgAAAAAAAAAwcbOeZ9aH/1ixddZYVceTvCnJVy6e+unufumAeZ6b5DWLy7/b3S8/6/4Tk9zV3f/rPHP8YJLnLy4/uqhrLYSDAAAAAAAAAAA4Cv5Vkmcs2r+e5NVV9SXn6X+yuz8wYJ0/neTnquo/Jbk+ye8m+UR2cjpXJflLSb5+0XeW5Ae7+3MD1rkgwkEAAAAAAAAAABwFz15qf02S/76i/x8l+cKBax1L8nWLx24+keT53f2WgWtcEOEgAAAAAAAAAADYP2/NzpFhX57k6iSfn+ShSSrJJ5P8TpK3JXltd39m3cUIBwEAAAAAAAAATNw8nXl602WstM4au7v2aZ7XJnntee7fluRfLB4bt7XpAgAAAAAAAAAAgPUQDgIAAAAAAAAAgIlyrBgAAADsxXw+bNyWv9fhAA39OQUAAAAmozPPPIf/M4IeQY1j45NIAAAAAAAAAACYKOEgAAAAAAAAAACYKOEgAAAAAAAAAACYqO1NFwAAAAAAAAAAwHrNujPr3nQZK42hxrGxcxAAAAAAAAAAAEyUcBAAAAAAAAAAAEyUY8UAAAAAAAAAACZuns48h//IrjHUODZ2DgIAAAAAAAAAgIkSDgIAAAAAAAAAgIkSDgIAAAAAAAAAgIna3nQBAAAAAAAAAACs1zzJLL3pMlaab7qACbJzEAAAAAAAAAAATJRwEAAAAAAAAAAATJRjxQAAAAAAAAAAJm6eznwUx4od/hrHxs5BAAAAAAAAAAAwUcJBAAAAAAAAAAAwUcJBAAAAAAAAAAAwUdubLgAAAAAAAAAAgPWadWfWvekyVhpDjWNj5yAAAAAAAAAAAJgo4SAAAAAAAAAAAJgox4oBAAAAAAAAAEzcfPE47MZQ49jYOQgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZq+6AWqqqHJXlekm9J8pgkD07yiSQ3J/nNJL/S3e9aMcc3JPmBJE9N8nlJPp7kPUle1d1vW1/1AAAAAAAAAADjNU9nlt50GSvNR1Dj2BxIOKiqvj3JzyR56Fm3Ll88nprkcUm+dZfxleRnsxMMWnZFkmcleVZVvSrJC7vbTwkAAAAAAAAAAOQAwkFV9T1JXpOdI8xuy05I6LeSfDLJZdnZReibk9xznmn+Xs4Eg/5rkp9I8sHF2B9OcvXi/seTvHTfvwkAAAAAAAAAABihtYaDqurxSV6VnWDQO5J8c3d/+hxdr6uq47vM8djsBICS5L1Jnt7ddy2ub6yqtyS5IcmTk7y4ql7T3R/cz+8DAAAAAAAAAADGaGvN81+X5OIktyd59i7BoCRJd5/c5dYP5UyI6UVLwaDT4+5M8qLF5XaSv7GnigEAAAAAAAAAJmaWZNYjeGz6hZqgtYWDquqqJF+7uPyn3X37gDkqybcsLm/q7nefq9/i+d9bXH7rYhwAAAAAAAAAABxp69w56NuX2q8/3aiqB1fV46rqoRcwx6OSXLFo37Ci7+n7Vyb5wgstEgAAAAAAAAAApmqd4aCnLb5+Osn7q+ovVtXvJPlkkg8kub2q/qCqXlZV99tljscvtW9asd7y/cfv2gsAAAAAAAAA4IiZj+jB/tpe49xPWHz9UJLrkvzVc/R5VJKXJ/m2qvpz3X3rWfcfudS+ZcV6N+8ybqWqunJFl8vuzXwAAAAAAAAAAHAYrDMc9JDF16uSfFmSTyW5NsmvJPlMkicm+dEk35jkS5K8vqq+qruXQ2D3X2p/dsV6n1tq77YT0W5uXt0FAAAAAAAAAADGZZ3Hit138fXiJLMk39jdr+zuj3f3ie5+b5JnJrl+0e8rkjz7rDkuWWqfXLHeiaX2pQNrBgAAAAAAAACAyVjnzkF350xA6PXd/e6zO3T3vKr+VnZ2D0qS70ryhrPmOO34ivUuXmrfdS9rXXUM2WVJbryXcwIAAAAAAAAAHArzVGapTZex0nwENY7NOsNBd+RMOOj63Tp19/+sqg8nuSLJU84xx2mrjgq771J71RFkZ9dwy/nuV/nBAwAAAAAAAABgfNZ5rNjNS+3zhm+W+j78rOeXx125Yo7l3X9u3rUXAAAAAAAAAAAcEevcOeh/5sxOQMdW9D19/9RZz79vqX3VijmW779/RV8AAAAAAAAAgCNj3juPw24MNY7NOncO+s2l9mNW9H304uuHz3r+D5Pcumhfs2KOpy/N8aFVxQEAAAAAAAAAwNStMxz0liT3LNrP3q1TVV2T5KGLy3cs3+vuTvLmxeVVVfW0XeZ4Ws7sHPTmxTgAAAAAAAAAADjS1hYO6u5PJPm5xeXXV9V3nt2nqu6f5KeWnnrlOab6qZw5buy6qrr0rDkuTXLd4vLUWfMBAAAAAAAAAMCRtb3m+V+W5JuSfEGS11XVVyb5lSSfSfLEJC/OmR1/fqa7bzx7gu7+QFX9ZJJrkzw5yTur6seTfDA7x5W9OMnVi+7/qLt/f43fDwAAAAAAAADA6MxSmaU2XcZKY6hxbNYaDuruj1fVN2TniLHHJvlri8fZ/kWSv36eqV6S5OFJnpedINAvnaPPq5O8dE8FAwAAAAAAAADAhKztWLHTuvv9Sf5Ukr+V5D8n+WSSk0luSfKvk3xNdz+/u+85zxzz7n5+dnYhenOSWxdz3Lq4/vPd/YLunq/1mwEAAAAAAAAAgBFZ97FiSZLu/lySn1w89jLPW5O8dV+KAgAAAAAAAAA4IhwrdnStfecgAAAAAAAAAABgM4SDAAAAAAAAAABgooSDAAAAAAAAAABgorY3XQAAAAAAAAAAAOvVncy7Nl3GSt2brmB67BwEAAAAAAAAAAATJRwEAAAAAAAAAAAT5VgxAAAAAAAAAICJm6Uyy+E/VmwMNY6NnYMAAAAAAAAAAGCihIMAAAAAAAAAAGCihIMAAAAAAAAAAGCitjddAAAAABxJ8/mwcVv+zudIG/pzAwAAABx5s2xlNoI9ZMZQ49h4RQEAAAAAAAAAYKKEgwAAAAAAAAAAYKIcKwYAAAAAAAAAMHHdlXnXpstYqUdQ49jYOQgAAAAAAAAAACZKOAgAAAAAAAAAACZKOAgAAAAAAAAAACZqe9MFAAAAAAAAAACwXrNUZqlNl7HSGGocGzsHAQAAAAAAAADARAkHAQAAAAAAAADARDlWDAAAAAAAAABg4ma9lVkf/j1kxlDj2HhFAQAAAAAAAABgooSDAAAAAAAAAABgooSDAAAAAAAAAABgorY3XQAAAABwL8znw8du+RuhQ2Mv7yMAAADAAPNU5iPYQ2ae2nQJk3P433UAAAAAAAAAAGAQ4SAAAAAAAAAAAJgo4SAAAAAAAAAAAJio7U0XAAAAAAAAAADAes1TmaU2XcZK8xHUODZ2DgIAAAAAAAAAgIkSDgIAAAAAAAAAgIlyrBgAAAAAAAAAwMTNeiuzPvx7yIyhxrHxigIAAAAAAAAAwEQJBwEAAAAAAAAAwEQJBwEAAAAAAAAAwERtb7oAAAAAAAAAAADWa57KPLXpMlYaQ41jY+cgAAAAAAAAAACYKOEgAAAAAAAAAACYKMeKAQAAAAAAAABM3DxbmY1gD5n5CGocG68oAAAAAAAAAABMlHAQAAAAAAAAAABMlHAQAAAAAAAAAABM1PamCwAAAAAAAAAAYL1mvZVZH/49ZMZQ49h4RQEAAAAAAAAAYKKEgwAAAAAAAAAAYKIcKwYAAAAAAAAAMHHzVOYj2ENmntp0CZNz+N91AAAAAAAAAABgEOEgAAAAAAAAAACYKOEgAAAAAAAAAACYqO1NFwAAAAAAAAAAwHrNuzLr2nQZK81HUOPY2DkIAAAAAAAAAAAmSjgIAAAAAAAAAAAmyrFiAAAAMCZb/s5nEoa+j/P5/tYBAAAAHBmzbGU2gj1kxlDj2HhFAQAAAAAAAABgooSDAAAAAAAAAABgooSDAAAAAAAAAABgorY3XQAAAAAAAAAAAOs1763M+/DvITOGGsfGKwoAAAAAAAAAABMlHAQAAAAAAAAAABPlWDEAAAAAAAAAgImbZSuzEewhM4Yax8YrCgAAAAAAAAAAEyUcBAAAAAAAAAAAEyUcBAAAAAAAAAAAE7W96QIAAAAAAAAAAFiveZJZ16bLWGm+6QImyM5BAAAAAAAAAAAwUcJBAAAAAAAAAAAwUY4VAwAAgCTZ8vczjMBYfk7nNgAHAACAw2aercxHsIfMGGocG68oAAAAAAAAAABMlHAQAAAAAAAAAABMlHAQAAAAAAAAAABM1PamCwAAAAAAAAAAYL1mvZVZH/49ZMZQ49h4RQEAAAAAAAAAYKKEgwAAAAAAAAAAYKKEgwAAAAAAAAAAYKK2N10AAAAAAAAAAADrNU9lntp0GSuNocaxsXMQAAAAAAAAAABMlHAQAAAAAAAAAABMlGPFAAAAAAAAAAAmbt5bmfXh30NmPoIax8YrCgAAAAAAAAAAEyUcBAAAAAAAAAAAEyUcBAAAAAAAAAAAE7W96QIAAADgnLb8PQuM1iZ+f+fzg18TAAAARmSWymwEe8jMUpsuYXIO/7sOAAAAAAAAAAAMIhwEAAAAAAAAAAAT5VgxAAAAAAAAAICJm3dl3of/yK4x1Dg2dg4CAAAAAAAAAICJEg4CAAAAAAAAAICJEg4CAAAAAAAAAICJ2t50AQAAAAAAAAAArNc8W5mNYA+Z+QhqHBuvKAAAAAAAAAAATJRwEAAAAAAAAAAATJRjxQAAAAAAAAAAJm7eW5n34d9DZgw1jo1XFAAAAAAAAAAAJko4CAAAAAAAAAAAJko4CAAAAAAAAAAAJmp70wUAAAAwYVv+JuVQqdp0BZzWvekKpmfovzfz+f7WAQAAAIfULJVZDv/nQ2OocWx8SgsAAAAAAAAAABMlHAQAAAAAAAAAABPlWDEAAAAAAAAAgImb91bmffj3kBlDjWPjFQUAAAAAAAAAgIkSDgIAAAAAAAAAgIkSDgIAAAAAAAAAgIna3nQBAAAAAAAAAACs1zzJLLXpMlaab7qACbJzEAAAAAAAAAAATJRwEAAAAAAAAAAATJRjxQAAAAAAAAAAJm7eW5n34d9DZgw1jo1XFAAAAAAAAAAAJko4CAAAAAAAAAAAJko4CAAAAAAAAAAAJmp70wUAAABwgLb8jci+qzrYcVsDx+3FQX+PB637YMftxfyAa93E93jQDvrfxfn8YNcDAACAhVlvZdaH//PBMdQ4Nl5RAAAAAAAAAACOhKp6UlX97aq6vqpurqoTVfXZqvpAVb22qr5qDWt+Z1X9alV9pKrurqoPVdXrqupp+73Wudg5CAAAAAAAAACAyauqG5I8/Ry3jid53OLxvVX1uiQv6O6Te1zvkiSvT/LMs279icXju6vq5d39Y3tZZxXhIAAAAAAAAACAietU5jn8x8D3emu8YvH11uyEdt6R5I+THEvy5Un+5qLPc7KTqfnuPa736pwJBv2nJD+9WPuJSf52ksck+dGq+kh3/9we19qVcBAAAAAAAAAAAEfBTdkJ5byxu2dn3Xv3Ysegdyb5oiTfVVU/093vGLJQVV2TM+Gif5vkWUtr3lhVb0nyX5J8QZKfqKo3dPenhqy1ytY6JgUAAAAAAAAAgMOku5/Z3b98jmDQ6fu3Z2f3oNO+bQ/L/fDi6yzJXzl7zcVaL15cPjjJ8/ew1nkJBwEAAAAAAAAAwI7fWGo/ZsgEVXW/JF+7uHx7d9+yS9dfSfKZRfvZQ9a6EI4VAwAAAAAAAACYuFlvZdaHfw+ZQ1Dj8aX2fOAcT01y8aJ9w26duvtkVb07yTOSPLWqLuruewauuauNv6IAAAAAAAAAAHBIXLPUvmngHI+/F3Ocvr+d5HED1zsvOwcBAAAAAAAAAHAYXVZV5+1wniO77rWq2kpy7dJTvzxwqkcutVfVd/NZ4943cM1dCQcBAAAAAAAAAHAY3XgBfc6fHrp3fig7R4IlyZu6+70D57n/UvuzK/p+bql9v4Hrnddaw0FV1RfY9Ybu/rMr5vqGJD+QnTfh85J8PMl7kryqu9+2lzoBAAAAAAAAAKZsnsq89zNHsx7zfc36XLiquibJP1xc3pbkL+9hukuW2idX9D2x1L50D2vu6tDvHFQ7+0P9bHaCQcuuSPKsJM+qqlcleWF3X2gYCQAAAAAAAACAw+0pST667kWq6ouTvCk7OZoTSb6juz+2hynvXmofX9H34qX2XXtYc1cHFQ76mST/7Dz3P3eee38vZ4JB/zXJTyT5YJLHJPnhJFcv7n88yUv3XCkAAAAAAAAAAIfBR7v7lnUuUFWPSvIfkjw4ySzJd3X3DXuc9o6l9qqjwu671F51BNkgBxUOuq27/8e9HVRVj81OAChJ3pvk6d19OiV1Y1W9JckNSZ6c5MVV9Zru/uC+VAwAAHCYbW1tuoL1q4HbBw8dtzV03LD3oo8NfA+PHRs2Lkm2h43t7YG1DnwveuC4Grqh8MBxdWo+bL0kOTUbNm42bFzNBtY6HzruYN+LPY89SEP//R76XgAAAMDCLJVZDv/nirMDPFasqh6R5NeSPCJJJ3led79pH6ZeDjRdmZ3My24eudS+eR/W/v8c9nf9h3ImwPSipWBQkqS770zyosXldpK/cYC1AQAAAAAAAAAwQlX1sCRvT/LoxVMv6u5f2Kfp37fUvmpF39P3TyX5X/u0/v/j0IaDqqqSfMvi8qbufve5+i2e/73F5bcuxgEAAAAAAAAAwP+nqh6Y5FeTPGHx1LXd/Yp9XOLGJCcX7WvOU8fxJE87Paa7T+7Wdy8ObTgoyaOSXLForzrL7fT9K5N84boKAgAAAAAAAABgvKrqPkn+fZInLZ76+9394/u5RnffkeQ/Li6/rqqu3KXrs5M8YNHej+PMzumgwkHfXlW/V1V3VdUdVfX7VfXzVfXV5xnz+KX2TSvmX77/+F17AQAAAAAAAAAcQd2V+Qge3es7MGqxU8+bknzl4qmf7u6XDpjnuVXVi8fLd+n2k4uv20leUVXHzprjYUlOh5I+leTn7m0dF2p7XROf5QlnXT928fieqvo3SZ7b3Z8+q88jl9q3rJj/5l3GXZDzJLROu+zezgkAAAAAAAAAwKHyr5I8Y9H+9SSvrqovOU//k939gSELdfevV9UvJfnOJH8hydur6qeS3JrkiUlekuQLFt2v7e7/PWSdC7HucNCdSd6Sna2Sbkry2SSfl53z1F6Y5KFJvjXJm6vq67v7nqWx919qf3bFOp9bat9vQJ03r+4CAAAAAAAAAMCIPXup/TVJ/vuK/n+U5Av3sN7zsnNs2J9P8tWLx7J5kh/r7lfuYY2V1h0OuqK7P3WO599eVdcluT7J1dkJC/3lJP9kqc8lS+2TK9Y5sdS+dEihAAAAAAAAAABTNc9W5tnadBkrjaHGC9XddyX5pqr67iTPTfJlSR6U5GNJ3pHkn3b3u9Zdx1rDQbsEg07f+1hVfVuS9yc5nuRF+X/DQXcvtY+vWOripfZd97bOrD6K7LIkNw6YFwAAAAAAAACAQ6C7a5/meW2S196L/v8yyb/cj7WHWPfOQefV3X9QVW9P8k1JHltVj+juWxe371jquuqosPsutVcdQXauOm453/2qffnZAAAAAAAAAACAA3UY9mJ631L7iqX2cmDnyhVzLO/8c/OeKwIAAAAAAAAAgAnY6M5BC7tty7McGrpqxRzL99+/t3IAAAAAAAAAAKZl1pXZ/pyqtVZjqHFsDsPOQU9Yat+61P7DpetrVszx9MXXDyf50P6UBQAAAAAAAAAA47bRcFBVPTrJ1y8u/6C7P3z6Xnd3kjcvLq+qqqftMsfTcmbnoDcvxgEAAAAAAAAAwJG3tmPFquqbk1zf3ad2uf/5Sd6Q5KLFU684Ry764j4AACAASURBVLefSvL92anzuqp6enfftTTHpUmuW1yeWvQHAAA4eFuHYWPWQ6j2sAXwsYGv6bFjg4b1xRet7rSP42aXDhs3v2TY95ckpwaOnR8f9j7Otwe+/0N/bAb+udDWqWEDt04O//uk7btnw9YcOO7YXfcMGlcnDnZcZsO+v52x82HjxvJ3Zgf935n5wNcTAACAQ2velfkIjuwaQ41js7ZwUHZCOxdV1RuTvCs7x33dleRhSf5skhcmeeii72/lHOGg7v5AVf1kkmuTPDnJO6vqx5N8MMljkrw4ydWL7v+ou39/Xd8MAAAAAAAAAACMzTrDQUnyiCQvWjx288YkL+juE7vcf0mShyd5XnaCQL90jj6vTvLSPdQJAAAAAAAAAACTs85w0PcmuSbJlyd5dHZ2DHpAks8muTnJbyf5+e5+1/km6e55kucvdiD6gSRPWcx1e5Ibk7yyu69f1zcBAAAAAAAAAABjtbZwUHffkOSGfZzvrUneul/zAQAAAAAAAAAcFd1bmffWpstYqUdQ49h4RQEAAAAAAAAAYKKEgwAAAAAAAAAAYKLWdqwYAAAAAAAAAACHwyyVWWrTZaw0hhrHxs5BAAAAAAAAAAAwUcJBAAAAAAAAAAAwUcJBAAAAAAAAAAAwUdubLgAAAAAAAAAAgPWadzLv2nQZK8170xVMj52DAAAAAAAAAABgooSDAAAAAAAAAABgohwrBgAAcNrWEfj7iRq4bfDQcdvHho1L0pccHzRufp9h407d/+JB404+cNj/tD55/2E/byfvN3zr51P3GTZ2PuwlzXzo2z/0V3E+cLnZwHEnh41Lku07h/3cHP/ssH21j98x7Of7+KdPDRq3fceJQeO27hz+otbdA8eeGvgD0AP3OB867qDt5b+J84G/jAAAAKzVvLcy78P/GegYahwbrygAAAAAAAAAAEyUcBAAAAAAAAAAAEyUcBAAAAAAAAAAAEzUsAPuAQAAAAAAAAAYjU5lntp0GSv1CGocGzsHAQAAAAAAAADARAkHAQAAAAAAAADARDlWDAAAAAAAAABg4mZdmfXhP7JrDDWOjZ2DAAAAAAAAAABgooSDAAAAAAAAAABgooSDAAAAAAAAAABgorY3XQAAAAAAAAAAAOs1763M+/DvITOGGsfGKwoAAAAAAAAAABMlHAQAAAAAAAAAABMlHAQAAAAAAAAAABO1vekCAAAA9t3WEfg7iKph444Ne236+EXDxt3n4kHjkuTUAy4ZNO7uhx0fNO6uhw57bU48ZNh7cfL+PWjc7D7DxiXJ/JL5oHG9PWxcjg2sdeCPd4a+NLNhC9ap4f/WbN09bM1jdw4bd/yOYR8BXfzJY4PGXfqJYf9mXHL7yUHjkmT7M3cPGld3nhg27uQ9g8ZlNvD3qYf/7h+4of8dng98bQAAALgg81TmPfSDl4MzH/zhELs5Ap+YAwAAAAAAAADA0SQcBAAAAAAAAAAAE+VYMQAAAAAAAACAievUKI7s6hHUODZ2DgIAAAAAAAAAgIkSDgIAAAAAAAAAgIkSDgIAAAAAAAAAgIna3nQBAAAAAAAAAACs17yTedemy1hp3puuYHrsHAQAAAAAAAAAABMlHAQAAAAAAAAAABPlWDEAAAAAAAAAgImb91bmffj3kBlDjWPjFQUAAAAAAAAAgIkSDgIAAAAAAAAAgIkSDgIAAAAAAAAAgIna3nQBAAAAR1rVsHHbxwYN6+MXDRo3f8Clg8adeNiwcUnyuc8f9j9Z7/r8Ya/p3Q/pQeNOPeDUoHG5dDZo2LGLh41LkouOzQeN29oa9tpUHey47mHv/dBx8/nA398ks9mwv9c6eWLY7/7Ju4aNu/shw8adGDju0gdcMmhcktz3Y8P+zbj49mG1bn3mrkHj6uQ9g8bl1MDf/R72+wQAAMD0zLsyH/g5yEEaQ41jY+cgAAAAAAAAAACYKOEgAAAAAAAAAACYKMeKAQAAAAAAAABM3DyVeQ7/kV1jqHFs7BwEAAAAAAAAAAATJRwEAAAAAAAAAAATJRwEAAAAAAAAAAATtb3pAgAAAAAAAAAAWK/uyrxr02Ws1COocWzsHAQAAAAAAAAAABMlHAQAAAAAAAAAABPlWDEAAAAAAAAA/g979x9reVrXB/z9nHPmzszuLBV2hcVdEAtN2aakJQVCAwGt1FjECrQ1Vm3cAIJtQiN/CLTauKL/iJhiaBuxUtcaldj6Y9GAlrZIUlt1NdrSIGoppLsiCywguzu7c+fe8/SPezacTmf2znzuPT++3/t6JU/me875fr7P5/z6Pufc+ZznAUZuPpBlxYaQ49CYOQgAAAAAAAAAAEZKcRAAAAAAAAAAAIyU4iAAAAAAAAAAABip2aYTAAAAuKLJgH7P0IrrYM+mpbB+eqcUt//460pxDz/pTCnuwS+r3b8kOf/kWtzujfu1wHMXS2GnTu/V4k7V8pxO56W4JJm2Xoprxbiqan99zevRH6W//WLs/unaefHi2dp7ce/62p+OHrrhVCnu4rn6eX/vulqu507XzotnZ7Vcp587X4pr2S3FZa94Tuzrfd8nqY/78/p5EQAA4CSZ95b5mv9+UjGEHIdmQH9pBwAAAAAAAAAAroXiIAAAAAAAAAAAGCnLigEAAAAAAAAAjJxlxU4uMwcBAAAAAAAAAMBIKQ4CAAAAAAAAAICRUhwEAAAAAAAAAAAjNdt0AgAAAAAAAAAArFZPMk/bdBqH6ptOYITMHAQAAAAAAAAAACOlOAgAAAAAAAAAAEbKsmIAAAAAAAAAACM37y3zvv3Lig0hx6ExcxAAAAAAAAAAAIyU4iAAAAAAAAAAABgpxUEAAAAAAAAAADBSs00nAAAAnACTgfwuoR1hLetp7T72nVOluP3HX1eKO//ks6W4Lzx1Wuyvl+KSZO/GvVLc7PqLpbid07W42XReiptOqnH1x7SqtfX3WbPePHuvnzOqf5DZL75uqq/TvVP7pbjdU7X+LhTPiUmyv1N7VKtxfVI7n9bO3sn0s7XXd+vF98V+7TlMklT7rKp+zpgf4T4CAAAM0Dwt8yP8PWNd5tn+HIdmIH+hBwAAAAAAAAAArpXiIAAAAAAAAAAAGCnFQQAAAAAAAAAAMFLVJe4BAAAAAAAAABiIeW+Z97bpNA41hByHxsxBAAAAAAAAAAAwUoqDAAAAAAAAAABgpCwrBgAAAAAAAAAwcpYVO7nMHAQAAAAAAAAAACOlOAgAAAAAAAAAAEZKcRAAAAAAAAAAAIzUbNMJAAAAAAAAAACwYr2l97bpLA43hBwHxsxBAAAAAAAAAAAwUoqDAAAAAAAAAABgpCwrBgAA8KhWn66275wqxc0fd7YU9/CTzpTivvDUaSnu/C29FLd308VSXJKcPnehFLezs1eKm03mpbjppPbYtFaLG5LJQO7jvDhV9Saew9m01mf1dTqtvi+mtbjd2X4pLkkuTE+X4s5PaufvpHY+bfPa+fu6vdpjOvmz4jnqkd1SXJKkD+O9DwAAcNLM0zLP9i/ZNYQch8bMQQAAAAAAAAAAMFKKgwAAAAAAAAAAYKQUBwEAAAAAAAAAwEjNNp0AAAAAAAAAAACrNe8t8942ncahhpDj0Jg5CAAAAAAAAAAARkpxEAAAAAAAAAAAjJRlxQAAAAAAAAAARq73lj6AJbuGkOPQmDkIAAAAAAAAAABGSnEQAAAAAAAAAACMlOIgAAAAAAAAAAAYqdmmEwAAAAAAAAAAYLXmPZn3tuk0DjXvm85gfMwcBAAAAAAAAAAAI6U4CAAAAAAAAAAARsqyYgAAwNWbDOT3Ba04Ne5sWu6yX3e6FHfhprOluAe/rJbr+SfX5uTdu+liKe70uQuluCQ5vbNXiptN90txk+LLprX1znM8WXN/J8GQHtPq1N/V1+m0eNpvrfY+bDu1/pIk52ph1bPU+fmpUtx0t3b+nl6ojRdnLhafi71aXJLkYvE91df8Xqx+rpnPjzcPAACANem9pQ9gWbEh5Dg0A/nLPgAAAAAAAAAAcK0UBwEAAAAAAAAAwEgpDgIAAAAAAAAAgJGabToBAAAAAAAAAABWq/eWeW+bTuNQfQA5Do2ZgwAAAAAAAAAAYKQUBwEAAAAAAAAAwEhZVgwAAAAAAAAAYOR6kt43ncXhBpDi4Jg5CAAAAAAAAAAARkpxEAAAAAAAAAAAjJTiIAAAAAAAAAAAGKnZphMAAAAAAAAAAGC15mmZp206jUMNIcehMXMQAAAAAAAAAACMlOIgAAAAAAAAAAAYKcuKAQDASTQZyO8EWnH62Gnt/vUzO7X+kuw97kwp7qEn1b6WnX9yKSx7N+6V4k6fu1CL26n1lySz6X4pbjrp5T4rJm29/XGyrfv1Ni/GTcuzf9fe90mS6in8XC3swn7tTp7frZ33Z+eLcQ/VxqdTu/Xzd5sXXzn7xbi+5vNw9XNU9XEBAAA4Jr239L79S3YNIcehGcj/CAAAAAAAAAAAANdKcRAAAAAAAAAAAIyU4iAAAAAAAAAAABip2mLlAAAAAAAAAAAMxry3zHvbdBqHGkKOQ2PmIAAAAAAAAAAAGCnFQQAAAAAAAAAAMFKKgwAAAAAAAAAAYKRmm04AAAAAAAAAAIDV6v2gbbsh5Dg0Zg4CAAAAAAAAAICRUhwEAAAAAAAAAAAjtZHioNbaW1trfal95VXEfG1r7Rdaa/e21i4s/v2F1trXriFlAAAAAAAAAIDh6i19AC29bfqRGp21Fwe11v5Kkjdcw/6ttfbOJO9L8ooktyTZWfz7iiTva629s7Xm1QEAAAAAAAAAAEvWWhzUWpsk+ddJZkk+dZVhP5DktYvt30vy95M8b/Hv7y2uf22S7z++TAEAAAAAAAAAYPjWPXPQP07y3CQfSfKuw3ZurT0jyRsXF38nyQt67+/uvd/de393khcurk+SN7XWnr6CnAEAAAAAAAAAYJBm6+qotfaUfHF2n3+Y5CuvIuwN+WKOr++9P7x8Y+/9fGvt9Un+22K/70zy+mNJGAAA2Lzq6sHTaSlsft1Orb8kj9xUi334SbX7uHvjfiludv3FUtzOzl6tv2ktzySZTno5tmLS1tsfDEH1fTHvtXPb0d73tfNNL57694vn090ba7/Ve/jB2th2+gu1Ozg9Xx8Tpxdqj03mxee/O38DAABcjd5bevE7+zoNIcehWefMQf8qybkkP9l7//XDdm6ttSTfsLj4kd77b15uv8X1f7i4+PJFHAAAAAAAAAAAnHhrKQ5qrX1jkpcl+WyS77rKsK9Icsti+4OH7Pvo7bcmedq15gcAAAAAAAAAAGO08mXFWmtfkuRHFhff1Hv/9FWG3ra0/ZFD9l2+/bYkH7vKPgAAAAAAAAAARm/eW3kp8HUaQo5Ds/LioCRvTXJzkv+a5F3XEPeUpe17D9n3nivEXZXW2q2H7HLztR4TAAAAAAAAAAA2baXFQa21FyZ5TZK9JN/Re+/XEH7D0vaDh+z70NL2uWvo41H3HL4LAAAAAAAAAAAMy2RVB26t7ST5sSQtyT/vvX/oGg9xZml795B9Lyxtn73GfgAAAAAAAAAAYJRWOXPQP01yW5L/k+T7CvGPLG3vHLLv6aXthwt9HbYU2c1J7i4cFwAAAAAAAABg43o/aNtuCDkOzUqKg1prz0zyTxYXX997f+ix9r+CB5a2D1sq7Pql7cOWIPv/9N7vfazbW2vXekgAAAAAAAAAANi4Vc0c9IYczPbzv5Nc11r7psvs85eXtv9Ga+3mxfYvL4qJlgt2bj2kv+WZf+651mQBAAAAAAAAAGCMVlUc9OgyX38+yc9exf7/bGn7K5I8lOTDS9c985D45dv/4Cr6AwAAAAAAAAA4MQ6WFdv+lZMsK3b8JptO4DF8LMknFtsvPmTfFy3+/ZMkH19VQgAAAAAAAAAAMCQrKQ7qvd/ee2+P1ZJ831LIVy3d9vHFMXqSuxa3P7O19vzL9bW4/tGZg+5axAEAAAAAAAAAwIm3zTMHJcnbk+wttt/RWju7fOPi8jsWF/cW+wMAAAAAAAAAAElmm07gsfTe/6i19rYkb07ynCS/0Vr7wSQfTfL0JG9K8uzF7j/Ue//jzWQKAAAbMtn2ev8jmtTWv+6nT5Xi9m44XYpLkodvrD0XjzyhOPnpuYulsJ3TtbjZZF6KKz6FRzJpJpSFTau+D+e9ftKonm+q57fq+fThc9XxohZXHZ9Of64+Jk7O75bi2v5+rcPaU7h+R/ncNh/KnQQAALZZT0s/wnfvdenZ/hyHZquLgxa+O8kTk7wqB4VA777MPu9K8j3rTAoAAAAAAAAAALbd1v/MuPc+772/OsnXJbkrySeS7C7+vSvJS3vvr+m9+/kMAAAAAAAAAAAs2djMQb33O5LccQ37vzfJe1eVDwAAAAAAAADAWPVF23ZDyHFotn7mIAAAAAAAAAAAoEZxEAAAAAAAAAAAjJTiIAAAAAAAAAAAGKnZphMAAAAAAAAAAGC1em/pvW06jUMNIcehMXMQAAAAAAAAAACMlOIgAAAAAAAAAAAYKcuKAQAAAAAAAACMXV+0bTeEHAfGzEEAAAAAAAAAADBSioMAAAAAAAAAADgRWmtPbK29rLX2ltba+1prn2mt9UW78xj7uWPpuIe1rzyufi/HsmIAAAAAAAAAAJwU9206gXVTHAQAsC0ma57UcT5fb3+cbK3V4orvi376VClu98/VvyJdeELtPu49bq8Ud+p0LW42rb33p5PaQt+t1RcInxwhluM178X38Mh5jR6/ozym1U820+JHsOr5dFY8f198XG2MuvCEWtxRxsRTn6+Nw+2R3VqHrfjsd+9h1mjd3/cAAOByeksfwt951pvjPUn+IMnXrLifZx1y+8dW2bniIAAAAAAAAAAAToq3JLk7yd299/taa0/Liotzeu//c5XHP4ziIAAAAAAAAAAAToTe+/duOod1UxwEAAAAAAAAADByvQ9jheUh5Dg0FjoGAAAAAAAAAICRUhwEAAAAAAAAAAAr0lp7f2vt/tbabmvtU621X2+tvbm19vh19G9ZMQAAAAAAAAAAttHNrbXH3KH3fu+acjmKlyxtf2mSFy/am1prt/fe71pl54qDAAAAAAAAAABGrveW3h+70GYbXJLj3VcRss136kNJfinJbyf5RJJTSf5ikm9J8jVJviTJz7fWvr73/r5VJaE4CAAAAAAAAAAAjtfbe+93XOb630ryb1trr0vyo0mmSX68tfaM3vvDq0hEcRAAAAAAAAAAANvouUk+uekkKnrvnz/k9ne21p6T5DVJvizJK5P89CpyURwEAAAAAAAAAMA2+mTv/d5NJ7FC78xBcVCSvDiKgwAAAAAAAAAAKOntoG27IeR4fD68tH3LqjqZrOrAAAAAAAAAAADAFa2lEkpxEAAAAAAAAAAArN9fWtr+xKo6sawYAMBJNTkBdeLz+aYz4FGt9uOHPq29TvfPnirF7d5Qf1/s3tBrgWf3S2GnTtXippPa+6K14v3j2M1P1rTKW20Tz8XEe/HYVc9v1fNp9fx9sThe7N4wLcbVx8QzxXG4PVjrs+0V34vd+2lrnITvJgAAsAV6H8ZXoSHkeIxet7T9wVV14lsXAAAAAAAAAABcpdba7a21vmh3XOb2Z7XWnnHIMV6X5NWLi59M8ovHn+kBMwcBAAAAAAAAAHAitNZemGS5cOempe1ntNZuX96/935noZu/luTHW2sfSPK+JB9Kcn8O6nSemeRbk/zNxb77SV7Xe3+o0M9VURwEAAAAAAAAAMBJ8Zok33aF216waMvuLPYzTfKSRbuS+5O8uvf+nmIfV0VxEAAAAAAAAADA2PVF23ZDyPFw783BkmF/PcmzkzwpyY1JWpLPJvnvSX41yZ299y+sOhnFQQAAAAAAAAAAnAi999uT3H7EY9yZx5hRqPf+qST/ZtE2brLpBAAAAAAAAAAAgNUwcxAAAAAAAAAAwMj13tJ723QahxpCjkNj5iAAAAAAAAAAABgpxUEAAAAAAAAAADBSioMAAAAAAAAAAGCkZptOAAAAAAAAAACANeibToBNMHMQAAAAAAAAAACMlOIgAAAAAAAAAAAYKcuKAQAwXpNiLfx8frx5HKaa55BMWi1uOi2Fzc/U4nbPFfNMsn9dbT7e6en9Wty09jqdTtY7b/Ckmaf4Sua9/nrj5Kq+bk7Ce7F6H6uPafV8Wj5/F8eL6vh0lDGxOg5Xx/1M9mpxa/7IdyQ+1wIAAMeg95Y+gL9JDSHHofFtDQAAAAAAAAAARkpxEAAAAAAAAAAAjJTiIAAAAAAAAAAAGKnZphMAAAAAAAAAAGDF+qJtuyHkODBmDgIAAAAAAAAAgJFSHAQAAAAAAAAAACNlWTEAAAAAAAAAgNFri7bthpDjsJg5CAAAAAAAAAAARkpxEAAAAAAAAAAAjJTiIAAAAAAAAAAAGKnZphMAAAAAAAAAAGDF+qJtuyHkODBmDgIAAAAAAAAAgJFSHAQAAAAAAAAAACNlWTEAALjURA39FbW23v5m01LY3pli3HX1+zc/My/FnZrW4qbN3LoAQ1Q9f0+L48XFM7X+9q6rfx6qjsM7xXG/rPq5pg9oDPa5FgAAWGZZsRPLt0MAAAAAAAAAABgpxUEAAAAAAAAAADBSioMAAAAAAAAAAGCkZptOAAAAAAAAAACAFetJett0Fofrm05gfMwcBAAAAAAAAAAAI6U4CAAAAAAAAAAARkpxEAAAAAAAAAAAjNRs0wkAAAAAAAAAALBavR+0bTeEHIfGzEEAAAAAAAAAADBSioMAAAAAAAAAAGCkLCsGAAAAAAAAADB2fdG23RByHBgzBwEAAAAAAAAAwEgpDgIAAAAAAAAAgJFSHAQAAAAAAAAAACM123QCAADACdBaKazPar9nmO/U+pvvlMKSJH02L8VNJrUFtFtbbxxXNu+11xusU/V1OnHOuKJ1n4er40V1fJrvTEtxB7HrHfdb8XMGAADAidPbQdt2Q8hxYMwcBAAAAAAAAAAAI6U4CAAAAAAAAAAARsqyYgAAAAAAAAAAI9eSDGEFcYuKHT8zBwEAAAAAAAAAwEgpDgIAAAAAAAAAgJFSHAQAAAAAAAAAACM123QCAAAAAAAAAACsWF+0bTeEHAfGzEEAAAAAAAAAADBSioMAAAAAAAAAAGCkLCsGAAAAAAAAADB2vR20bTeEHAfGzEEAAAAAAAAAADBSioMAAAAAAAAAAGCkFAcBAAAAAAAAAMBIzTadAAAAcAK04hrRxbj5rBg3LYUdmPZSWGu1uHWbDCRPgGtVPb/Ne3FsKyqPF8Xx6ShjYnUcXvfnBQAAgBOnL9q2G0KOA2PmIAAAAAAAAAAAGCnFQQAAAAAAAAAAMFKWFQMAAAAAAAAAGDvLip1YZg4CAAAAAAAAAICRUhwEAAAAAAAAAAAjpTgIAAAAAAAAAABGarbpBAAAAAAAAAAAWLG+aNtuCDkOjJmDAAAAAAAAAABgpBQHAQAAAAAAAADASFlWDAAAAAAAAABg7Ho7aNtuCDkOjJmDAAAAAAAAAABgpBQHAQAAAAAAAADASCkOAgAAAAAAAACAkZptOgEAAIAr6a24tnR1Seqj/Hyimmrra40DYLPWft4f0JhYHvcBAAC4Kq0ftG03hByHxsxBAAAAAAAAAAAwUoqDAAAAAAAAAABgpCwrBgAAAAAAAAAwdn3Rtt0QchwYMwcBAAAAAAAAAMBIKQ4CAAAAAAAAAICRUhwEAAAAAAAAAAAjpTgIAAAAAAAAAABGSnEQAAAAAAAAAACMlOIgAAAAAAAAAAAYKcVBAAAAAAAAAAAwUrNNJwAAAAAAAAAAwGq1JK1vOovDtU0nMEJmDgIAAAAAAAAAgJFSHAQAAAAAAAAAACNlWTEAAGBrtV6c47Y6Ne68GHeEPnuvTZJbjas/OAAch7Wf9wc0JpbHfQAAAK5Obwdt2w0hx4ExcxAAAAAAAAAAAIyU4iAAAAAAAAAAABgpxUEAAAAAAAAAADBSs00nAAAAAAAAAADAivVF23ZDyHFgzBwEAAAAAAAAAAAjpTgIAAAAAAAAAABGyrJiAAAAAAAAAABjZ1mxE8vMQQAAAAAAAAAAMFKKgwAAAAAAAAAAYKQUBwEAAAAAAAAAwEjNVnXg1trjkrw0yXOTPCfJLUm+NMnZJJ9P8uEk703yrt77/VdxvK9N8tokz1sc59NJfjvJj/Xef3UV9wEAAAAAAAAAYAxaP2jbbgg5Ds3KioNyUMTzs1e47UuTvHjRvqu19q2991+73I6ttZbkR3NQGLTsliSvSPKK1tqPJfmO3ruXCAAAAAAAAAAALKyyOChJ7knygSS/u9j+0xwsZXZrkr+b5JVJbkryntbac3vv/+Myx/iBfLEw6PeSvDXJR5M8Pckbkzx7cfunk3zPyu4JAAAAAAAAAAAMzCqLgz7Qe3/qY9z+c621lyf5xSQ7Sb43yd9Z3qG19owcFAAlye8keVHv/eHF5btba+9J8sEcLFv2ptbaT/TeP3qcdwIAADgG1Uk+i3GTvWLcfinswH4rhfVei1u3eTHPiTmAgS1XPb+tW3m8KI5PRxkTq+Pwuj8vAAAAnDh90bbdEHIcmMmqDtx7P/RPCL33X0rykcXFF11mlzfkiwVMr18qDHo0/nyS1y8uzpJ8Zy1bAAAAAAAAAAAYn5UVB12Dhxb/nlm+srXWknzD4uJHeu+/ebngxfV/uLj48kUcAAAAAAAAAACceBstDmqt3Zbkry4ufuSSm78iyS2L7Q8ecqhHb781ydOOJTkAAAAAAAAAABi42eG7HK/W2nU5KPr5+iRvTDJd3PQjl+x629L2pYVDl1q+/bYkHztKjgAAAAAAAAAAo9IXbdsNIceBWUtxUGvt9iQ/8Ri7vC3JT19y3VOWtu89pIt7rhB3VVprtx6yy83XekwAAAAAAAAAANi0tc8cdInfT/IdvfffusxtNyxtP3jIXI0vvwAAIABJREFUcR5a2j5XyOOew3cBAAAAAAAAAIBhWVdx0C8l+Z3F9tkkT0/yjUlekeSnW2vf2Xv/lUtizixt7x5y/AtL22ePkigAAAAAAAAAwNi0ftC23RByHJq1FAf13j+f5PNLV92d5N2ttX+Q5CeT3NVae3Xv/c6lfR5Z2t45pIvTS9sPF1I8bCmym3OQMwAAAAAAAAAADMZGlxXrvf9Ua+1lOZhF6F+01u7qvX9ucfMDS7setlTY9Uvbhy1Bdrk87n2s21tr13pIAAAAAAAAAADYuMmmE0hy1+Lf65P8raXrlwt2bj3kGMsz/9xzHEkBAAAAAAAAAMDQbXTmoIVPL21/+dL2h5e2n3nIMZZv/4MjZwQAAAAAAAAAMCa9HbRtN4QcB2YbZg66ZWl7eUmwjyX5xGL7xYcc40WLf/8kycePJy0AAAAAAAAAABi2bSgO+ntL2x96dKP33vPFJcee2Vp7/uWCF9c/OnPQXYs4AAAAAAAAAAA48Va2rFhr7fYk7+69P/IY+7whyUsXFz+e5L9cssvbk3x7DvJ8R2vtRb33h5fizyZ5x+Li3mJ/AABg2xRr+NvevBQ32a31N9kthSVJ2l7ttxfzeW2K3F6cWrca15rfYVzJpPjYzE2PzBpVX6dc2brPw9Xxojo+HWVMrI7D1XG/+jkDAADgRPIV6kRaWXFQkjuS/HBr7edzUPTz0RwsG3ZDkmcl+ZYkL1jsu5vk23vve8sH6L3/UWvtbUnenOQ5SX6jtfaDi2M9Pcmbkjx7sfsP9d7/eIX3BwAAAAAAAAAABmWVxUFJ8oQczPzz7Y+xz71JXtV7/49XuP27kzwxyatyUAj07svs864k33OEPAEAAAAAAAAAYHRWWRz01UlekuSrktyW5ElJbkzySJL7kvx+kl9J8nO99/NXOkjvfZ7k1YsZiF6b5LlJbkrymSR3J3ln7/19K7wfAAAAAAAAAAAwSCsrDuq9fzQHy3+985iO994k7z2OYwEAAAAAAAAAnCStH7RtN4Qch2ay6QQAAAAAAAAAAIDVUBwEAAAAAAAAAAAjtbJlxQAAAAAAAAAA2BJ90bbdEHIcGDMHAQAAAAAAAADASCkOAgAAAAAAAACAkVIcBAAAAAAAAAAAIzXbdAIAAAAAAAAAAKxYT1rfdBJXYQg5DoyZgwAAAAAAAAAAYKQUBwEAAAAAAAAAwEhZVgwAAC41n6+3v8mAavb7mudz3dsvhc0eKcadr39FmjzSSnH7+7Xnf7/X+vMlEGCzqufv6nhRHZ9m5+tjfnUcro77Zev+XLMJPtcCAAAQfxcGAAAAAAAAABi/vmjbbgg5DoyfcgAAAAAAAAAAwEgpDgIAAAAAAAAAgJGyrBgAAAAAAAAAwNhZVuzEMnMQAAAAAAAAAACMlOIgAAAAAAAAAAAYKcVBAAAAAAAAAAAwUrNNJwAAAAAAAAAAwGq1ftC23RByHBozBwEAAAAAAAAAwEgpDgIAAAAAAAAAgJFSHAQAAAAAAAAAACOlOAgAAAAAAAAAAEZKcRAAAAAAAAAAAIyU4iAAAAAAAAAAABip2aYTAACAlZnPN53B1TlKnpOB1PvPey1uf78UNnmkFrfzYDHPJNPzrRS3e2Faits/XXvu9ye119tsWnts5r32uCTJpNWfjyGo3r+jPKYM39jfF0ex7vfG/rzW3/5+8fxdHC92iuPTUcbE6jhcHffLnzOGZOyfa4fymRYAAIauL9q2G0KOA+NbFwAAAAAAAAAAjJTiIAAAAAAAAAAAGCnLigEAAAAAAAAAjFzrB23bDSHHoTFzEAAAAAAAAAAAjJTiIAAAAAAAAAAAGCnFQQAAAAAAAAAAMFKzTScAAAAAAAAAAMAa9E0nwCaYOQgAAAAAAAAAAEZKcRAAAAAAAAAAAIyUZcUAAAAAAAAAAMauZxjLig0hx4ExcxAAAAAAAAAAAIyU4iAAAAAAAAAAABgpxUEAAAAAAAAAADBSs00nAADAhsznm86Ak6TXFolu+7XX6fThi6W4nQdOl+IOYmtfr3YfnpbiLp6txc2mxcd0UnwOmwXCj9tkA4/pvLe19zkEm3guOH69+Pren9d+c3fxYu38neJ4sfNA7f7tPLBfikvq43B13K9+zmCLnITvJhO/0wUAYPNaP2jbbgg5Do1vJAAAAAAAAAAAMFKKgwAAAAAAAAAAYKQsKwYAAAAAAAAAMHZ90bbdEHIcGDMHAQAAAAAAAADASCkOAgAAAAAAAACAkVIcBAAAAAAAAAAAIzXbdAIAAAAAAAAAAKxW6wdt2w0hx6ExcxAAAAAAAAAAAIyU4iAAAAAAAAAAAE6E1toTW2sva629pbX2vtbaZ1prfdHuXFGf39Ra+7XW2p+21h5prX28tfZTrbXnr6K/S1lWDAAAAAAAAABg7PqibbvV53jfyntYaK2dSfLvkrzskpu+fNG+ubV2R+/9+1eZh5mDAAAAAAAAAAA4ie5J8h9WePx35YuFQR9I8vIkz0vy6iQfzUHdzltaa69ZYQ5mDgIAAAAAAAAA4MR4S5K7k9zde7+vtfa0JB877k5aay9O8s2Li7+c5BW99/3F5btba+9J8rtJnprkra21f997//xx55GYOQgAAAAAAAAAgBOi9/69vfdf6b2venmxNy7+3U/yj5YKgx7N4zNJ3rS4+PgczCa0EmYOAgDYFvP5pjOA1enFRaKL74t24WIpbufP9kpxSXL6s9NS3CNPqMXtXV/7Ord3av/wnS5jOqk9F9Mj/CSlelactCEsnD4sHlPWZd5bObYXY/fntbi9/doJbu9C7fw9+0JtvDj92dr79yhjYnUcLn8ern7OgHXyfQ8AgG3QF23bDSHHQ7TWziX56sXF9/fe773Crr+Q5AtJHpfklUl+eBX5mDkIAAAAAAAAAACOz/OSnF5sf/BKO/Xed5P85qMxrbVTq0hGcRAAAAAAAAAAAByf25a2P3LIvo/ePkvyF1aRjGXFAAAAAAAAAADYRje39thLgj/Gkl2b9JSl7cPyu+eSuA8fdzKKgwAAAAAAAAAARq71g7btLsnx7qsJWU0mR3LD0vaDh+z70NL2uRXkYlkxAAAAAAAAAAA4RmeWtncP2ffC0vbZFeRi5iAAAAAAAAAAALbSc5N8ctNJFDyytL1zyL6nl7YfXkEuioMAAAAAAAAAAEavL9q2+39z/GTv/d4NZXIUDyxtH7ZU2PVL24ctQVZiWTEAAAAAAAAAADg+ywVNtx6y71OWtu9ZQS6KgwAAAAAAAAAA4Bh9eGn7mYfs++jte0n+1yqSURwEAAAAAAAAAADH5+4ku4vtF19pp9baTpLnPxrTe9+90r5HoTgIAAAAAAAAAOAk6ANoI9B7fyDJf1pcfElr7UpLi70yyeMW27+4qnwUBwEAAAAAAAAAwFVqrd3eWuuLdscVdnvb4t9Zkn/ZWptecoybkvzg4uLnk/z4SpJdJAAAAAAAAAAAAKPXWnthkmcsXXXT0vYzWmu3L+/fe7+z0k/v/T+31t6d5JuS/O0k72+tvT3JJ5I8K8l3J3nqYvc3994/V+nnaigOAgCAIZvPa3GTgUwiOq/NIdsuXCzFzR64UIpLkrP3nyrFXXjC9PCdLuOhG2r97Z6qvWam01pca/uluCSZtlrcvNcCJ20kcxbDFqi+D4/WZy1ub14bE3cv1M7DebAWd+aztcf07P218/BRxsTqOFx+Eoei+rkNAADgmLR+0LbdGnJ8TZJvu8JtL1i0ZXceoa9X5WDZsJcm+apFWzZP8v2993ceoY9DDeR/BAAAAAAAAAAAYDh67w/33r8uybckeX+STyXZTXJPkp9J8sLe+x2rzsPMQQAAAAAAAAAAnAi999uT3H7EY9yZa5hRqPf+MzkoBtoIMwcBAAAAAAAAAMBImTkIAAAAAAAAAGDs+qJtuyHkODBmDgIAAAAAAAAAgJFSHAQAAAAAAAAAACNlWTEAAAAAAAAAgJFr/aBtuyHkODRmDgIAAAAAAAAAgJFSHAQAAAAAAAAAACOlOAgAAAAAAAAAAEZqtukEAAAAAAAAAABYsb5o224IOQ6MmYMAAAAAAAAAAGCkFAcBAAAAAAAAAMBIWVYMAADYXr04f+z+filscn631l+SM5+pxZ593JlS3MVztd96XNg5VYrbndUe07ZTCluo9Tmd1F43895KcZNmnmPGq/q+qNqf1/vb25+W4nZ3a38e23uodj49fX/t/H32vtq5pjo+HWVMrI7D5XEfAACAq2NZsRPLzEEAAAAAAAAAADBSioMAAAAAAAAAAGCkFAcBAAAAAAAAAMBI1RZVBwAAAAAAAABgMNqibbsh5Dg0Zg4CAAAAAAAAAICRUhwEAAAAAAAAAAAjZVkxAAAAAAAAAICx64u27YaQ48CYOQgAAAAAAAAAAEZKcRAAAAAAAAAAAIyU4iAAAAAAAAAAABip2aYTAAAAAAAAAABgxXrS+qaTuApDyHFgzBwEAAAAAAAAAAAjpTgIAAAAAAAAAABGyrJiAABwEs3ntbjJmn9f0Ivzx+7X7l97ZLfWX5LZFx4pxV1/X+1r2d51tbj9nVrchenpUlzO1cKSJDvVwP1S1KTVeiu+m8omg5j7mVWZ9+ILtagX+5sXX6Z7+9NaYJILu8Xz24O189vs/lp/1/1pKSzX37dXiquOT0cZE6vjcHncX7fq5ygAAIBN6xnGkl1DyHFgzBwEAAAAAAAAAP+XvbuPlfS66wP+/d293hfbITUEahGHQjGNQwsIiCPeEqNCIxRTkSBUEtpCICbQSikhIJICUlGgtLxEDaK0vKWxUlARlARDE1qoEiyIEuKgqKWKQ14I1MZJqPNCbK93r/fO6R/zrHay7O7ce+6dO/M8+/lIR3OemfN7zm/unZe9s785B2CiFAcBAAAAAAAAAMBEKQ4CAAAAAAAAAICJ6tscHQAAAAAAAACAcWnrToB1sHIQAAAAAAAAAABMlOIgAAAAAAAAAACYKMVBAAAAAAAAAAAwUdvrTgAAAAAAAAAAgNWqNm+bbgw5jo2VgwAAAAAAAAAAYKIUBwEAAAAAAAAAwETZVgwAAAAAAAAAYOra0DbdGHIcGSsHAQAAAAAAAADARCkOAgAAAAAAAACAiVIcBAAAAAAAAAAAE7W97gQAAIARmc364raO+HsJrXNT6nO73VPW6bNdcScePNYVd/2Ja7vido/3/Rl4euuarri+n8rg+r6wdrwvbnur7/F9rPPhXdX3OJ216ptwDbY67+NRG9PPtFfrvI+7s764c7O+J8bOTv9HVWcfPtEVt/1g3+vbtR/o+9lc/8C5rrgTDz7aFdf7/nSQ98Tu9+Gj1vvvGgAAgJGqNm+bbgw5jo2VgwAAAAAAAAAAYKIUBwEAAAAAAAAAwETZVgwAAAAAAAAAYOra0DbdGHIcGSsHAQAAAAAAAADARCkOAgAAAAAAAACAiVIcBAAAAAAAAAAAE7W97gQAAAAAAAAAAFitavO26caQ49hYOQgAAAAAAAAAACZKcRAAAAAAAAAAAEzUSouDquqLqur7q+q3q+q+qjpbVQ9X1bur6s6qevo+z/c1VfXaqrp/ONf9w/HXrOo+AAAAAAAAAACMXhtR41Btr+rEVXV3kmdc4qbjST5naN9SVf85yR2ttZ0rnKuS/GySF1500xOTPCfJc6rq55N8Z2vNwwQAAAAAAAAAALLalYOeOFw+kOSnknxDkqcl+dIkL0nyF8Pt/zTJnUvO9SO5UBj0jiTPG871vOE4w+0/fAh5AwAAAAAAAADAJKxs5aAk70ry/Ul+vbW2e9Ftbx1WDHpzkr+T5HlV9R9ba79/8Umq6uYk3zccvj3JM1prjw7H91TVbya5O8lTk7y0ql7dWnvfCu4PAAAAAAAAAACMysqKg1prX7vk9ger6nuS/NZw1Tck+WvFQUm+OxfyfNFCYdD585yuqhclecsw7sVJXnSQ3AEAgKvUAXYprp3HuuK2Pv7o8kGXcGq7byHYtnWqKy451hV1enZN53zJ2d3qitu9ru93cfxEX9z2sVlX3LGt3rij3027qm/OWev7HY5FW8P92511Pi9mfa8Z53b74nbO9j33zz3S/5qx/eG+j7mu/UDfz/ST/u/F34Xbm1MfOtMV1/t+0fv+dJD3RAAAADZUG9qmG0OOI7PKbcX24vcW+p998Y1VVUm+bjh8V2vtrZc6yXD9nwyHzx7iAAAAAAAAAADgqrbu4qDjC/1LfWXys5I8cejfveRc52+/KclnHiwtAAAAAAAAAAAYv5VtK7ZHty3033WJ25+y5PZc5vanJHl/b1IAAAAAAAAAAFNSbd423RhyHJu1FQdV1VaSly1c9auXGPakhf79S05532Xi9pLLTUuG3Lif8wEAAAAAAAAAwCZY58pB353kaUP/da21t19izOMW+g8vOd8jC/3r95nLfcuHAAAAAAAAAADAuGytY9Kqui3Jvx0O/zLJP7vM0JML/Z0lpz270D/VmRoAAAAAAAAAAEzGka8cVFV/N8nrhrnPJvlHrbUPXWb4mYX+8SWnPrHQf3SfaS3bhuzGJPfs85wAAAAAAAAAAJujrTsB1uFIi4Oq6rOS/E6SG5LsJnlea+3uK4Q8tNBftlXYdQv9ZVuQfYLW2v1Xur2q9nM6AAAAAAAAAADYCEe2rVhVfXqS/5nk0zOvRfu21trrloQtFu3ctGTs4uo/9+0/QwAAAAAAAAAAmJYjWTmoqp6Q5HeT/O3hqhe11l6zh9B3LvRvWTJ28fZ795EeAAAAAAAAAMCkVWuptvn7io0hx7FZ+cpBVfX4JP8jyecOV72stfYzewx/f5IHhv5tS8Y+Y7j8iyR/tp8cAQAAAAAAAABgilZaHFRV1yZ5fZIvGq761621H9trfGutJblrOLylqr7kMvN8SS6sHHTXEAcAAAAAAAAAAFe1lRUHVdXxJK9L8uXDVT/VWvvBjlO9Msm5of/TVXXqonlOJfnp4fDcMB4AAAAAAAAAAK562ys8939J8syh/8Ykr6qqv3eF8TuttXdffGVr7d1V9ZNJXpbkqUneXFU/luR9ST47yUuTfOEw/Cdaa+85rDsAAAAcktmsL25r5Tshf6KDLEK623cfa+exrrhjHz3dFXdtV1RSs5Ndccd2jnXOmJze6fuTdedT+h43j17fF7d94tzyQZdwzTW7XXHHjnU+n5Icq77HeHXG9eqdr7U65ExWN99uZ+zubt/j9LHH+p6L5852fnT08DVdYSc+3P+6f+0H+uKuf6DvOXzqQ2e64npfv3vfL3rfnw70nnjUev+dAQAAcLVpQ9t0Y8hxZFZZHPT1C/2/n+R/Lxn/50k+8zK3/UCST0vybZkXAv3KJca8KknPykQAAAAAAAAAADBJR/w13D6ttVlr7QVJbk9yV5IHkuwMl3cleVZr7Y7Wmq8JAQAAAAAAAADAYGUrB7UVrOXdWntDkjcc9nkBAAAAAAAAAKas2rxtujHkODajWDkIAAAAAAAAAADYP8VBAAAAAAAAAAAwUYqDAAAAAAAAAABgorbXnQAAAAAAAAAAACvWhrbpxpDjyFg5CAAAAAAAAAAAJkpxEAAAAAAAAAAATJTiIAAAAAAAAAAAmKjtdScAAAAAAAAAAMBqVZu3TTeGHMfGykEAAAAAAAAAADBRioMAAAAAAAAAAGCibCsGAABsrtmsL25rDd+DaJ1r3Z7b7Qqr7HTFHftIX57Xnuv7XRw7e6orLkm2T/f9yfrow8e64s58ct/j5rFP6svzsVN9v/tjJ/rikuTYsb7f49ZW3+OmOteA7o1rrY40bjbri0uS3d2+x9vu2b7Hdx7ti9v+eF/cyY/0/WxOfah/3fDrPnSuK+7Eg492xW19vC+udh7riut9v+h+f1qH3vd9AAAA9qYNbdONIceRsXIQAAAAAAAAAABMlOIgAAAAAAAAAACYKMVBAAAAAAAAAAAwUdvrTgAAAAAAAAAAgNWqNm+bbgw5jo2VgwAAAAAAAAAAYKIUBwEAAAAAAAAAwETZVgwAAAAAAAAAYOra0DbdGHIcGSsHAQAAAAAAAADARCkOAgAAAAAAAACAiVIcBAAAAAAAAAAAE7W97gQAAAAAAAAAAFi9auvOgHWwchAAAAAAAAAAAEyU4iAAAAAAAAAAAJgo24oBAACsU+tcx/fcbldYdc639Vd9cScf68szSbYfOdkVd+Ljx7viHv2Uvu/PnP3kvj+tdx53rCtu99r+tZ8fO9kX27ZnfRMe68y1+sLS+6PZ7ZuwzvV/52rrTN+cx093xj3UF3fiI30/1FMf7nvun3xwpysuSbY/fqYrrk6f7YvbeawrLrudz6fe9wsAAAA4r7Vx/H05hhxHxspBAAAAAAAAAAAwUYqDAAAAAAAAAABgohQHAQAAAAAAAADARG2vOwEAAAAAAAAAAFar2rxtujHkODZWDgIAAAAAAAAAgIlSHAQAAAAAAAAAABNlWzEAAAAAAAAAgKlrQ9t0Y8hxZKwcBAAAAAAAAAAAE6U4CAAAAAAAAAAAJkpxEAAAAAAAAAAATNT2uhMAAAAAAAAAAGC1ajZvm24MOY6NlYMAAAAAAAAAAGCiFAcBAAAAAAAAAMBE2VYMAACYnlnnurNbI/r+RGt9cbt9P5s6s9MXd263Ky5Jrtk51xV37PTxrrgTHz3RFbfz+L4/rXce1/d427m+uuKS5Ny1fXPOjh/ri+sL6/8qU+9Tv/NhutX3tEiSbJ/uew4ff7gz7qG+O3n8r/qeh9sPne2K2zrd/0PtfZ1K7+tU7+twb9yY9L4PAwAAsFptaJtuDDmOzIg++QYAAAAAAAAAAPZDcRAAAAAAAAAAAEyU4iAAAAAAAAAAAJio7XUnAAAAAAAAAADAalWbt003hhzHxspBAAAAAAAAAAAwUYqDAAAAAAAAAABgomwrBgAAAAAAAAAwda3N26YbQ44jY+UgAAAAAAAAAACYKMVBAAAAAAAAAAAwUYqDAAAAAAAAAABgorbXnQAAAAAAAAAAAKtVbd423RhyHBsrBwEAAAAAAAAAwEQpDgIAAAAAAAAAgIlSHAQAAAAAAAAAABO1ve4EAAAANsZs1h+7NZLvXrTODbt74x7r3yC8On8fx84+1hW3dXqnK+6aj13TFXfyVF/c7OSxrrgkOdcZOztefXHbfXHpDEvnw23rXF/g1k7/43v7zG7fnJ1xxx7te15U5/OpNy67ffdvHtv5Gt77+jZ1B3lPBAAAYHP5M/iqNJJPrwEAAAAAAAAAgP1SHAQAAAAAAAAAABNlWzEAAAAAAAAAgImrNm+bbgw5jo2VgwAAAAAAAAAAYKIUBwEAAAAAAAAAwEQpDgIAAAAAAAAAgInaXncCAAAAAAAAAACsWGvztunGkOPIWDkIAAAAAAAAAAAmSnEQAAAAAAAAAABMlG3FAAAAAAAAAAAmrtq8bbox5Dg2Vg4CAAAAAAAAAICJUhwEAAAAAAAAAAATpTgIAAAAAAAAAAAmanvdCQAAAEzCbHa0822N5Lse7QAbhO92/kxnfXPW7m5f3JmdvriHO3+Hx471xSU5vt0X27Y7c63qm68zrnofb51xde4Az/tzfY+39D5Ou59PR/s8PNBrxkFix+Co32cAAACYnja0TTeGHEdmJJ8mAwAAAAAAAAAA+6U4CAAAAAAAAAAAJsq2YgAAAAAAAAAAE1dt3jbdGHIcGysHAQAAAAAAAADARCkOAgAAAAAAAACAiVIcBAAAAAAAAAAAE7W97gQAAAAAAAAAAFixWZu3TTeGHEfGykEAAAAAAAAAADBRioMAAAAAAAAAAGCibCsGAAAAAAAAADB1bWibbgw5joyVgwAAAAAAAAAAYKIUBwEAAAAAAAAAwEQpDgIAAAAAAAAAgInaXncCAAAAdJjN+uK2RvQdkda5uXhvXOePNNUXWOeqb76tc31xB1DVmWtv3FE76sfaQcyOONd13Mep6339BgAAgAOqJDWCP/VH8onSqIzoU2EAAAAAAAAAAGA/FAcBAAAAAAAAAMBE2VYMAAAAAAAAAGDqWsaxhfgIUhwbKwcBAAAAAAAAAMBEKQ4CAAAAAAAAAICJUhwEAAAAAAAAAMBVp6o+o6p+sqrurapHquojVfW2qvreqrr2gOf+oapqe2xfeUh36ZK2V3lyAAAAAAAAAAA2QEuqrTuJPTiiHKvq9iS/nOTxC1dfm+TWod1RVc9qrf3p0WS0OoqDAAAAAAAAAAC4alTVFyT51cyLgR5O8m+SvCnJqSTPTfLtSZ6c5PVVdWtr7eEDTvl5S25//wHPf0WKgwAAAAAAAAAAuJq8MvPCoHNJntlae8vCbW+sqvck+fEktyR5SZKXH2Sy1tr/OUj8QW2tc3IAAAAAAAAAAI5AG1Fboaq6NclXDoevuqgw6LxXJLl36L+4qq5ZbVarpTgIAAAAAAAAAICrxbMX+q++1IDW2izJa4bDG3KhmGiUFAcBAAAAAAAAAHC1ePpw+UiSP7rCuLsX+l+xunRWT3EQAAAAAAAAAABXi6cMl+9trZ27wrh3XSKmS1X9blV9uKp2quovq+r3quplVXXDQc67V9tHMQkAAAAbYjY72vm2roLvpLTOTdB74w7yK6w6QDCHqvf3z+E76tdFAAAAWJNqLTWCzyQuyvHGWvKZVmvt/j2fu+pkkicMh1eMa619tKoeSXJdkiftdY7L+OqF/qcmuW1oL62q57fW7jrg+a9IcRAAAAAAAAAAAJvonj2M2c834h630H94D+PPFwddv485Fv1xkt9I8rYkDyS5JsmTk/zjJM9M8jeS/HpV/cPW2m93zrGU4iAAAAAAAAAAAK4GJxf6O3sYf3a4PNUx1ytbaz90iev/MMlrquo7kvxskmNJfrGqbm6tPdoxz1KKgwAAAAAAAAAA2ES3JvngIZ7vzEL/+B7Gnxgu912001r72JLbf66qnprkjiSfnuTrk/zyfufZC8VBAABtsuvPAAAgAElEQVQAAAAAAABTNxvapvvEHD/YWrv/EM/+0EJ/L1uFXTdc7mULsh4/l3lxUJLclhUVB22t4qQAAAAAAAAAALBJWmtnkjw4HN50pbFVdUMuFAfdt6KU3rnQf+KK5lAcBAAAAAAAAADAVePe4fLmqrrSjlu3XCLmsNWKzvsJbCsGAAAAAAAAADBx1VqqtXWnsdQR5PgHSZ6e+apAX5zkDy8z7raF/ptXlMvnLvQfWNEcVg4CAAAAAAAAAOCq8RsL/W+91ICq2kryzcPhx5K8aUW5fMdC/+4VzaE4CAAAAAAAAACAq0Nr7W1Jfn84fEFVfeklhn1PkqcM/Z9qrT22eGNVPb+q2tB+6OLgqvq8qrr5SnlU1XckecFw+MEkr9vH3dgX24oBAAAAAAAAAHA1+a7Mtwo7leR3qupHM18d6FSS5yZ54TDu3Ule0XH+L07yi1X1piS/neSPk3w48zqdW5L8kyT/YBi7m+Q7WmuP9N2V5RQHAQAAAAAAAABMXRvapjuCHFtr76iqb0zyS0k+KcmPXmLYu5Pc3lp7qHOaY0m+emiX8+EkL2it/WbnHHuiOAgAAAAAAAAAgKtKa+23qurzM19F6PYkNyXZSfLeJL+W5N+31k53nv4NmW8Z9qVJvjDJ30zyKUkqyUeS/K8k/z3Jna21jx/kfuyF4iAAAAAAAAAAAK46rbU/T/KSoe0n7s4kd17h9r9M8p+GtnaKgwAAAFid2aw/dmvr8PJgro1h3WjodJDXGwAAALgqtJF8PjSGHMfFJ60AAAAAAAAAADBRioMAAAAAAAAAAGCiFAcBAAAAAAAAAMBEba87AQAAAAAAAAAAVqvavG26MeQ4NlYOAgAAAAAAAACAiVIcBAAAAAAAAAAAE2VbMQAAAAAAAACAqWtt3jbdGHIcGSsHAQAAAAAAAADARCkOAgAAAAAAAACAiVIcBAAAAAAAAAAAE7XS4qCq+rSq+tqqenlV/XZVPVhVbWh3dpzva6rqtVV1f1WdHS5fW1Vfs4L0AQAAAAAAAAAmoWbjaRyu7RWf/0OHcZKqqiQ/m+SFF930xCTPSfKcqvr5JN/ZWmuHMScAAAAAAAAAAIzdUW4rdl+S3+mM/ZFcKAx6R5LnJXnacPmO4foXJvnhgyQIAAAAAAAAAABTsuqVg16e5J4k97TWPlRVn5nk/fs5QVXdnOT7hsO3J3lGa+3R4fieqvrNJHcneWqSl1bVq1tr7zuM5AEAAFij2RGvH7x1lN+fgYk76ucvAAAAsFxr87bpxpDjyKz0k8/W2r9qrf231tpBthf77lwoYnrRQmHQ+TlOJ3nRcLid5MUHmAsAAAAAAAAAACZjo78WWVWV5OuGw3e11t56qXHD9X8yHD57iAMAAAAAAAAAgKvaRhcHJfmsJE8c+ncvGXv+9puSfOaqEgIAAAAAAAAAgLHYXj5krZ6y0H/XkrGLtz8lyfsPPx0AAAAAAAAAgBFqQ9t0Y8hxZDa9OOhJC/37l4y97zJxS1XVTUuG3Lif8wEAAAAAAAAAwCbY9OKgxy30H14y9pGF/vX7nOe+5UMAAAAAAAAAAGBcNr046ORCf2fJ2LML/VMryAUAAAAAAAAAYJSqtVTb/D27xpDj2Gx6cdCZhf7xJWNPLPQf3ec8y7YhuzHJPfs8JwAAAAAAAAAArNWmFwc9tNBftlXYdQv9ZVuQfYLW2v1Xur2q9nM6AAAAAAAAAADYCFvrTmCJxaKdm5aMXVz9574V5AIAAAAAAAAAAKOy6SsHvXOhf8uSsYu337uCXAAAAAAAAAAAxqm1edt0Y8hxZDZ95aD3J3lg6N+2ZOwzhsu/SPJnq0oIAAAAAAAAAADGYqOLg1prLcldw+EtVfUllxo3XH9+5aC7hjgAAAAAAAAAALiqbfq2YknyyiTfnnmuP11Vz2itPXr+xqo6leSnh8Nzw3gAAADYn9ls3RnszdZGf8+HVRvL4xQAAADYPC3JGD5asBzMoVtpcVBVfUWSmxeuesJC/+aqev7i+NbanRefo7X27qr6ySQvS/LUJG+uqh9L8r4kn53kpUm+cBj+E6219xzaHQAAAAAAAAAAgBFb9cpBdyT5lsvc9uVDW3TnZcb+QJJPS/JtmRcC/colxrwqyQ/uP0UAAAAAAAAAAJimUaxF3lqbtdZekOT2JHcleSDJznB5V5JntdbuaK2NYQEsAAAAAAAAAAA4EitdOai19vwkzz/E870hyRsO63wAAAAAAAAAAFeDai3V2rrTWGoMOY7NKFYOAgAAAAAAAAAA9k9xEAAAAAAAAAAATJTiIAAAAAAAAAAAmKjtdScAAAAAAAAAAMCKtSStrTuL5UaQ4thYOQgAAAAAAAAAACZKcRAAAAAAAAAAAEyUbcUAAAAAAAAAAKautZFsKzaCHEfGykEAAAAAAAAAADBRioMAAAAAAAAAAGCiFAcBAAAAAAAAAMBEba87AQAAAGAfZrP+2C3fEdoYB/k9AgAAAPSYDW3TjSHHkfGpIAAAAAAAAAAATJTiIAAAAAAAAAAAmCjbigEAAAAAAAAATFy1lmpt3WksNYYcx8bKQQAAAAAAAAAAMFGKgwAAAAAAAAAAYKIUBwEAAAAAAAAAwERtrzsBAAAAAAAAAABWrLV523RjyHFkrBwEAAAAAAAAAAATpTgIAAAAAAAAAAAmyrZiAAAAAAAAAACTN5JtxTKGHMfFykEAAAAAAAAAADBRioMAAAAAAAAAAGCiFAcBAAAAAAAAAMBEba87AQAAAAAAAAAAVqy1edt0Y8hxZKwcBAAAAAAAAAAAE6U4CAAAAAAAAAAAJsq2YgAAAAAAAAAAUzcb2qYbQ44jY+UgAAAAAAAAAACYKMVBAAAAAAAAAAAwUYqDAAAAAAAAAABgorbXnQAAAAAAAAAAAKtVraVaW3caS40hx7GxchAAAAAAAAAAAEyU4iAAAAAAAAAAAJgo24oBAAAAAAAAAExda/O26caQ48hYOQgAAAAAAAAAACZKcRAAAAAAAAAAAEyU4iAAAAAAAAAAAJio7XUnAAAAAOzDlu/5TELv73E2O9w8AAAAgKvHrM3bphtDjiPjE0UAAAAAAAAAAJgoxUEAAAAAAAAAADBRthUDAAAAAAAAAJi6lqSNYMuuEaQ4NlYOAgAAAAAAAACAiVIcBAAAAAAAAAAAE6U4CAAAAAAAAAAAJmp73QkAAAAAAAAAALBqLWlt3UnswRhyHBcrBwEAAAAAAAAAwEQpDgIAAAAAAAAAgIlSHAQAAAAAAAAAABO1ve4EAAAAAAAAAABYsdbmbdONIceRsXIQAAAAAAAAAABMlOIgAAAAAAAAAACYKNuKAQAAwDps+b4OHXofN7PZ4eYBAAAAjM+szdumG0OOI+OTSAAAAAAAAAAAmCjFQQAAAAAAAAAAMFGKgwAAAAAAAAAAYKK2150AAAAAAAAAAAAr1mbztunGkOPIWDkIAAAAAAAAAAAmSnEQAAAAAAAAAABMlG3FAAAAAAAAAACmrrV523RjyHFkrBwEAAAAAAAAAAATpTgIAAAAAAAAAAAmSnEQAAAAAAAAAABM1Pa6EwAAAAAAAAAAYMVmbd423RhyHBkrBwEAAAAAAAAAwEQpDgIAAAAAAAAAgImyrRgAAAAAAAAAwNS1Nm+bbgw5joyVgwAAAAAAAAAAYKIUBwEAAAAAAAAAwEQpDgIAAAAAAAAAgInaXncCAAAAAAAAAAAcgdbWnQFrYOUgAAAAAAAAAACYKMVBAAAAAAAAAAAwUbYVAwAAAAAAAACYutbGsa3YGHIcGSsHAQAAAAAAAADARCkOAgAAAAAAAACAiVIcBAAAAAAAAAAAE7W97gQAAAAAAAAAAFix2Syp2bqzWG42ghxHxspBAAAAAAAAAAAwUYqDAAAAAAAAAABgomwrBgAAAAAAAAAwda3N26YbQ44jY+UgAAAAAAAAAACYKMVBAAAAAAAAAAAwUYqDAAAAAAAAAABgorbXnQAAAAAAAAAAACvW2rxtujHkODJWDgIAAAAAAAAAgIlSHAQAAAAAAAAAABOlOAgAAAAAAAAAACZqe90JAAAAAAAAAACwYrOWVFt3FsvNRpDjyFg5CAAAAAAAAAAAJkpxEAAAAAAAAAAATJRtxQAAAAAAAAAAJq61WVqbrTuNpcaQ49hYOQgAAAAAAAAAACZKcRAAAAAAAAAAAEyU4iAAAAAAAAAAAJio7XUnAAAAAAAAAADAirUks7buLJYbQYpjY+UgAAAAAAAAAACYKMVBAAAAAAAAAAAwUbYVAwAAAAAAAACYutbmbdONIceRsXIQAAAAAAAAAABMlOIgAAAAAAAAAACYKMVBAAAAAAAAAAAwUdvrTgAAAAAAAAAAgBWbzZLM1p3FcrMR5DgyVg4CAAAAAAAAAICJUhwEAAAAAAAAAAATZVsxAAAAAAAAAICpa23eNt0YchwZKwcBAAAAAAAAAMBEKQ4CAAAAAAAAAICJUhwEAAAAAAAAAAATtb3uBAAAAGDUtnzvhhHofZzOZoebBwAAALA2bTZLy+b/rd98HnHofIIJAAAAAAAAAAATpTgIAAAAAAAAAAAmyrZiAAAAAAAAAABT19q8bbox5DgyVg4CAAAAAAAAAICJUhwEAAAAAAAAAAATpTgIAAAAAAAAAAAmanvdCQAAAAAAAAAAsGKtJbO27iyWayPIcWSsHAQAAAAAAAAAABOlOAgAAAAAAAAAACbKtmIAAAAAAAAAAFPXWpLZurNYzrZih250KwdV1WdU1U9W1b1V9UhVfaSq3lZV31tV1647PwAAAAAAAAAA2BSjWjmoqm5P8stJHr9w9bVJbh3aHVX1rNban64jPwAAAAAAAAAA2CSjWTmoqr4gya9mXhj0cJIfSPJlSb4qyS8Mw56c5PVVdf1akgQAAAAAAAAAgA0yppWDXpn5KkHnkjyztfaWhdveWFXvSfLjSW5J8pIkLz/6FAEAAAAAAAAANk+btbRq605jqdY2P8exGcXKQVV1a5KvHA5fdVFh0HmvSHLv0H9xVV1zFLkBAAAAAAAAAMCmGkVxUJJnL/RffakBrbVZktcMhzfkQjERAAAAAAAAAABclcayrdjTh8tHkvzRFcbdvdD/iiS/u7KMAAAAAAAAAADGos2SzNadxXJtBDmOzFiKg54yXL63tXbuCuPedYmYparqpiVDbtzruQAAAAAAAAAA2HxV9RlJ/kWS25N8RpKzSd6b5FeT/IfW2ulDmue5Sb41yednvhvWB5P8fpKfaa299TDmuJKNLw6qqpNJnjAc3n+lsa21j1bVI0muS/KkfUxzX2d6AAAAAAAAAACMTFXdnuSXkzx+4eprk9w6tDuq6lmttT89wBwnk/xakq+96Ka/NbRvqqofaq39cO8ce7G1ypMfksct9B/ew/hHhsvrV5ALAAAAAAAAAAAjVlVfkPnqQI/PvBblB5J8WZKvSvILw7AnJ3l9VR2k/uRVuVAY9KYkz07ytCQvSPK+zOt2Xl5VdxxgjqU2fuWgJCcX+jt7GH92uDy1jzmWrTJ0Y5J79nE+AAAAAAAAAICN0WYtrdq601iqtSPJ8ZWZrxJ0LskzW2tvWbjtjVX1niQ/nuSWJC9J8vL9TlBVtyX5puHwt5I8p7W2OxzfU1W/meSPMt/O7Mer6r+21j7WdW+WGMPKQWcW+sf3MP7EcPnoXidord1/pZb5Xm8AAAAAAAAAAIxYVd2a5CuHw1ddVBh03iuS3Dv0X1xV13RM9X3D5W6Sf75QGJQkaa09mOSlw+ENma8mtBJjKA56aKG/l6Warhsu97IFGQAAAAAAAAAAV49nL/RffakBrbVZktcMhzfkQjHRngxbkX3VcPi7w8I0l/LaJB8f+l+/nzn2Y+OLg1prZ5I8OBzedKWxVXVDLhQH3bfKvAAAAAAAAAAAGJ2nD5ePZL6t1+XcvdD/in3O8bRc2Pnq7ssNaq3tJHnr+ZjOFYqW2vjioMH5pZpurqrtK4y75RIxAAAAAAAAAABXtzYbT1utpwyX722tnbvCuHddIma/c1x8nivNs53kc/Y5z55cqdBmk/xB5pVb1yX54iR/eJlxty3033yI8x873/nABz5wiKcFALjgzK5dUQFGaVbrzgBWp7V1ZwBwVbv//svtPAAA0O+i//M+drlxTM/ZnElG8Kf+2ZxZPLyx6sqfv11hy66/pqpOJnnCcHjFuNbaR6vqkcxrVZ601zkGi+OX5be4M9aTkrxzn3MtNZbioN9I8i+H/rfmEsVBVbWV5JuHw48ledMhzv+p5ztPe9rTDvG0AAAAAABwaU960p3rTgEAmL5PTfLn606Co3FP3rjuFHrcs4cx+/n23uMW+nv51vb54qDr9zHHfud5ZKG/33n2ZBTbirXW3pbk94fDF1TVl15i2PfkwrJMP9Vae+xIkgMAAAAAAAAAYAxOLvR39jD+7HB5aoXznF3o73eePRnLykFJ8l2ZbxV2KsnvVNWPZr460Kkkz03ywmHcu5O84pDn/uMktw79/5dk95DPD4zTjblQqXprkg+uMRdgurzWAEfBaw1wFLzWAEfBaw1wFLzWAEdhla81x3Jh95w/PsTzspk+mP1vibUpbszh12gs7ll2fA/jTwyXj65wnhML/f3OsyejKQ5qrb2jqr4xyS8l+aQkP3qJYe9Ocntr7aFDnvtskrcf5jmB8btob8sP7mcvS4C98loDHAWvNcBR8FoDHAWvNcBR8FoDHIUjeK2xldhVorV2LslY36tWkfdiPcletvC6brjcyxZkvfNct9Df7zx7Moptxc5rrf1Wks9P8u8yLwQ6neRjmRfuvDTJF7bW3ru+DAEAAAAAAAAA2ESttTNJHhwOb7rS2Kq6IRcKd+7b51SLhU1XnCefuLLTfufZk9GsHHRea+3Pk7xkaAAAAAAAAAAAsFf3Jnl6kpurantYXelSbrkoZj/eeZnzXGmec0lWsiDOqFYOAgAAAID/397dR/tW1fUef3/weHjSlCRsoDJEMTllFIJ5UB691C3BMjQLG+pBzLQ7uEJIKNZF7MHE0stVU0QLzHtVKIiALPEBFMIAh3XvSOBcRW+AiTyIyIMc0e/9Y83tXm1/j+e3z+Hs336/xjhjz/lb3zV/a/9xvmOtub9rTkmSJEmSpBlc0X7uDOw3Iu6QXvvKKb/jGmDTgHH+gyRrgfUL51TVpmGxs7A4SJIkSZIkSZIkSZIkSavF3/TaxwwKSLId8NLWvQv41DRfUFXfAj7RuocnGba12FHAD7X2BdN8xzQsDpIkSZIkSZIkSZIkSdKqUFVXA59p3WOTHDAg7ERgXWufUVXf6R9MsiFJtX9vHPJVf9J+rgHeleRhS8bYFXhL694FvG+632RyFgdJkiRJkiRJkiRJkiRpNXkNcD9d4c7Hkrw+yfokhyU5Ezi9xW0E/nRzvqCqPgl8uHV/Ebg0yS8m2T/JMcBngT3a8ddV1Tc295cZZ82WGliSJEmSJEmSJEmSJEna1lTV55P8KvBBum29/mhA2EbgiLZF2OZ6eRv/ucBh7V/f94Dfr6ozZ/iOsSwOkqTNVFU3A3mor0PSfDPXSNoazDWStgZzjaStwVwjaWsw10jaGsw10pZXVRcl2YduFaEjgMcDm4AvAucB76yq+2b8jvuBI5K8GNgA/BTwaOBWuq3N3llVV83yHZNIVW3p75AkSZIkSZIkSZIkSZL0ENjuob4ASZIkSZIkSZIkSZIkSVuGxUGSJEmSJEmSJEmSJEnSnLI4SJIkSZIkSZIkSZIkSZpTFgdJkiRJkiRJkiRJkiRJc8riIEmSJEmSJEmSJEmSJGlOWRwkSZIkSZIkSZIkSZIkzSmLgyRJkiRJkiRJkiRJkqQ5ZXGQJEmSJEmSJEmSJEmSNKcsDpKkKSXZI8mrk3wkyQ1J7k3y7SQ3J7kwydFJ1kwx3k8keU+SLya5P8ltST6d5DenGUfS/Gn55k+SXNdyzZ1Jrk7y2iQ7PdTXJ2nblOTpSU5J8tEkNyV5IMk9STYmOTvJQVOO9/NJzm/3Og+0n+cn+fkt9TtIWtmSnJ6kev8OneAcc42ksZLsmuR3klyZ5GstX3w1yT8leWuSAyYYw3wjaagka5Mcm+Tvk/x773nqhiR/nmT9hOOYa6RVJsluSY5M8qY2J3N775no7M0Yb+Y8kmSnJCe1OeU7Wz67rs057zHtNUla2VJVD/U1SNKKkeRNwO8CGRN6LfCCqvq3MeMdC7wL2H5IyGeBI6vqjmmvVdLKluQI4H8CjxoScgPw3Kq6cetdlaRtXZLLgYMnCP1L4BVVtWnEWAHeA7xyxDjvBV5VPlhKapL8FN3zUP9Fh8Oq6rIh8eYaSRNJ8ivAu4HHjAi7sKqeP+R8842kkZI8AbgE+MkxoW8HThyUK8w10uqVZNT/6XOqasOE4yxLHknyZLqc9tQhId8EXlxVfzfJdUla+Vw5SJKmsztdYdC9wAeBY4ADgf2BlwDXtLj9gY8necSwgZL8Z7obuO2BW4H/CjwT+AXg/Ba2Hjg/iflaWkXaH9XOpSsMugd4A/As4D8BZ7WwpwKXjMozklalx7WfXwXOAF4I/AxwAPDbwC3t+EuAs8eM9QcsTkR9Hji6jXV069OO//4yXLekOdCeW86iKwz6+oSnmWskjZXkpcCH6QqDvg6cBvwssB9wBN2cyqXAd0YMY76RNFRbwb1fGPS/gQ10z1I/B7yJbk4Y4ATgtUOGMtdIArgJ+NhmnjtzHmlzxhezWBh0Ft3c8rPo5prvoZt7Pi/JPpt5nZJWGFcOkqQpJHkLcAfw7qr61oDjDwP+F/Ci9tF/q6ofuEFrD5vXAXsBdwNPr6ovLYl5F/BbrfuyqvrAsv0ikrZpST4FHAo8CBxcVVctOX4ScHrrnlpVb9q6VyhpW5XkYuADwF9X1XcHHN8VuBL4sfbRwVX1mQFxe9Hdq6yhWwHk4Kq6v3d8J+ByuoLoB4G9l97LSFp9khxP9yb99cAFwOvboYErB5lrJE0iyTq6P4RtD3wGeF5VfXNI7NpBKyOabySNk+QFwF+17lXAQUufqZLs1449HPgGsFtVPdg7bq6RVrEkp9G9QH5NVd2a5InAl9vhiVYOWq48kuSNwKmt+ztV9dYlxw8APt2+51NV9ZyJf1FJK5YrUUjSFKrq5Ko6fVBhUDv+XbqCnoWJqBcOGeqX6QqDAN485CHwJLqHzIW2pFUgyTPoCoMA3r+0MKj5U7qHRIDjkzx8a1ybpG1fVR1ZVecOKgxqx28HTux9NOxe5QQWtwQ6rj8R1ca5DziuddcAx2/+VUuaB20bjoUXI17N4jPRKOYaSZN4B11h0O3AUcMKgwBGbJlqvpE0zrN77TcPeqaqqs/RrcQBsAuw95IQc420ilXVqVV1cVXdOsMwM+eRNlf8mta9jm4ueem1XgW8v3UPa8WPkuacxUGStMyq6g66ZWcBnjwk7Pm99tlDxrmPblshgKclecqyXKCkbV0/P/zFoICq+h7dyiDQTUYduoWvSdJ8uazX/oF7lba3/S+17vVV9dlBg7TPb2jd57fzJK1efwY8gu6N2MvGBZtrJE0iyd50W2AAvLMVOk87hvlG0iTW9to3jojrv+S5/ULDXCNpVsuYRw4FHt3a57S55EHO7rWPmvqCJa04FgdJ0pax8GA47KbroPbzhqr62ohxLu+1D5z5qiStBAv54V7gcyPizA+SNld/0nvQvcqewONa+/IBx/sWjj8eeOJslyVppUryIuBI4E4mX/XUXCNpEr/Sa5+30EiyS5KnJHnMBGOYbyRNYmOv/aQRcQsvWBTwf3ufm2skzWq58shBA+IGuZZuDhqcX5ZWBYuDJGmZJdkNWNe61w84/gi6G7aBx5foH183NErSPFn4v/7F/r71A5gfJG2uQ3rtQfci68YcZ8hxc5G0CiV5NHBG655cVbdNeKq5RtIk1ref3wSuS/LrSf6FrhhxI3B7khuTnNrmWwYx30iaxIeAu1v75CQPWxqQZF/giNb9cFXd3TtsrpE0q+XKIxON0+aeF1ZDMxdJq4DFQZK0/E5icU/YcwccfzywsMzjzWPGuqnXfsKM1yVpG5dkB2DX1h2ZH6rqGyy+2WF+kDSRJNsBr+t9NOhepZ9TvFeRNM7pwI8C/wi8f4rzzDWSJvHj7edXgHcAHwT2WRKzJ/BG4Kokuw8Yw3wjaaxW4LwBuB94NnBNkpcmWZ/k8CSn0q3AsRb4Z+C3lwxhrpE0q+XKIwv9e6vqrgnH+ZEk24+MlLTiWRwkScsoyTOB41v3ZuDPBoQ9ste+Z8yQ9/baw96AkzQ/pskPsJgjzA+SJnUC8DOtfUFVXTsgxnsVSRNJciDwCuBB4FVVVVOcbq6RNIkfbj/3Bv4LcBfwKmA3YAfgGcBHW8zTgPNaMXSf+UbSRKrqAmB/uoLnnwbOAa4CLqUrQryPrijowKr62pLTzTWSZrVceWRhnGnmlweNI2nOWBwkScskyWOBv6JbNaiAl1XVfQNCd+i1N40Z9oFee8fZrlDSCjBNfoDFHGF+kDRWkkOAP27drwOvHhLqvYqksZKsBd5Ltyrq26vq/0w5hLlG0iR2bj+3B74L/EJVnVlVt1XVA63Q+UgWC4SeBRy1ZAzzjaSJJHk48GLgeSyu/N73WOBo4NABx8w1kma1XHlkYZxp5pcHjSNpzlgcJGkuJVmTpJbh34YJv++RwCV0W4YBnFJVnxwS/u1ee+2YofvLON4/ybVIWtGmyQ+wmCPMD5JGSvITwAV0RcwPAC+qqluHhHuvImkSpwDrgH8DTtuM8801kibRzxXnVdVnlwZU1ffotnhfcPSIMcw3kgZKsjPwceANwGPotk5dR5cXHgX8HHAF3YplFyV5zZIhzDWSZrVceWRhnGnmlweNI2nOWBwkSTNKsgNwIbBf++htVfXHI075Vq89bpnGnXvtSZaAlLSyTZMfYDFHmB8kDRPQNvMAAAgBSURBVJVkT+BjwC50b9wfXVWXjzjFexVJIyXZG3h96x5XVfeOih/CXCNpEv1c8dFhQVX1r8AtrfuMEWOYbyQNcxpwcGsfW1UnV9X1VbWpqu6uqkuBw4BP0a0q9LYk+/TON9dImtVy5ZGFcaaZXx40jqQ5s+ahvgBJ2hKq6sEk65ZhqH8fdTDJGuBcugdDgPdV1Yljxry513780KjOE3rtm8bESlrhqurbSW4HdmVMfkiyC4sPb+YHSQMl2Z3u7dfd6bY9fXlVXTDmNO9VJI1zAt1bqDcCOyX5tQExT+u1n5PkR1v7olZMZK6RNImbgIX8cfOowBb7OGC3JZ+bbySNlCTAMa27sarOGRTX5px/j24Foe3aOSe0w+YaSbNarjxyM/BMYOckj66quyYY57aqemBEnKQ5YHGQpLlVVddvyfGTbAf8Jd0e1AAfAX5zguu6J8lNdDdde48J7x+/bnOuU9KKcx1wELBXkjVV9eCQOPODpJGS7ApcCjypfXRcVX1gglO/0Gt7ryJpkIWl558EfGiC+N/rtfcE7sVcI2ky/8riSkAPGxO7cHzpM5T5RtI4jwV+uLU/Pyb2c712P2eYayTNarnyyBeAF/TifmBbVvj+y+9PHjKGpDnktmKStPnOBBbekL0YeEnb534SV7SfT+29QTvIIb32lVNen6SVaSE/7MzidoWDmB8kDZXkUcA/AD/ePnpdVb1rwtO/DHy1tQ8ZFcjisvu3AF+Z5holrXrmGkmT+HSv/eShUZ2FguhblnxuvpE0Tr+ocNxL9Q8fcp65RtKsliuPXNFrjxpnfxZXpnd+WVoFLA6SpM2Q5G3AK1r3E8ALq+o7UwzxN732hiHfsRPwotb9QlVtnPY6Ja1I/fxwzKCAtnLZS1v3Lrr97iUJ+P49xCXA09tHf1hVb5n0/Koq4MLW3TvJ+iHfs57FN9UubOdJWgWqakNVZdQ/4LTeKYf1jn2ljWGukTSJvwUW5luOGhaU5BDgMa37mf4x842kCdwJ3N3aB7TVNIbp/6H9ywsNc42kWS1jHrkM+GZrv6xtnTjIhl573Bb0kuaAxUGSNKUkb2RxL+l/BH5pM/ZivQD4Umu/Psmgt9/eCuzSa0taBarqahYns49NcsCAsBOBda19xpTFiZLmWJK1dPcZz24fnVFVv7sZQ/13Ft+CfUeSHZd8z47AO1r3wRYvSdMy10gaqaruAN7Xuj+b5NeWxiR5JP8xP5w5YCjzjaSh2mrwl7Tu7sAbBsUl2QXov3hx8ZIQc42kWc2cR6pqE/A/Wncd8NqlMW3O+djWvbyqrpn90iVt62JRsiRNLslxLN5U3QL8KosV2MPcMOgP90meC1xEV6h5K/AHwNV0BUG/weKesFcAh1bVd2f+BSStCEn2pVvKdUfgHuCP6FYH2pFuO8NXttCNwP5V9a2H4jolbXuS/DWLb9V/EjgeGPXQt2nY6oRJ3gy8rnU/TzcJ/iW6LT1OBvZtx95cVafMeOmS5kx7qeLU1j2sqi4bEmeukTRSkh8BrgX2oPsj2HuA8+lW+fhJulyx8Pb8u6vqt4aMY76RNFSSvYHPATu1jy4CzgFuBHYA1tM9X+3Rjn+iqg4fMI65RlqlkhwI7NX7aFcWX/y+ksWCZwCq6uwh48ycR1rx9LXAj7WP3gt8GLgfOAw4BXhE6z+rqv55kt9R0spmcZAkTSHJZYzf63WpPReWzh8w3m8A7wTWDjn3auCIqrp9yu+UtMIleR7wQeCHhoRspMsPX9x6VyVpW5dk2ge8/1dVTxwy1nbAWcDLR5z/fuCV7U1bSfq+KYqDzDWSxkqyjm6Lsb1GhP058KphK6uabySNk+Rw4EN0f9Af5ZPAC6vqGwPGMNdIq1SSs4GXTRrftmMeNM6y5JEkewF/BzxlSMjdwK9X1dJV0CTNKbcVk6SHUFWdBexHd6N3I/Bt4A661YJeDTzbwiBpdaqqi4B9gLfTFQLdB9xF98bHycC+FgZJ2pKq6ntVdSxwBN2e918FNrWfFwLPrapXOKEtaRbmGkmTqKrrgJ8GTgL+CbiTLlfcDHwEeE5VHTtqy2XzjaRxqurjdCuRnQxcBtwGfIduZY0vA+cCzwcOH1QY1MYw10iayXLlkTZ3vC9dTruWbm75PuAGujnnfSwMklYXVw6SJEmSJEmSJEmSJEmS5pQrB0mSJEmSJEmSJEmSJElzyuIgSZIkSZIkSZIkSZIkaU5ZHCRJkiRJkiRJkiRJkiTNKYuDJEmSJEmSJEmSJEmSpDllcZAkSZIkSZIkSZIkSZI0pywOkiRJkiRJkiRJkiRJkuaUxUGSJEmSJEmSJEmSJEnSnLI4SJIkSZIkSZIkSZIkSZpTFgdJkiRJkiRJkiRJkiRJc8riIEmSJEmSJEmSJEmSJGlOWRwkSZIkSZIkSZIkSZIkzSmLgyRJkiRJkiRJkiRJkqQ5ZXGQJEmSJEmSJEmSJEmSNKcsDpIkSZIkSZIkSZIkSZLmlMVBkiRJkiRJkiRJkiRJ0pyyOEiSJEmSJEmSJEmSJEmaUxYHSZIkSZIkSZIkSZIkSXPK4iBJkiRJkiRJkiRJkiRpTlkcJEmSJEmSJEmSJEmSJM0pi4MkSZIkSZIkSZIkSZKkOWVxkCRJkiRJkiRJkiRJkjSnLA6SJEmSJEmSJEmSJEmS5pTFQZIkSZIkSZIkSZIkSdKcsjhIkiRJkiRJkiRJkiRJmlMWB0mSJEmSJEmSJEmSJElz6v8DAKI153JiN4gAAAAASUVORK5CYII=">

%% Cell type:code id: tags:

``` python
assert np.isfinite(dh.gather_array(ρ.name)).all()
```
Original line number Diff line number Diff line
%% Cell type:markdown id: tags:

# Shan-Chen Two-Component Lattice Boltzmann

%% Cell type:code id: tags:

``` python
from lbmpy.session import *
from lbmpy.updatekernels import create_stream_pull_with_output_kernel
from lbmpy.macroscopic_value_kernels import macroscopic_values_getter, macroscopic_values_setter
from lbmpy.maxwellian_equilibrium import get_weights
```

%% Cell type:markdown id: tags:

This is based on section 9.3.3 of Krüger et al.'s "The Lattice Boltzmann Method", Springer 2017 (http://www.lbmbook.com).
Sample code is available at [https://github.com/lbm-principles-practice/code/](https://github.com/lbm-principles-practice/code/blob/master/chapter9/shanchen.cpp).

%% Cell type:markdown id: tags:

## Parameters

%% Cell type:code id: tags:

``` python
N = 64       # domain size
omega_a = 1. # relaxation rate of first component
omega_b = 1. # relaxation rate of second component

# interaction strength
g_aa = 0.
g_ab = g_ba = 6.
g_bb = 0.

rho0 = 1.

stencil = LBStencil(Stencil.D2Q9)
weights = get_weights(stencil, c_s_sq=sp.Rational(1, 3))
weights = get_weights(stencil)
```

%% Cell type:markdown id: tags:

## Data structures

We allocate two sets of PDF's, one for each phase. Additionally, for each phase there is one field to store its density and velocity.

To run the simulation on GPU, change the `default_target` to gpu

%% Cell type:code id: tags:

``` python
dim = stencil.D
dh = ps.create_data_handling((N, ) * dim, periodicity=True, default_target=ps.Target.CPU)

src_a = dh.add_array('src_a', values_per_cell=stencil.Q)
dst_a = dh.add_array_like('dst_a', 'src_a')

src_b = dh.add_array('src_b', values_per_cell=stencil.Q)
dst_b = dh.add_array_like('dst_b', 'src_b')

ρ_a = dh.add_array('rho_a')
ρ_b = dh.add_array('rho_b')
u_a = dh.add_array('u_a', values_per_cell=stencil.D)
u_b = dh.add_array('u_b', values_per_cell=stencil.D)
u_bary = dh.add_array_like('u_bary', u_a.name)

f_a = dh.add_array('f_a', values_per_cell=stencil.D)
f_b = dh.add_array_like('f_b', f_a.name)
```

%% Cell type:markdown id: tags:

## Force & combined velocity

The two LB methods are coupled using a force term. Its symbolic representation is created in the next cells.
The force value is not written to a field, but directly evaluated inside the collision kernel.

%% Cell type:markdown id: tags:

The force between the two components is
$\mathbf{F}_k(\mathbf{x})=-\psi(\rho_k(\mathbf{x}))\sum\limits_{k^\prime\in\{A,B\}}g_{kk^\prime}\sum\limits_{i=1}^{q}w_i\psi(\rho_{k^\prime}(\mathbf{x}+\mathbf{c}_i))\mathbf{c}_i$
for $k\in\{A,B\}$
and with
$\psi(\rho)=\rho_0\left[1-\exp(-\rho/\rho_0)\right]$.

%% Cell type:code id: tags:

``` python
def psi(dens):
    return rho0 * (1. - sp.exp(-dens / rho0));
```

%% Cell type:code id: tags:

``` python
zero_vec = sp.Matrix([0] * dh.dim)

force_a = zero_vec
for factor, ρ in zip([g_aa, g_ab], [ρ_a, ρ_b]):
    force_a += sum((psi(ρ[d]) * w_d * sp.Matrix(d)
                    for d, w_d in zip(stencil, weights)),
                   zero_vec) * psi(ρ_a.center) * -1 * factor

force_b = zero_vec
for factor, ρ in zip([g_ba, g_bb], [ρ_a, ρ_b]):
    force_b += sum((psi(ρ[d]) * w_d * sp.Matrix(d)
                    for d, w_d in zip(stencil, weights)),
                   zero_vec) * psi(ρ_b.center) * -1 * factor

f_expressions = ps.AssignmentCollection([
    ps.Assignment(f_a.center_vector, force_a),
    ps.Assignment(f_b.center_vector, force_b)
])
```

%% Cell type:markdown id: tags:

The barycentric velocity, which is used in place of the individual components' velocities in the equilibrium distribution and Guo force term, is
$\vec{u}=\frac{1}{\rho_a+\rho_b}\left(\rho_a\vec{u}_a+\frac{1}{2}\vec{F}_a+\rho_b\vec{u}_b+\frac{1}{2}\vec{F}_b\right)$.

%% Cell type:code id: tags:

``` python
u_full = list(ps.Assignment(u_bary.center_vector,
                           (ρ_a.center * u_a.center_vector + ρ_b.center * u_b.center_vector) / (ρ_a.center + ρ_b.center)))
```

%% Cell type:markdown id: tags:

## Kernels

%% Cell type:code id: tags:

``` python
lbm_config_a = LBMConfig(stencil=stencil, relaxation_rate=omega_a, compressible=True,
                         velocity_input=u_bary, density_input=ρ_a, force_model=ForceModel.GUO,
                         force=f_a, kernel_type='collide_only')

lbm_config_b = LBMConfig(stencil=stencil, relaxation_rate=omega_b, compressible=True,
                         velocity_input=u_bary, density_input=ρ_b, force_model=ForceModel.GUO,
                         force=f_b, kernel_type='collide_only')



collision_a = create_lb_update_rule(lbm_config=lbm_config_a,
                                    optimization={'symbolic_field': src_a})

collision_b = create_lb_update_rule(lbm_config=lbm_config_b,
                                    optimization={'symbolic_field': src_b})
```

%% Cell type:code id: tags:

``` python
stream_a = create_stream_pull_with_output_kernel(collision_a.method, src_a, dst_a,
                                                 {'density': ρ_a, 'velocity': u_a})
stream_b = create_stream_pull_with_output_kernel(collision_b.method, src_b, dst_b,
                                                 {'density': ρ_b, 'velocity': u_b})

config = ps.CreateKernelConfig(target=dh.default_target)

stream_a_kernel = ps.create_kernel(stream_a, config=config).compile()
stream_b_kernel = ps.create_kernel(stream_b, config=config).compile()
collision_a_kernel = ps.create_kernel(collision_a, config=config).compile()
collision_b_kernel = ps.create_kernel(collision_b, config=config).compile()

force_kernel = ps.create_kernel(f_expressions, config=config).compile()
u_kernel = ps.create_kernel(u_full, config=config).compile()
```

%% Cell type:markdown id: tags:

## Initialization

%% Cell type:code id: tags:

``` python
init_a = macroscopic_values_setter(collision_a.method, velocity=(0, 0),
                                   pdfs=src_a.center_vector, density=ρ_a.center)
init_b = macroscopic_values_setter(collision_b.method, velocity=(0, 0),
                                   pdfs=src_b.center_vector, density=ρ_b.center)
init_a_kernel = ps.create_kernel(init_a, ghost_layers=0).compile()
init_b_kernel = ps.create_kernel(init_b, ghost_layers=0).compile()


dh.run_kernel(init_a_kernel)
dh.run_kernel(init_b_kernel)
```

%% Cell type:code id: tags:

``` python
def init():
    dh.fill(ρ_a.name, 0.1, slice_obj=ps.make_slice[:, :0.5])
    dh.fill(ρ_a.name, 0.9, slice_obj=ps.make_slice[:, 0.5:])

    dh.fill(ρ_b.name, 0.9, slice_obj=ps.make_slice[:, :0.5])
    dh.fill(ρ_b.name, 0.1, slice_obj=ps.make_slice[:, 0.5:])

    dh.fill(f_a.name, 0.0)
    dh.fill(f_b.name, 0.0)

    dh.run_kernel(init_a_kernel)
    dh.run_kernel(init_b_kernel)

    dh.fill(u_a.name, 0.0)
    dh.fill(u_b.name, 0.0)
```

%% Cell type:markdown id: tags:

## Timeloop

%% Cell type:code id: tags:

``` python
sync_pdfs = dh.synchronization_function([src_a.name, src_b.name])
sync_ρs = dh.synchronization_function([ρ_a.name, ρ_b.name])

def time_loop(steps):
    dh.all_to_gpu()
    for i in range(steps):
        sync_ρs()  # force values depend on neighboring ρ's
        dh.run_kernel(force_kernel)
        dh.run_kernel(u_kernel)
        dh.run_kernel(collision_a_kernel)
        dh.run_kernel(collision_b_kernel)

        sync_pdfs()
        dh.run_kernel(stream_a_kernel)
        dh.run_kernel(stream_b_kernel)

        dh.swap(src_a.name, dst_a.name)
        dh.swap(src_b.name, dst_b.name)
    dh.all_to_cpu()
```

%% Cell type:code id: tags:

``` python
def plot_ρs():
    plt.figure(dpi=200)
    plt.subplot(1,2,1)
    plt.title("$\\rho_A$")
    plt.scalar_field(dh.gather_array(ρ_a.name), vmin=0, vmax=2)
    plt.colorbar()
    plt.subplot(1,2,2)
    plt.title("$\\rho_B$")
    plt.scalar_field(dh.gather_array(ρ_b.name), vmin=0, vmax=2)
    plt.colorbar()
```

%% Cell type:markdown id: tags:

## Run the simulation
### Initial state

%% Cell type:code id: tags:

``` python
init()
plot_ρs()
```

%% Output

img src="data:image/png;base64,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">

%% Cell type:markdown id: tags:

### Run the simulation until converged

%% Cell type:code id: tags:

``` python
init()
time_loop(10000)
plot_ρs()
```

%% Output

img src="data:image/png;base64,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">

%% Cell type:code id: tags:

``` python
assert np.isfinite(dh.gather_array(ρ_a.name)).all()
assert np.isfinite(dh.gather_array(ρ_b.name)).all()
```
Original line number Diff line number Diff line
%% Cell type:code id: tags:
``` python
from IPython.display import clear_output
from lbmpy.session import *
from lbmpy.relaxationrates import relaxation_rate_from_lattice_viscosity
from pystencils.typing import BasicType, TypedSymbol
```
%% Cell type:markdown id: tags:
# Demo: Interpolation Bounce Back Boundaries
In this notebook we present how to use interpolation bounce back boundaries. We will show this on a simple flow around sphere in two dimensions using the linearised bounce back boundary by [Bouzidi et. al.](https://doi.org/10.1063/1.1399290) and the `QuadraticBounceBack` boundary condition by [Geier et. al.](https://www.sciencedirect.com/science/article/pii/S0898122115002126)
The first part of the demo is similar to other demos / tutorials, so we will not go into detail about these parts
%% Cell type:code id: tags:
``` python
stencil = LBStencil(Stencil.D2Q9)
reference_length = 30
maximal_velocity = 0.05
reynolds_number = 500
kinematic_vicosity = (reference_length * maximal_velocity) / reynolds_number
initial_velocity=(maximal_velocity, 0)
omega = relaxation_rate_from_lattice_viscosity(kinematic_vicosity)
```
%% Cell type:code id: tags:
``` python
domain_size = (400, 150)
dim = len(domain_size)
circle_mid = np.array((40, 75))
circle_rad = 10
```
%% Cell type:code id: tags:
``` python
dh = ps.create_data_handling(domain_size=domain_size)
src = dh.add_array('pdfs', values_per_cell=len(stencil))
dh.fill(src.name, 0.0, ghost_layers=True)
dst = dh.add_array('pdfs_tmp', values_per_cell=len(stencil))
dh.fill(dst.name, 0.0, ghost_layers=True)
velField = dh.add_array('velField', values_per_cell=dh.dim)
dh.fill('velField', 0.0, ghost_layers=True)
densityField = dh.add_array('densityField', values_per_cell=1)
dh.fill('densityField', 1.0, ghost_layers=True)
```
%% Cell type:code id: tags:
``` python
lbm_config = LBMConfig(stencil=stencil, method=Method.CUMULANT, relaxation_rate=omega,
                       compressible=True, output={"velocity": velField, "density": densityField})
method = create_lb_method(lbm_config=lbm_config)
```
%% Cell type:code id: tags:
``` python
init = pdf_initialization_assignments(method, 1.0, (0.0, 0.0, 0.0), src.center_vector)
ast_init = ps.create_kernel(init, target=dh.default_target)
kernel_init = ast_init.compile()
dh.run_kernel(kernel_init)
```
%% Cell type:code id: tags:
``` python
lbm_optimisation = LBMOptimisation(symbolic_field=src, symbolic_temporary_field=dst)
update = create_lb_update_rule(lb_method=method,
                               lbm_config=lbm_config,
                               lbm_optimisation=lbm_optimisation)
ast_kernel = ps.create_kernel(update, target=dh.default_target)
kernel = ast_kernel.compile()
```
%% Cell type:code id: tags:
``` python
def set_sphere(x, y, *_):
    return (x-circle_mid[0])**2 + (y-circle_mid[1])**2 < circle_rad**2
```
%% Cell type:markdown id: tags:
# Interpolation Boundary Conditions implementation details
The most important part of the interpolation bounce back boundary is, that we need to define the distance to the wall for each boundary cell. Thus, we need to provide a Python CallBack function to the boundary that calculates the normalised wall distance `q` for each cell and stores the value in `boundary_data`. The normalised wall distance is defined as:
$$
\begin{align}
q = \frac{|\boldsymbol{x}_{F} - \boldsymbol{x}_{w}|}{|\boldsymbol{x}_{F} - \boldsymbol{x}_{b}|}.
\end{align}
$$
 The variable `boundary_data` is an index vector that every boundary condition holds internally. For simple boundaries it stores the `x`- and `y`- (and `z` in 3D) coordinate to represent a fluid cell that is next to a boundary cell and the lattice direction `dir` to get from the fluid cell to the boundary cell.
In the case of the interpolation boundaries we have an additional value `q` that needs to be stored in each cell. This value needs to be between 0 and 1, otherwise the boundary condition would fall back to a simple bounce back boundary without interpolation.
<center>
<img src="../img/Boundary.svg" alt="Boundary.svg" width="400" height="400">
</center>
Two dimensional representation of the boundary nodes with the normalised wall distance `q`. The figure was inspired by [Directional lattice Boltzmann boundary conditions](https://doi.org/10.13097/archive-ouverte/unige:160770).
The linear Bouzidi boundary condition is implemented using the following equation
$$
\begin{align}
    f_{\bar{i}}^{t + 1}(\boldsymbol{x}_b) =
\begin{cases}
    \frac{1}{2q} f_{i}(\boldsymbol{x}_F) + \frac{2q-1}{2q} f_{\bar{i}}(\boldsymbol{x}_{F}), & \text{if } q \geq 0.5\\
    2 q f_{i}(\boldsymbol{x}_F) + (1 - 2q) f_{i}(\boldsymbol{x}_{FF}),              & q > 0 \land q < 0.5 \\
    f_{i}(\boldsymbol{x}_F),              & q = -1
\end{cases}
\end{align}
$$
where $f_{\bar{i}}^{t + 1}(\boldsymbol{x}_b)$ is the missing lattice link that will be needed in the next streaming step. Furthermore, $f_{i}(\boldsymbol{x}_F)$ represents the lattice link flowing in wall direction at $\boldsymbol{x}_{F}$, $f_{\bar{i}}(\boldsymbol{x}_{F})$ is the inverse direction at $\boldsymbol{x}_{F}$ and $f_{i}(\boldsymbol{x}_{FF})$ is the lattice link at the next cell.
**The linearised bounce back boundary by [Bouzidi et. al.](https://doi.org/10.1063/1.1399290) needs a second fluid node for the interpolation. This fluid node is not guaranteed to exist. In this case, we implemented a fallback scenario to a simple bounce back scheme with interpolation by setting `q` to -1.**
To overcome this problem, we can use the `QuadraticBounceBack` boundary condition by [Geier et. al.](https://www.sciencedirect.com/science/article/pii/S0898122115002126). It uses the following rule:
$$
\begin{align}
f_{\bar{i}}^{\mathrm{p}}(\boldsymbol{x}_F) &= \frac{f_{\bar{i}}(\boldsymbol{x}_F) - f_{i}(\boldsymbol{x}_F)}{2} + \frac{f_{\bar{i}}(\boldsymbol{x}_F) + f_{i}(\boldsymbol{x}_F)- \omega(f_{\bar{i}}^{\mathrm{eq}}(\boldsymbol{x}_F) + f_{i}^{\mathrm{eq}}(\boldsymbol{x}_F))}{2 - 2\omega} \\
f_{\bar{i}}^{\mathrm{wall}}(\boldsymbol{x}_F) &= (1 - q)f_{\bar{i}}^{\mathrm{p}}(\boldsymbol{x}_F) + q f_{\bar{i}}(\boldsymbol{x}_F) \\
f_{\bar{i}}^{t + 1}(\boldsymbol{x}_b) &= \frac{1}{q+1} f_{\bar{i}}^{\mathrm{wall}}(\boldsymbol{x}_F) + \frac{q}{q+1}f_{i}(\boldsymbol{x}_F)
\end{align}
$$
In this BC the idea is to realise the interpolation with the pre collision PDF value (marked with the subscript p). Since the pre collision PDF value is not available a simple reconstruction needs to be done. This happens via the BGK rule and the relaxation rate for the fluid viscosity. Thus, this boundary condition needs the equilibrium at the wall. However, the equilibrium at the wall can be calculated inplace from the PDFs. Thus, this BC does not need any further information and can be applied in all cases. Furthermore, we have no more branches with the subgrid distance `q`
%% Cell type:code id: tags:
``` python
def init_wall_distance(boundary_data, **_):
    dim = boundary_data.dim
    coords = [coord for coord, _ in zip(['x', 'y', 'z'], range(dim))]
    for cell in boundary_data.index_array:
        direction = np.array(stencil[cell['dir']])
        fluid_cell = np.array(tuple([cell[coord] for coord in coords])) - np.array([0.5] * dim)
        boundary_cell = fluid_cell + direction
        f = fluid_cell - circle_mid
        d = (boundary_cell - circle_mid) - f
        a = d.dot(d)
        b = 2.0 * ( d.dot(f))
        c = f.dot(f) - circle_rad**2
        bb4ac = b * b - ( 4.0 * a * c )
        assert bb4ac > 0
        sqrtbb4ac = np.sqrt(bb4ac)
        q = np.min( [( -b + sqrtbb4ac ) / ( 2.0 * a ), ( -b - sqrtbb4ac ) / ( 2.0 * a )] )
        assert q > 0 and q < 1
        cell['q'] = q
```
%% Cell type:code id: tags:
``` python
bh = LatticeBoltzmannBoundaryHandling(method, dh, src.name, name="bh")
inflow = UBB(initial_velocity)
outflow = ExtrapolationOutflow(stencil[4], method)
wall = NoSlip("wall")
# obstacle = NoSlip("obstacle")
# obstacle = NoSlipLinearBouzidi("obstacle", init_wall_distance=init_wall_distance)
obstacle = QuadraticBounceBack(omega, "obstacle", init_wall_distance=init_wall_distance)
bh.set_boundary(inflow, slice_from_direction('W', dim))
bh.set_boundary(outflow, slice_from_direction('E', dim))
for direction in ('N', 'S'):
    bh.set_boundary(wall, slice_from_direction(direction, dim))
bh.set_boundary(obstacle, mask_callback=set_sphere)
plt.figure(dpi=200)
plt.boundary_handling(bh)
```
%% Output
img src="data:image/png;base64,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AAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAAAAAAAAAAFEkMDQAAAAAAAAAAAAAUSQwNAAAAAAAAAAAAABRJDA0AAAAA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SZLDDz88ffv23eH7Xbp0ybHHHptHH3208Z3mDBo0aIfP3guUd2XdunXrml2zdOnSXH/99XnggQfy6quv7nCvd999N2vWrGnxt7VkyJAhLT4/8MADs379+h3OyR+JoQEAAAAAAAAAAABo4r1ToZPsNPbt169fs/f/8Ic/tPj8/Q455JAm7zSne/fuO3z2/pOrW7vunXfe2e753Llz89WvfjX19fUtzvueTZs2tWpdc1qaM/m3WZubk3/T/JnlAAAAAAAAAAAAAHxoNTQ0NF5XVFS0em1zdvZ+a/bYG2praxtD6L59+2bmzJl55pln8vvf/z5bt25NQ0NDGhoaMnfu3MZ39oW5P+ycDA0AAAAAAAAAAABAE7179268fu211zJo0KAdrn399ddb3OPVV1/d6fdee+217b67t916662pr69P586d8+ijj2bo0KHNrnv/qdl0PCdDAwAAAAAAAAAAANDExz/+8cbrX/3qVy2u3dHzj33sY0mSlStX7jCYTpJt27Zl8eLFTd7pCL/97W+TJH/2Z3+2wxA6SRYtWrS3RqIVxNAAAAAAAAAAAAAANHHcccflwAMPTJL8z//5P9PQ0NDsuldeeSUPPfRQs89Gjx6dJGloaMjNN9+8w2/97//9v/PWW281eacj1NfXJ0k2bty4wzWvvvpq7rnnnr01Eq0ghgYAAAAAAAAAAACgia5du+ZLX/pSkuTXv/51Zs6cud2a+vr6TJ48OVu3bm12jwkTJqR///5Jkquuuiq/+c1vtluzatWqTJ06NUnSvXv3xm92hKOOOipJ8sILL2ThwoXbPd+4cWPOPvvsbNq0aW+PRgsqO3oAgD0xs1fz/6cybW3VXp6Ef29H/2wAAAAAAAAAAIAyTJ8+Pf/rf/2v1NXV5eKLL86vf/3r/PVf/3X69u2bF154Idddd11+9atfZfjw4fnVr3613fv77bdfZs+enc9+9rNZt25dTjzxxEybNi2nnHJKKisrs2DBglxzzTV5/fXXkySzZs3KwQcfvLd/ZqO/+qu/yk033ZR33303Y8aMyUUXXZRPfepT6datW5555plcf/31efHFF3PCCSfkySef7LA5aUoMDQAAAAAAAAAAAMB2DjjggDz44IMZPXp0Xn311dxxxx254447mqz50pe+lE9/+tM7PNF57NixueWWW3Leeedl/fr1ufTSS3PppZc2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nHDCCXn44Yc3wxMAAAAAAAAAAAAAAE2hvLkLWB9/+MMfcvbZZ2fBggU1rr/22mt57bXXMnHixLz44ou5995765xfXV2dr3zlKxk5cmSN63PmzMk999yTe+65J2eeeWZuvvnmFAqFTfUYAAAAAAAAAAAAAEATKJkw9B133JHTTjstq1evznbbbZezzz47hx9+eLp06ZK5c+dmxowZuf/++9OyZct617jooouKQeh+/frlggsuyG677ZYZM2bkqquuyuTJkzNy5Mh069Ytl1122eZ6NAAAAAAAAAAAAABgA5REGHratGk588wzs3r16hxxxBG5//7706lTp1rjzj333KxYsaLONaZPn56rrroqSXLAAQdk3LhxadOmTZLkwAMPzLHHHpsBAwZk0qRJufLKK3Paaadlt91223QPBQAAAAAAAAAAAABslLLmLqAxzj333Cxfvjxdu3bN3XffXWcQeo2Kioo6r1977bWpqqpKkowYMaIYhF6jbdu2GTFiRJKkqqoq1113XdMUDwAAAAAAAAAAAABsElt8GPqFF17Io48+miT52te+lq5du673GtXV1bnvvvuSJH369MkhhxxS57hDDjkke+65Z5Lk3nvvTXV19QZWDQAAAAAAAAAAAABsalt8GPoPf/hDsX3iiScW22+++WZefPHFLFiwYJ1rzJw5M3PmzEmSDBgwoMGxa/pnz56dl19+eQMqBgAAAAAAAAAAAAA2hy0+DP3kk08mSTp16pS+ffvmv/7rv/LBD34wXbp0Se/evdO1a9fsuuuuufTSS7No0aI615g2bVqx3adPnwbvt3b/2vMAAAAAAAAAAAAAgC1LeXMXsC5Tp05NkvTs2TPnnntubrzxxlpjZs6cmUsuuSR33XVX/vd//zfdu3ev0T9r1qxiu7KyssH79ejRo8556zJ79uwG+1977bVGrwUAAAAAAAAAAAAArNsWH4b+17/+lSR54YUX8uyzz6Zz58654oorcsIJJ6Rjx455/vnn8/3vfz8PPfRQpkyZkhNPPDHjx49PWdm/D71+5513iu327ds3eL927doV2/WdNF2XtUPUAAAAAAAAAAAAAMCmV7buIc1r8eLFSZLly5enRYsWeeihh3LWWWelW7duadWqVQ444IA88MADOeqoo5Ikjz/+eO6+++4aayxbtqzYrqioaPB+rVq1KraXLl3aVI8BAAAAAAAAAAAAADSxLT4M3bp162L7xBNPzCGHHFJrTFlZWX784x8XP9955531rrFixYoG77d8+fJiu02bNo2uc9asWQ3+TJw4sdFrAQAAAAAAAAAAANC0li5dmksvvTQf/OAH065duxQKhRQKhZx//vlJkttuu6147eWXX27WWmm88uYuYF06dOhQPB16zenPddl7772z0047Zc6cOXnqqadqrbHGokWLGrzfmnslSfv27RtdZ2VlZaPHAgAAAAAAAAAAAJvW5x74XOYvnd/cZWxyXdt0zahPjdos91q4cGF+85vf5MEHH8zUqVMzb968tGzZMttvv30OPPDAHHvssfnsZz+bFi1abJZ61sfKlSvz0Y9+NI8//nhzl7LFevnll9OrV6/1mjN48ODce++9m6agRtriw9A9evTI3Llzk6w7cNyjR4/MmTMn8+bNq3F97XmzZ89ucI1Zs2bVWA8AAAAAAAAAAAAoPfOXzs+8JfPWPZBGueWWW/Kd73wnCxYsqHF96dKlefvtt/Piiy/mt7/9bfbaa6/8/Oc/z+GHH77JayoUCkmSiy++OJdcckmDY//whz8Ug9BDhw7NkCFD0rVr1yQp/klp2uLD0HvvvXfxpOdVq1Y1OHZNf3l5zcfaa6+9iu0XXnihwTXW7u/bt+961QoAAAAAAAAAAACwtfn2t7+dn/zkJ0nezWiefPLJOfbYY7PLLrtkxYoV+fvf/54777wzjz76aKZOnZqPfvSj+c1vfpPPfvazzVz5v/35z39Okuywww655ZZbtsjTq7ckgwcPzmWXXbbOcR07dtwM1TRsiw9DH3nkkbntttuSJDNmzMjHPvaxese+9NJLSZKddtqpxvVevXqle/fuefXVVzN27NgG7zdu3LjiGj179tzwwgEAAAAAAAAAAABK3I033lgMQvfo0SP3339/PvjBD9YYc/jhh2fYsGEZNWpUvvSlL2X58uX54he/mN133z377bdfM1Rd25w5c5Iku+66qyB0I3Tu3Dn77LNPc5fRKGXNXcC6HHvssWnZsmWS5O6776533NixY4tHrx9xxBE1+gqFQgYPHpzk3ZOfn3zyyTrXePLJJ4snQw8ePLh4fDoAAAAAAAAAAADA+80///nPDB8+PEnSvn37PPbYY7WC0Gv73Oc+l9tvvz1JsmLFipx66qmprq7eLLWuy/Lly5OkmEll67HFh6G33XbbnH766UmSP/3pT/nd735Xa8w777yT888/v/j5rLPOqjXm/PPPT3n5uwdhn3vuuVm6dGmN/qVLl+bcc89N8u4R7muvBwAAAAAAAAAAAPB+c91112XZsmVJkosvvji77777OuecfPLJOeaYY5IkU6ZMyQMPPFBrTM+ePVMoFDJ06NAG1xo6dGgKhUJ69uxZ5/w1Lr300hQKhRo/Q4cOzcsvv1z8PHbs2CTvHr679rj3rt0Yb7zxRi666KL069cvnTt3TuvWrdOzZ8+ceuqpmTBhQr1z1tzz5z//eZ1jTj/99OKYNZnW97ruuutSKBRSXl6et99+e71r3xpt8WHo5N2/SHfeeeckyamnnppzzz03o0ePztNPP53bbrstBx10UP76178mSc4+++wceOCBtdbo3bt38bcTJk2alP79+2fUqFGZNGlSRo0alf79+2fSpElJkm9/+9vZY489Ns/DAQAAAAAAAAAAAGxhqqurc8cddyRJ2rRpkzPOOKPRc88777xi+9Zbb23y2prTI488kt133z2XX355/vrXv2bhwoVZvnx5/vnPf+Y3v/lNjjjiiHzta1/L6tWra8zr1q1b9tprryTJ6NGj61x7zJgxxfa6xuy3337p2LFj8fqagPjaIfH3i/LmLqAxunXrlocffjjHHntspk+fnhtuuCE33HBDrXFf/vKXc/3119e7zuWXX5558+blV7/6VSZPnpyTTz651phhw4blsssua9L6AQAAAAAAAAAAAErJ3/72t/zrX/9Kkhx55JHp1KlTo+d+5CMfSdu2bbNkyZJ6T0reGI888khWrFiRfffdN8m7B+mec845NcZss8022W677fL8888nSU477bRMmjQpBxxwQI2AdkVFRaPv+9e//jWf/vSns2LFirRs2TJf/epXM3jw4LRr1y6TJ0/OFVdckZkzZ+bGG29Mu3btcuWVV9aYP2DAgEydOrV4SvXa5syZkxkzZhQ/T506NW+88Ua6detWvFZdXZ3x48cnSQYOHNjourd2JRGGTpK+ffvmr3/9a2666abcddddefHFF7No0aJst9126d+/f84666wMGjSowTXKysryy1/+Mp/5zGcycuTIPPXUU5k/f366du2aAw88MGeddVaOOuqozfREAAAAAAAAAAAAAFumZ599ttj+0Ic+tF5zW7RokQ9+8IN54okn8sYbb+TVV19N9+7dm6y23r171/i83XbbZZ999qlz7Jrr7dq1K/5Z39h1OfPMM7NixYq0aNEiDzzwQD7+8Y8X+w488MCceOKJOfzwwzN16tT85Cc/yZe+9KXsvffexTEDBw7MTTfdlLlz5+aFF15Inz59in1rToLee++9s3Tp0rz00ksZO3ZsPvvZzxbHPPvss8WA+oABAzboGRrrrbfeypQpU9Y5rlevXsXvtrmUTBg6efcvwOHDh2f48OEbtc7RRx+do48+uomqAgAAAAAAAAAAANi6zJ8/v9jeYYcd1nv+9ttvX2wvWLCgScPQzWHixIl56qmnkiSnn356jSD0Gttss01GjhyZww8/PKtXr87Pfvaz3HjjjcX+tQPMY8aMqRGGXnNa9MCBA4th6DFjxtQIQ68ZU1ZWliOOOKJpH/A97rvvvtx3333rHDd69OhmP6W6rFnvDgAAAAAAAAAAAMAW55133im2N+Tk37XnvP32201SU3P685//XGwPGzas3nH9+/dP3759a81J3g2IrwlAjxkzpkbfms8DBw4shovrG/PBD34wnTt3rtH38ssvp7q6OtXV1Y14mq2LMDQAAAAAAAAAAAAANXTo0KHYXrRo0XrPX3tOx44dm6Sm5jRlypQkSUVFRfr169fg2IMPPjhJ8uKLL2bFihU1+tacDr3mlOckefXVVzN9+vQUCoUMGDAggwYNSpJMnTo1b7zxRpKkuro648ePT5LNchLzkCFDiuHqhn6a+1ToRBgaAAAAAAAAAAAAgPfYdttti+25c+eu9/zXX3+9zrVK1b/+9a8kSZcuXVJeXt7g2B122CHJuwHmN998s0bfmvDw3Llz88ILLyRJRo8enSTZa6+90q1bt1RWVmbXXXdNdXV1MTT93HPPZcGCBUn+HajmXcLQAAAAAAAAAAAAANTwwQ9+sNiePHnyes1dtWpVnnvuuSRJt27d0r179yatrTkVCoV1jqmurq63b+0g85gxY5L8+5TotU9ZXtN+75hCoZAjjzxyPSre+glDAwAAAAAAAAAAAFDDPvvsky5duiRJxo0bl4ULFzZ67p///OcsWbIkSXL44YfX6i8reze+unr16gbXWbx4caPvuamt+S4WLFiQqqqqBseuORW7UChkm222qdG34447pnfv3kn+HXRe82dDYeg1f37gAx+oteb7nTA0AAAAAAAAAAAAADUUCoWceuqpSZKlS5fmF7/4RaPnjhgxotgeOnRorf4OHTokSd58880G1/n73//e6Htuavvss0+SZMWKFes8KXvixIlJkj322CMVFRW1+tecDj127Ni8+uqrefHFF1MoFGqcGj1o0KAkydSpUzNv3ryMGzcuSc3ANO8ShgYAAAAAAAAAAACglq9//etp1apVkuTSSy/N9OnT1znnd7/7XR588MEkyV577ZVPfepTtcb06tUrSfLMM8+kurq6znWmTJmS559/vsF7tW7dOkmyfPnydda1sT760Y8W27/85S/rHffEE09k6tSpteasbU2gee7cubn55puTvPtddevWrTimsrIyu+66a6qrq3PDDTdkwYIFSVIjMM27hKEBAAAAAAAAAAAAqKVXr1656qqrkiSLFi3KRz7ykTz77LP1jv/973+fIUOGJEkqKiry61//OmVltaOqawK9r776au68885a/e+8806+/OUvr7O+HXfcMUkyY8aMdT/MRjrooINy4IEHJkluueWW/OlPf6o1ZuHChTnrrLOSJGVlZTn77LPrXGvt051/+tOf1rr23nFrxhQKhRx55JF1rtmzZ88UCoUUCoVGPc/WpLy5CwAAAAAAAAAAAABgy3TeeeflpZdeyvXXX59XXnklBxxwQD7/+c/n2GOPzS677JKVK1fmhRdeyG9/+9s8+uijSd4NQt9xxx350Ic+VOeap5xySi655JK8/fbbGTZsWKZPn55PfOITKRQKmTRpUq655prMmTMn/fr1y+TJk+ut7bDDDsvMmTPzP//zP/n5z3+e/v37F0+L7tixY7bbbrsm/S5GjhyZgw8+OCtWrMgxxxyTc889N5/+9KfTvn37TJ48OVdccUVeeumlJMnw4cOzzz771LlO9+7ds/vuu2f69OlZuHBhkvrD0L/61a+KY/bZZ59su+22TfpM9XnrrbcyZcqUdY5r0aJF+vbtuxkqqp8wNAAAAAAAAAAAAAD1uu6669KnT59897vfzb/+9a/8+te/zq9//es6x/bp0yc333xz8fTnunTr1i233HJLPv/5z2fZsmW5+OKLc/HFFxf7W7dunTvuuCMPPvhgg2Ho4cOH56677sry5cvzla98pUbfkCFDctttt63fg67Dfvvtl/vvvz8nnnhi3n777VxzzTW55pprao376le/mh/96EcNrjVgwIBM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FDJmzJjmLqeklDd3AQAAAAAAAAAAAABN7fc/fCpL3l7R3GVscm07VuSkCw9s7jKg2QhDAwAAAAAAAAAAAFudJW+vyOK3ljd3GTSj2267LaeddlqSZObMmU6o3kqVNXcBAAAAAAAAAAAAAAAbQhgaAAAAAAAAAAAAAChJwtAAAAAAAAAAAAAAQEkShgYAAAAAAAAAAACgXitWrMjPfvazDBo0KN26dUtFRUV22GGHHH300fnNb36T1atXN2qdOXPm5Jvf/GZ69+6dtm3bplu3bjn66KPz0EMPrXPuPffck+OOOy6VlZVp1apVOnTokF133TVHHHFEvve972XixInFsWPGjEmhUMhpp51WvNarV68UCoUaP2PGjKlxjyeffDIXXXRRBg4cmB122CEVFRXp2LFj9tprr5x99tmZOnVq476wJH/84x9zyimnZNddd027du3SqVOn7L333jn55JPz3//931m6dGmj13qvP/3pTznllFPSq1evtGnTJh07dswHP/jBXHDBBXnttdc2eN1SVd7cBQAAAAAAAAAAAACwZfrnP/+Zo446KtOmTatx/fXXX89DDz2Uhx56KD//+c9z3333pUuXLvWuM2nSpBxzzDGZN29e8drSpUuLa3z961/PddddV2veqlWr8vnPfz5/+MMfalxfsWJFFi1alJkzZ2bChAl56KGHMmnSpA1+zttuu61GeHqNlStXZtq0aZk2bVp+8Ytf5Kc//WnOOeecetdZsGBBPve5z+XRRx+t1Td16tRMnTo1o0aNyq233pqhQ4euV42LFy/OqaeemnvuuafG9WXLluW5557Lc889l5tuuil33nlnPvWpT63X2qVMGBoAAAAAAAAAAACAWhYtWpQPf/jDeemll5Ikxx13XL785S+ne/fumTlzZm644YaMHTs2EyZMyKc+9amMHz8+LVq0qLXOkiVLcuKJJ2bhwoX5zne+k6OPPjqtWrXK//3f/+VHP/pRXnvttVx//fXZeeed881vfrPG3JtuuqkYhD788MNz+umnZ7fddkv79u3zr3/9K1OmTMlDDz2Uf/3rX8U5Bx54YJ5//vncd999ueiii5Ik//u//5vu3bvXWLtXr17FdlVVVbbZZpsce+yxGTBgQPbYY4+0a9cur776ap555pn89Kc/zfz58/O1r30tffr0yYc//OE6n3PQoEF5/vnnkyT7779/zjzzzOyzzz5p1apVZs2alXHjxmXUqFHr/b/FqlWr8ulPfzqjR49OoVDIySefnBNOOCG9evXKypUrM3HixFx99dV55ZVX8pnPfCaPP/549t9///W+TykShgYAAAAAAAAAAACglksvvbQYhL7ooovygx/8oNi3//775zOf+UxOPfXU/Nd//VeeeOKJjBw5MmeffXatdd5444289dZb+fOf/5wjjzyyeP2ggw7KZz7zmRx88MGZPXt2vve97+WUU07JdtttVxzz+9//Pkly8MEHZ/To0Skvrxl9/fCHP5zzzjuvRhi6Xbt22WeffWqcFN27d+/07Nmz3mc96qij8oUvfCFt27atcb1fv3455phjct555+XII4/Mc889l4svvrjOMPR3v/vdYhD6q1/9akaMGJFCoVDjOzvuuONyxRVX5M0336y3lrpcd911GT16dFq2bJn77rsvRx11VI3+Qw45JKeeemqOOOKI/O1vf8v555+f8ePHr9c9SlVZcxcAAAAAAAAAAAAAwJZl+fLlueWWW5Ike+21Vy655JJaYwqFQn72s59l2223TZLccMMN9a531lln1QhCr9G9e/dcffXVSd49Wfn222+v0T937twkyWGHHVYrCL22Ll26NPxA67DTTjvVCkKvrVOnTvnP//zPJMmECROyYMGCGv1vvvlmRo4cmST50Ic+lOuvv75GEHptFRUV2X777Rtd28qVK4vf0de+9rVaQeg1ttlmm/z4xz8u1jh9+vRG36OUCUMDAAAAAAAAAAAAUMPTTz+dt956K0kydOjQtGjRos5xHTt2zEknnZQkmTp1al577bU6x5122mn13uv4449P586dkyR//vOfa/TtuOOOSZL7778/8+fPX59H2CiLFy/Oyy+/nL/97W+ZMmVKpkyZkpYtWxb7n3322RrjR48enSVLliRJzjvvvHq/rw0xceLE4ve65ruuz9qB8yeeeKLJatiSCUMDAAAAAAAAAAAAUMOUKVOK7YMPPrjBsWv3rz1vjYqKinzgAx+od37Lli3Tr1+/OucPGTIkSTJ9+vTsvvvu+fKXv5w777wzs2fPXvdDrKf58+fnwgsvzJ577pkOHTqkV69e2WeffbLvvvtm3333zTHHHFNj7NomT55cbNd1AvbGmDRpUrF96KGHplAo1PvTvn374tg1p2pv7eo/LxwAAAAAAAAAAACA96V//etfxfb222/f4NgddtihznlrdOnSJeXlDUdW19zjvfO//OUvZ8aMGbnqqquycOHC3Hrrrbn11luTJLvttluOO+64nHPOOdl1110bfqB1ePrpp/OJT3wiCxYsaNT4pUuX1vi8djh6zWnWTWXevHkbNG/NSdVbO2FoAAAAAAAAAAAAAOpVKBQa7K+urt6o+eta4/LLL8+ZZ56Z//qv/8qjjz6aJ598MkuWLMmMGTNy9dVX56c//Wl++tOf5itf+co671OXFStW5KSTTsqCBQvSsmXLnHvuuRk8eHB69+6dbbbZJq1atUqSvPTSS9ltt93WWW9TW7VqVbE9ZsyYbLvtto2at912222qkrYowtAAAAAAAAAAAAAA1NClS5die+7cuendu3e9Y19//fU6562xYMGCrFq1Ki1atKh3jTWnH9c1P0l22WWXXHjhhbnwwguzcuXKTJw4MX/4wx/y85//PMuWLcs555yTgw8+OP369Vvns73XY489lpdeeilJcuONN+aMM86oc9ybb75Z7xpdu3Yttl977bX06tVrveuoz9rh54qKiuyzzz5NtvbWoKy5CwAAAAAAAAAAAABgy7J24Pb//u//Ghw7ceLEOuetsWLFijz77LP1zq+qqspf//rXeue/V8uWLdO/f/9cd911+e1vf5vk3ZOa77rrrhrjGnMidZL87W9/K7ZPPvnkesdNmjSp3r4PfehDxfa4ceMadd/GWjvg/cgjjzTp2lsDYWgAAAAAAAAAAAAAath///3TuXPnJMntt9+eVatW1TnunXfeye9///skyV577ZUdd9yxznG33357vfe65557iqcuf/SjH12vOj/ykY8U2/Pnz6/R17p162J7+fLl9a5RVVVVbC9ZsqTOMatXr87IkSPrXWPQoEFp165dkmTEiBH1fl8b4vDDDy+emH3zzTfn7bffbrK1twbC0AAAAAAAAAAAAADU0KpVq5x++ulJ3j05+dJLL601prq6Ol/72teKIeSvfe1r9a530003ZcKECbWuz507N8OHD0+StG3bNkOGDKnR/5vf/KZGWPm91j4puVevXjX61g5mz5gxo9419thjj2K7vtD2f/zHf+SZZ56pd43OnTvnrLPOSpI8/fTTOf/881NdXV3n2JUrV2bevHn1rvVerVu3Ln5Hc+fOzcknn5zFixfXO/6dd97JDTfc0Oj1S115cxcAAAAAAAAAAAAAwJbn+9//fu6+++689NJL+cEPfpApU6bky1/+crp3756ZM2fmhhtuyJgxY5Ikhx56aM4888w61+nWrVvatm2bj33sY/nGN76Ro48+Oq1atcrEiRPzwx/+MK+++mqS5Ac/+EG22267GnNPPfXUDB8+PCeccEIOO+yw7LbbbmndunVef/31/OlPf8pNN92UJGnfvn1OOeWUGnP79euX1q1bZ9myZfne976X8vLy9OzZM2Vl754lvNNOO6VNmzb5xCc+ke222y7z5s3Ld7/73fzzn//Msccem65du2b69On5xS9+kUcffTT9+/fPX/7yl3q/rx/84Af505/+lOeffz433HBDnnjiiZx11lnZd999U1FRkdmzZ2fChAn57W9/m8suuyxDhw5t9P8WF1xwQR599NE8+uijeeihh7LXXnvlK1/5Sg499NB07tw577zzTv7+979nzJgxuffee9O6desGw+lbE2FoAAAAAAAAAAAAAGrp0KFDHn300Rx11FF54YUXcs899+See+6pNa5///75n//5n7Ro0aLOddq2bZu77rorRx11VH70ox/lRz/6Ua0x5513Xr75zW/WOf/111/PTTfdVAw+v1fnzp0zatSoVFZW1qr/vPPOy1VXXZVnnnkmn/jEJ2r0jx49OgMHDky7du1yxx135LjjjsuyZcvys5/9LD/72c9qjB04cGBuuOGG7LPPPnXWsOY5H3vssXzmM5/JuHHj8vTTT9cbEF9fLVq0yP3335+vfOUrueOOO/LKK6/kwgsvrHf8e0PlW7Oy5i4AAAAAAAAAAAAAgC1Tz5498+yzz+aGG27IgAEDsu2226Zly5bZfvvt88lPfjK//vWvM27cuHTp0qXBdQ444IA888wzOe+884qnO2+77bb55Cc/mT/+8Y+5/vrr65z3wgsvZMSIETnuuOOy1157Zdttt015eXm22WabHHLIIbnkkkvy97//PR//+MfrnH/FFVfkF7/4RY444oh06dKl3sD2Jz7xiUyaNCmnnHJKunfvnpYtW6Zbt24ZMGBARo4cmUcffTTt2rVb5/fVtWvXjB07NnfffXc++9nPprKyMq1atco222yTffbZJ1/84hdz33335Qtf+MI613qvNm3a5Pbbb8+kSZNy9tlnZ++9906nTp1SXl6ezp07Z7/99suwYcNy1113Zdq0aeu9fqkqVFdXVzd3Ee8Hs2fPTo8ePZIks2bNqvXbB+tr6pBCndeP3vGBjVoXAAAAAAAAAACA5tGh73fqvP78kOc3at2mzq81pxdffDFVVVUpLy/PHnvs0eDY3//wqSx5e8Vmqqz5tO1YkZMuPLC5y4BGW5+/jxujvAlqAgAAAAAAAAAAANiiCAjD+0NZcxcAAAAAAAAAAAAAALAhhKEBAAAAAAAAAAAAgJIkDA0AAAAAAAAAAAAAlKSSDkNfcMEFKRQKxZ8xY8asc87DDz+cE044IZWVlWnVqlUqKytzwgkn5OGHH970BQMAAAAAAAAAAAAATaZkw9DPPvtsrr322kaPr66uzllnnZWjjjoq99xzT+bMmZMVK1Zkzpw5ueeee3LUUUflrLPOSnV19SasGgAAAAAAAAAAAABoKiUZhl69enXOOOOMVFVVZbvttmvUnIsuuigjR45MkvTr1y933nlnJk6cmDvvvDP9+vVLkowcOTLf+973NlndAAAAAAAAAAAAAEDTKckw9E9/+tM89dRT6dOnT4YNG7bO8dOnT89VV12VJDnggAPyl7/8JSeffHIOPPDAnHzyyZkwYUIOOOCAJMmVV16ZGTNmbNL6AQAAAAAAAAAAAICNV3Jh6FmzZhVPb77ppptSUVGxzjnXXnttqqqqkiQjRoxImzZtavS3bds2I0aMSJJUVVXluuuua9qiAQAAAAAAAAAAAIAmV3Jh6HPOOSeLFi3KkCFDMnDgwHWOr66uzn333Zck6dOnTw455JA6xx1yyCHZc889kyT33ntvqqurm6xmAAAAAAAAAAAAAKDplVQY+ve//30eeOCBdOnSJT/+8Y8bNWfmzJmZM2dOkmTAgAENjl3TP3v27Lz88ssbVSsAAAAAAAAAAAAAUFNTH1hc3qSrbUJvvfVWvv71rydJrrzyynTr1q1R86ZNm1Zs9+nTp8Gxa/dPmzYtvXr1anR9s2fPbrD/tddea/RaAAAAAAAAAAAAQG0tWrRIVVVVVq1aldWrV6esrKTOhIX3vVWrVmXVqlVJ3v37uSmUTBj6ggsuyNy5c3PYYYdl2LBhjZ43a9asYruysrLBsT169KhzXmOsPRcAAAAAAAAAAABoeq1bt87y5ctTXV2dRYsWpWPHjs1dErAe3nrrrWK7bdu2TbJmSfxKxIQJE3LLLbekvLw8N998cwqFQqPnvvPOO8V2+/btGxzbrl27YnvRokXrXygAAAAAAAAAAACwyawdfp47d27efvvtrF69uhkrAtaluro6y5Yty7x58zJv3rzi9W222aZJ1t/iT4ZesWJFzjzzzFRXV+cb3/hG9t133/Wav2zZsmK7oqKiwbGtWrUqtpcuXbpe91nXSdKvvfZaDjrooPVaEwAAAAAAAAAAAPi3du3apU2bNlm6dGlWrVqVOXPmpFAopEWLFs1dGlCPVatWpbq6usa1Tp061cjtbowtPgz9wx/+MNOmTcvOO++ciy++eL3nt27duthesWJFg2OXL19ebLdp02a97lNZWbl+hQEAAAAAAAAAAADrpVAoZOedd84rr7xSPPS0uro6VVVVzVwZ0FjdunXLtttu22TrbdFh6BdeeCE/+tGPkiQjRoxIu3bt1nuNDh06FNuLFi1qcOzixYuL7fbt26/3vQAAAAAAAAAAAIBNq6ysLLvssksWL16cd955p3hKNLBlKisrS0VFRdq1a5f27dunoqKiSdffosPQ1157bVasWJFdd901S5Ysye9+97taY6ZMmVJsP/bYY5k7d26S5NOf/nTatWtX48Tm2bNnN3i/WbNmFds9evTY2PIBAAAAAAAAAACATaBQKKR9+/YOPgW27DD08uXLkyQvvfRSPv/5z69z/A9+8INie+bMmWnXrl322muv4rUXXnihwflr9/ft23d9ywUAAAAAAAAAAAAANqOy5i5gU+vVq1e6d++eJBk7dmyDY8eNG5ck2WmnndKzZ89NXRoAAAAAAAAAAAAAsBG26DD0bbfdlurq6gZ/Lr744uL40aNHF6+vCTMXCoUMHjw4ybsnPz/55JN13uvJJ58sngw9ePDgFAqFTftwAAAAAAAAAAAAAMBG2aLD0E3l/PPPT3l5eZLk3HPPzdKlS2v0L126NOeee26SpLy8POeff/7mLhEAAAAAAAAAAAAAWE/vizB07969M3z48CTJpEmT0r9//4waNSqTJk3KqFGj0r9//0yaNClJ8u1vfzt77LFHc5YLAAAAAAAAAAAAADRCeXMXsLlcfvnlmTdvXn71q19l8uTJOfnkk2uNGTZsWC677LJmqA4AAAAAAAAAAAAAWF/vi5Ohk6SsrCy//OUv8+CDD2bw4MHp3r17Kioq0r179wwePDh//OMfc8stt6Ss7H3zlQAAAAAA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CUMDAAAAAAAAAAAAACVJGBoAAAAAAAAAAAAAKEnC0AAAAAAAAAAAAABASRKGBgAAAAAAAAAAAABKkjA0AAAAAAAAAAAAAFCShKEBAAAAAAAAAAAAgJIkDA0AAAAAAAAAAAAAlCRhaAAAAAAAAAAAAACgJAlDAwAAAAAAAAAAAAAlSRgaAAAAAAAAAAAAAChJwtAAAAAAAAAAAAAAQEkShgYAAAAAAAAAAAAASpIwNAAAAAAAAAAAAABQkoShAQAAAAAAAAAAAICSJAwNAAAAAAAAAAAAAJQkYWgAAAAAAAAAAAAAoCQJQwMAAAAAAAAAAAAAJUkYGgAAAAAAAAAAAAAoScLQAAAAAAAAAAAAAEBJEoYGAAAAAAAAAAAAAEqSMDQAAAAAAAAAAAAAUJKEoQEAAAAAAAAAAACAkiQMDQAAAAAAAAAAAACUJGFoAAAAAAAAAAAAAKAkCUMDAAAAAAAAAAAAACVJGBoAAAAAAAAAAAAAKEnC0AAAAAAAAAAAAABASRKGBgAAAAAAAAAAAABKkjA0AAAAAAAAAAAAAFCShKEBAAAAAAAAAAAAgJIkDA0AAAAAAAAAAAAAlCRhaAAAAAAAAAAAAACgJAlDAwAAAAAAAAAAAAAlSRgaAAAAAAAAAAAAAChJwtAAAAAAAAAAAAAAQEkShgYAAAAAAAAAAAAASpIwNAAAAAAAAAAAAABQkoShAQAAAAAAAAAAAICSJAwNAAAAAAAAAAAAAJQkYWgAAAAAAAAAAAAAoCQJQwMAAAAAAAAAAAAAJUkYGgAAAAAAAAAAAAAoScLQAAAAAAAAAAAAAEBJEoYGAAAAAAAAAAAAAEqSMDQAAAAAAAAAAAAAUJKEoQEAAAAAAAAAAACAkiQMDQAAAAAAAAAAAACUJGFoAAAAAAAAAAAAAKAkCUMDAAAAAAAAAAAAACVJGBoAAAAAAAAAAAAAKEnC0AAAAAAAAAAAAABASRKGBgAAAAAAAAAAAABKkjA0AAAAAAAAAAAAAFCShKEBAAAAAAAAAAAAgJIkDA0AAAAAAAAAAAAAlCRhaAAAAAAAAAAAAACgJAlDAwAAAAAAAAAAAAAlSRgaAAAAAAAAAAAAAChJwtAAAAAAAAAAAAAAQEkShgYAAAAAAAAAAAAASpIwNAAAAAAAAAAAAABQkoShAQAAAAAAAAAAAICSJAwNAAAAAAAA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9p4xY8asc473L4AmVk1JeuCBB6o7depUnaTOnz333LN6xowZzV0m8D5R31703p8BAwbUu8bq1aurzzzzzAbnn3nmmdWrV6/efA8GlLSG9pMhQ4Y0ep2m2p+mT59eveeee9a7RqdOnaoffPDBjXxqYGvQFPvXrbfe2uh3tFtvvbXBtexfQGMceeSRjdpzTj311Orly5c3uJb3L2Bzaqr9y/sXsLn96U9/atSe07Vr1+qHH3643nW8ewGbW1PsX969gC3JX//61+ry8vIae8fo0aPrHe/9C2DTKA8l59lnn81JJ52UJUuWpH379vmP//iPDBo0KEuXLs3vfve7/OIXv8jf//73HHPMMXnqqafSvn375i4ZeJ84++yzc84559Tb365du3r7LrrooowcOTJJ0q9fv1xwwQXZbbfdMmPGjFx11VWZPHlyRo4cmW7duuWyyy5r8tqBrVuPHj3St2/fPPLII+s9tyn2p0WLFuVTn/pU/v73vydJzjjjjJx88slp06ZNRo8enR/96EdZuHBhTjzxxDzxxBP5wAc+sOEPC2xVNmb/WuN///d/071793r7Kysr6+2zfwGNNWfOnCRJ9+7dc+KJJ+aII47IzjvvnFWrVuWJJ57I1VdfnTlz5uTXv/51qqqq8tvf/rbetbx/AZtTU+5fa3j/AjaXHj16ZNCgQdl///3To0eP7Ljjjlm9enVmz56du+66K3fffXfmz5+fY489Nk899VSde4Z3L6A5NMX+tYZ3L6A5rV69OmeccUaqqqqy3XbbZd68eeuc4/0LYBNp7jQ262/gwIHVSarLy8urH3/88Vr9V111VfG3fC699NJmqBB4v1mz51x88cUbNP/FF18s/qbkAQccUL1kyZIa/YsXL64+4IADinvf9OnTm6BqYGv3/e9/v/r++++vnjt3bnV1dXX1zJkzi/tVY09Wbar96eKLLy7e+6qrrqrV//jjjxfvM2jQoPV7UGCr0xT719qn48ycOXODa7F/AY11zDHHVI8aNaq6qqqqzv433nijunfv3sU9Zdy4cXWO8/4FbG5NtX95/wI2t/r2rbXdc889xT3lhBNOqNXv3QtoDk2xf3n3ArYU1157bXWS6j59+lT/x3/8xzpPhvb+BbDplDVZqprN4qmnnsqYMWOSJMOGDcuhhx5aa8y3vvWt9O3bN0ly3XXXZeXKlZuzRID1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">
%% Cell type:code id: tags:
``` python
def timeloop(timeSteps):
    for i in range(timeSteps):
        bh()
        dh.run_kernel(kernel)
        dh.swap(src.name, dst.name)
```
%% Cell type:code id: tags:
``` python
mask = np.fromfunction(set_sphere, (domain_size[0], domain_size[1], len(domain_size)))
if 'is_test_run' not in globals():
    timeloop(50000)  # initial steps
    def run():
        timeloop(50)
        return np.ma.array(dh.gather_array('velField'), mask=mask)
    animation = plt.vector_field_magnitude_animation(run, frames=600, rescale=True)
    set_display_mode('video')
    res = display_animation(animation)
else:
    timeloop(10)
    res = None
res
```
%% Output
    <IPython.core.display.HTML object>

noxfile.py

0 → 100644
+170 −0
Original line number Diff line number Diff line
from __future__ import annotations
from typing import Sequence
from argparse import ArgumentParser

import os
import nox
import subprocess
import re

nox.options.sessions = ["lint", "typecheck"]


def get_cuda_version(session: nox.Session) -> None | tuple[int, ...]:
    query_args = ["nvcc", "--version"]

    try:
        query_result = subprocess.run(query_args, capture_output=True)
    except FileNotFoundError:
        return None

    matches = re.findall(r"release \d+\.\d+", str(query_result.stdout))
    if matches:
        match = matches[0]
        version_string = match.split()[-1]
        try:
            return tuple(int(v) for v in version_string.split("."))
        except ValueError:
            pass

    session.warn("nvcc was found, but I am unable to determine the CUDA version.")
    return None


def install_cupy(
    session: nox.Session, cupy_version: str, skip_if_no_cuda: bool = False
):
    if cupy_version is not None:
        cuda_version = get_cuda_version(session)
        if cuda_version is None or cuda_version[0] not in (11, 12):
            if skip_if_no_cuda:
                session.skip(
                    "No compatible installation of CUDA found - Need either CUDA 11 or 12"
                )
            else:
                session.warn(
                    "Running without cupy: no compatbile installation of CUDA found. Need either CUDA 11 or 12."
                )
                return

        cuda_major = cuda_version[0]
        cupy_package = f"cupy-cuda{cuda_major}x=={cupy_version}"
        session.install(cupy_package)


def check_external_doc_dependencies(session: nox.Session):
    dot_args = ["dot", "--version"]
    try:
        _ = subprocess.run(dot_args, capture_output=True)
    except FileNotFoundError:
        session.error(
            "Unable to build documentation: "
            "Command `dot` from the `graphviz` package (https://www.graphviz.org/) is not available"
        )


def editable_install(session: nox.Session, opts: Sequence[str] = ()):
    if opts:
        opts_str = "[" + ",".join(opts) + "]"
    else:
        opts_str = ""
    session.install("-e", f".{opts_str}")


def install_pystencils_master(session: nox.Session):
    session.install("git+https://i10git.cs.fau.de/pycodegen/pystencils.git@master")


def install_sympy_master(session: nox.Session):
    session.install("--upgrade", "git+https://github.com/sympy/sympy.git@master")


@nox.session(python="3.10", tags=["qa", "code-quality"])
def lint(session: nox.Session):
    """Lint code using flake8"""

    session.install("flake8")
    session.run("flake8", "src/lbmpy")


@nox.session(python="3.10", tags=["qa", "code-quality"])
def typecheck(session: nox.Session):
    """Run MyPy for static type checking"""
    editable_install(session)
    session.install("mypy")
    session.run("mypy", "src/lbmpy")


def run_testsuite(session: nox.Session, coverage: bool = True):
    num_cores = os.cpu_count()

    args = [
        "pytest",
        "-v",
        "-n",
        str(num_cores),
        "-m",
        "not longrun",
        "--html",
        "test-report/index.html",
        "--junitxml=report.xml",
    ]

    if coverage:
        args += [
            "--cov-report=term",
            "--cov=.",
        ]

    session.run(*args)

    if coverage:
        session.run("coverage", "html")
        session.run("coverage", "xml")


@nox.session(python=["3.10", "3.11", "3.12", "3.13"])
def testsuite_cpu(session: nox.Session):
    install_pystencils_master(session)
    editable_install(session, ["alltrafos", "use_cython", "interactive", "tests"])
    run_testsuite(session, coverage=False)


@nox.session(python=["3.10", "3.11", "3.12", "3.13"])
@nox.parametrize("cupy_version", ["12", "13"], ids=["cupy12", "cupy13"])
def testsuite_gpu(session: nox.Session, cupy_version: str | None):
    install_cupy(session, cupy_version, skip_if_no_cuda=True)
    install_pystencils_master(session)
    editable_install(session, ["alltrafos", "use_cython", "interactive", "tests"])
    run_testsuite(session)


@nox.parametrize("cupy_version", [None, "12", "13"], ids=["cpu", "cupy12", "cupy13"])
@nox.session(python="3.10", tags=["test"])
def testsuite_pystencils2(session: nox.Session, cupy_version: str | None):
    if cupy_version is not None:
        install_cupy(session, cupy_version, skip_if_no_cuda=True)

    session.install(
        "git+https://i10git.cs.fau.de/pycodegen/pystencils.git@v2.0-dev"
    )
    editable_install(session, ["alltrafos", "use_cython", "interactive", "tests"])

    run_testsuite(session)


@nox.session
def quicktest(session: nox.Session):
    parser = ArgumentParser()
    parser.add_argument(
        "--sympy-master", action="store_true", help="Use latest SymPy master revision"
    )
    args = parser.parse_args(session.posargs)

    install_pystencils_master(session)
    editable_install(session)

    if args.sympy_master:
        install_sympy_master(session)

    session.run("python", "quicktest.py")
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ authors = [
]
license = { file = "COPYING.txt" }
requires-python = ">=3.10"
dependencies = ["pystencils>=1.3", "sympy>=1.6,<=1.11.1", "numpy>=1.8.0", "appdirs", "joblib"]
dependencies = ["pystencils>=1.3", "sympy>=1.12", "numpy>=1.8.0", "appdirs", "joblib", "packaging"]
classifiers = [
    "Development Status :: 4 - Beta",
    "Framework :: Jupyter",
+9 −1
Original line number Diff line number Diff line
@@ -3,7 +3,12 @@ testpaths = src tests doc/notebooks
pythonpath = src
python_files = test_*.py *_test.py scenario_*.py
norecursedirs = *.egg-info .git .cache .ipynb_checkpoints htmlcov
addopts = --doctest-modules --durations=20  --cov-config pytest.ini
addopts = 
       --doctest-modules --durations=20
       --cov-config pytest.ini
       --ignore=src/lbmpy/custom_code_nodes.py
       --ignore=src/lbmpy/lookup_tables.py
       --ignore=src/lbmpy/phasefield_allen_cahn/contact_angle.py
markers =
       longrun: tests only run at night since they have large execution time
       notebook: mark for notebooks
@@ -24,7 +29,10 @@ omit = doc/*
       setup.py
       conftest.py
       versioneer.py
       quicktest.py
       noxfile.py
       src/lbmpy/_version.py
       src/lbmpy/_compat.py
       venv/

[report]
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ from .lbstep import LatticeBoltzmannStep
from .macroscopic_value_kernels import (
    pdf_initialization_assignments,
    macroscopic_values_getter,
    strain_rate_tensor_getter,
    compile_macroscopic_values_getter,
    compile_macroscopic_values_setter,
    create_advanced_velocity_setter_collision_rule,
@@ -42,6 +43,7 @@ __all__ = [
    "LatticeBoltzmannStep",
    "pdf_initialization_assignments",
    "macroscopic_values_getter",
    "strain_rate_tensor_getter",
    "compile_macroscopic_values_getter",
    "compile_macroscopic_values_setter",
    "create_advanced_velocity_setter_collision_rule",

src/lbmpy/_compat.py

0 → 100644
+42 −0
Original line number Diff line number Diff line
from pystencils import __version__ as ps_version

#   Determine if we're running pystencils 1.x or 2.x
version_tokes = ps_version.split(".")

PYSTENCILS_VERSION_MAJOR = int(version_tokes[0])
IS_PYSTENCILS_2 = PYSTENCILS_VERSION_MAJOR == 2

if IS_PYSTENCILS_2:
    from pystencils.defaults import DEFAULTS

    def get_loop_counter_symbol(coord: int):
        return DEFAULTS.spatial_counters[coord]

    def get_supported_instruction_sets():
        from pystencils import Target
        vector_targets = Target.available_vector_cpu_targets()
        isas = []
        for target in vector_targets:
            tokens = target.name.split("_")
            isas.append(tokens[-1].lower())
        return isas

else:
    from pystencils.backends.simd_instruction_sets import (
        get_supported_instruction_sets as get_supported_instruction_sets_,
    )

    get_supported_instruction_sets = get_supported_instruction_sets_

    def get_loop_counter_symbol(coord: int):
        from pystencils.astnodes import LoopOverCoordinate

        return LoopOverCoordinate.get_loop_counter_symbol(coord)


def import_guard_pystencils1(feature):
    if IS_PYSTENCILS_2:
        raise ImportError(
            f"The following feature is not yet available when running pystencils 2.x: {feature}"
        )
    return True
Original line number Diff line number Diff line
import itertools
from pystencils import CreateKernelConfig, Field, Assignment, AssignmentCollection
from pystencils.slicing import shift_slice, get_slice_before_ghost_layer, normalize_slice
from lbmpy.advanced_streaming.utility import is_inplace, get_accessor, numeric_index, \
    Timestep, get_timesteps, numeric_offsets
from pystencils import CreateKernelConfig, Field, Assignment, AssignmentCollection, Target
from pystencils.slicing import (
    shift_slice,
    get_slice_before_ghost_layer,
    normalize_slice,
)
from lbmpy.advanced_streaming.utility import (
    is_inplace,
    get_accessor,
    numeric_index,
    Timestep,
    get_timesteps,
    numeric_offsets,
)
from pystencils.datahandling import SerialDataHandling
from pystencils.enums import Target
from itertools import chain


class LBMPeriodicityHandling:

    def __init__(self, stencil, data_handling, pdf_field_name,
                 streaming_pattern='pull', ghost_layers=1,
                 cupy_direct_copy=True):
    def __init__(
        self,
        stencil,
        data_handling,
        pdf_field_name,
        streaming_pattern="pull",
        ghost_layers=1,
        cupy_direct_copy=True,
    ):
        """
        Periodicity Handling for Lattice Boltzmann Streaming.

@@ -25,7 +40,7 @@ class LBMPeriodicityHandling:
        Choose your weapon depending on your use case.
        """
        if not isinstance(data_handling, SerialDataHandling):
            raise ValueError('Only serial data handling is supported!')
            raise ValueError("Only serial data handling is supported!")

        self.stencil = stencil
        self.dim = stencil.D
@@ -56,12 +71,16 @@ class LBMPeriodicityHandling:
        self.comm_slices = []
        timesteps = get_timesteps(streaming_pattern)
        for timestep in timesteps:
            slices_per_comm_dir = get_communication_slices(stencil=stencil,
            slices_per_comm_dir = get_communication_slices(
                stencil=stencil,
                comm_stencil=copy_directions,
                streaming_pattern=streaming_pattern,
                prev_timestep=timestep,
                                                           ghost_layers=ghost_layers)
            self.comm_slices.append(list(chain.from_iterable(v for k, v in slices_per_comm_dir.items())))
                ghost_layers=ghost_layers,
            )
            self.comm_slices.append(
                list(chain.from_iterable(v for k, v in slices_per_comm_dir.items()))
            )

        if self.target == Target.GPU and not cupy_direct_copy:
            self.device_copy_kernels = list()
@@ -81,11 +100,11 @@ class LBMPeriodicityHandling:
            arr[dst] = arr[src]

    def _compile_copy_kernels(self, timestep):
        assert self.target == Target.GPU
        pdf_field = self.dh.fields[self.pdf_field_name]
        kernels = []
        for src, dst in self.comm_slices[timestep.idx]:
            kernels.append(
                periodic_pdf_copy_kernel(pdf_field, src, dst, target=self.target))
            kernels.append(periodic_pdf_gpu_copy_kernel(pdf_field, src, dst))
        return kernels

    def _periodicity_handling_gpu(self, prev_timestep):
@@ -100,7 +119,12 @@ class LBMPeriodicityHandling:


def get_communication_slices(
        stencil, comm_stencil=None, streaming_pattern='pull', prev_timestep=Timestep.BOTH, ghost_layers=1):
    stencil,
    comm_stencil=None,
    streaming_pattern="pull",
    prev_timestep=Timestep.BOTH,
    ghost_layers=1,
):
    """
    Return the source and destination slices for periodicity handling or communication between blocks.

@@ -116,7 +140,9 @@ def get_communication_slices(
    if comm_stencil is None:
        comm_stencil = itertools.product(*([-1, 0, 1] for _ in range(stencil.D)))

    pdfs = Field.create_generic('pdfs', spatial_dimensions=len(stencil[0]), index_shape=(stencil.Q,))
    pdfs = Field.create_generic(
        "pdfs", spatial_dimensions=len(stencil[0]), index_shape=(stencil.Q,)
    )
    write_accesses = get_accessor(streaming_pattern, prev_timestep).write(pdfs, stencil)
    slices_per_comm_direction = dict()

@@ -130,7 +156,9 @@ def get_communication_slices(
            d = stencil.index(streaming_dir)
            write_index = numeric_index(write_accesses[d])[0]

            origin_slice = get_slice_before_ghost_layer(comm_dir, ghost_layers=ghost_layers, thickness=1)
            origin_slice = get_slice_before_ghost_layer(
                comm_dir, ghost_layers=ghost_layers, thickness=1
            )
            src_slice = _fix_length_one_slices(origin_slice)

            write_offsets = numeric_offsets(write_accesses[d])
@@ -138,7 +166,9 @@ def get_communication_slices(

            # TODO: this is just a hotfix. _trim_slice_in_direction breaks FreeSlip BC with adjacent periodic side
            if streaming_pattern != "pull":
                src_slice = shift_slice(_trim_slice_in_direction(src_slice, tangential_dir), write_offsets)
                src_slice = shift_slice(
                    _trim_slice_in_direction(src_slice, tangential_dir), write_offsets
                )

            neighbour_transform = _get_neighbour_transform(comm_dir, ghost_layers)
            dst_slice = shift_slice(src_slice, neighbour_transform)
@@ -152,10 +182,10 @@ def get_communication_slices(
    return slices_per_comm_direction


def periodic_pdf_copy_kernel(pdf_field, src_slice, dst_slice,
                             domain_size=None, target=Target.GPU):
    """Copies a rectangular array slice onto another non-overlapping array slice"""
    from pystencils.gpucuda.kernelcreation import create_cuda_kernel
def periodic_pdf_gpu_copy_kernel(pdf_field, src_slice, dst_slice, domain_size=None):
    """Generate a GPU kernel which copies all values from one slice of a field
    to another non-overlapping slice."""
    from pystencils import create_kernel

    pdf_idx = src_slice[-1]
    assert isinstance(pdf_idx, int), "PDF index needs to be an integer constant"
@@ -176,18 +206,28 @@ def periodic_pdf_copy_kernel(pdf_field, src_slice, dst_slice,
    def _stop(s):
        return s.stop if isinstance(s, slice) else s

    offset = [_start(s1) - _start(s2) for s1, s2 in zip(normalized_from_slice, normalized_to_slice)]
    assert offset == [_stop(s1) - _stop(s2) for s1, s2 in zip(normalized_from_slice, normalized_to_slice)], \
        "Slices have to have same size"

    copy_eq = AssignmentCollection(main_assignments=[Assignment(pdf_field(pdf_idx), pdf_field[tuple(offset)](pdf_idx))])
    config = CreateKernelConfig(iteration_slice=dst_slice, skip_independence_check=True)
    ast = create_cuda_kernel(copy_eq, config=config)
    if target == Target.GPU:
        from pystencils.gpucuda import make_python_function
        return make_python_function(ast)
    else:
        raise ValueError('Invalid target:', target)
    offset = [
        _start(s1) - _start(s2)
        for s1, s2 in zip(normalized_from_slice, normalized_to_slice)
    ]
    assert offset == [
        _stop(s1) - _stop(s2)
        for s1, s2 in zip(normalized_from_slice, normalized_to_slice)
    ], "Slices have to have same size"

    copy_eq = AssignmentCollection(
        main_assignments=[
            Assignment(pdf_field(pdf_idx), pdf_field[tuple(offset)](pdf_idx))
        ]
    )
    config = CreateKernelConfig(
        iteration_slice=dst_slice,
        skip_independence_check=True,
        target=Target.GPU,
    )

    ast = create_kernel(copy_eq, config=config)
    return ast.compile()


def _extend_dir(direction):
Original line number Diff line number Diff line
@@ -2,10 +2,17 @@ import numpy as np
import sympy as sp
import pystencils as ps

from .._compat import IS_PYSTENCILS_2

if IS_PYSTENCILS_2:
    from pystencils import TypedSymbol, create_type
    from pystencils.types.quick import Arr
    from lbmpy.lookup_tables import TranslationArraysNode
else:
    from pystencils.typing import TypedSymbol, create_type
from lbmpy.advanced_streaming.utility import get_accessor, inverse_dir_index, is_inplace, Timestep
from lbmpy.custom_code_nodes import TranslationArraysNode
    from ..custom_code_nodes import TranslationArraysNode

from lbmpy.advanced_streaming.utility import get_accessor, inverse_dir_index, is_inplace, Timestep
from itertools import product


@@ -64,13 +71,21 @@ class BetweenTimestepsIndexing:
        assert f_dir in ['in', 'out']
        inv = '_inv' if inverse else ''
        name = f"f_{f_dir}{inv}_dir_idx"
        if IS_PYSTENCILS_2:
            return TypedSymbol(name, Arr(self._index_dtype, self._q))
        else:
            return TypedSymbol(name, self._index_dtype)

    def _offset_array_symbols(self, f_dir, inverse):
        assert f_dir in ['in', 'out']
        inv = '_inv' if inverse else ''
        name_base = f"f_{f_dir}{inv}_offsets_"

        if IS_PYSTENCILS_2:
            symbols = [TypedSymbol(name_base + d, Arr(self._index_dtype, self._q)) for d in self._coordinate_names]
        else:
            symbols = [TypedSymbol(name_base + d, self._index_dtype) for d in self._coordinate_names]
        
        return symbols

    def _array_symbols(self, f_dir, inverse, index):
@@ -169,6 +184,10 @@ class BetweenTimestepsIndexing:
            indices, offsets = self._get_translated_indices_and_offsets(f_dir, inv)
            index_array_symbol = self._index_array_symbol(f_dir, inv)
            symbols_defined.add(index_array_symbol)

            if IS_PYSTENCILS_2:
                array_content.append((index_array_symbol, indices))
            else:
                array_content.append((self._index_dtype, index_array_symbol.name, indices))

        for f_dir, inv in self._required_offset_arrays:
@@ -176,8 +195,14 @@ class BetweenTimestepsIndexing:
            offset_array_symbols = self._offset_array_symbols(f_dir, inv)
            symbols_defined |= set(offset_array_symbols)
            for d, arrsymb in enumerate(offset_array_symbols):
                if IS_PYSTENCILS_2:
                    array_content.append((arrsymb, offsets[d]))
                else:
                    array_content.append((self._offsets_dtype, arrsymb.name, offsets[d]))

        if IS_PYSTENCILS_2:
            return TranslationArraysNode(array_content)
        else:
            return TranslationArraysNode(array_content, symbols_defined)

#   end class AdvancedStreamingIndexing
Original line number Diff line number Diff line
import sympy as sp

from .._compat import IS_PYSTENCILS_2

from lbmpy.advanced_streaming.indexing import BetweenTimestepsIndexing
from lbmpy.advanced_streaming.utility import Timestep, get_accessor
from lbmpy.custom_code_nodes import LbmWeightInfo
from pystencils.boundaries.boundaryhandling import BoundaryOffsetInfo
from pystencils.assignment import Assignment
from pystencils.astnodes import Block, Conditional, LoopOverCoordinate, SympyAssignment
from pystencils.simp.assignment_collection import AssignmentCollection
from pystencils.simp.simplifications import sympy_cse_on_assignment_list
from pystencils import Assignment
from pystencils.simp import AssignmentCollection, sympy_cse_on_assignment_list
from pystencils.stencil import inverse_direction
from pystencils.sympyextensions import fast_subs

if IS_PYSTENCILS_2:
    from lbmpy.lookup_tables import LbmWeightInfo
else:
    from lbmpy.custom_code_nodes import LbmWeightInfo
    from pystencils.astnodes import Block, Conditional, LoopOverCoordinate, SympyAssignment  # TODO replace


def direction_indices_in_direction(direction, stencil):
    for i, offset in enumerate(stencil):
@@ -58,6 +63,9 @@ def border_conditions(direction, field, ghost_layers=1):


def boundary_conditional(boundary, direction, streaming_pattern, prev_timestep, lb_method, output_field, cse=False):
    if IS_PYSTENCILS_2:
        raise NotImplementedError("In-Kernel Boundaries are not yet available on pystencils 2.0")

    stencil = lb_method.stencil

    dir_indices = direction_indices_in_direction(direction, stencil)
@@ -67,7 +75,7 @@ def boundary_conditional(boundary, direction, streaming_pattern, prev_timestep,

    assignments = []
    for direction_idx in dir_indices:
        rule = boundary(f_out, f_in, direction_idx, inv_dir, lb_method, index_field=None)
        rule = boundary(f_out, f_in, direction_idx, inv_dir, lb_method, index_field=None, force_vector=None)

        #   rhs: replace f_out by post collision symbols.
        rhs_substitutions = {f_out(i): sym for i, sym in enumerate(lb_method.post_collision_pdf_symbols)}
Original line number Diff line number Diff line
from dataclasses import replace
import numpy as np

from pystencils import Assignment, CreateKernelConfig, create_kernel, Field, Target
from pystencils import Assignment, CreateKernelConfig, create_kernel, Field, Target, FieldType
from pystencils.boundaries import BoundaryHandling
from pystencils.boundaries.createindexlist import numpy_data_type_for_boundary_object
from pystencils.simp import add_subexpressions_for_field_reads
@@ -9,6 +10,11 @@ from pystencils.stencil import inverse_direction
from lbmpy.advanced_streaming.indexing import BetweenTimestepsIndexing
from lbmpy.advanced_streaming.utility import is_inplace, Timestep, AccessPdfValues

from .._compat import IS_PYSTENCILS_2

if IS_PYSTENCILS_2:
    from pystencils.types import PsNumericType


class LatticeBoltzmannBoundaryHandling(BoundaryHandling):
    """
@@ -18,13 +24,16 @@ class LatticeBoltzmannBoundaryHandling(BoundaryHandling):
    """

    def __init__(self, lb_method, data_handling, pdf_field_name, streaming_pattern='pull',
                 name="boundary_handling", flag_interface=None, target=Target.CPU, openmp=False):
                 name="boundary_handling", flag_interface=None, target=Target.CPU, openmp=False, **kwargs):
        self._lb_method = lb_method
        self._streaming_pattern = streaming_pattern
        self._inplace = is_inplace(streaming_pattern)
        self._prev_timestep = None
        super(LatticeBoltzmannBoundaryHandling, self).__init__(data_handling, pdf_field_name, lb_method.stencil,
                                                               name, flag_interface, target, openmp)
        super(LatticeBoltzmannBoundaryHandling, self).__init__(
            data_handling, pdf_field_name, lb_method.stencil,
            name, flag_interface, target=target, openmp=openmp,
            **kwargs
        )

    #   ------------------------- Overridden methods of pystencils.BoundaryHandling -------------------------

@@ -50,7 +59,7 @@ class LatticeBoltzmannBoundaryHandling(BoundaryHandling):

    def _add_inplace_boundary(self, boundary_obj, flag=None):
        if boundary_obj not in self._boundary_object_to_boundary_info:
            sym_index_field = Field.create_generic('indexField', spatial_dimensions=1,
            sym_index_field = Field.create_generic('indexField', spatial_dimensions=1, field_type=FieldType.INDEXED,
                                                   dtype=numpy_data_type_for_boundary_object(boundary_obj, self.dim))

            ast_even = self._create_boundary_kernel(self._data_handling.fields[self._field_name], sym_index_field,
@@ -65,10 +74,15 @@ class LatticeBoltzmannBoundaryHandling(BoundaryHandling):
        return self._boundary_object_to_boundary_info[boundary_obj].flag

    def _create_boundary_kernel(self, symbolic_field, symbolic_index_field, boundary_obj, prev_timestep=Timestep.BOTH):
        if IS_PYSTENCILS_2:
            additional_args = {"default_dtype": self._default_dtype}
        else:
            additional_args = dict()
            
        return create_lattice_boltzmann_boundary_kernel(
            symbolic_field, symbolic_index_field, self._lb_method, boundary_obj,
            prev_timestep=prev_timestep, streaming_pattern=self._streaming_pattern,
            target=self._target, cpu_openmp=self._openmp)
            target=self._target, cpu_openmp=self._openmp, **additional_args)

    class InplaceStreamingBoundaryInfo(object):

@@ -156,22 +170,69 @@ class LatticeBoltzmannBoundaryHandling(BoundaryHandling):

def create_lattice_boltzmann_boundary_kernel(pdf_field, index_field, lb_method, boundary_functor,
                                             prev_timestep=Timestep.BOTH, streaming_pattern='pull',
                                             target=Target.CPU, **kernel_creation_args):
                                             target=Target.CPU, force_vector=None, **kernel_creation_args):
    from .._compat import IS_PYSTENCILS_2

    indexing = BetweenTimestepsIndexing(
        pdf_field, lb_method.stencil, prev_timestep, streaming_pattern, np.int32, np.int32)

    dim = lb_method.stencil.D
    f_out, f_in = indexing.proxy_fields
    dir_symbol = indexing.dir_symbol
    inv_dir = indexing.inverse_dir_symbol

    boundary_assignments = boundary_functor(f_out, f_in, dir_symbol, inv_dir, lb_method, index_field)
    if IS_PYSTENCILS_2:
        from pystencils.types.quick import SInt
        config = CreateKernelConfig(
            index_field=index_field,
            target=target,
            index_dtype=SInt(32),
            skip_independence_check=True,
            **kernel_creation_args
        )

        default_data_type: PsNumericType = config.get_option("default_dtype")

        if force_vector is None:
            force_vector_type = np.dtype([(f"F_{i}", default_data_type.numpy_dtype) for i in range(dim)], align=True)
            force_vector = Field.create_generic('force_vector', spatial_dimensions=1,
                                                dtype=force_vector_type, field_type=FieldType.INDEXED)

        boundary_assignments = boundary_functor(f_out, f_in, dir_symbol, inv_dir, lb_method, index_field, force_vector)
        boundary_assignments = indexing.substitute_proxies(boundary_assignments)

        if pdf_field.dtype != default_data_type:
            boundary_assignments = add_subexpressions_for_field_reads(boundary_assignments, data_type=default_data_type)

        elements: list[Assignment] = []

        index_arrs_node = indexing.create_code_node()
        elements += index_arrs_node.get_array_declarations()
        
        for node in boundary_functor.get_additional_code_nodes(lb_method)[::-1]:
            elements += node.get_array_declarations()
            
        elements += [Assignment(dir_symbol, index_field[0]('dir'))]
        elements += boundary_assignments.all_assignments

        kernel = create_kernel(elements, config=config)
        return kernel
    else:
        config = CreateKernelConfig(index_fields=[index_field], target=target, default_number_int="int32",
                                    skip_independence_check=True, **kernel_creation_args)

        default_data_type = config.data_type.default_factory()

        if force_vector is None:
            force_vector_type = np.dtype([(f"F_{i}", default_data_type.c_name) for i in range(dim)], align=True)
            force_vector = Field.create_generic('force_vector', spatial_dimensions=1,
                                                dtype=force_vector_type, field_type=FieldType.INDEXED)

        config = replace(config, index_fields=[index_field, force_vector])

        boundary_assignments = boundary_functor(f_out, f_in, dir_symbol, inv_dir, lb_method, index_field, force_vector)
        boundary_assignments = indexing.substitute_proxies(boundary_assignments)

        if pdf_field.dtype != default_data_type:
            boundary_assignments = add_subexpressions_for_field_reads(boundary_assignments, data_type=default_data_type)

Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ class MuskerLaw(ImplicitWallFunctionModel):
        def law(u_p, y_p):
            arctan = sp.Float(5.424) * sp.atan(sp.Float(0.119760479041916168) * y_p - sp.Float(0.488023952095808383))
            logarithm = (sp.Float(0.434) * sp.log((y_p + sp.Float(10.6)) ** sp.Float(9.6)
                                                  / (y_p ** 2 - sp.Float(8.15) * y_p + sp.Float(86)) ** 2, 10))
                                                  / (y_p ** 2 - sp.Float(8.15) * y_p + sp.Float(86)) ** 2))
            return (arctan + logarithm - sp.Float(3.50727901936264842)) - u_p

        u_plus = velocity_symbol / self.u_tau[0]
Original line number Diff line number Diff line
@@ -58,16 +58,16 @@ from dataclasses import dataclass, field, replace
from typing import Union, List, Tuple, Any, Type, Iterable
from warnings import warn, filterwarnings

import lbmpy.moment_transforms
import pystencils.astnodes
from ._compat import IS_PYSTENCILS_2

import sympy as sp
import sympy.core.numbers

from lbmpy.enums import Stencil, Method, ForceModel, CollisionSpace, SubgridScaleModel
import lbmpy.forcemodels as forcemodels
from lbmpy.fieldaccess import CollideOnlyInplaceAccessor, PdfFieldAccessor, PeriodicTwoFieldsAccessor
from lbmpy.fluctuatinglb import add_fluctuations_to_collision_rule
from lbmpy.partially_saturated_cells import add_psm_to_collision_rule, PSMConfig
from lbmpy.partially_saturated_cells import (replace_by_psm_collision_rule, PSMConfig,
                                             add_psm_solid_collision_to_collision_rule)
from lbmpy.non_newtonian_models import add_cassons_model, CassonsParameters
from lbmpy.methods import (create_mrt_orthogonal, create_mrt_raw, create_central_moment,
                           create_srt, create_trt, create_trt_kbc)
@@ -81,17 +81,22 @@ from lbmpy.stencils import LBStencil
from lbmpy.turbulence_models import add_sgs_model
from lbmpy.updatekernels import create_lbm_kernel, create_stream_pull_with_output_kernel
from lbmpy.advanced_streaming.utility import Timestep, get_accessor
from .forcemodels import AbstractForceModel

import pystencils
from pystencils import CreateKernelConfig, create_kernel
from pystencils.astnodes import Conditional, Block
from pystencils.cache import disk_cache_no_fallback
from pystencils.node_collection import NodeCollection
from pystencils.typing import collate_types
from pystencils.field import Field
from pystencils.simp import sympy_cse, SimplificationStrategy
# needed for the docstring
from lbmpy.methods.abstractlbmethod import LbmCollisionRule, AbstractLbMethod
from lbmpy.methods.cumulantbased import CumulantBasedLbMethod

if IS_PYSTENCILS_2:
    from pystencils import Kernel as KernelFunction
else:
    from pystencils.astnodes import KernelFunction

# Filter out JobLib warnings. They are not useful for use:
# https://github.com/joblib/joblib/issues/683
filterwarnings("ignore", message="Persisting input arguments took")
@@ -102,7 +107,7 @@ class LBMConfig:
    """
    **Below all parameters for the LBMConfig are explained**
    """
    stencil: lbmpy.stencils.LBStencil = LBStencil(Stencil.D2Q9)
    stencil: LBStencil = LBStencil(Stencil.D2Q9)
    """
    All stencils are defined in :class:`lbmpy.enums.Stencil`. From that :class:`lbmpy.stencils.LBStencil` 
    class will be created
@@ -161,7 +166,7 @@ class LBMConfig:
    truncated. Order 2 is sufficient to approximate Navier-Stokes. This parameter has no effect on cumulant-based
    methods, whose equilibrium terms have no contributions above order one.
    """
    c_s_sq: sympy.Rational = sp.Rational(1, 3)
    c_s_sq: sp.Expr = sp.Rational(1, 3)
    """
    The squared lattice speed of sound used to derive the LB method. It is very uncommon to use a value different 
    to 1 / 3.
@@ -178,7 +183,7 @@ class LBMConfig:
    If this argument is not provided, Gram-Schmidt orthogonalisation of the default modes is performed.
    """

    force_model: Union[lbmpy.forcemodels.AbstractForceModel, ForceModel] = None
    force_model: Union[AbstractForceModel, ForceModel] = None
    """
    Force model to determine how forcing terms enter the collision rule.
    Possibilities are defined in :class: `lbmpy.enums.ForceModel`
@@ -338,9 +343,9 @@ class LBMConfig:
    Instance of :class:`lbmpy.methods.LbmCollisionRule`. If this parameter is `None`,
    the update rule is derived via *create_lb_update_rule*.
    """
    ast: pystencils.astnodes.KernelFunction = None
    ast: KernelFunction = None
    """
    Instance of *pystencils.astnodes.KernelFunction*. If this parameter is `None`,
    Instance of *pystencils.KernelFunction*. If this parameter is `None`,
    the ast is derived via `create_lb_ast`.
    """

@@ -376,8 +381,8 @@ class LBMConfig:
        if not self.compressible and self.method in (Method.MONOMIAL_CUMULANT, Method.CUMULANT):
            raise ValueError("Incompressible cumulant-based methods are not supported (yet).")

        if self.zero_centered and (self.entropic or self.fluctuating):
            raise ValueError("Entropic and fluctuating methods can only be created with `zero_centered=False`.")
        if self.zero_centered and self.entropic:
            raise ValueError("Entropic methods can only be created with `zero_centered=False`.")

        #   Check or infer delta-equilibrium
        if self.delta_equilibrium is not None:
@@ -468,7 +473,7 @@ class LBMConfig:
        }

        if self.psm_config is not None and self.psm_config.fraction_field is not None:
            self.force = [(1.0 - self.psm_config.fraction_field.center) * f for f in self.force]
            self.force = [(1.0 - self.psm_config.fraction_field_symbol) * f for f in self.force]

        if isinstance(self.force_model, str):
            new_force_model = ForceModel[self.force_model.upper()]
@@ -555,7 +560,6 @@ def create_lb_function(ast=None, lbm_config=None, lbm_optimisation=None, config=

    res.method = ast.method
    res.update_rule = ast.update_rule
    res.ast = ast
    return res


@@ -571,9 +575,7 @@ def create_lb_ast(update_rule=None, lbm_config=None, lbm_optimisation=None, conf
        update_rule = create_lb_update_rule(lbm_config.collision_rule, lbm_config=lbm_config,
                                            lbm_optimisation=lbm_optimisation, config=config)

    field_types = set(fa.field.dtype for fa in update_rule.defined_symbols if isinstance(fa, Field.Access))

    config = replace(config, data_type=collate_types(field_types), ghost_layers=1)
    config = replace(config, ghost_layers=1)
    ast = create_kernel(update_rule, config=config)

    ast.method = update_rule.method
@@ -599,7 +601,11 @@ def create_lb_update_rule(collision_rule=None, lbm_config=None, lbm_optimisation

    lb_method = collision_rule.method

    field_data_type = config.data_type[lbm_config.field_name].numpy_dtype
    if IS_PYSTENCILS_2:
        fallback_field_data_type = config.get_option("default_dtype")
    else:
        fallback_field_data_type = config.data_type[lbm_config.field_name].numpy_dtype

    q = collision_rule.method.stencil.Q

    if lbm_optimisation.symbolic_field is not None:
@@ -607,10 +613,11 @@ def create_lb_update_rule(collision_rule=None, lbm_config=None, lbm_optimisation
    elif lbm_optimisation.field_size:
        field_size = tuple([s + 2 for s in lbm_optimisation.field_size] + [q])
        src_field = Field.create_fixed_size(lbm_config.field_name, field_size, index_dimensions=1,
                                            layout=lbm_optimisation.field_layout, dtype=field_data_type)
                                            layout=lbm_optimisation.field_layout, dtype=fallback_field_data_type)
    else:
        src_field = Field.create_generic(lbm_config.field_name, spatial_dimensions=collision_rule.method.dim,
                                         index_shape=(q,), layout=lbm_optimisation.field_layout, dtype=field_data_type)
                                         index_shape=(q,), layout=lbm_optimisation.field_layout,
                                         dtype=fallback_field_data_type)

    if lbm_optimisation.symbolic_temporary_field is not None:
        dst_field = lbm_optimisation.symbolic_temporary_field
@@ -684,11 +691,6 @@ def create_lb_collision_rule(lb_method=None, lbm_config=None, lbm_optimisation=N
    else:
        collision_rule = lb_method.get_collision_rule(pre_simplification=pre_simplification)

    if lbm_config.psm_config is not None:
        if lbm_config.psm_config.fraction_field is None or lbm_config.psm_config.object_velocity_field is None:
            raise ValueError("Specify a fraction and object velocity field in the PSM Config")
        collision_rule = add_psm_to_collision_rule(collision_rule, lbm_config.psm_config)

    if lbm_config.galilean_correction:
        from lbmpy.methods.cumulantbased import add_galilean_correction
        collision_rule = add_galilean_correction(collision_rule)
@@ -706,6 +708,11 @@ def create_lb_collision_rule(lb_method=None, lbm_config=None, lbm_optimisation=N
                                                     bulk_relaxation_rate=lbm_config.relaxation_rates[1],
                                                     limiter=cumulant_limiter)

    if lbm_config.psm_config is not None:
        if lbm_config.psm_config.fraction_field is None or lbm_config.psm_config.object_velocity_field is None:
            raise ValueError("Specify a fraction and object velocity field in the PSM Config")
        collision_rule = replace_by_psm_collision_rule(collision_rule, lbm_config.psm_config)

    if lbm_config.entropic:
        if lbm_config.subgrid_scale_model or lbm_config.cassons:
            raise ValueError("Choose either entropic, subgrid-scale or cassons")
@@ -783,7 +790,7 @@ def create_lb_method(lbm_config=None, **params):
    if lbm_config.psm_config is None:
        fraction_field = None
    else:
        fraction_field = lbm_config.psm_config.fraction_field
        fraction_field = lbm_config.psm_config.fraction_field_symbol

    common_params = {
        'compressible': lbm_config.compressible,
@@ -869,46 +876,42 @@ def create_lb_method(lbm_config=None, **params):


def create_psm_update_rule(lbm_config, lbm_optimisation):
    node_collection = []
    if IS_PYSTENCILS_2:
        raise NotImplementedError(
            "`create_psm_update_rule` is not yet available when using pystencils 2.0. "
            "To instead derive a (potentially less efficient) PSM kernel without branches, "
            "use `create_lb_update_rule` with a `PsmConfig` object instead."
        )
    
    from pystencils.astnodes import Conditional, Block
    from pystencils.node_collection import NodeCollection

    if lbm_config.psm_config is None:
        raise ValueError("Specify a PSM Config in the LBM Config, when creating a psm update rule")

    config_without_particles = copy.deepcopy(lbm_config)
    config_without_particles.psm_config.max_particles_per_cell = 0

    # Use regular lb update rule for no overlapping particles
    config_without_psm = copy.deepcopy(lbm_config)
    config_without_psm.psm_config = None
    # TODO: the force is still multiplied by (1.0 - self.psm_config.fraction_field.center)
    #  (should not harm if memory bound since self.psm_config.fraction_field.center should always be 0.0)
    lb_update_rule = create_lb_update_rule(
        lbm_config=config_without_psm, lbm_optimisation=lbm_optimisation
    )
    node_collection.append(
        Conditional(
            lbm_config.psm_config.fraction_field.center(0) <= 0.0,
            Block(lb_update_rule.all_assignments),
        )
    )
        lbm_config=config_without_particles, lbm_optimisation=lbm_optimisation)

    node_collection = lb_update_rule.all_assignments

    # Only one particle, i.e., no individual_fraction_field is provided
    if lbm_config.psm_config.individual_fraction_field is None:
        assert lbm_config.psm_config.MaxParticlesPerCell == 1
        psm_update_rule = create_lb_update_rule(
            lbm_config=lbm_config, lbm_optimisation=lbm_optimisation
        )
        node_collection.append(
            Conditional(
                lbm_config.psm_config.fraction_field.center(0) > 0.0,
                Block(psm_update_rule.all_assignments),
            )
        )
        assert lbm_config.psm_config.max_particles_per_cell == 1
        fraction_field = lbm_config.psm_config.fraction_field
    else:
        for p in range(lbm_config.psm_config.MaxParticlesPerCell):
            # Add psm update rule for p overlapping particles
            config_with_p_particles = copy.deepcopy(lbm_config)
            config_with_p_particles.psm_config.MaxParticlesPerCell = p + 1
        fraction_field = lbm_config.psm_config.individual_fraction_field

    for p in range(lbm_config.psm_config.max_particles_per_cell):

        psm_solid_collision = add_psm_solid_collision_to_collision_rule(lb_update_rule, lbm_config, p)
        psm_update_rule = create_lb_update_rule(
                lbm_config=config_with_p_particles, lbm_optimisation=lbm_optimisation
            )
            collision_rule=psm_solid_collision, lbm_config=lbm_config, lbm_optimisation=lbm_optimisation)

        node_collection.append(
            Conditional(
                    lbm_config.psm_config.individual_fraction_field.center(p) > 0.0,
                fraction_field.center(p) > 0.0,
                Block(psm_update_rule.all_assignments),
            )
        )
Original line number Diff line number Diff line
import numpy as np
import sympy as sp

from ._compat import IS_PYSTENCILS_2

if IS_PYSTENCILS_2:
    raise ImportError("`lbmpy.custom_code_nodes` is only available when running with pystencils 1.x")

from pystencils.typing import TypedSymbol, create_type
from pystencils.backends.cbackend import CustomCodeNode

@@ -44,14 +49,14 @@ class MirroredStencilDirections(CustomCodeNode):
        return tuple(direction)

    @staticmethod
    def _mirrored_symbol(mirror_axis):
    def _mirrored_symbol(mirror_axis, _stencil):
        axis = ['x', 'y', 'z']
        return TypedSymbol(f"{axis[mirror_axis]}_axis_mirrored_stencil_dir", create_type('int32'))

    def __init__(self, stencil, mirror_axis, dtype=np.int32):
        offsets_dtype = create_type(dtype)

        mirrored_stencil_symbol = MirroredStencilDirections._mirrored_symbol(mirror_axis)
        mirrored_stencil_symbol = MirroredStencilDirections._mirrored_symbol(mirror_axis, stencil)
        mirrored_directions = [stencil.index(MirroredStencilDirections.mirror_stencil(direction, mirror_axis))
                               for direction in stencil]
        code = "\n"
Original line number Diff line number Diff line
@@ -4,11 +4,12 @@ import sympy as sp

from pystencils import Field
# ------------------------------------------------ Interface -----------------------------------------------------------
from pystencils.astnodes import LoopOverCoordinate

from pystencils.stencil import inverse_direction

from lbmpy.enums import Stencil
from lbmpy.stencils import LBStencil
from ._compat import get_loop_counter_symbol

__all__ = ['PdfFieldAccessor', 'CollideOnlyInplaceAccessor', 'StreamPullTwoFieldsAccessor',
           'AAEvenTimeStepAccessor', 'AAOddTimeStepAccessor',
@@ -114,7 +115,7 @@ class PeriodicTwoFieldsAccessor(PdfFieldAccessor):
                lower_limit = self._ghostLayers
                upper_limit = field.spatial_shape[coord_id] - 1 - self._ghostLayers
                limit_diff = upper_limit - lower_limit
                loop_counter = LoopOverCoordinate.get_loop_counter_symbol(coord_id)
                loop_counter = get_loop_counter_symbol(coord_id)
                if dir_element == 0:
                    periodic_pull_direction.append(0)
                elif dir_element == 1:
Original line number Diff line number Diff line
@@ -4,17 +4,18 @@ import pystencils as ps
from pystencils.field import Field


def welford_assignments(field, mean_field, sum_of_products_field=None):
def welford_assignments(field, mean_field, sum_of_squares_field=None, sum_of_cubes_field=None):
    r"""
    Creates the assignments for the kernel creation of Welford's algorithm
    (https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm).
    This algorithm is an online algorithm for the mean and variance calculation of sample data, here implemented for
    the execution on vector fields, e.g., velocity.
    The calculation of the variance is optional and only performed if a field for the sum of products is given.
    the execution on scalar or vector fields, e.g., velocity.
    The calculation of the variance / the third-order central moments is optional and only performed if a field for
    the sum of squares / sum of cubes is given.

    The mean value is directly updated in the mean vector field.
    The variance must be retrieved in a post-processing step. Let :math `M_{2,n}` denote the value of the sum of
    products after the first :math `n` samples. According to Welford the biased sample variance
    The variance / covariance must be retrieved in a post-processing step. Let :math `M_{2,n}` denote the value of the
    sum of squares after the first :math `n` samples. According to Welford the biased sample variance
    :math `\sigma_n^2` and the unbiased sample variance :math `s_n^2` are given by

    .. math ::
@@ -22,6 +23,9 @@ def welford_assignments(field, mean_field, sum_of_products_field=None):
        s_n^2 = \frac{M_{2,n}}{n-1},

    respectively.

    Liekwise, to the 3rd-order central moment(s) of the (vector) field, the sum of cubes field must be divided
    by :math `n` in a post-processing step.
    """

    if isinstance(field, Field):
@@ -40,22 +44,41 @@ def welford_assignments(field, mean_field, sum_of_products_field=None):
    else:
        raise ValueError("Mean vector field has to be a pystencils Field or Field.Access")

    if sum_of_products_field is None:
        # sum of products will not be calculated, i.e., the variance is not retrievable
        welford_sum_of_products_field = None
    if sum_of_squares_field is None:
        # sum of products will not be calculated, i.e., the covariance matrix is not retrievable
        welford_sum_of_squares_field = None
    else:
        if isinstance(sum_of_squares_field, Field):
            welford_sum_of_squares_field = sum_of_squares_field.center
        elif isinstance(sum_of_squares_field, Field.Access):
            welford_sum_of_squares_field = sum_of_squares_field
        else:
            raise ValueError("Sum of squares field has to be a pystencils Field or Field.Access")

        assert welford_sum_of_squares_field.field.values_per_cell() == dim ** 2, \
            (f"Sum of squares field does not have the right layout. "
             f"Index dimension: {welford_sum_of_squares_field.field.values_per_cell()}, expected: {dim ** 2}")

    if sum_of_cubes_field is None:
        # sum of cubes will not be calculated, i.e., the 3rd-order central moments are not retrievable
        welford_sum_of_cubes_field = None
    else:
        if isinstance(sum_of_products_field, Field):
            welford_sum_of_products_field = sum_of_products_field.center
            assert sum_of_products_field.values_per_cell() == dim**2, \
                (f"Sum of products field does not have the right layout. "
                 f"Index dimension: {sum_of_products_field.values_per_cell()}, expected: {dim**2}")
        elif isinstance(sum_of_products_field, Field.Access):
            welford_sum_of_products_field = sum_of_products_field
            assert sum_of_products_field.field.values_per_cell() == dim**2, \
                (f"Sum of products field does not have the right layout. "
                 f"Index dimension: {sum_of_products_field.field.values_per_cell()}, expected: {dim**2}")
        if isinstance(sum_of_cubes_field, Field):
            welford_sum_of_cubes_field = sum_of_cubes_field.center
        elif isinstance(sum_of_cubes_field, Field.Access):
            welford_sum_of_cubes_field = sum_of_cubes_field
        else:
            raise ValueError("Variance vector field has to be a pystencils Field or Field.Access")
            raise ValueError("Sum of cubes field has to be a pystencils Field or Field.Access")

        assert welford_sum_of_cubes_field.field.values_per_cell() == dim ** 3, \
            (f"Sum of cubes field does not have the right layout. "
             f"Index dimension: {welford_sum_of_cubes_field.field.values_per_cell()}, expected: {dim ** 3}")

    # for the calculation of the thrid-order moments, the variance must also be calculated
    if welford_sum_of_cubes_field is not None:
        assert welford_sum_of_squares_field is not None

    # actual assignments

    counter = sp.Symbol('counter')
    delta = sp.symbols(f"delta_:{dim}")
@@ -67,7 +90,7 @@ def welford_assignments(field, mean_field, sum_of_products_field=None):
        main_assignments.append(ps.Assignment(welford_mean_field.at_index(i),
                                              welford_mean_field.at_index(i) + delta[i] / counter))

    if sum_of_products_field is not None:
    if sum_of_squares_field is not None:
        delta2 = sp.symbols(f"delta2_:{dim}")
        for i in range(dim):
            main_assignments.append(
@@ -76,7 +99,21 @@ def welford_assignments(field, mean_field, sum_of_products_field=None):
            for j in range(dim):
                idx = i * dim + j
                main_assignments.append(ps.Assignment(
                    welford_sum_of_products_field.at_index(idx),
                    welford_sum_of_products_field.at_index(idx) + delta[i] * delta2[j]))
                    welford_sum_of_squares_field.at_index(idx),
                    welford_sum_of_squares_field.at_index(idx) + delta[i] * delta2[j]))

        if sum_of_cubes_field is not None:
            for i in range(dim):
                for j in range(dim):
                    for k in range(dim):
                        idx = (i * dim + j) * dim + k
                        main_assignments.append(ps.Assignment(
                            welford_sum_of_cubes_field.at_index(idx),
                            welford_sum_of_cubes_field.at_index(idx)
                            - delta[k] / counter * welford_sum_of_squares_field(i * dim + j)
                            - delta[j] / counter * welford_sum_of_squares_field(k * dim + i)
                            - delta[i] / counter * welford_sum_of_squares_field(j * dim + k)
                            + delta2[i] * (2 * delta[j] - delta2[j]) * delta[k]
                        ))

    return main_assignments
Original line number Diff line number Diff line
@@ -3,36 +3,84 @@
to generate a fluctuating LBM the equilibrium moment values have to be scaled and an additive (random)
correction term is added to the collision rule
"""
from typing import overload

from ._compat import IS_PYSTENCILS_2

import numpy as np
import sympy as sp

from lbmpy.moments import MOMENT_SYMBOLS, is_shear_moment, get_order
from lbmpy.equilibrium import ContinuousHydrodynamicMaxwellian
from pystencils import Assignment, TypedSymbol
from pystencils.rng import PhiloxFourFloats, random_symbol
from pystencils.simp.assignment_collection import SymbolGen

if IS_PYSTENCILS_2:
    from pystencils.sympyextensions.random import RngBase, Philox
    from pystencils.sympyextensions import tcast
else:
    from pystencils.rng import PhiloxFourFloats, random_symbol


@overload
def add_fluctuations_to_collision_rule(collision_rule, temperature=None, amplitudes=(),
                                       block_offsets=(0, 0, 0), seed=TypedSymbol("seed", np.uint32),
                                       rng_node=PhiloxFourFloats, c_s_sq=sp.Rational(1, 3)):
    """"""
                                       *,
                                       block_offsets, seed, rng_node, c_s_sq):
    """Fluctuating LB implementation for pystencils 1.3"""


@overload
def add_fluctuations_to_collision_rule(collision_rule, temperature=None, amplitudes=(),
                                       *,
                                       rng: 'RngBase | None' = None, c_s_sq):
    """Fluctuating LB implementation for pystencils 2.0
    
    Args:
        collision_rule: The base collision rule
        temperature: Expression representing the fluid temperature
        amplitudes: If ``temperature`` was not specified, expression representing the fluctuation amplitude
        rng: Random number generator instance used to compute the fluctuations.
            If `None`, the float32 Philox RNG will be used.
    """


def add_fluctuations_to_collision_rule(collision_rule, temperature=None, amplitudes=(),
                                       c_s_sq=sp.Rational(1, 3), **kwargs):
    if not (temperature and not amplitudes) or (temperature and amplitudes):
        raise ValueError("Fluctuating LBM: Pass either 'temperature' or 'amplitudes'.")
    if collision_rule.method.conserved_quantity_computation.zero_centered_pdfs:
        raise ValueError("The fluctuating LBM is not implemented for zero-centered PDF storage.")
    
    method = collision_rule.method
    if not amplitudes:
        amplitudes = fluctuation_amplitude_from_temperature(method, temperature, c_s_sq)
    if block_offsets == 'walberla':
        block_offsets = tuple(TypedSymbol("block_offset_{}".format(i), np.uint32) for i in range(3))

    if not method.is_weighted_orthogonal:
        raise ValueError("Fluctuations can only be added to weighted-orthogonal methods")

    rng_symbol_gen = random_symbol(collision_rule.subexpressions, seed=seed,
                                   rng_node=rng_node, dim=method.dim, offsets=block_offsets)
    if IS_PYSTENCILS_2:
        rng: RngBase = kwargs.get("rng", Philox("fluctuation_rng", np.float32, TypedSymbol("seed", np.uint32)))
        ts = TypedSymbol("time_step", np.uint32)

        def _rng_symbol_gen():
            while True:
                rx, rasm = rng.get_random_vector(ts)
                collision_rule.subexpressions.insert(0, rasm)
                for i in range(rng.vector_size):
                    yield tcast.as_numeric(rx[i])

        rng_symbol_gen = _rng_symbol_gen()
    else:
        block_offsets = kwargs.get("block_offsets", (0, 0, 0))
        rng_node = kwargs.get("rng_node", PhiloxFourFloats)
        seed = kwargs.get("seed", TypedSymbol("seed", np.uint32))

        if block_offsets == 'walberla':
            block_offsets = tuple(TypedSymbol("block_offset_{}".format(i), np.uint32) for i in range(3))

        rng_symbol_gen = random_symbol(
            collision_rule.subexpressions, seed=seed,
            rng_node=rng_node, dim=method.dim, offsets=block_offsets
        )

    correction = fluctuation_correction(method, rng_symbol_gen, amplitudes)

    for i, corr in enumerate(correction):
@@ -44,9 +92,7 @@ def fluctuation_amplitude_from_temperature(method, temperature, c_s_sq=sp.Symbol
    """Produces amplitude equations according to (2.60) and (3.54) in Schiller08"""
    normalization_factors = sp.matrix_multiply_elementwise(method.moment_matrix, method.moment_matrix) * \
        sp.Matrix(method.weights)
    density = method.zeroth_order_equilibrium_moment_symbol
    if method.conserved_quantity_computation.zero_centered_pdfs:
        density += 1
    density = method._cqc.density_symbol
    mu = temperature * density / c_s_sq
    return [sp.sqrt(mu * norm * (1 - (1 - rr) ** 2))
            for norm, rr in zip(normalization_factors, method.relaxation_rates)]
Original line number Diff line number Diff line
@@ -10,11 +10,18 @@ from lbmpy.macroscopic_value_kernels import (
    create_advanced_velocity_setter_collision_rule, pdf_initialization_assignments)
from lbmpy.simplificationfactory import create_simplification_strategy
from lbmpy.stencils import LBStencil
from pystencils import create_data_handling, create_kernel, make_slice, Target, Backend

from pystencils import CreateKernelConfig
from pystencils import create_data_handling, create_kernel, make_slice, Target
from pystencils.slicing import SlicedGetter
from pystencils.timeloop import TimeLoop


from ._compat import IS_PYSTENCILS_2
if not IS_PYSTENCILS_2:
    from pystencils import Backend


class LatticeBoltzmannStep:

    def __init__(self, domain_size=None, lbm_kernel=None, periodicity=False,
@@ -24,7 +31,9 @@ class LatticeBoltzmannStep:
                 velocity_input_array_name=None, time_step_order='stream_collide', flag_interface=None,
                 alignment_if_vectorized=64, fixed_loop_sizes=True,
                 timeloop_creation_function=TimeLoop,
                 lbm_config=None, lbm_optimisation=None, config=None, **method_parameters):
                 lbm_config=None, lbm_optimisation=None,
                 config: CreateKernelConfig | None = None,
                 **method_parameters):

        if optimization is None:
            optimization = {}
@@ -36,6 +45,9 @@ class LatticeBoltzmannStep:
                raise ValueError("When passing a data_handling, the domain_size parameter can not be specified")

        if config is not None:
            if IS_PYSTENCILS_2:
                target = config.get_target()
            else:
                target = config.target
        else:
            target = optimization.get('target', Target.CPU)
@@ -60,6 +72,10 @@ class LatticeBoltzmannStep:
                                                                              lbm_config, lbm_optimisation, config)

        # the parallel datahandling understands only numpy datatypes. Strings lead to an errors
        if IS_PYSTENCILS_2:
            from pystencils import create_type
            field_dtype = create_type(config.get_option("default_dtype")).numpy_dtype
        else:
            field_dtype = config.data_type.default_factory().numpy_dtype

        if lbm_kernel:
@@ -75,10 +91,19 @@ class LatticeBoltzmannStep:
        self.density_data_name = name + "_density" if density_data_name is None else density_data_name
        self.density_data_index = density_data_index

        if IS_PYSTENCILS_2:
            self._gpu = target.is_gpu()
        else:
            self._gpu = target == Target.GPU

        layout = lbm_optimisation.field_layout

        alignment = False

        if IS_PYSTENCILS_2:
            if config.get_target().is_vector_cpu() and config.cpu.vectorize.enable:
                alignment = alignment_if_vectorized
        else:
            if config.backend == Backend.C and config.cpu_vectorize_info:
                alignment = alignment_if_vectorized

@@ -150,10 +175,14 @@ class LatticeBoltzmannStep:
        self._sync_tmp = data_handling.synchronization_function([self._tmp_arr_name], stencil_name, target,
                                                                stencil_restricted=True)

        self._boundary_handling = LatticeBoltzmannBoundaryHandling(self.method, self._data_handling, self._pdf_arr_name,
        self._boundary_handling = LatticeBoltzmannBoundaryHandling(
            self.method, self._data_handling, self._pdf_arr_name,
            name=name + "_boundary_handling",
            flag_interface=flag_interface,
                                                                   target=target, openmp=config.cpu_openmp)
            target=target,
            openmp=config.cpu_openmp,
            **({"default_dtype": field_dtype} if IS_PYSTENCILS_2 else dict())
        )

        self._lbm_config = lbm_config
        self._lbm_optimisation = lbm_optimisation
@@ -223,7 +252,7 @@ class LatticeBoltzmannStep:
    @property
    def config(self):
        """Configutation of pystencils parameters"""
        return self.config
        return self._config

    def _get_slice(self, data_name, slice_obj, masked):
        if slice_obj is None:
@@ -439,12 +468,19 @@ class LatticeBoltzmannStep:
        rho_field = rho_field.center if self.density_data_index is None else rho_field(self.density_data_index)
        vel_field = self._data_handling.fields[self.velocity_data_name]

        if IS_PYSTENCILS_2:
            gen_config = CreateKernelConfig(target=Target.CPU)
            gen_config.cpu.openmp.enable = self._config.cpu.openmp.get_option("enable")
            gen_config.default_dtype = self._config.get_option("default_dtype")
        else:
            gen_config = CreateKernelConfig(target=Target.CPU, cpu_openmp=self._config.cpu_openmp)

        getter_eqs = cqc.output_equations_from_pdfs(pdf_field.center_vector,
                                                    {'density': rho_field, 'velocity': vel_field})
        getter_kernel = create_kernel(getter_eqs, target=Target.CPU, cpu_openmp=self._config.cpu_openmp).compile()
        getter_kernel = create_kernel(getter_eqs, config=gen_config).compile()

        setter_eqs = pdf_initialization_assignments(lb_method, rho_field,
                                                    vel_field.center_vector, pdf_field.center_vector)
        setter_eqs = create_simplification_strategy(lb_method)(setter_eqs)
        setter_kernel = create_kernel(setter_eqs, target=Target.CPU, cpu_openmp=self._config.cpu_openmp).compile()
        setter_kernel = create_kernel(setter_eqs, config=gen_config).compile()
        return getter_kernel, setter_kernel
+128 −0
Original line number Diff line number Diff line
from typing import Sequence, Any
from abc import ABC, abstractmethod
import numpy as np
import sympy as sp

from ._compat import IS_PYSTENCILS_2

if not IS_PYSTENCILS_2:
    raise ImportError("`lbmpy.lookup_tables` is only available when running with pystencils 2.x")

from pystencils import Assignment
from pystencils.sympyextensions import TypedSymbol
from pystencils.types.quick import Arr
from pystencils.types import UserTypeSpec, create_type


class LookupTables(ABC):
    @abstractmethod
    def get_array_declarations(self) -> list[Assignment]:
        pass


class NeighbourOffsetArrays(LookupTables):

    @staticmethod
    def neighbour_offset(dir_idx, stencil):
        if isinstance(sp.sympify(dir_idx), sp.Integer):
            return stencil[dir_idx]
        else:
            return tuple(
                [
                    sp.IndexedBase(symbol, shape=(1,))[dir_idx]
                    for symbol in NeighbourOffsetArrays._offset_symbols(stencil)
                ]
            )

    @staticmethod
    def _offset_symbols(stencil):
        q = len(stencil)
        dim = len(stencil[0])
        return [
            TypedSymbol(f"neighbour_offset_{d}", Arr(create_type("int32"), q))
            for d in ["x", "y", "z"][:dim]
        ]

    def __init__(self, stencil, offsets_dtype: UserTypeSpec = np.int32):
        self._offsets_dtype = create_type(
            offsets_dtype
        )  # TODO: Currently, this has no effect
        self._stencil = stencil
        self._dim = len(stencil[0])

    def get_array_declarations(self) -> list[Assignment]:
        array_symbols = NeighbourOffsetArrays._offset_symbols(self._stencil)
        return [
            Assignment(arrsymb, tuple((d[i] for d in self._stencil)))
            for i, arrsymb in enumerate(array_symbols)
        ]


class MirroredStencilDirections(LookupTables):

    @staticmethod
    def mirror_stencil(direction, mirror_axis):
        assert mirror_axis <= len(
            direction
        ), f"only {len(direction)} axis available for mirage"
        direction = list(direction)
        direction[mirror_axis] = -direction[mirror_axis]

        return tuple(direction)

    @staticmethod
    def _mirrored_symbol(mirror_axis, stencil):
        axis = ["x", "y", "z"]
        q = len(stencil)
        return TypedSymbol(
            f"{axis[mirror_axis]}_axis_mirrored_stencil_dir", Arr(create_type("int32"), q)
        )

    def __init__(self, stencil, mirror_axis, dtype=np.int32):
        self._offsets_dtype = create_type(dtype)  # TODO: Currently, this has no effect

        self._mirrored_stencil_symbol = MirroredStencilDirections._mirrored_symbol(
            mirror_axis, stencil
        )
        self._mirrored_directions = tuple(
            stencil.index(
                MirroredStencilDirections.mirror_stencil(direction, mirror_axis)
            )
            for direction in stencil
        )

    def get_array_declarations(self) -> list[Assignment]:
        return [Assignment(self._mirrored_stencil_symbol, self._mirrored_directions)]


class LbmWeightInfo(LookupTables):
    def __init__(self, lb_method, data_type="double"):
        self._weights = lb_method.weights
        self._weights_array = TypedSymbol("weights", Arr(create_type(data_type), len(self._weights)))

    def weight_of_direction(self, dir_idx, lb_method=None):
        if isinstance(sp.sympify(dir_idx), sp.Integer):
            assert lb_method is not None
            return lb_method.weights[dir_idx].evalf(17)
        else:
            return sp.IndexedBase(self._weights_array, shape=(1,))[dir_idx]

    def get_array_declarations(self) -> list[Assignment]:
        return [Assignment(self._weights_array, tuple(self._weights))]


class TranslationArraysNode(LookupTables):

    def __init__(self, array_content: Sequence[tuple[TypedSymbol, Sequence[Any]]]):
        self._decls = [
            Assignment(symb, tuple(content)) for symb, content in array_content
        ]

    def __str__(self):
        return "Variable PDF Access Translation Arrays"

    def __repr__(self):
        return "Variable PDF Access Translation Arrays"

    def get_array_declarations(self) -> list[Assignment]:
        return self._decls
Original line number Diff line number Diff line
import functools
import sympy as sp
from copy import deepcopy
from lbmpy.simplificationfactory import create_simplification_strategy
from pystencils import create_kernel, CreateKernelConfig
from pystencils import create_kernel, CreateKernelConfig, Assignment
from pystencils.field import Field, get_layout_of_array
from pystencils.enums import Target
from pystencils import Target

from lbmpy.advanced_streaming.utility import get_accessor, Timestep
from lbmpy.relaxationrates import get_shear_relaxation_rate
from lbmpy.utils import second_order_moment_tensor


def pdf_initialization_assignments(lb_method, density, velocity, pdfs,
                                   streaming_pattern='pull', previous_timestep=Timestep.BOTH,
                                   set_pre_collision_pdfs=False):
    """Assignments to initialize the pdf field with equilibrium"""
def get_field_accesses(lb_method, pdfs, streaming_pattern, previous_timestep, pre_collision_pdfs):
    if isinstance(pdfs, Field):
        accessor = get_accessor(streaming_pattern, previous_timestep)
        if set_pre_collision_pdfs:
        if pre_collision_pdfs:
            field_accesses = accessor.read(pdfs, lb_method.stencil)
        else:
            field_accesses = accessor.write(pdfs, lb_method.stencil)
    elif streaming_pattern == 'pull' and not set_pre_collision_pdfs:
    elif streaming_pattern == 'pull' and not pre_collision_pdfs:
        field_accesses = pdfs
    else:
        raise ValueError("Invalid value of pdfs: A PDF field reference is required to derive "
                         + f"initialization assignments for streaming pattern {streaming_pattern}.")
    return field_accesses


def get_individual_or_common_fraction_field(psm_config):
    if psm_config.individual_fraction_field is not None:
        return psm_config.individual_fraction_field
    else:
        return psm_config.fraction_field


def pdf_initialization_assignments(lb_method, density, velocity, pdfs, psm_config=None,
                                   streaming_pattern='pull', previous_timestep=Timestep.BOTH,
                                   set_pre_collision_pdfs=False):
    """Assignments to initialize the pdf field with equilibrium"""
    field_accesses = get_field_accesses(lb_method, pdfs, streaming_pattern, previous_timestep, set_pre_collision_pdfs)

    if isinstance(density, Field):
        density = density.center

    if isinstance(velocity, Field):
        velocity = velocity.center_vector

@@ -35,23 +49,40 @@ def pdf_initialization_assignments(lb_method, density, velocity, pdfs,
    setter_eqs = lb_method.get_equilibrium(conserved_quantity_equations=inp_eqs)
    setter_eqs = setter_eqs.new_with_substitutions({sym: field_accesses[i]
                                                    for i, sym in enumerate(lb_method.post_collision_pdf_symbols)})

    if lb_method.fraction_field is not None:
        if psm_config is None:
            raise ValueError("If setting up LBM with PSM, please specify a PSM config in the macroscopic setter")
        else:
            for equ in setter_eqs:
                if equ.lhs in lb_method.first_order_equilibrium_moment_symbols:
                    pos = lb_method.first_order_equilibrium_moment_symbols.index(equ.lhs)
                    new_rhs = 0
                    if isinstance(equ.rhs, sp.core.Add):
                        for summand in equ.rhs.args:
                            if summand in velocity:
                                new_rhs += (1.0 - psm_config.fraction_field.center) * summand
                            else:
                                new_rhs += summand.subs(lb_method.fraction_field, psm_config.fraction_field.center)
                    else:
                        new_rhs += (1.0 - psm_config.fraction_field.center) * equ.rhs

                    fraction_field = get_individual_or_common_fraction_field(psm_config)
                    for p in range(psm_config.max_particles_per_cell):
                        new_rhs += psm_config.object_velocity_field(p * lb_method.dim + pos) * fraction_field.center(p)

                    setter_eqs.subexpressions.remove(equ)
                    setter_eqs.subexpressions.append(Assignment(equ.lhs, new_rhs))

    return setter_eqs


def macroscopic_values_getter(lb_method, density, velocity, pdfs,
def macroscopic_values_getter(lb_method, density, velocity, pdfs, psm_config=None,
                              streaming_pattern='pull', previous_timestep=Timestep.BOTH,
                              use_pre_collision_pdfs=False):
    if isinstance(pdfs, Field):
        accessor = get_accessor(streaming_pattern, previous_timestep)
        if use_pre_collision_pdfs:
            field_accesses = accessor.read(pdfs, lb_method.stencil)
        else:
            field_accesses = accessor.write(pdfs, lb_method.stencil)
    elif streaming_pattern == 'pull' and not use_pre_collision_pdfs:
        field_accesses = pdfs
    else:
        raise ValueError("Invalid value of pdfs: A PDF field reference is required to derive "
                         + f"getter assignments for streaming pattern {streaming_pattern}.")

    field_accesses = get_field_accesses(lb_method, pdfs, streaming_pattern, previous_timestep, use_pre_collision_pdfs)

    cqc = lb_method.conserved_quantity_computation
    assert not (velocity is None and density is None)
    output_spec = {}
@@ -59,12 +90,54 @@ def macroscopic_values_getter(lb_method, density, velocity, pdfs,
        output_spec['velocity'] = velocity
    if density is not None:
        output_spec['density'] = density
    return cqc.output_equations_from_pdfs(field_accesses, output_spec)
    getter_equ = cqc.output_equations_from_pdfs(field_accesses, output_spec)

    if lb_method.fraction_field is not None:
        if psm_config.fraction_field is None:
            raise ValueError("If setting up LBM with PSM, please specify a PSM config in the macroscopic getter")
        else:
            if lb_method.force_model is not None:
                for equ in getter_equ:
                    if equ.lhs in lb_method.force_model.symbolic_force_vector:
                        new_rhs = equ.rhs.subs(lb_method.fraction_field, psm_config.fraction_field.center)
                        getter_equ.subexpressions.remove(equ)
                        getter_equ.subexpressions.append(Assignment(equ.lhs, new_rhs))

            for i, equ in enumerate(getter_equ.main_assignments[-lb_method.dim:]):
                new_rhs = (1.0 - psm_config.fraction_field.center) * equ.rhs
                fraction_field = get_individual_or_common_fraction_field(psm_config)
                for p in range(psm_config.max_particles_per_cell):
                    new_rhs += psm_config.object_velocity_field(p * lb_method.dim + i) * fraction_field.center(p)
                getter_equ.main_assignments.remove(equ)
                getter_equ.main_assignments.append(Assignment(equ.lhs, new_rhs))
        getter_equ.topological_sort()
    return getter_equ


macroscopic_values_setter = pdf_initialization_assignments


def strain_rate_tensor_getter(lb_method, strain_rate_tensor, pdfs, streaming_pattern='pull',
                              previous_timestep=Timestep.BOTH, use_pre_collision_pdfs=False):

    field_accesses = get_field_accesses(lb_method, pdfs, streaming_pattern, previous_timestep, use_pre_collision_pdfs)

    if isinstance(strain_rate_tensor, Field):
        strain_rate_tensor = strain_rate_tensor.center_vector

    omega_s = get_shear_relaxation_rate(lb_method)
    equilibrium = lb_method.equilibrium_distribution
    rho = equilibrium.density if equilibrium.compressible else equilibrium.background_density

    f_neq = sp.Matrix([field_accesses[i] for i in range(lb_method.stencil.Q)]) - lb_method.get_equilibrium_terms()
    pi = second_order_moment_tensor(f_neq, lb_method.stencil)
    strain_rate_tensor_equ = - 1.5 * (omega_s / rho) * pi

    assignments = [Assignment(strain_rate_tensor[i * lb_method.stencil.D + j], strain_rate_tensor_equ[i, j])
                   for i in range(lb_method.stencil.D) for j in range(lb_method.stencil.D)]
    return assignments


def compile_macroscopic_values_getter(lb_method, output_quantities, pdf_arr=None,
                                      ghost_layers=1, iteration_slice=None,
                                      field_layout='numpy', target=Target.CPU,
Original line number Diff line number Diff line
@@ -18,51 +18,106 @@ from pystencils.cache import disk_cache
from pystencils.sympyextensions import remove_higher_order_terms

from lbmpy.moments import MOMENT_SYMBOLS
from lbmpy.continuous_distribution_measures import continuous_moment, continuous_central_moment, continuous_cumulant
from lbmpy.continuous_distribution_measures import (
    continuous_moment,
    continuous_central_moment,
    continuous_cumulant,
)


def get_weights(stencil, c_s_sq=sp.Rational(1, 3)):
    if c_s_sq != sp.Rational(1, 3) and c_s_sq != sp.Symbol("c_s") ** 2:
        warnings.warn("Weights of discrete equilibrium are only valid if c_s^2 = 1/3")

def get_weights(stencil):
    def weight_for_direction(direction):
        abs_sum = sum([abs(d) for d in direction])
        return get_weights.weights[stencil.Q][abs_sum]
        squared_length = sum([d**2 for d in direction])
        return get_weights.weights[stencil.D][stencil.Q][squared_length]

    return [weight_for_direction(d) for d in stencil]


get_weights.weights = {
    9: {
get_weights.weights = dict(
    {
        2: dict(
            {
                9: dict(
                    {
                        0: sp.Rational(4, 9),
                        1: sp.Rational(1, 9),
                        2: sp.Rational(1, 36),
    },
    7: {
                    }
                ),
                # weights taken from Coreixas et al. (2017), PRE.
                # https://doi.org/10.1103/PhysRevE.96.033306
                # (Appendix D Table 1)
                17: dict(
                    {
                        0: sp.S((575 + 193 * sp.sqrt(193)) / 8100),
                        1: sp.S((3355 - 91 * sp.sqrt(193)) / 18000),
                        2: sp.S((655 + 17 * sp.sqrt(193)) / 27000),
                        8: sp.S((685 - 49 * sp.sqrt(193)) / 54000),
                        9: sp.S((1445 - 101 * sp.sqrt(193)) / 162000),
                    }
                ),
                # weights taken from Coreixas et al. (2017), PRE.
                # https://doi.org/10.1103/PhysRevE.96.033306
                # (Appendix D Table 1)
                37: dict(
                    {
                        0: sp.S(0.23315066913235250228650),
                        1: sp.S(0.10730609154221900241246),
                        2: sp.S(0.05766785988879488203006),
                        4: sp.S(0.01420821615845075026469),
                        5: sp.S(0.00535304900051377523273),
                        8: sp.S(0.00101193759267357547541),
                        9: sp.S(0.00024530102775771734547),
                        10: sp.S(0.00028341425299419821740),
                    }
                ),
            }
        ),
        3: dict(
            {
                7: dict(
                    {
                        0: Zero(),
                        1: sp.Rational(1, 6),
    },
    15: {
                    }
                ),
                15: dict(
                    {
                        0: sp.Rational(2, 9),
                        1: sp.Rational(1, 9),
                        3: sp.Rational(1, 72),
    },
    19: {
                    }
                ),
                19: dict(
                    {
                        0: sp.Rational(1, 3),
                        1: sp.Rational(1, 18),
                        2: sp.Rational(1, 36),
    },
    27: {
                    }
                ),
                27: dict(
                    {
                        0: sp.Rational(8, 27),
                        1: sp.Rational(2, 27),
                        2: sp.Rational(1, 54),
                        3: sp.Rational(1, 216),
                    }
                ),
            }
        ),
    }
)


@disk_cache
def discrete_maxwellian_equilibrium(stencil, rho=sp.Symbol("rho"), u=sp.symbols("u_:3"), order=2,
                                    c_s_sq=sp.Symbol("c_s") ** 2, compressible=True):
def discrete_maxwellian_equilibrium(
    stencil,
    rho=sp.Symbol("rho"),
    u=sp.symbols("u_:3"),
    order=2,
    c_s_sq=sp.Symbol("c_s") ** 2,
    compressible=True,
):
    """
    Returns the common discrete LBM equilibrium as a list of sympy expressions

@@ -74,16 +129,26 @@ def discrete_maxwellian_equilibrium(stencil, rho=sp.Symbol("rho"), u=sp.symbols(
        c_s_sq: square of speed of sound
        compressible: compressibility
    """
    weights = get_weights(stencil, c_s_sq)
    weights = get_weights(stencil)
    assert stencil.Q == len(weights)
    u = u[: stencil.D]

    res = [discrete_equilibrium(e_q, u, rho, w_q, order, c_s_sq, compressible) for w_q, e_q in zip(weights, stencil)]
    res = [
        discrete_equilibrium(e_q, u, rho, w_q, order, c_s_sq, compressible)
        for w_q, e_q in zip(weights, stencil)
    ]
    return tuple(res)


def discrete_equilibrium(v=sp.symbols("v_:3"), u=sp.symbols("u_:3"), rho=sp.Symbol("rho"), weight=sp.Symbol("w"),
                         order=2, c_s_sq=sp.Symbol("c_s") ** 2, compressible=True):
def discrete_equilibrium(
    v=sp.symbols("v_:3"),
    u=sp.symbols("u_:3"),
    rho=sp.Symbol("rho"),
    weight=sp.Symbol("w"),
    order=2,
    c_s_sq=sp.Symbol("c_s") ** 2,
    compressible=True,
):
    """
    Returns the common discrete LBM equilibrium depending on the mesoscopic velocity and the directional lattice weight

@@ -111,39 +176,60 @@ def discrete_equilibrium(v=sp.symbols("v_:3"), u=sp.symbols("u_:3"), rho=sp.Symb
    u_times_u = 0
    for u_alpha in u:
        u_times_u += u_alpha * u_alpha
    fq += sp.Rational(1, 2) / c_s_sq**2 * e_times_u ** 2 - sp.Rational(1, 2) / c_s_sq * u_times_u
    fq += (
        sp.Rational(1, 2) / c_s_sq**2 * e_times_u**2
        - sp.Rational(1, 2) / c_s_sq * u_times_u
    )

    if order <= 2:
        return fq * rho_outside * weight

    fq += sp.Rational(1, 6) / c_s_sq**3 * e_times_u**3 - sp.Rational(1, 2) / c_s_sq**2 * u_times_u * e_times_u
    fq += (
        sp.Rational(1, 6) / c_s_sq**3 * e_times_u**3
        - sp.Rational(1, 2) / c_s_sq**2 * u_times_u * e_times_u
    )

    return sp.expand(fq * rho_outside * weight)


@disk_cache
def generate_equilibrium_by_matching_moments(stencil, moments, rho=sp.Symbol("rho"), u=sp.symbols("u_:3"),
                                             c_s_sq=sp.Symbol("c_s") ** 2, order=None):
def generate_equilibrium_by_matching_moments(
    stencil,
    moments,
    rho=sp.Symbol("rho"),
    u=sp.symbols("u_:3"),
    c_s_sq=sp.Symbol("c_s") ** 2,
    order=None,
):
    """
    Computes discrete equilibrium, by setting the discrete moments to values taken from the continuous Maxwellian.
    The number of moments has to match the number of directions in the stencil. For documentation of other parameters
    see :func:`get_equilibrium_values_of_maxwell_boltzmann_function`
    """
    from lbmpy.moments import moment_matrix
    assert len(moments) == stencil.Q, f"Moment count({len(moments)}) does not match stencil size({stencil.Q})"
    continuous_moments_vector = get_equilibrium_values_of_maxwell_boltzmann_function(moments, stencil.D, rho, u, c_s_sq,
                                                                                     order, space="moment")

    assert (
        len(moments) == stencil.Q
    ), f"Moment count({len(moments)}) does not match stencil size({stencil.Q})"
    continuous_moments_vector = get_equilibrium_values_of_maxwell_boltzmann_function(
        moments, stencil.D, rho, u, c_s_sq, order, space="moment"
    )
    continuous_moments_vector = sp.Matrix(continuous_moments_vector)
    M = moment_matrix(moments, stencil)
    assert M.rank() == stencil.Q, f"Rank of moment matrix ({M.rank()}) does not match stencil size ({stencil.Q})"
    assert (
        M.rank() == stencil.Q
    ), f"Rank of moment matrix ({M.rank()}) does not match stencil size ({stencil.Q})"
    return M.inv() * continuous_moments_vector


@disk_cache
def continuous_maxwellian_equilibrium(dim=3, rho=sp.Symbol("rho"),
def continuous_maxwellian_equilibrium(
    dim=3,
    rho=sp.Symbol("rho"),
    u=sp.symbols("u_:3"),
    v=sp.symbols("v_:3"),
                                      c_s_sq=sp.Symbol("c_s") ** 2):
    c_s_sq=sp.Symbol("c_s") ** 2,
):
    """
    Returns sympy expression of Maxwell Boltzmann distribution

@@ -158,15 +244,24 @@ def continuous_maxwellian_equilibrium(dim=3, rho=sp.Symbol("rho"),
    v = v[:dim]

    vel_term = sum([(v_i - u_i) ** 2 for v_i, u_i in zip(v, u)])
    return rho / (2 * sp.pi * c_s_sq) ** (sp.Rational(dim, 2)) * sp.exp(- vel_term / (2 * c_s_sq))
    return (
        rho
        / (2 * sp.pi * c_s_sq) ** (sp.Rational(dim, 2))
        * sp.exp(-vel_term / (2 * c_s_sq))
    )


# -------------------------------- Equilibrium moments  ----------------------------------------------------------------
@disk_cache
def get_equilibrium_values_of_maxwell_boltzmann_function(moments, dim, rho=sp.Symbol("rho"),
def get_equilibrium_values_of_maxwell_boltzmann_function(
    moments,
    dim,
    rho=sp.Symbol("rho"),
    u=sp.symbols("u_:3"),
                                                         c_s_sq=sp.Symbol("c_s") ** 2, order=None,
                                                         space="moment"):
    c_s_sq=sp.Symbol("c_s") ** 2,
    order=None,
    space="moment",
):
    """
    Computes equilibrium values from the continuous Maxwell Boltzmann equilibrium.

@@ -186,16 +281,30 @@ def get_equilibrium_values_of_maxwell_boltzmann_function(moments, dim, rho=sp.Sy
    # trick to speed up sympy integration (otherwise it takes multiple minutes, or aborts):
    # use a positive, real symbol to represent c_s_sq -> then replace this symbol afterwards with the real c_s_sq
    c_s_sq_helper = sp.Symbol("csq_helper", positive=True, real=True)
    mb = continuous_maxwellian_equilibrium(dim, rho, u, MOMENT_SYMBOLS[:dim], c_s_sq_helper)
    mb = continuous_maxwellian_equilibrium(
        dim, rho, u, MOMENT_SYMBOLS[:dim], c_s_sq_helper
    )
    if space == "moment":
        result = [continuous_moment(mb, moment, MOMENT_SYMBOLS[:dim]).subs(c_s_sq_helper, c_s_sq)
                  for moment in moments]
        result = [
            continuous_moment(mb, moment, MOMENT_SYMBOLS[:dim]).subs(
                c_s_sq_helper, c_s_sq
            )
            for moment in moments
        ]
    elif space == "central moment":
        result = [continuous_central_moment(mb, moment, MOMENT_SYMBOLS[:dim], velocity=u).subs(c_s_sq_helper, c_s_sq)
                  for moment in moments]
        result = [
            continuous_central_moment(
                mb, moment, MOMENT_SYMBOLS[:dim], velocity=u
            ).subs(c_s_sq_helper, c_s_sq)
            for moment in moments
        ]
    elif space == "cumulant":
        result = [continuous_cumulant(mb, moment, MOMENT_SYMBOLS[:dim]).subs(c_s_sq_helper, c_s_sq)
                  for moment in moments]
        result = [
            continuous_cumulant(mb, moment, MOMENT_SYMBOLS[:dim]).subs(
                c_s_sq_helper, c_s_sq
            )
            for moment in moments
        ]
    else:
        raise ValueError("Only moment, central moment or cumulant space are supported")

@@ -206,9 +315,15 @@ def get_equilibrium_values_of_maxwell_boltzmann_function(moments, dim, rho=sp.Sy


@disk_cache
def get_moments_of_discrete_maxwellian_equilibrium(stencil, moments,
                                                   rho=sp.Symbol("rho"), u=sp.symbols("u_:3"),
                                                   c_s_sq=sp.Symbol("c_s") ** 2, order=None, compressible=True):
def get_moments_of_discrete_maxwellian_equilibrium(
    stencil,
    moments,
    rho=sp.Symbol("rho"),
    u=sp.symbols("u_:3"),
    c_s_sq=sp.Symbol("c_s") ** 2,
    order=None,
    compressible=True,
):
    """Compute moments of discrete maxwellian equilibrium.

    Args:
@@ -221,6 +336,7 @@ def get_moments_of_discrete_maxwellian_equilibrium(stencil, moments,
        compressible: compressible or incompressible form
    """
    from lbmpy.moments import discrete_moment

    if order is None:
        order = 4
    mb = discrete_maxwellian_equilibrium(stencil, rho, u, order, c_s_sq, compressible)
@@ -246,12 +362,16 @@ def compressible_to_incompressible_moment_value(term, rho, u):
    Returns:
        incompressible equilibrium value
    """
    warnings.warn("Usage of `compressible_to_incompressible_moment_value` is deprecated,"
                  " and the method will be removed soon.")
    warnings.warn(
        "Usage of `compressible_to_incompressible_moment_value` is deprecated,"
        " and the method will be removed soon."
    )
    term = sp.sympify(term)
    term = term.expand()
    if term.func != sp.Add:
        args = [term, ]
        args = [
            term,
        ]
    else:
        args = term.args

@@ -264,15 +384,25 @@ def compressible_to_incompressible_moment_value(term, rho, u):
            res += t
    return res


# -------------------------------- Equilibrium cumulants ---------------------------------------------------------------


@disk_cache
def get_cumulants_of_discrete_maxwellian_equilibrium(stencil, cumulants,
                                                     rho=sp.Symbol("rho"), u=sp.symbols("u_:3"),
                                                     c_s_sq=sp.Symbol("c_s") ** 2, order=None, compressible=True):
def get_cumulants_of_discrete_maxwellian_equilibrium(
    stencil,
    cumulants,
    rho=sp.Symbol("rho"),
    u=sp.symbols("u_:3"),
    c_s_sq=sp.Symbol("c_s") ** 2,
    order=None,
    compressible=True,
):
    from lbmpy.cumulants import discrete_cumulant

    if order is None:
        order = 4
    mb = discrete_maxwellian_equilibrium(stencil, rho, u, order, c_s_sq, compressible)
    return tuple([discrete_cumulant(mb, cumulant, stencil).expand() for cumulant in cumulants])
    return tuple(
        [discrete_cumulant(mb, cumulant, stencil).expand() for cumulant in cumulants]
    )
Original line number Diff line number Diff line
@@ -105,22 +105,27 @@ class AbstractLbMethod(abc.ABC):
        the subexpressions, that assign the number to the newly introduced symbol
        """
        rr = relaxation_rates if relaxation_rates is not None else self.relaxation_rates
        unique_relaxation_rates = set()
        subexpressions = {}
        symbolic_relaxation_rates = list()
        for relaxation_rate in rr:
            relaxation_rate = sp.sympify(relaxation_rate)
            if relaxation_rate not in unique_relaxation_rates:
                # special treatment for zero, sp.Zero would be an integer ..
            if isinstance(relaxation_rate, sp.Symbol):
                symbolic_relaxation_rate = relaxation_rate
            else:
                if isinstance(relaxation_rate, Zero):
                    relaxation_rate = 0.0
                if not isinstance(relaxation_rate, sp.Symbol):
                    rt_symbol = sp.Symbol(f"rr_{len(subexpressions)}")
                    subexpressions[relaxation_rate] = rt_symbol
            unique_relaxation_rates.add(relaxation_rate)
                if relaxation_rate in subexpressions:
                    symbolic_relaxation_rate = subexpressions[relaxation_rate]
                else:
                    symbolic_relaxation_rate = sp.Symbol(f"rr_{len(subexpressions)}")
                    subexpressions[relaxation_rate] = symbolic_relaxation_rate
            symbolic_relaxation_rates.append(symbolic_relaxation_rate)

        new_rr = [subexpressions[sp.sympify(e)] if sp.sympify(e) in subexpressions else e for e in rr]
        substitutions = [Assignment(e[1], e[0]) for e in subexpressions.items()]
        if relaxation_rates_modifier is not None:
            new_rr = [r * relaxation_rates_modifier for r in new_rr]
            symbolic_relaxation_rates = [r * relaxation_rates_modifier for r in symbolic_relaxation_rates]
        else:
            for srr in symbolic_relaxation_rates:
                assert isinstance(srr, sp.Symbol)

        return substitutions, sp.diag(*new_rr)
        return substitutions, sp.diag(*symbolic_relaxation_rates)
Original line number Diff line number Diff line
@@ -201,19 +201,23 @@ def create_from_equilibrium(stencil, equilibrium, conserved_quantity_computation

    if cspace.collision_space == CollisionSpace.POPULATIONS:
        return MomentBasedLbMethod(stencil, equilibrium, mom_to_rr_dict, conserved_quantity_computation=cqc,
                                   force_model=force_model, zero_centered=zero_centered, fraction_field=fraction_field,
                                   force_model=force_model, zero_centered=zero_centered,
                                   fraction_field=fraction_field,
                                   moment_transform_class=None)
    elif cspace.collision_space == CollisionSpace.RAW_MOMENTS:
        return MomentBasedLbMethod(stencil, equilibrium, mom_to_rr_dict, conserved_quantity_computation=cqc,
                                   force_model=force_model, zero_centered=zero_centered, fraction_field=fraction_field,
                                   force_model=force_model, zero_centered=zero_centered,
                                   fraction_field=fraction_field,
                                   moment_transform_class=cspace.raw_moment_transform_class)
    elif cspace.collision_space == CollisionSpace.CENTRAL_MOMENTS:
        return CentralMomentBasedLbMethod(stencil, equilibrium, mom_to_rr_dict, conserved_quantity_computation=cqc,
                                          force_model=force_model, zero_centered=zero_centered,
                                          fraction_field=fraction_field,
                                          central_moment_transform_class=cspace.central_moment_transform_class)
    elif cspace.collision_space == CollisionSpace.CUMULANTS:
        return CumulantBasedLbMethod(stencil, equilibrium, mom_to_rr_dict, conserved_quantity_computation=cqc,
                                     force_model=force_model, zero_centered=zero_centered,
                                     fraction_field=fraction_field,
                                     central_moment_transform_class=cspace.central_moment_transform_class,
                                     cumulant_transform_class=cspace.cumulant_transform_class)

@@ -334,7 +338,7 @@ def create_mrt_raw(stencil, relaxation_rates, continuous_equilibrium=True, conse


def create_central_moment(stencil, relaxation_rates, nested_moments=None,
                          continuous_equilibrium=True, conserved_moments=True, fraction_field=None, **kwargs):
                          continuous_equilibrium=True, conserved_moments=True, **kwargs):
    r"""
    Creates moment based LB method where the collision takes place in the central moment space.

@@ -348,7 +352,6 @@ def create_central_moment(stencil, relaxation_rates, nested_moments=None,
        continuous_equilibrium: determines if the discrete or continuous maxwellian equilibrium is
                        used to compute the equilibrium moments.
        conserved_moments: If lower order moments are conserved or not.
        fraction_field: fraction field for the PSM method
    Returns:
        :class:`lbmpy.methods.momentbased.CentralMomentBasedLbMethod` instance
    """
@@ -371,8 +374,8 @@ def create_central_moment(stencil, relaxation_rates, nested_moments=None,
        nested_moments = cascaded_moment_sets_literature(stencil)

    rr_dict = _get_relaxation_info_dict(relaxation_rates, nested_moments, stencil.D, conserved_moments)
    if fraction_field is not None:
        relaxation_rates_modifier = (1.0 - fraction_field.center)
    if 'fraction_field' in kwargs and kwargs['fraction_field'] is not None:
        relaxation_rates_modifier = (1.0 - kwargs['fraction_field'])
        rr_dict = _get_relaxation_info_dict(relaxation_rates, nested_moments, stencil.D,
                                            relaxation_rates_modifier=relaxation_rates_modifier)

@@ -489,7 +492,7 @@ def create_mrt_orthogonal(stencil, relaxation_rates, continuous_equilibrium=True
    check_and_set_mrt_space(CollisionSpace.RAW_MOMENTS)

    if weighted:
        weights = get_weights(stencil, sp.Rational(1, 3))
        weights = get_weights(stencil)
    else:
        weights = None

@@ -527,7 +530,7 @@ def create_mrt_orthogonal(stencil, relaxation_rates, continuous_equilibrium=True


# ----------------------------------------- Cumulant method creators ---------------------------------------------------
def create_cumulant(stencil, relaxation_rates, cumulant_groups, conserved_moments=True, fraction_field=None, **kwargs):
def create_cumulant(stencil, relaxation_rates, cumulant_groups, conserved_moments=True, **kwargs):
    r"""Creates a cumulant-based lattice Boltzmann method.

    Args:
@@ -547,8 +550,8 @@ def create_cumulant(stencil, relaxation_rates, cumulant_groups, conserved_moment
    """
    cumulant_to_rr_dict = _get_relaxation_info_dict(relaxation_rates, cumulant_groups, stencil.D, conserved_moments)

    if fraction_field is not None:
        relaxation_rates_modifier = (1.0 - fraction_field.center)
    if 'fraction_field' in kwargs and kwargs['fraction_field'] is not None:
        relaxation_rates_modifier = (1.0 - kwargs['fraction_field'])
        cumulant_to_rr_dict = _get_relaxation_info_dict(relaxation_rates, cumulant_groups, stencil.D,
                                                        relaxation_rates_modifier=relaxation_rates_modifier)