From 2f7b33ed781f03fdecf2d7bcef09ef88f6466e92 Mon Sep 17 00:00:00 2001 From: Markus Holzer <markus.holzer@fau.de> Date: Tue, 24 May 2022 16:08:47 +0200 Subject: [PATCH] Adaption for CodeGen pipeline --- .gitignore | 4 +- .gitlab-ci.yml | 121 +++++++++----- .../FlowAroundSphereCodeGen.cpp | 24 +-- .../FlowAroundSphereCodeGen.py | 7 +- .../FluidParticleCoupling/GeneratedLBM.py | 47 +++--- .../GeneratedLBMWithForce.py | 50 +++--- .../benchmark_multiphase.cpp | 18 +-- .../PhaseFieldAllenCahn/multiphase_codegen.py | 117 +++++++------- .../UniformGridCPU/UniformGridCPU.cpp | 8 +- .../UniformGridCPU/UniformGridCPU.py | 3 +- .../UniformGridGPU/UniformGridGPU.cpp | 8 +- .../UniformGridGPU/UniformGridGPU.py | 5 +- .../old_ideas/UniformGridGPU.py | 2 +- .../CPU/InitializerFunctions.cpp | 142 ++++++++--------- .../PhaseFieldAllenCahn/CPU/multiphase.cpp | 14 +- .../CPU/multiphase_codegen.py | 125 ++++++--------- .../GPU/InitializerFunctions.cpp | 148 +++++++++--------- .../PhaseFieldAllenCahn/GPU/multiphase.cpp | 18 +-- .../GPU/multiphase_codegen.py | 140 +++++++---------- .../PhaseFieldAllenCahn/GPU/util.cpp | 30 ++-- .../PorousMediaCumulantLBMKernel.py | 50 +++--- .../codegen/02_LBMLatticeModelGeneration.cpp | 4 +- .../codegen/02_LBMLatticeModelGeneration.py | 3 +- .../codegen/03_AdvancedLBMCodegen.cpp | 6 +- .../codegen/03_AdvancedLBMCodegen.py | 93 ++++++----- apps/tutorials/codegen/HeatEquationKernel.py | 30 ++-- .../lbmpy_walberla/additional_data_handler.py | 2 +- python/lbmpy_walberla/packinfo.py | 4 +- python/lbmpy_walberla/sparse.py | 4 +- .../templates/LatticeModel.tmpl.cpp | 4 +- .../templates/LatticeModel.tmpl.h | 135 ++++++++-------- .../tests/test_walberla_codegen.py | 3 +- .../lbmpy_walberla/walberla_lbm_generation.py | 103 +++++++----- python/pystencils_walberla/boundary.py | 12 +- python/pystencils_walberla/codegen.py | 9 +- python/pystencils_walberla/jinja_filters.py | 28 +++- .../pystencils_walberla/kernel_selection.py | 2 +- .../templates/Boundary.tmpl.cpp | 2 +- .../templates/Boundary.tmpl.h | 6 +- python/pystencils_walberla/utility.py | 2 +- python/waLBerla_tests/test_blockforest.py | 9 +- python/waLBerla_tests/test_field.py | 10 +- src/core/DataTypes.h | 2 +- src/python_coupling/export/BasicExport.cpp | 5 + tests/cuda/SimpleKernelTest.cpp | 38 ++--- tests/cuda/codegen/CodegenJacobiGPU.cpp | 20 +-- tests/cuda/codegen/CodegenPoissonGPU.cpp | 14 +- tests/cuda/codegen/CudaJacobiKernel.py | 5 +- tests/cuda/codegen/CudaPoisson.py | 3 +- .../codegen/GeneratedFieldPackInfoTestGPU.cpp | 2 +- .../codegen/GeneratedFieldPackInfoTestGPU.py | 6 +- tests/cuda/codegen/MicroBenchmarkGpuLbm.cpp | 8 +- tests/cuda/codegen/MicroBenchmarkGpuLbm.py | 10 +- tests/field/codegen/CodegenJacobiCPU.cpp | 20 +-- tests/field/codegen/CodegenPoissonCPU.cpp | 16 +- tests/field/codegen/EK.cpp | 20 +-- tests/field/codegen/EK.py | 2 + .../codegen/GeneratedFieldPackInfoTest.cpp | 66 ++++---- .../codegen/GeneratedFieldPackInfoTest.py | 6 +- tests/field/codegen/JacobiKernel.py | 5 +- tests/field/codegen/MultipleFieldSwaps.cpp | 16 +- tests/field/codegen/MultipleFieldSwaps.py | 7 +- tests/field/codegen/Poisson.py | 3 +- .../FieldLayoutAndVectorizationTest.cpp | 14 +- .../FieldLayoutAndVectorizationTest.py | 3 +- tests/lbm/codegen/FluctuatingMRT.cpp | 18 +-- tests/lbm/codegen/FluctuatingMRT.py | 28 ++-- tests/lbm/codegen/GeneratedFreeSlip.cpp | 13 +- tests/lbm/codegen/GeneratedFreeSlip.py | 65 ++++---- tests/lbm/codegen/GeneratedOutflowBC.cpp | 16 +- tests/lbm/codegen/GeneratedOutflowBC.py | 57 +++---- tests/lbm/codegen/InplaceStreamingCodegen.py | 68 ++++---- .../codegen/InplaceStreamingCodegenTest.cpp | 3 +- tests/lbm/codegen/LbCodeGenerationExample.cpp | 10 +- tests/lbm/codegen/LbCodeGenerationExample.py | 7 +- .../lbm/codegen/LbmPackInfoGenerationTest.py | 2 +- .../codegen/StreamInCellIntervalCodegen.py | 15 +- .../StreamInCellIntervalCodegenTest.cpp | 8 +- 78 files changed, 1115 insertions(+), 1038 deletions(-) diff --git a/.gitignore b/.gitignore index 4430e54af..c755c9f0b 100644 --- a/.gitignore +++ b/.gitignore @@ -72,6 +72,4 @@ cmake_install.cmake CMakeDefs.h /moduleStatistics.json /walberla-config.cmake -/cmake-build-debug/ -/cmake-build-release/ -/cmake-build-debug-remote/ +cmake-build-* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c47ea2f9c..af80860b1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -503,7 +503,7 @@ gcc_9_serial: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:9 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -526,7 +526,7 @@ gcc_9_mpionly: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:9 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -547,7 +547,7 @@ gcc_9_hybrid: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:9 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -567,7 +567,7 @@ gcc_9_serial_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:9 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -591,7 +591,7 @@ gcc_9_mpionly_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:9 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -613,7 +613,7 @@ gcc_9_hybrid_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:9 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -633,12 +633,20 @@ gcc_9_hybrid_dbg: gcc_9_hybrid_dbg_sp: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:9 + before_script: + - pip3 install lbmpy==1.0 jinja2 pytest + - cd python + - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla + - cd .. + - CC=gcc CXX=g++ pip3 install pycuda variables: WALBERLA_BUILD_WITH_CUDA: "ON" CMAKE_BUILD_TYPE: "DebugOptimized" WALBERLA_DOUBLE_ACCURACY: "OFF" WALBERLA_BUILD_WITH_PARMETIS: "OFF" WALBERLA_BUILD_WITH_METIS: "OFF" + WALBERLA_BUILD_WITH_CODEGEN: "ON" + WALBERLA_BUILD_WITH_PYTHON: "ON" only: variables: - $ENABLE_NIGHTLY_BUILDS @@ -650,7 +658,7 @@ gcc_10_serial: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:10 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -673,7 +681,7 @@ gcc_10_mpionly: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:10 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -694,7 +702,7 @@ gcc_10_hybrid: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:10 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -714,7 +722,7 @@ gcc_10_serial_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:10 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -738,7 +746,7 @@ gcc_10_mpionly_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:10 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -760,7 +768,7 @@ gcc_10_hybrid_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:10 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -780,12 +788,20 @@ gcc_10_hybrid_dbg: gcc_10_hybrid_dbg_sp: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:10 + before_script: + - pip3 install lbmpy==1.0 jinja2 pytest + - cd python + - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla + - cd .. + - CC=gcc CXX=g++ pip3 install pycuda variables: WALBERLA_BUILD_WITH_CUDA: "ON" CMAKE_BUILD_TYPE: "DebugOptimized" WALBERLA_DOUBLE_ACCURACY: "OFF" WALBERLA_BUILD_WITH_PARMETIS: "OFF" WALBERLA_BUILD_WITH_METIS: "OFF" + WALBERLA_BUILD_WITH_CODEGEN: "ON" + WALBERLA_BUILD_WITH_PYTHON: "ON" only: variables: - $ENABLE_NIGHTLY_BUILDS @@ -797,7 +813,7 @@ gcc_11_serial: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:11 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -820,7 +836,7 @@ gcc_11_mpionly: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:11 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -842,11 +858,12 @@ gcc_11_hybrid: image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:11 stage: pretest before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. - CC=gcc CXX=g++ pip3 install pycuda + - pip3 list variables: WALBERLA_BUILD_WITH_CUDA: "ON" WALBERLA_BUILD_WITH_CODEGEN: "ON" @@ -859,7 +876,7 @@ gcc_11_serial_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:11 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -880,7 +897,7 @@ gcc_11_mpionly_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:11 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -899,7 +916,7 @@ gcc_11_hybrid_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:11 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -916,12 +933,20 @@ gcc_11_hybrid_dbg: gcc_11_hybrid_dbg_sp: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:11 + before_script: + - pip3 install lbmpy==1.0 jinja2 pytest + - cd python + - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla + - cd .. + - CC=gcc CXX=g++ pip3 install pycuda variables: WALBERLA_BUILD_WITH_CUDA: "ON" CMAKE_BUILD_TYPE: "DebugOptimized" WALBERLA_DOUBLE_ACCURACY: "OFF" WALBERLA_BUILD_WITH_PARMETIS: "OFF" WALBERLA_BUILD_WITH_METIS: "OFF" + WALBERLA_BUILD_WITH_CODEGEN: "ON" + WALBERLA_BUILD_WITH_PYTHON: "ON" tags: - cuda11 - docker @@ -1422,7 +1447,7 @@ clang_11.0_serial: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:11.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1445,7 +1470,7 @@ clang_11.0_mpionly: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:11.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1466,7 +1491,7 @@ clang_11.0_hybrid: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:11.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1486,7 +1511,7 @@ clang_11.0_serial_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:11.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1510,7 +1535,7 @@ clang_11.0_mpionly_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:11.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1532,7 +1557,7 @@ clang_11.0_hybrid_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:11.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1552,12 +1577,20 @@ clang_11.0_hybrid_dbg: clang_11.0_hybrid_dbg_sp: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:11.0 + before_script: + - pip3 install lbmpy==1.0 jinja2 pytest + - cd python + - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla + - cd .. + - CC=gcc CXX=g++ pip3 install pycuda variables: WALBERLA_BUILD_WITH_CUDA: "ON" CMAKE_BUILD_TYPE: "DebugOptimized" WALBERLA_DOUBLE_ACCURACY: "OFF" WALBERLA_BUILD_WITH_PARMETIS: "OFF" WALBERLA_BUILD_WITH_METIS: "OFF" + WALBERLA_BUILD_WITH_CODEGEN: "ON" + WALBERLA_BUILD_WITH_PYTHON: "ON" only: variables: - $ENABLE_NIGHTLY_BUILDS @@ -1569,7 +1602,7 @@ clang_12.0_serial: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:12.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1592,7 +1625,7 @@ clang_12.0_mpionly: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:12.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1613,7 +1646,7 @@ clang_12.0_hybrid: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:12.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1633,7 +1666,7 @@ clang_12.0_serial_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:12.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1657,7 +1690,7 @@ clang_12.0_mpionly_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:12.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1679,7 +1712,7 @@ clang_12.0_hybrid_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:12.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1699,12 +1732,20 @@ clang_12.0_hybrid_dbg: clang_12.0_hybrid_dbg_sp: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:12.0 + before_script: + - pip3 install lbmpy==1.0 jinja2 pytest + - cd python + - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla + - cd .. + - CC=gcc CXX=g++ pip3 install pycuda variables: WALBERLA_BUILD_WITH_CUDA: "ON" CMAKE_BUILD_TYPE: "DebugOptimized" WALBERLA_DOUBLE_ACCURACY: "OFF" WALBERLA_BUILD_WITH_PARMETIS: "OFF" WALBERLA_BUILD_WITH_METIS: "OFF" + WALBERLA_BUILD_WITH_CODEGEN: "ON" + WALBERLA_BUILD_WITH_PYTHON: "ON" only: variables: - $ENABLE_NIGHTLY_BUILDS @@ -1716,7 +1757,7 @@ clang_13.0_serial: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:13.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1739,7 +1780,7 @@ clang_13.0_mpionly: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:13.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1760,7 +1801,7 @@ clang_13.0_hybrid: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:13.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1777,7 +1818,7 @@ clang_13.0_serial_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:13.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1798,7 +1839,7 @@ clang_13.0_mpionly_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:13.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1817,7 +1858,7 @@ clang_13.0_hybrid_dbg: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:13.0 before_script: - - pip3 install lbmpy==0.4.1 jinja2 pytest + - pip3 install lbmpy==1.0 jinja2 pytest - cd python - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla - cd .. @@ -1835,12 +1876,20 @@ clang_13.0_hybrid_dbg_sp: extends: .build_template image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:13.0 stage: pretest + before_script: + - pip3 install lbmpy==1.0 jinja2 pytest + - cd python + - python3 -m pytest --junitxml=report.xml pystencils_walberla lbmpy_walberla + - cd .. + - CC=gcc CXX=g++ pip3 install pycuda variables: WALBERLA_BUILD_WITH_CUDA: "ON" CMAKE_BUILD_TYPE: "DebugOptimized" WALBERLA_DOUBLE_ACCURACY: "OFF" WALBERLA_BUILD_WITH_PARMETIS: "OFF" WALBERLA_BUILD_WITH_METIS: "OFF" + WALBERLA_BUILD_WITH_CODEGEN: "ON" + WALBERLA_BUILD_WITH_PYTHON: "ON" tags: - cuda11 - docker diff --git a/apps/benchmarks/FlowAroundSphereCodeGen/FlowAroundSphereCodeGen.cpp b/apps/benchmarks/FlowAroundSphereCodeGen/FlowAroundSphereCodeGen.cpp index 48f029dee..bdd1ccbe1 100644 --- a/apps/benchmarks/FlowAroundSphereCodeGen/FlowAroundSphereCodeGen.cpp +++ b/apps/benchmarks/FlowAroundSphereCodeGen/FlowAroundSphereCodeGen.cpp @@ -73,21 +73,21 @@ auto VelocityCallback = [](const Cell& pos, const shared_ptr< StructuredBlockFor real_t inflow_velocity, const bool constant_inflow = true) { if (constant_inflow) { - Vector3< real_t > result(inflow_velocity, 0.0, 0.0); + Vector3< real_t > result(inflow_velocity, real_c(0.0), real_c(0.0)); return result; } else { Cell globalCell; CellInterval domain = SbF->getDomainCellBB(); - real_t h_y = real_c(domain.ySize()); - real_t h_z = real_c(domain.zSize()); + auto h_y = real_c(domain.ySize()); + auto h_z = real_c(domain.zSize()); SbF->transformBlockLocalToGlobalCell(globalCell, block, pos); - real_t y1 = real_c(globalCell[1] - (h_y / 2.0 - 0.5)); - real_t z1 = real_c(globalCell[2] - (h_z / 2.0 - 0.5)); + auto y1 = real_c(globalCell[1] - (h_y / 2.0 - 0.5)); + auto z1 = real_c(globalCell[2] - (h_z / 2.0 - 0.5)); - real_t u = (inflow_velocity * real_c(16)) / (h_y * h_y * h_z * h_z) * (h_y / real_c(2.0) - y1) * + real_t u = (inflow_velocity * real_c(16.0)) / (h_y * h_y * h_z * h_z) * (h_y / real_c(2.0) - y1) * (h_y / real_c(2.0) + y1) * (h_z / real_c(2.0) - z1) * (h_z / real_c(2.0) + z1); Vector3< real_t > result(u, 0.0, 0.0); @@ -151,9 +151,9 @@ int main(int argc, char** argv) auto parameters = config->getOneBlock("Parameters"); const uint_t timesteps = parameters.getParameter< uint_t >("timesteps", uint_c(10)); - const real_t omega = parameters.getParameter< real_t >("omega", real_t(1.9)); - const real_t u_max = parameters.getParameter< real_t >("u_max", real_t(0.05)); - const real_t reynolds_number = parameters.getParameter< real_t >("reynolds_number", real_t(1000)); + const real_t omega = parameters.getParameter< real_t >("omega", real_c(1.9)); + const real_t u_max = parameters.getParameter< real_t >("u_max", real_c(0.05)); + const real_t reynolds_number = parameters.getParameter< real_t >("reynolds_number", real_c(1000.0)); const uint_t diameter_sphere = parameters.getParameter< uint_t >("diameter_sphere", uint_t(5)); const bool constant_inflow = parameters.getParameter< bool >("constant_inflow", true); @@ -162,8 +162,8 @@ int main(int argc, char** argv) // create fields BlockDataID pdfFieldID = blocks->addStructuredBlockData< PdfField_T >(pdfFieldAdder, "PDFs"); - BlockDataID velFieldID = field::addToStorage< VelocityField_T >(blocks, "velocity", real_t(0), field::fzyx); - BlockDataID densityFieldID = field::addToStorage< ScalarField_T >(blocks, "density", real_t(0), field::fzyx); + BlockDataID velFieldID = field::addToStorage< VelocityField_T >(blocks, "velocity", real_c(0.0), field::fzyx); + BlockDataID densityFieldID = field::addToStorage< ScalarField_T >(blocks, "density", real_c(0.0), field::fzyx); #if defined(WALBERLA_BUILD_WITH_CUDA) BlockDataID pdfFieldIDGPU = cuda::addGPUFieldToStorage< PdfField_T >(blocks, pdfFieldID, "PDFs on GPU", true); @@ -300,7 +300,7 @@ int main(int argc, char** argv) timeloop.run(); simTimer.end(); WALBERLA_LOG_INFO_ON_ROOT("Simulation finished") - auto time = simTimer.last(); + auto time = real_c(simTimer.last()); auto nrOfCells = real_c(cellsPerBlock[0] * cellsPerBlock[1] * cellsPerBlock[2]); auto mlupsPerProcess = nrOfCells * real_c(timesteps) / time * 1e-6; WALBERLA_LOG_RESULT_ON_ROOT("MLUPS per process " << mlupsPerProcess) diff --git a/apps/benchmarks/FlowAroundSphereCodeGen/FlowAroundSphereCodeGen.py b/apps/benchmarks/FlowAroundSphereCodeGen/FlowAroundSphereCodeGen.py index 8d3b556bb..c170a8101 100644 --- a/apps/benchmarks/FlowAroundSphereCodeGen/FlowAroundSphereCodeGen.py +++ b/apps/benchmarks/FlowAroundSphereCodeGen/FlowAroundSphereCodeGen.py @@ -33,7 +33,8 @@ with CodeGeneration() as ctx: 'velocity': velocity_field } - lbm_config = LBMConfig(stencil=stencil, method=Method.CUMULANT, relaxation_rate=omega, galilean_correction=True, + lbm_config = LBMConfig(stencil=stencil, method=Method.CUMULANT, compressible=True, + relaxation_rate=omega, galilean_correction=True, field_name='pdfs', streaming_pattern=streaming_pattern, output=output) lbm_optimisation = LBMOptimisation(symbolic_field=pdfs, cse_global=False, cse_pdfs=False) @@ -66,9 +67,9 @@ with CodeGeneration() as ctx: generate_sweep(ctx, 'FlowAroundSphereCodeGen_MacroSetter', setter_assignments, target=target) # boundaries - ubb = UBB(lambda *args: None, dim=dim) + ubb = UBB(lambda *args: None, dim=dim, data_type=data_type) ubb_data_handler = UBBAdditionalDataHandler(stencil, ubb) - outflow = ExtrapolationOutflow(stencil[4], lb_method, streaming_pattern=streaming_pattern) + outflow = ExtrapolationOutflow(stencil[4], lb_method, streaming_pattern=streaming_pattern, data_type=data_type) outflow_data_handler = OutflowAdditionalDataHandler(stencil, outflow, target=target) generate_alternating_lbm_boundary(ctx, 'FlowAroundSphereCodeGen_UBB', ubb, lb_method, diff --git a/apps/benchmarks/FluidParticleCoupling/GeneratedLBM.py b/apps/benchmarks/FluidParticleCoupling/GeneratedLBM.py index 982aa6167..8274c20a5 100644 --- a/apps/benchmarks/FluidParticleCoupling/GeneratedLBM.py +++ b/apps/benchmarks/FluidParticleCoupling/GeneratedLBM.py @@ -1,22 +1,22 @@ import sympy as sp from sympy.core.cache import clear_cache import pystencils as ps -from lbmpy.creationfunctions import create_lb_method_from_existing, create_lb_method +from lbmpy.creationfunctions import LBMConfig, LBMOptimisation, Method, Stencil, create_lb_method from lbmpy_walberla import generate_lattice_model from pystencils_walberla import CodeGeneration from pystencils_walberla import get_vectorize_instruction_set from lbmpy.creationfunctions import create_lb_collision_rule from lbmpy.moments import is_even, get_order, MOMENT_SYMBOLS -from lbmpy.stencils import get_stencil +from lbmpy.stencils import LBStencil from collections import OrderedDict with CodeGeneration() as ctx: generatedMethod = 'TRTlike' - #generatedMethod = 'D3Q27TRTlike' - #generatedMethod = 'cumulant' + # generatedMethod = 'D3Q27TRTlike' + # generatedMethod = 'cumulant' clear_cache() @@ -28,7 +28,7 @@ with CodeGeneration() as ctx: omegaVisc = sp.Symbol('omega_visc') omegaBulk = ps.fields(f'omega_bulk: {dtype_string}[3D]', layout='fzyx') omegaMagic = sp.Symbol('omega_magic') - stencil = get_stencil('D3Q19', 'walberla') + stencil = LBStencil(Stencil.D3Q19) x, y, z = MOMENT_SYMBOLS one = sp.Rational(1, 1) @@ -44,33 +44,43 @@ with CodeGeneration() as ctx: ] # relaxation rate for first group of moments (1,x,y,z) is set to zero internally - relaxation_rates=[omegaBulk.center_vector, omegaBulk.center_vector, omegaMagic, omegaVisc, omegaVisc, omegaMagic] + relaxation_rates = [omegaBulk.center_vector, omegaBulk.center_vector, + omegaMagic, omegaVisc, omegaVisc, omegaMagic] - methodWithForce = create_lb_method(stencil=stencil, method='mrt', maxwellian_moments=False, - nested_moments=moments, relaxation_rates=relaxation_rates) + lbm_config = LBMConfig(stencil=stencil, method=Method.MRT, continuous_equilibrium=False, + zero_centered=False, delta_equilibrium=False, + nested_moments=moments, relaxation_rates=relaxation_rates) - #print(methodWithForce.relaxation_rates) - #print(methodWithForce.moment_matrix) - collision_rule = create_lb_collision_rule(lb_method=methodWithForce, optimization={'cse_global': True}) + lbm_opt = LBMOptimisation(cse_global=True) + + methodWithForce = create_lb_method(lbm_config=lbm_config) + + # print(methodWithForce.relaxation_rates) + # print(methodWithForce.moment_matrix) + collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) generate_lattice_model(ctx, 'GeneratedLBM', collision_rule, field_layout='fzyx', cpu_vectorize_info=cpu_vectorize_info) - if generatedMethod == 'D3Q27TRTlike': omegaVisc = sp.Symbol('omega_visc') omegaBulk = ps.fields(f'omega_bulk: {dtype_string}[3D]', layout='fzyx') omegaMagic = sp.Symbol('omega_magic') - stencil = get_stencil('D3Q27', 'walberla') + stencil = LBStencil(Stencil.D3Q27) relaxation_rates = [omegaVisc, omegaBulk.center_vector, omegaMagic, omegaVisc, omegaMagic, omegaVisc] - methodWithForce = create_lb_method(stencil=stencil, method='mrt', maxwellian_moments=False, weighted=True, - compressible=False, relaxation_rates=relaxation_rates) + lbm_config = LBMConfig(stencil=stencil, method=Method.MRT, maxwellian_moments=False, weighted=True, + compressible=False, relaxation_rates=relaxation_rates) + + lbm_opt = LBMOptimisation(cse_global=True) + + methodWithForce = create_lb_method(lbm_config=lbm_config) - collision_rule = create_lb_collision_rule(lb_method=methodWithForce, optimization={'cse_global': True}) + collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) generate_lattice_model(ctx, 'GeneratedLBM', collision_rule, field_layout='fzyx', cpu_vectorize_info=cpu_vectorize_info) +# using create_with_continuous_maxwellian_eq_moments won't work probably if generatedMethod == 'cumulant': x, y, z = MOMENT_SYMBOLS @@ -122,7 +132,7 @@ with CodeGeneration() as ctx: else: return 1 - stencil = get_stencil('D3Q27', 'walberla') + stencil = LBStencil(Stencil.D3Q27) omega = sp.Symbol('omega') rr_dict = OrderedDict((c, get_relaxation_rate(c, omega)) @@ -139,6 +149,3 @@ with CodeGeneration() as ctx: generate_lattice_model(ctx, 'GeneratedLBM', collision_rule, field_layout='fzyx', cpu_vectorize_info=cpu_vectorize_info) - - - diff --git a/apps/benchmarks/FluidParticleCoupling/GeneratedLBMWithForce.py b/apps/benchmarks/FluidParticleCoupling/GeneratedLBMWithForce.py index 9eb861b8c..4968f0670 100644 --- a/apps/benchmarks/FluidParticleCoupling/GeneratedLBMWithForce.py +++ b/apps/benchmarks/FluidParticleCoupling/GeneratedLBMWithForce.py @@ -1,22 +1,20 @@ import sympy as sp from sympy.core.cache import clear_cache import pystencils as ps -from lbmpy.creationfunctions import create_lb_method_from_existing, create_lb_ast, create_lb_method +from lbmpy.creationfunctions import LBMConfig, LBMOptimisation, ForceModel, Method, Stencil, create_lb_method from lbmpy_walberla import generate_lattice_model from pystencils_walberla import CodeGeneration from pystencils_walberla import get_vectorize_instruction_set from lbmpy.creationfunctions import create_lb_collision_rule from lbmpy.moments import MOMENT_SYMBOLS, is_even, get_order -from lbmpy.stencils import get_stencil -from lbmpy.forcemodels import Luo +from lbmpy.stencils import LBStencil from collections import OrderedDict with CodeGeneration() as ctx: forcing = (sp.symbols('fx'), 0, 0) - forcemodel = Luo(forcing) generatedMethod = 'TRTlike' # generatedMethod = 'D3Q27TRTlike' @@ -35,7 +33,7 @@ with CodeGeneration() as ctx: omegaVisc = sp.Symbol('omega_visc') omegaBulk = ps.fields(f'omega_bulk: {dtype_string}[3D]', layout='fzyx') omegaMagic = sp.Symbol('omega_magic') - stencil = get_stencil('D3Q19', 'walberla') + stencil = LBStencil(Stencil.D3Q19) x, y, z = MOMENT_SYMBOLS one = sp.Rational(1, 1) @@ -51,29 +49,42 @@ with CodeGeneration() as ctx: ] # relaxation rate for first group of moments (1,x,y,z) is set to zero internally - relaxation_rates=[omegaBulk.center_vector, omegaBulk.center_vector, omegaMagic, omegaVisc, omegaVisc, omegaMagic] + relaxation_rates = [omegaBulk.center_vector, omegaBulk.center_vector, + omegaMagic, omegaVisc, omegaVisc, omegaMagic] - methodWithForce = create_lb_method(stencil=stencil, method='mrt', maxwellian_moments=False, - force_model=forcemodel, nested_moments=moments, relaxation_rates=relaxation_rates) + lbm_config = LBMConfig(stencil=stencil, method=Method.MRT, continuous_equilibrium=False, + zero_centered=False, delta_equilibrium=False, + force=forcing, force_model=ForceModel.LUO, + nested_moments=moments, relaxation_rates=relaxation_rates) + + lbm_opt = LBMOptimisation(cse_global=True) + + methodWithForce = create_lb_method(lbm_config=lbm_config) + + # print(methodWithForce.relaxation_rates) + # print(methodWithForce.moment_matrix) + collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) + generate_lattice_model(ctx, 'GeneratedLBMWithForce', collision_rule, field_layout='fzyx', + cpu_vectorize_info=cpu_vectorize_info) - #print(methodWithForce.relaxation_rates) - #print(methodWithForce.moment_matrix) - collision_rule = create_lb_collision_rule(lb_method=methodWithForce, optimization={'cse_global': True}) - generate_lattice_model(ctx, 'GeneratedLBMWithForce', collision_rule, field_layout='fzyx', cpu_vectorize_info=cpu_vectorize_info) - if generatedMethod == 'D3Q27TRTlike': omegaVisc = sp.Symbol('omega_visc') omegaBulk = ps.fields(f'omega_bulk: {dtype_string}[3D]', layout='fzyx') omegaMagic = sp.Symbol('omega_magic') - stencil = get_stencil('D3Q27', 'walberla') + stencil = LBStencil(Stencil.D3Q27) relaxation_rates = [omegaVisc, omegaBulk.center_vector, omegaMagic, omegaVisc, omegaMagic, omegaVisc] - methodWithForce = create_lb_method(stencil=stencil, method='mrt', maxwellian_moments=False, weighted=True, - compressible=False, force_model=forcemodel, relaxation_rates=relaxation_rates) + lbm_config = LBMConfig(stencil=stencil, method=Method.MRT, maxwellian_moments=False, weighted=True, + force=forcing, force_model=ForceModel.LUO, + compressible=False, relaxation_rates=relaxation_rates) + + lbm_opt = LBMOptimisation(cse_global=True) - collision_rule = create_lb_collision_rule(lb_method=methodWithForce, optimization={'cse_global': True}) + methodWithForce = create_lb_method(lbm_config=lbm_config) + + collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) generate_lattice_model(ctx, 'GeneratedLBMWithForce', collision_rule, field_layout='fzyx', cpu_vectorize_info=cpu_vectorize_info) @@ -128,7 +139,7 @@ with CodeGeneration() as ctx: else: return 1 - stencil = get_stencil('D3Q27', 'walberla') + stencil = LBStencil(Stencil.D3Q27) omega = sp.Symbol('omega') rr_dict = OrderedDict((c, get_relaxation_rate(c, omega)) @@ -199,7 +210,7 @@ with CodeGeneration() as ctx: else: return omegaMagic - stencil = get_stencil('D3Q27', 'walberla') + stencil = LBStencil(Stencil.D3Q27) omegaVisc = sp.Symbol('omega_visc') omegaMagic = sp.Symbol('omega_magic') @@ -219,4 +230,3 @@ with CodeGeneration() as ctx: generate_lattice_model(ctx, 'GeneratedLBMWithForce', collision_rule, field_layout='fzyx', cpu_vectorize_info=cpu_vectorize_info) - diff --git a/apps/benchmarks/PhaseFieldAllenCahn/benchmark_multiphase.cpp b/apps/benchmarks/PhaseFieldAllenCahn/benchmark_multiphase.cpp index 5af04a355..b757f3a5b 100644 --- a/apps/benchmarks/PhaseFieldAllenCahn/benchmark_multiphase.cpp +++ b/apps/benchmarks/PhaseFieldAllenCahn/benchmark_multiphase.cpp @@ -86,14 +86,14 @@ int main(int argc, char** argv) const std::string timeStepStrategy = parameters.getParameter< std::string >("timeStepStrategy", "normal"); const uint_t timesteps = parameters.getParameter< uint_t >("timesteps", uint_c(50)); const real_t remainingTimeLoggerFrequency = - parameters.getParameter< real_t >("remainingTimeLoggerFrequency", 3.0); + parameters.getParameter< real_t >("remainingTimeLoggerFrequency", real_c(3.0)); const uint_t scenario = parameters.getParameter< uint_t >("scenario", uint_c(1)); const uint_t warmupSteps = parameters.getParameter< uint_t >("warmupSteps", uint_t(2)); #if defined(WALBERLA_BUILD_WITH_CUDA) // CPU fields - BlockDataID vel_field = field::addToStorage< VelocityField_T >(blocks, "vel", real_t(0), field::fzyx); - BlockDataID phase_field = field::addToStorage< PhaseField_T >(blocks, "phase", real_t(0), field::fzyx); + BlockDataID vel_field = field::addToStorage< VelocityField_T >(blocks, "vel", real_c(0.0), field::fzyx); + BlockDataID phase_field = field::addToStorage< PhaseField_T >(blocks, "phase", real_c(0.0), field::fzyx); // GPU fields BlockDataID lb_phase_field_gpu = cuda::addGPUFieldToStorage< cuda::GPUField< real_t > >( blocks, "lb phase field on GPU", Stencil_phase_T::Size, field::fzyx, 1); @@ -105,11 +105,11 @@ int main(int argc, char** argv) cuda::addGPUFieldToStorage< PhaseField_T >(blocks, phase_field, "phase field on GPU", true); #else BlockDataID lb_phase_field = - field::addToStorage< PdfField_phase_T >(blocks, "lb phase field", real_t(0), field::fzyx); + field::addToStorage< PdfField_phase_T >(blocks, "lb phase field", real_c(0.0), field::fzyx); BlockDataID lb_velocity_field = - field::addToStorage< PdfField_hydro_T >(blocks, "lb velocity field", real_t(0), field::fzyx); - BlockDataID vel_field = field::addToStorage< VelocityField_T >(blocks, "vel", real_t(0), field::fzyx); - BlockDataID phase_field = field::addToStorage< PhaseField_T >(blocks, "phase", real_t(0), field::fzyx); + field::addToStorage< PdfField_hydro_T >(blocks, "lb velocity field", real_c(0.0), field::fzyx); + BlockDataID vel_field = field::addToStorage< VelocityField_T >(blocks, "vel", real_c(0.0), field::fzyx); + BlockDataID phase_field = field::addToStorage< PhaseField_T >(blocks, "phase", real_c(0.0), field::fzyx); #endif if (timeStepStrategy != "phase_only" && timeStepStrategy != "hydro_only" && timeStepStrategy != "kernel_only") @@ -120,7 +120,7 @@ int main(int argc, char** argv) auto bubbleParameters = config->getOneBlock("Bubble"); const Vector3< real_t > bubbleMidPoint = bubbleParameters.getParameter< Vector3< real_t > >("bubbleMidPoint"); - const real_t bubbleRadius = bubbleParameters.getParameter< real_t >("bubbleRadius", 20.0); + const real_t bubbleRadius = bubbleParameters.getParameter< real_t >("bubbleRadius", real_c(20.0)); initPhaseField_bubble(blocks, phase_field, bubbleRadius, bubbleMidPoint); } else if (scenario == 2) @@ -327,7 +327,7 @@ int main(int argc, char** argv) #endif simTimer.end(); WALBERLA_LOG_INFO_ON_ROOT("Simulation finished") - auto time = simTimer.last(); + auto time = real_c(simTimer.last()); auto nrOfCells = real_c(cellsPerBlock[0] * cellsPerBlock[1] * cellsPerBlock[2]); auto mlupsPerProcess = nrOfCells * real_c(timesteps) / time * 1e-6; WALBERLA_LOG_RESULT_ON_ROOT("MLUPS per process: " << mlupsPerProcess) diff --git a/apps/benchmarks/PhaseFieldAllenCahn/multiphase_codegen.py b/apps/benchmarks/PhaseFieldAllenCahn/multiphase_codegen.py index f74db05e9..e9bfa1dae 100644 --- a/apps/benchmarks/PhaseFieldAllenCahn/multiphase_codegen.py +++ b/apps/benchmarks/PhaseFieldAllenCahn/multiphase_codegen.py @@ -1,20 +1,20 @@ -from pystencils import fields, Target, TypedSymbol +import numpy as np +import sympy as sp + +from pystencils import fields, Target +from pystencils.typing import TypedSymbol from pystencils.simp import sympy_cse from lbmpy import LBMConfig, LBStencil, Method, Stencil -from lbmpy.creationfunctions import create_lb_method +from lbmpy.creationfunctions import LBMOptimisation, create_lb_method, create_lb_update_rule +from lbmpy.phasefield_allen_cahn.kernel_equations import initializer_kernel_phase_field_lb, \ + initializer_kernel_hydro_lb, interface_tracking_force, hydrodynamic_force, add_interface_tracking_force, \ + add_hydrodynamic_force, hydrodynamic_force_assignments +from lbmpy.phasefield_allen_cahn.parameter_calculation import AllenCahnParameters from pystencils_walberla import CodeGeneration, generate_sweep, generate_pack_info_for_field, generate_info_header from lbmpy_walberla import generate_lb_pack_info -from lbmpy.phasefield_allen_cahn.kernel_equations import initializer_kernel_phase_field_lb, \ - initializer_kernel_hydro_lb, interface_tracking_force, \ - hydrodynamic_force, get_collision_assignments_hydro, get_collision_assignments_phase - -from lbmpy.phasefield_allen_cahn.force_model import MultiphaseForceModel - -import numpy as np - with CodeGeneration() as ctx: field_type = "float64" if ctx.double_accuracy else "float32" @@ -25,22 +25,11 @@ with CodeGeneration() as ctx: ######################## # PARAMETER DEFINITION # ######################## - - density_liquid = 1.0 - density_gas = 0.001 - surface_tension = 0.0001 - M = 0.02 - - # phase-field parameter - drho3 = (density_liquid - density_gas) / 3 - # interface thickness - W = 5 - # coefficient related to surface tension - beta = 12.0 * (surface_tension / W) - # coefficient related to surface tension - kappa = 1.5 * surface_tension * W - # relaxation rate allen cahn (h) - w_c = 1.0 / (0.5 + (3.0 * M)) + # In the codegneration skript we only need the symbolic parameters + parameters = AllenCahnParameters(density_heavy=1.0, density_light=0.001, + dynamic_viscosity_heavy=0.03, dynamic_viscosity_light=0.03, + surface_tension=0.0001, mobility=0.02, interface_thickness=5, + gravitational_acceleration=1e-6) ######################## # FIELDS # @@ -63,65 +52,73 @@ with CodeGeneration() as ctx: # RELAXATION RATES AND EXTERNAL FORCES # ######################################## - # calculate the relaxation rate for the hydro lb as well as the body force - density = density_gas + C.center * (density_liquid - density_gas) - + # relaxation rate for interface tracking LB step + relaxation_rate_allen_cahn = 1.0 / (0.5 + (3.0 * parameters.symbolic_mobility)) + # calculate the relaxation rate for hydrodynamic LB step + rho_L = parameters.symbolic_density_light + rho_H = parameters.symbolic_density_heavy + density = rho_L + C.center * (rho_H - rho_L) # force acting on all phases of the model - body_force = np.array([0, 1e-6, 0]) + body_force = [0, 0, 0] + body_force[1] = parameters.symbolic_gravitational_acceleration * density - relaxation_time = 0.03 + 0.5 - relaxation_rate = 1.0 / relaxation_time + omega = parameters.omega(C) ############### # LBM METHODS # ############### - lbm_config_phase = LBMConfig(stencil=stencil_phase, method=Method.SRT, relaxation_rate=w_c, compressible=True) + rates = [0.0] + rates += [relaxation_rate_allen_cahn] * stencil_phase.D + rates += [1.0] * (stencil_phase.Q - stencil_phase.D - 1) + + lbm_config_phase = LBMConfig(stencil=stencil_phase, method=Method.MRT, compressible=True, + delta_equilibrium=False, + force=sp.symbols(f"F_:{stencil_phase.D}"), velocity_input=u, + weighted=True, relaxation_rates=rates, + output={'density': C_tmp}, kernel_type='stream_pull_collide') method_phase = create_lb_method(lbm_config=lbm_config_phase) - lbm_config_hydro = LBMConfig(stencil=stencil_hydro, method=Method.MRT, weighted=True, - relaxation_rates=[relaxation_rate, 1, 1, 1, 1, 1]) + lbm_config_hydro = LBMConfig(stencil=stencil_hydro, method=Method.MRT, compressible=False, + weighted=True, relaxation_rate=omega, + force=sp.symbols(f"F_:{stencil_hydro.D}"), + output={'velocity': u}, kernel_type='collide_stream_push') method_hydro = create_lb_method(lbm_config=lbm_config_hydro) # create the kernels for the initialization of the g and h field - h_updates = initializer_kernel_phase_field_lb(h, C, u, method_phase, W) - g_updates = initializer_kernel_hydro_lb(g, u, method_hydro) - - force_h = [f / 3 for f in interface_tracking_force(C, stencil_phase, W, fd_stencil=LBStencil(Stencil.D3Q27))] - force_model_h = MultiphaseForceModel(force=force_h) + h_updates = initializer_kernel_phase_field_lb(method_phase, C, u, h, parameters) + h_updates = h_updates.new_with_substitutions(parameters.parameter_map()) - force_g = hydrodynamic_force(g, C, method_hydro, relaxation_time, density_liquid, density_gas, kappa, beta, - body_force, - fd_stencil=LBStencil(Stencil.D3Q27)) + g_updates = initializer_kernel_hydro_lb(method_hydro, 1, u, g) + g_updates = g_updates.new_with_substitutions(parameters.parameter_map()) - force_model_g = MultiphaseForceModel(force=force_g, rho=density) + force_h = interface_tracking_force(C, stencil_phase, parameters) + hydro_force = hydrodynamic_force(g, C, method_hydro, parameters, body_force) #################### # LBM UPDATE RULES # #################### - phase_field_LB_step = get_collision_assignments_phase(lb_method=method_phase, - velocity_input=u, - output={'density': C_tmp}, - force_model=force_model_h, - symbolic_fields={"symbolic_field": h, - "symbolic_temporary_field": h_tmp}, - kernel_type='stream_pull_collide') + lbm_optimisation = LBMOptimisation(symbolic_field=h, symbolic_temporary_field=h_tmp) + phase_field_LB_step = create_lb_update_rule(lbm_config=lbm_config_phase, + lbm_optimisation=lbm_optimisation) - phase_field_LB_step = sympy_cse(phase_field_LB_step) + phase_field_LB_step = add_interface_tracking_force(phase_field_LB_step, force_h) + phase_field_LB_step = phase_field_LB_step.new_with_substitutions(parameters.parameter_map()) + phase_field_LB_step = sympy_cse(phase_field_LB_step) # --------------------------------------------------------------------------------------------------------- + force_Assignments = hydrodynamic_force_assignments(g, u, C, method_hydro, parameters, body_force) - hydro_LB_step = get_collision_assignments_hydro(lb_method=method_hydro, - density=density, - velocity_input=u, - force_model=force_model_g, - sub_iterations=2, - symbolic_fields={"symbolic_field": g, - "symbolic_temporary_field": g_tmp}, - kernel_type='collide_stream_push') + lbm_optimisation = LBMOptimisation(symbolic_field=g, symbolic_temporary_field=g_tmp) + hydro_LB_step = create_lb_update_rule(lbm_config=lbm_config_hydro, + lbm_optimisation=lbm_optimisation) + + hydro_LB_step = add_hydrodynamic_force(hydro_LB_step, force_Assignments, C, g, parameters) + hydro_LB_step = hydro_LB_step.new_with_substitutions(parameters.parameter_map()) hydro_LB_step = sympy_cse(hydro_LB_step) + ################### # GENERATE SWEEPS # ################### diff --git a/apps/benchmarks/UniformGridCPU/UniformGridCPU.cpp b/apps/benchmarks/UniformGridCPU/UniformGridCPU.cpp index c5fef7d89..9916a71e1 100644 --- a/apps/benchmarks/UniformGridCPU/UniformGridCPU.cpp +++ b/apps/benchmarks/UniformGridCPU/UniformGridCPU.cpp @@ -84,8 +84,8 @@ int main(int argc, char** argv) // Creating fields BlockDataID pdfFieldId = blocks->addStructuredBlockData< PdfField_T >(pdfFieldAdder, "pdfs"); - BlockDataID velFieldId = field::addToStorage< VelocityField_T >(blocks, "vel", real_t(0), field::fzyx); - BlockDataID densityFieldId = field::addToStorage< ScalarField_T >(blocks, "density", real_t(1.0), field::fzyx); + BlockDataID velFieldId = field::addToStorage< VelocityField_T >(blocks, "vel", real_c(0.0), field::fzyx); + BlockDataID densityFieldId = field::addToStorage< ScalarField_T >(blocks, "density", real_c(1.0), field::fzyx); // Initialize velocity on cpu if (initShearFlow) @@ -270,7 +270,7 @@ int main(int argc, char** argv) timeLoop.singleStep(); real_t remainingTimeLoggerFrequency = - parameters.getParameter< real_t >("remainingTimeLoggerFrequency", -1.0); // in seconds + parameters.getParameter< real_t >("remainingTimeLoggerFrequency", real_c(-1.0)); // in seconds if (remainingTimeLoggerFrequency > 0) { auto logger = timing::RemainingTimeLogger(timeLoop.getNrOfTimeSteps() * uint_c(outerIterations), @@ -287,7 +287,7 @@ int main(int argc, char** argv) timeLoop.run(); simTimer.end(); WALBERLA_LOG_INFO_ON_ROOT("Simulation finished") - real_t time = simTimer.last(); + auto time = real_c(simTimer.last()); WALBERLA_MPI_SECTION() { walberla::mpi::reduceInplace(time, walberla::mpi::MAX); diff --git a/apps/benchmarks/UniformGridCPU/UniformGridCPU.py b/apps/benchmarks/UniformGridCPU/UniformGridCPU.py index 2ea96523a..c8f500174 100644 --- a/apps/benchmarks/UniformGridCPU/UniformGridCPU.py +++ b/apps/benchmarks/UniformGridCPU/UniformGridCPU.py @@ -69,6 +69,7 @@ options_dict = { 'entropic': { 'method': Method.TRT_KBC_N4, 'compressible': True, + 'zero_centered': False, 'relaxation_rates': [omega, omega_free], 'entropic': True, 'entropic_newton_iterations': False @@ -148,8 +149,6 @@ with CodeGeneration() as ctx: collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) if optimize: - collision_rule = insert_fast_divisions(collision_rule) - collision_rule = insert_fast_sqrts(collision_rule) collision_rule = insert_constants(collision_rule) collision_rule = insert_zeros(collision_rule) collision_rule = insert_aliases(collision_rule) diff --git a/apps/benchmarks/UniformGridGPU/UniformGridGPU.cpp b/apps/benchmarks/UniformGridGPU/UniformGridGPU.cpp index b12c534a4..4d2ee1afa 100644 --- a/apps/benchmarks/UniformGridGPU/UniformGridGPU.cpp +++ b/apps/benchmarks/UniformGridGPU/UniformGridGPU.cpp @@ -86,8 +86,8 @@ int main(int argc, char** argv) // Creating fields BlockDataID pdfFieldCpuID = - field::addToStorage< PdfField_T >(blocks, "pdfs cpu", real_t(std::nan("")), field::fzyx); - BlockDataID velFieldCpuID = field::addToStorage< VelocityField_T >(blocks, "vel", real_t(0), field::fzyx); + field::addToStorage< PdfField_T >(blocks, "pdfs cpu", real_c(std::nan("")), field::fzyx); + BlockDataID velFieldCpuID = field::addToStorage< VelocityField_T >(blocks, "vel", real_c(0.0), field::fzyx); // Initialize velocity on cpu if (initShearFlow) @@ -294,7 +294,7 @@ int main(int argc, char** argv) timeLoop.singleStep(); double remainingTimeLoggerFrequency = - parameters.getParameter< double >("remainingTimeLoggerFrequency", -1.0); // in seconds + parameters.getParameter< real_t >("remainingTimeLoggerFrequency", real_c(-1.0)); // in seconds if (remainingTimeLoggerFrequency > 0) { auto logger = timing::RemainingTimeLogger(timeLoop.getNrOfTimeSteps() * uint_c(outerIterations), @@ -316,7 +316,7 @@ int main(int argc, char** argv) cudaDeviceSynchronize(); simTimer.end(); WALBERLA_LOG_INFO_ON_ROOT("Simulation finished") - auto time = simTimer.last(); + auto time = real_c(simTimer.last()); auto nrOfCells = real_c(cellsPerBlock[0] * cellsPerBlock[1] * cellsPerBlock[2]); auto mlupsPerProcess = nrOfCells * real_c(timesteps) / time * 1e-6; diff --git a/apps/benchmarks/UniformGridGPU/UniformGridGPU.py b/apps/benchmarks/UniformGridGPU/UniformGridGPU.py index ce61f5f0e..e8fa9906a 100644 --- a/apps/benchmarks/UniformGridGPU/UniformGridGPU.py +++ b/apps/benchmarks/UniformGridGPU/UniformGridGPU.py @@ -4,7 +4,7 @@ import pystencils as ps from dataclasses import replace -from pystencils.data_types import TypedSymbol +from pystencils.typing import TypedSymbol from pystencils.fast_approximation import insert_fast_sqrts, insert_fast_divisions from lbmpy import LBMConfig, LBMOptimisation, LBStencil, Method, Stencil @@ -78,6 +78,7 @@ options_dict = { 'entropic': { 'method': Method.TRT_KBC_N4, 'compressible': True, + 'zero_centered': False, 'relaxation_rates': [omega, omega_free], 'entropic': True, 'entropic_newton_iterations': False @@ -184,7 +185,7 @@ with CodeGeneration() as ctx: # Boundaries noslip = NoSlip() - ubb = UBB((0.05, 0, 0)) + ubb = UBB((0.05, 0, 0), data_type=field_type) generate_alternating_lbm_boundary(ctx, 'UniformGridGPU_NoSlip', noslip, lb_method, field_name=pdfs.name, streaming_pattern=streaming_pattern, target=ps.Target.GPU) diff --git a/apps/benchmarks/UniformGridGPU/old_ideas/UniformGridGPU.py b/apps/benchmarks/UniformGridGPU/old_ideas/UniformGridGPU.py index c861cb155..619c9fbfc 100644 --- a/apps/benchmarks/UniformGridGPU/old_ideas/UniformGridGPU.py +++ b/apps/benchmarks/UniformGridGPU/old_ideas/UniformGridGPU.py @@ -7,7 +7,7 @@ from lbmpy.fieldaccess import StreamPullTwoFieldsAccessor from pystencils_walberla import generate_pack_info_from_kernel from lbmpy_walberla import generate_lattice_model, generate_boundary from pystencils_walberla import CodeGeneration, generate_sweep -from pystencils.data_types import TypedSymbol +from pystencils.typing import TypedSymbol from pystencils.fast_approximation import insert_fast_sqrts, insert_fast_divisions from lbmpy.macroscopic_value_kernels import macroscopic_values_getter, macroscopic_values_setter diff --git a/apps/showcases/PhaseFieldAllenCahn/CPU/InitializerFunctions.cpp b/apps/showcases/PhaseFieldAllenCahn/CPU/InitializerFunctions.cpp index 979c87ff3..d7cb146a0 100644 --- a/apps/showcases/PhaseFieldAllenCahn/CPU/InitializerFunctions.cpp +++ b/apps/showcases/PhaseFieldAllenCahn/CPU/InitializerFunctions.cpp @@ -33,9 +33,9 @@ using PhaseField_T = GhostLayerField< real_t, 1 >; using FlagField_T = FlagField< uint8_t >; void initPhaseField_sphere(const shared_ptr< StructuredBlockStorage >& blocks, BlockDataID phaseFieldID, - const real_t R = 10, + const real_t R = real_c(10.0), const Vector3< real_t > bubbleMidPoint = Vector3< real_t >(0.0, 0.0, 0.0), - const bool bubble = true, const real_t W = 5) + const bool bubble = true, const real_t W = real_c(5.0)) { for (auto& block : *blocks) { @@ -43,21 +43,21 @@ void initPhaseField_sphere(const shared_ptr< StructuredBlockStorage >& blocks, B // clang-format off WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ(phaseField, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); - real_t Ri = sqrt((globalCell[0] - bubbleMidPoint[0]) * (globalCell[0] - bubbleMidPoint[0]) + - (globalCell[1] - bubbleMidPoint[1]) * (globalCell[1] - bubbleMidPoint[1]) + - (globalCell[2] - bubbleMidPoint[2]) * (globalCell[2] - bubbleMidPoint[2])); - if (bubble) phaseField->get(x, y, z) = 0.5 + 0.5 * tanh(2.0 * (Ri - R) / W); - else phaseField->get(x, y, z) = 0.5 - 0.5 * tanh(2.0 * (Ri - R) / W); + real_t Ri = sqrt((real_c(globalCell[0]) - bubbleMidPoint[0]) * (real_c(globalCell[0]) - bubbleMidPoint[0]) + + (real_c(globalCell[1]) - bubbleMidPoint[1]) * (real_c(globalCell[1]) - bubbleMidPoint[1]) + + (real_c(globalCell[2]) - bubbleMidPoint[2]) * (real_c(globalCell[2]) - bubbleMidPoint[2])); + if (bubble) phaseField->get(x, y, z) = real_c(0.5) + real_c(0.5) * real_c(tanh(2.0 * (Ri - R) / W)); + else phaseField->get(x, y, z) = real_c(0.5) - real_c(0.5) * real_c(tanh(2.0 * (Ri - R) / W)); ) // clang-format on } } void init_Taylor_bubble(const shared_ptr< StructuredBlockStorage >& blocks, BlockDataID phaseFieldID, - const real_t D = 5, const real_t H = 2, const real_t DT = 20, const real_t Donut_x0 = 40) + const real_t D = real_c(5.0), const real_t H = real_c(2.0), const real_t DT = real_c(20.0), const real_t Donut_x0 = real_c(40.0)) { - auto Mx = blocks->getDomainCellBB().xMax() / 2.0; - auto Mz = blocks->getDomainCellBB().zMax() / 2.0; + auto Mx = real_c(blocks->getDomainCellBB().xMax()) / real_c(2.0); + auto Mz = real_c(blocks->getDomainCellBB().zMax()) / real_c(2.0); for (auto& block : *blocks) { @@ -65,42 +65,42 @@ void init_Taylor_bubble(const shared_ptr< StructuredBlockStorage >& blocks, Bloc WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ( phaseField, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); - real_t Ri = D * sqrt(pow(H, 2) - pow(DT - sqrt(pow(globalCell[0] - Mx, 2) + pow(globalCell[2] - Mz, 2)), 2)); + real_t Ri = D * real_c(sqrt(pow(H, 2) - pow(DT - sqrt(pow(real_c(globalCell[0]) - Mx, 2) + pow(real_c(globalCell[2]) - Mz, 2)), 2))); - real_t shifter = atan2((globalCell[2] - Mz), (globalCell[0] - Mx)); + real_t shifter = atan2((real_c(globalCell[2]) - Mz), (real_c(globalCell[0]) - Mx)); if (shifter < 0) shifter = shifter + 2 * math::pi; - if ((globalCell[1] < Donut_x0 + Ri * sin(shifter / 2.0)) && (globalCell[1] > Donut_x0 - Ri)) { + if ((real_c(globalCell[1]) < Donut_x0 + Ri * sin(shifter / 2.0)) && (real_c(globalCell[1]) > Donut_x0 - Ri)) { phaseField->get(x, y, z) = 0.0; - } else { phaseField->get(x, y, z) = 1.0; }) + } else { phaseField->get(x, y, z) = real_c(1.0); }) } } void init_bubble_field(const shared_ptr< StructuredBlockStorage >& blocks, BlockDataID phaseFieldID, real_t R, - real_t W = 5) + real_t W = real_c(5.0)) { Vector3< real_t > bubbleMidPoint; - auto X = blocks->getDomainCellBB().xMax(); - auto Y = blocks->getDomainCellBB().yMax(); - auto Z = blocks->getDomainCellBB().zMax(); + auto X = real_c(blocks->getDomainCellBB().xMax()); + auto Y = real_c(blocks->getDomainCellBB().yMax()); + auto Z = real_c(blocks->getDomainCellBB().zMax()); // 20 percent from the top are filled with the gas phase - real_t gas_top = Y - Y / 5.0; + real_t gas_top = Y - Y / real_c(5.0); // Diameter of the bubble - real_t D = R * 2; + real_t D = R * real_c(2.0); // distance in between the bubbles - int dist = 4; - auto nx = static_cast< unsigned int >(floor(X / (D + dist * W))); - auto nz = static_cast< unsigned int >(floor(Z / (D + dist * W))); + real_t dist = real_c(4.0); + auto nx = uint_c(floor(X / (D + dist * W))); + auto nz = uint_c(floor(Z / (D + dist * W))); // fluctuation of the bubble radii std::vector< std::vector< real_t > > fluctuation_radius(nx, std::vector< real_t >(nz, 0.0)); std::vector< std::vector< real_t > > fluctuation_pos(nx, std::vector< real_t >(nz, 0.0)); - real_t max_fluctuation_radius = R / 5; - real_t max_fluctuation_pos = (dist * W) / 3.0; + real_t max_fluctuation_radius = R / real_c(5.0); + real_t max_fluctuation_pos = (dist * W) / real_c(3.0); for (unsigned int i = 0; i < nx; ++i) { for (unsigned int j = 0; j < nz; ++j) @@ -118,35 +118,35 @@ void init_bubble_field(const shared_ptr< StructuredBlockStorage >& blocks, Block for (unsigned int i = 0; i < nx; ++i) { for (unsigned int j = 0; j < nz; ++j) { - bubbleMidPoint[0] = (i + 1) * (D + (dist * W)) - (D + (dist * W)) / 2.0 + fluctuation_pos[i][j]; + bubbleMidPoint[0] = real_c(i + 1) * (D + (dist * W)) - (D + (dist * W)) / real_c(2.0) + fluctuation_pos[i][j]; bubbleMidPoint[1] = R + W + 4; - bubbleMidPoint[2] = (j + 1) * (D + (dist * W)) - (D + (dist * W)) / 2.0 + fluctuation_pos[i][j]; + bubbleMidPoint[2] = real_c(j + 1) * (D + (dist * W)) - (D + (dist * W)) / real_c(2.0) + fluctuation_pos[i][j]; - real_t Ri = sqrt((globalCell[0] - bubbleMidPoint[0]) * (globalCell[0] - bubbleMidPoint[0]) + - (globalCell[1] - bubbleMidPoint[1]) * (globalCell[1] - bubbleMidPoint[1]) + - (globalCell[2] - bubbleMidPoint[2]) * (globalCell[2] - bubbleMidPoint[2])); - if (globalCell[0] >= i * (D + dist * W) && globalCell[0] <= (i + 1) * (D + dist * W) && - globalCell[2] >= j * (D + dist * W) && globalCell[2] <= (j + 1) * (D + dist * W)) - phaseField->get(x, y, z) = 0.5 + 0.5 * tanh(2.0 * (Ri - (R - fluctuation_radius[i][j])) / W); + real_t Ri = sqrt((real_c(globalCell[0]) - bubbleMidPoint[0]) * (real_c(globalCell[0]) - bubbleMidPoint[0]) + + (real_c(globalCell[1]) - bubbleMidPoint[1]) * (real_c(globalCell[1]) - bubbleMidPoint[1]) + + (real_c(globalCell[2]) - bubbleMidPoint[2]) * (real_c(globalCell[2]) - bubbleMidPoint[2])); + if (real_c(globalCell[0]) >= real_c(i) * (D + dist * W) && real_c(globalCell[0]) <= real_c(i + 1) * (D + dist * W) && + real_c(globalCell[2]) >= real_c(j) * (D + dist * W) && real_c(globalCell[2]) <= real_c(j + 1) * (D + dist * W)) + phaseField->get(x, y, z) = real_c(0.5) + real_c(0.5) * tanh(real_c(2.0) * (Ri - (R - fluctuation_radius[i][j])) / W); - if (globalCell[0] > nx * (D + dist * W)) phaseField->get(x, y, z) = 1.0; - if (globalCell[2] > nz * (D + dist * W)) phaseField->get(x, y, z) = 1.0; + if (real_c(globalCell[0]) > real_c(nx) * (D + dist * W)) phaseField->get(x, y, z) = real_c(1.0); + if (real_c(globalCell[2]) > real_c(nz) * (D + dist * W)) phaseField->get(x, y, z) = real_c(1.0); } } - if (globalCell[1] > gas_top) { - phaseField->get(x, y, z) = 0.5 + 0.5 * tanh(2.0 * (gas_top + 10 - globalCell[1]) / W); + if (real_c(globalCell[1]) > gas_top) { + phaseField->get(x, y, z) = real_c(0.5) + real_c(0.5) * tanh(real_c(2.0) * (gas_top + 10 - real_c(globalCell[1])) / W); }) } } void initPhaseField_RTI(const shared_ptr< StructuredBlockStorage >& blocks, BlockDataID phaseFieldID, - const real_t W = 5, const bool pipe = true) + const real_t W = real_c(5.0), const bool pipe = true) { - auto X = blocks->getDomainCellBB().xMax(); - auto Z = blocks->getDomainCellBB().zMax(); - auto halfY = (blocks->getDomainCellBB().yMax()) / 2.0; - real_t perturbation = 0.05; + auto X = real_c(blocks->getDomainCellBB().xMax()); + auto Z = real_c(blocks->getDomainCellBB().zMax()); + auto halfY = real_c(blocks->getDomainCellBB().yMax()) / real_c(2.0); + auto perturbation = real_c(0.05); if (pipe) { @@ -155,10 +155,10 @@ void initPhaseField_RTI(const shared_ptr< StructuredBlockStorage >& blocks, Bloc auto phaseField = block.getData< PhaseField_T >(phaseFieldID); WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ( phaseField, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); - real_t R = sqrt((globalCell[0] - X / 2) * (globalCell[0] - X / 2) + - (globalCell[2] - Z / 2) * (globalCell[2] - Z / 2)); - if (R > X) R = X; real_t tmp = perturbation * X * cos((2.0 * math::pi * R) / X); - phaseField->get(x, y, z) = 0.5 + 0.5 * tanh(((globalCell[1] - halfY) + tmp) / (W / 2.0));) + real_t R = sqrt((real_c(globalCell[0]) - X / 2) * (real_c(globalCell[0]) - X / 2) + + (real_c(globalCell[2]) - Z / 2) * (real_c(globalCell[2]) - Z / 2)); + if (R > X) R = X; real_t tmp = perturbation * X * cos((real_c(2.0) * math::pi * R) / X); + phaseField->get(x, y, z) = real_c(0.5) + real_c(0.5) * tanh(((real_c(globalCell[1]) - halfY) + tmp) / (W / real_c(2.0)));) } } else @@ -169,8 +169,8 @@ void initPhaseField_RTI(const shared_ptr< StructuredBlockStorage >& blocks, Bloc WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ( phaseField, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); real_t tmp = perturbation * X * - (cos((2.0 * math::pi * globalCell[0]) / X) + cos((2.0 * math::pi * globalCell[2]) / X)); - phaseField->get(x, y, z) = 0.5 + 0.5 * tanh(((globalCell[1] - halfY) - tmp) / (W / 2.0));) + (cos((real_c(2.0) * math::pi * real_c(globalCell[0])) / X) + cos((real_c(2.0) * math::pi * real_c(globalCell[2])) / X)); + phaseField->get(x, y, z) = real_c(0.5) + real_c(0.5) * tanh(((real_c(globalCell[1]) - halfY) - tmp) / (W / real_c(2.0)));) } } } @@ -182,12 +182,12 @@ void initTubeWithCylinder(const shared_ptr< StructuredBlockStorage >& blocks, Bl { if (eccentricity_or_pipe_ratio) { - auto Mx = blocks->getDomainCellBB().xMax() / 2.0; - auto Mz = blocks->getDomainCellBB().zMax() / 2.0; + auto Mx = real_c(blocks->getDomainCellBB().xMax()) / real_c(2.0); + auto Mz = real_c(blocks->getDomainCellBB().zMax()) / real_c(2.0); - auto R_outer = blocks->getDomainCellBB().xMax() / 2.0 + 1.0; + auto R_outer = real_c(blocks->getDomainCellBB().xMax()) / real_c(2.0) + real_c(1.0); - real_t const shift = eccentricity * Mx / 2; + auto const shift = real_c(eccentricity * Mx / real_c(2.0)); for (auto& block : *blocks) { @@ -196,31 +196,31 @@ void initTubeWithCylinder(const shared_ptr< StructuredBlockStorage >& blocks, Bl WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ(flagField, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); real_t R1; - if (globalCell[1] <= start_transition) { - R1 = sqrt((globalCell[0] - Mx) * (globalCell[0] - Mx) + (globalCell[2] - Mz) * (globalCell[2] - Mz)); - } else if (globalCell[1] > start_transition && globalCell[1] < start_transition + length_transition) { - real_t tmp = math::pi * (globalCell[1] - start_transition) / (length_transition); - real_t shift_tmp = shift * 0.5 * (1 - cos(tmp)); - R1 = sqrt((globalCell[0] - Mx - shift_tmp) * (globalCell[0] - Mx - shift_tmp) + - (globalCell[2] - Mz) * (globalCell[2] - Mz)); + if (real_c(globalCell[1]) <= start_transition) { + R1 = sqrt((real_c(globalCell[0]) - Mx) * (real_c(globalCell[0]) - Mx) + (real_c(globalCell[2]) - Mz) * (real_c(globalCell[2]) - Mz)); + } else if (real_c(globalCell[1]) > start_transition && real_c(globalCell[1]) < start_transition + length_transition) { + real_t tmp = math::pi * (real_c(globalCell[1]) - start_transition) / (length_transition); + real_t shift_tmp = shift * real_c(0.5) * (1 - cos(tmp)); + R1 = sqrt((real_c(globalCell[0]) - Mx - shift_tmp) * (real_c(globalCell[0]) - Mx - shift_tmp) + + (real_c(globalCell[2]) - Mz) * (real_c(globalCell[2]) - Mz)); } else { - R1 = sqrt((globalCell[0] - Mx - shift) * (globalCell[0] - Mx - shift) + - (globalCell[2] - Mz) * (globalCell[2] - Mz)); + R1 = sqrt((real_c(globalCell[0]) - Mx - shift) * (real_c(globalCell[0]) - Mx - shift) + + (real_c(globalCell[2]) - Mz) * (real_c(globalCell[2]) - Mz)); } - real_t R2 = sqrt((globalCell[0] - Mx) * (globalCell[0] - Mx) + (globalCell[2] - Mz) * (globalCell[2] - Mz)); + real_t R2 = sqrt((real_c(globalCell[0]) - Mx) * (real_c(globalCell[0]) - Mx) + (real_c(globalCell[2]) - Mz) * (real_c(globalCell[2]) - Mz)); if (R1 < R_in) addFlag(flagField->get(x, y, z), boundaryFlag); if (R2 > R_outer) addFlag(flagField->get(x, y, z), boundaryFlag);) } } else { - auto Mx = blocks->getDomainCellBB().xMax() / 2.0; - auto Mz = blocks->getDomainCellBB().zMax() / 2.0; + auto Mx = real_c(blocks->getDomainCellBB().xMax()) / real_c(2.0); + auto Mz = real_c(blocks->getDomainCellBB().zMax()) / real_c(2.0); - auto R_outer = blocks->getDomainCellBB().xMax() / 2.0 + 1.0; + auto R_outer = real_c(blocks->getDomainCellBB().xMax()) / real_c(2.0) + real_c(1.0); - real_t const shift = eccentricity * R_in; + auto const shift = real_c(eccentricity * R_in); real_t R_tmp; for (auto& block : *blocks) @@ -229,17 +229,17 @@ void initTubeWithCylinder(const shared_ptr< StructuredBlockStorage >& blocks, Bl auto boundaryFlag = flagField->getOrRegisterFlag(boundaryFlagUID); WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ( flagField, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); - if (globalCell[1] <= start_transition) { + if (real_c(globalCell[1]) <= start_transition) { R_tmp = R_in; - } else if (globalCell[1] > start_transition && globalCell[1] < start_transition + length_transition) { - real_t tmp = math::pi * (globalCell[1] - start_transition) / (length_transition); - real_t shift_tmp = shift * 0.5 * (1 - cos(tmp)); + } else if (real_c(globalCell[1]) > start_transition && real_c(globalCell[1]) < start_transition + length_transition) { + real_t tmp = math::pi * (real_c(globalCell[1]) - start_transition) / (length_transition); + real_t shift_tmp = shift * real_c(0.5) * (1 - cos(tmp)); R_tmp = R_in + shift_tmp; } else { R_tmp = R_in + shift; } - real_t R2 = sqrt((globalCell[0] - Mx) * (globalCell[0] - Mx) + (globalCell[2] - Mz) * (globalCell[2] - Mz)); + real_t R2 = sqrt((real_c(globalCell[0]) - Mx) * (real_c(globalCell[0]) - Mx) + (real_c(globalCell[2]) - Mz) * (real_c(globalCell[2]) - Mz)); if (R2 < R_tmp) addFlag(flagField->get(x, y, z), boundaryFlag); if (R2 > R_outer) addFlag(flagField->get(x, y, z), boundaryFlag);) } diff --git a/apps/showcases/PhaseFieldAllenCahn/CPU/multiphase.cpp b/apps/showcases/PhaseFieldAllenCahn/CPU/multiphase.cpp index e9f21f0f0..184672199 100644 --- a/apps/showcases/PhaseFieldAllenCahn/CPU/multiphase.cpp +++ b/apps/showcases/PhaseFieldAllenCahn/CPU/multiphase.cpp @@ -79,7 +79,7 @@ int main(int argc, char** argv) const std::string timeStepStrategy = parameters.getParameter< std::string >("timeStepStrategy", "normal"); const uint_t timesteps = parameters.getParameter< uint_t >("timesteps", uint_c(50)); const real_t remainingTimeLoggerFrequency = - parameters.getParameter< real_t >("remainingTimeLoggerFrequency", 3.0); + parameters.getParameter< real_t >("remainingTimeLoggerFrequency", real_c(3.0)); const uint_t scenario = parameters.getParameter< uint_t >("scenario", uint_c(1)); Vector3< int > overlappingWidth = @@ -90,11 +90,11 @@ int main(int argc, char** argv) /////////////////////// BlockDataID lb_phase_field = - field::addToStorage< PdfField_phase_T >(blocks, "lb phase field", real_t(0), field::fzyx); + field::addToStorage< PdfField_phase_T >(blocks, "lb phase field", real_c(0.0), field::fzyx); BlockDataID lb_velocity_field = - field::addToStorage< PdfField_hydro_T >(blocks, "lb velocity field", real_t(0), field::fzyx); - BlockDataID vel_field = field::addToStorage< VelocityField_T >(blocks, "vel", real_t(0), field::fzyx); - BlockDataID phase_field = field::addToStorage< PhaseField_T >(blocks, "phase", real_t(0), field::fzyx); + field::addToStorage< PdfField_hydro_T >(blocks, "lb velocity field", real_c(0.0), field::fzyx); + BlockDataID vel_field = field::addToStorage< VelocityField_T >(blocks, "vel", real_c(0.0), field::fzyx); + BlockDataID phase_field = field::addToStorage< PhaseField_T >(blocks, "phase", real_c(0.0), field::fzyx); BlockDataID flagFieldID = field::addFlagFieldToStorage< FlagField_T >(blocks, "flag field"); @@ -114,7 +114,7 @@ int main(int argc, char** argv) { auto bubbleParameters = config->getOneBlock("Bubble"); const Vector3< real_t > bubbleMidPoint = bubbleParameters.getParameter< Vector3< real_t > >("bubbleMidPoint"); - const real_t bubbleRadius = bubbleParameters.getParameter< real_t >("bubbleRadius", 20.0); + const real_t bubbleRadius = bubbleParameters.getParameter< real_t >("bubbleRadius", real_c(20.0)); const bool bubble = bubbleParameters.getParameter< bool >("bubble", true); initPhaseField_sphere(blocks, phase_field, bubbleRadius, bubbleMidPoint, bubble); } @@ -300,7 +300,7 @@ int main(int argc, char** argv) timeLoop->run(); simTimer.end(); WALBERLA_LOG_INFO_ON_ROOT("Simulation finished") - auto time = simTimer.last(); + auto time = real_c(simTimer.last()); auto nrOfCells = real_c(cellsPerBlock[0] * cellsPerBlock[1] * cellsPerBlock[2]); auto mlupsPerProcess = nrOfCells * real_c(timesteps) / time * 1e-6; WALBERLA_LOG_RESULT_ON_ROOT("MLUPS per process: " << mlupsPerProcess) diff --git a/apps/showcases/PhaseFieldAllenCahn/CPU/multiphase_codegen.py b/apps/showcases/PhaseFieldAllenCahn/CPU/multiphase_codegen.py index df7771178..a2dba9cb5 100644 --- a/apps/showcases/PhaseFieldAllenCahn/CPU/multiphase_codegen.py +++ b/apps/showcases/PhaseFieldAllenCahn/CPU/multiphase_codegen.py @@ -1,19 +1,18 @@ import numpy as np import sympy as sp -from pystencils import Assignment, fields, TypedSymbol, Target -from pystencils.astnodes import Block, Conditional -from pystencils.simp import sympy_cse +from pystencils import fields, Target +from pystencils.typing import TypedSymbol -from lbmpy import LBMConfig, LBStencil, Method, Stencil +from lbmpy import LBMConfig, LBMOptimisation, LBStencil, Method, Stencil, create_lb_update_rule from lbmpy.creationfunctions import create_lb_method from lbmpy.boundaries import NoSlip from lbmpy.phasefield_allen_cahn.contact_angle import ContactAngle -from lbmpy.phasefield_allen_cahn.force_model import MultiphaseForceModel from lbmpy.phasefield_allen_cahn.kernel_equations import initializer_kernel_phase_field_lb, \ - initializer_kernel_hydro_lb, interface_tracking_force, hydrodynamic_force, get_collision_assignments_hydro, \ - get_collision_assignments_phase + initializer_kernel_hydro_lb, interface_tracking_force, hydrodynamic_force, add_interface_tracking_force, \ + add_hydrodynamic_force, hydrodynamic_force_assignments +from lbmpy.phasefield_allen_cahn.parameter_calculation import AllenCahnParameters import pystencils_walberla from pystencils_walberla import CodeGeneration, generate_sweep, generate_pack_info_for_field, generate_info_header @@ -29,28 +28,8 @@ with CodeGeneration() as ctx: stencil_hydro = LBStencil(Stencil.D3Q27) assert (stencil_phase.D == stencil_hydro.D) - ######################## - # PARAMETER DEFINITION # - ######################## - - density_liquid = sp.Symbol("rho_H") - density_gas = sp.Symbol("rho_L") - - surface_tension = sp.Symbol("sigma") - mobility = sp.Symbol("mobility") - - gravitational_acceleration = sp.Symbol("gravity") - - relaxation_time_liquid = sp.Symbol("tau_H") - relaxation_time_gas = sp.Symbol("tau_L") - - # phase-field parameter - drho3 = (density_liquid - density_gas) / 3 - # interface thickness - W = sp.Symbol("interface_thickness") - # coefficients related to surface tension - beta = 12.0 * (surface_tension / W) - kappa = 1.5 * surface_tension * W + # In the codegneration skript we only need the symbolic parameters + parameters = AllenCahnParameters(0, 0, 0, 0, 0) ######################## # FIELDS # @@ -74,73 +53,65 @@ with CodeGeneration() as ctx: ######################################## # relaxation rate for interface tracking LB step - relaxation_rate_allen_cahn = 1.0 / (0.5 + (3.0 * mobility)) + relaxation_rate_allen_cahn = 1.0 / (0.5 + (3.0 * parameters.symbolic_mobility)) # calculate the relaxation rate for hydrodynamic LB step - density = density_gas + C.center * (density_liquid - density_gas) + rho_L = parameters.symbolic_density_light + rho_H = parameters.symbolic_density_heavy + density = rho_L + C.center * (rho_H - rho_L) # force acting on all phases of the model - body_force = np.array([0, gravitational_acceleration * density, 0]) - # calculation of the relaxation time via viscosities - # viscosity = viscosity_gas * viscosity_liquid + C.center\ - # * (density_liquid*viscosity_liquid - viscosity_liquid*viscosity_gas) - # relaxation_time = 3 * viscosity / density + 0.5 - - relaxation_time = 0.5 + relaxation_time_gas + C.center * (relaxation_time_liquid - relaxation_time_gas) - # calculate the relaxation time if the phase-field has values over one - # relaxation_rate = 1.0 / relaxation_time - relaxation_rate = sp.Symbol("s8") - relaxation_rate_cutoff = sp.Piecewise((1 / (0.5 + relaxation_time_liquid), C.center > 0.999), # True value - (1 / relaxation_time, True)) # Else value + body_force = [0, 0, 0] + body_force[1] = parameters.symbolic_gravitational_acceleration * density + + omega = parameters.omega(C) ############### # LBM METHODS # ############### - lbm_config_phase = LBMConfig(stencil=stencil_phase, method=Method.MRT, compressible=True, weighted=True, - relaxation_rates=[1, 1, 1, 1, 1, 1]) + + rates = [0.0] + rates += [relaxation_rate_allen_cahn] * stencil_phase.D + rates += [1.0] * (stencil_phase.Q - stencil_phase.D - 1) + + lbm_config_phase = LBMConfig(stencil=stencil_phase, method=Method.MRT, compressible=True, + delta_equilibrium=False, + force=sp.symbols(f"F_:{stencil_phase.D}"), velocity_input=u, + weighted=True, relaxation_rates=rates, + output={'density': C_tmp}, kernel_type='stream_pull_collide') method_phase = create_lb_method(lbm_config=lbm_config_phase) - method_phase.set_first_moment_relaxation_rate(relaxation_rate_allen_cahn) - lbm_config_hydro = LBMConfig(stencil=stencil_hydro, method=Method.MRT, weighted=True, - relaxation_rates=[relaxation_rate, 1, 1, 1, 1, 1]) + lbm_config_hydro = LBMConfig(stencil=stencil_hydro, method=Method.MRT, compressible=False, + weighted=True, relaxation_rate=omega, + force=sp.symbols(f"F_:{stencil_hydro.D}"), + output={'velocity': u}, kernel_type='collide_stream_push') method_hydro = create_lb_method(lbm_config=lbm_config_hydro) # create the kernels for the initialization of the g and h field - h_updates = initializer_kernel_phase_field_lb(h, C, u, method_phase, W) - g_updates = initializer_kernel_hydro_lb(g, u, method_hydro) - - force_h = [f / 3 for f in interface_tracking_force(C, stencil_phase, W)] - force_model_h = MultiphaseForceModel(force=force_h) + h_updates = initializer_kernel_phase_field_lb(method_phase, C, u, h, parameters) + g_updates = initializer_kernel_hydro_lb(method_hydro, 1, u, g) - force_g = hydrodynamic_force(g, C, method_hydro, relaxation_time, - density_liquid, density_gas, kappa, beta, body_force) - force_model_g = MultiphaseForceModel(force=force_g, rho=density) + force_h = interface_tracking_force(C, stencil_phase, parameters) + hydro_force = hydrodynamic_force(g, C, method_hydro, parameters, body_force) #################### # LBM UPDATE RULES # #################### - phase_field_LB_step = get_collision_assignments_phase(lb_method=method_phase, - velocity_input=u, - output={'density': C_tmp}, - force_model=force_model_h, - symbolic_fields={"symbolic_field": h, - "symbolic_temporary_field": h_tmp}, - kernel_type='stream_pull_collide') + lbm_optimisation = LBMOptimisation(symbolic_field=h, symbolic_temporary_field=h_tmp) + allen_cahn_update_rule = create_lb_update_rule(lbm_config=lbm_config_phase, + lbm_optimisation=lbm_optimisation) - phase_field_LB_step = sympy_cse(phase_field_LB_step) + allen_cahn_update_rule = add_interface_tracking_force(allen_cahn_update_rule, force_h) # --------------------------------------------------------------------------------------------------------- - hydro_LB_step = get_collision_assignments_hydro(lb_method=method_hydro, - density=density, - velocity_input=u, - force_model=force_model_g, - sub_iterations=2, - symbolic_fields={"symbolic_field": g, - "symbolic_temporary_field": g_tmp}, - kernel_type='collide_stream_push') + force_Assignments = hydrodynamic_force_assignments(g, u, C, method_hydro, parameters, body_force) + + lbm_optimisation = LBMOptimisation(symbolic_field=g, symbolic_temporary_field=g_tmp) + hydro_lb_update_rule = create_lb_update_rule(lbm_config=lbm_config_hydro, + lbm_optimisation=lbm_optimisation) - hydro_LB_step.set_sub_expressions_from_dict({**{relaxation_rate: relaxation_rate_cutoff}, - **hydro_LB_step.subexpressions_dict}) + hydro_lb_update_rule = add_hydrodynamic_force(hydro_lb_update_rule, force_Assignments, C, g, parameters) - contact_angle = ContactAngle(contact_angle_in_degrees, W) + contact_angle = ContactAngle(contact_angle_in_degrees, parameters.symbolic_interface_thickness, + data_type=field_type) ################### # GENERATE SWEEPS # @@ -171,13 +142,13 @@ with CodeGeneration() as ctx: generate_sweep(ctx, 'initialize_phase_field_distributions', h_updates, target=Target.CPU) generate_sweep(ctx, 'initialize_velocity_based_distributions', g_updates, target=Target.CPU) - generate_sweep(ctx, 'phase_field_LB_step', phase_field_LB_step, + generate_sweep(ctx, 'phase_field_LB_step', allen_cahn_update_rule, field_swaps=[(h, h_tmp), (C, C_tmp)], inner_outer_split=True, target=Target.CPU) generate_boundary(ctx, 'phase_field_LB_NoSlip', NoSlip(), method_phase, target=Target.CPU, streaming_pattern='pull') - generate_sweep(ctx, 'hydro_LB_step', hydro_LB_step, + generate_sweep(ctx, 'hydro_LB_step', hydro_lb_update_rule, field_swaps=[(g, g_tmp)], inner_outer_split=True, target=Target.CPU) diff --git a/apps/showcases/PhaseFieldAllenCahn/GPU/InitializerFunctions.cpp b/apps/showcases/PhaseFieldAllenCahn/GPU/InitializerFunctions.cpp index 979c87ff3..1d15f6a80 100644 --- a/apps/showcases/PhaseFieldAllenCahn/GPU/InitializerFunctions.cpp +++ b/apps/showcases/PhaseFieldAllenCahn/GPU/InitializerFunctions.cpp @@ -33,9 +33,9 @@ using PhaseField_T = GhostLayerField< real_t, 1 >; using FlagField_T = FlagField< uint8_t >; void initPhaseField_sphere(const shared_ptr< StructuredBlockStorage >& blocks, BlockDataID phaseFieldID, - const real_t R = 10, + const real_t R = real_c(10.0), const Vector3< real_t > bubbleMidPoint = Vector3< real_t >(0.0, 0.0, 0.0), - const bool bubble = true, const real_t W = 5) + const bool bubble = true, const real_t W = real_c(5.0)) { for (auto& block : *blocks) { @@ -43,21 +43,21 @@ void initPhaseField_sphere(const shared_ptr< StructuredBlockStorage >& blocks, B // clang-format off WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ(phaseField, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); - real_t Ri = sqrt((globalCell[0] - bubbleMidPoint[0]) * (globalCell[0] - bubbleMidPoint[0]) + - (globalCell[1] - bubbleMidPoint[1]) * (globalCell[1] - bubbleMidPoint[1]) + - (globalCell[2] - bubbleMidPoint[2]) * (globalCell[2] - bubbleMidPoint[2])); - if (bubble) phaseField->get(x, y, z) = 0.5 + 0.5 * tanh(2.0 * (Ri - R) / W); - else phaseField->get(x, y, z) = 0.5 - 0.5 * tanh(2.0 * (Ri - R) / W); + real_t Ri = sqrt((real_c(real_c(globalCell[0])) - bubbleMidPoint[0]) * (real_c(real_c(globalCell[0])) - bubbleMidPoint[0]) + + (real_c(globalCell[1]) - bubbleMidPoint[1]) * (real_c(globalCell[1]) - bubbleMidPoint[1]) + + (real_c(globalCell[2]) - bubbleMidPoint[2]) * (real_c(globalCell[2]) - bubbleMidPoint[2])); + if (bubble) phaseField->get(x, y, z) = real_c(0.5) + real_c(0.5) * real_c(tanh(real_c(2.0) * (Ri - R) / W)); + else phaseField->get(x, y, z) = real_c(0.5) - real_c(0.5) * tanh(real_c(2.0) * (Ri - R) / W); ) // clang-format on } } void init_Taylor_bubble(const shared_ptr< StructuredBlockStorage >& blocks, BlockDataID phaseFieldID, - const real_t D = 5, const real_t H = 2, const real_t DT = 20, const real_t Donut_x0 = 40) + const real_t D = 5.0, const real_t H = 2.0, const real_t DT = 20.0, const real_t Donut_x0 = 40.0) { - auto Mx = blocks->getDomainCellBB().xMax() / 2.0; - auto Mz = blocks->getDomainCellBB().zMax() / 2.0; + auto Mx = real_c(blocks->getDomainCellBB().xMax()) / real_c(2.0); + auto Mz = real_c(blocks->getDomainCellBB().zMax()) / real_c(2.0); for (auto& block : *blocks) { @@ -65,42 +65,42 @@ void init_Taylor_bubble(const shared_ptr< StructuredBlockStorage >& blocks, Bloc WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ( phaseField, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); - real_t Ri = D * sqrt(pow(H, 2) - pow(DT - sqrt(pow(globalCell[0] - Mx, 2) + pow(globalCell[2] - Mz, 2)), 2)); + real_t Ri = D * real_c(sqrt(pow(H, 2) - pow(DT - sqrt(pow(real_c(real_c(globalCell[0])) - Mx, 2) + pow(real_c(globalCell[2]) - Mz, 2)), 2))); - real_t shifter = atan2((globalCell[2] - Mz), (globalCell[0] - Mx)); + real_t shifter = atan2((real_c(globalCell[2]) - Mz), (real_c(globalCell[0]) - Mx)); if (shifter < 0) shifter = shifter + 2 * math::pi; - if ((globalCell[1] < Donut_x0 + Ri * sin(shifter / 2.0)) && (globalCell[1] > Donut_x0 - Ri)) { + if ((real_c(globalCell[1]) < Donut_x0 + Ri * sin(shifter / 2.0)) && (real_c(globalCell[1]) > Donut_x0 - Ri)) { phaseField->get(x, y, z) = 0.0; } else { phaseField->get(x, y, z) = 1.0; }) } } void init_bubble_field(const shared_ptr< StructuredBlockStorage >& blocks, BlockDataID phaseFieldID, real_t R, - real_t W = 5) + real_t W = 5.0) { Vector3< real_t > bubbleMidPoint; - auto X = blocks->getDomainCellBB().xMax(); - auto Y = blocks->getDomainCellBB().yMax(); - auto Z = blocks->getDomainCellBB().zMax(); + auto X = real_c(blocks->getDomainCellBB().xMax()); + auto Y = real_c(blocks->getDomainCellBB().yMax()); + auto Z = real_c(blocks->getDomainCellBB().zMax()); // 20 percent from the top are filled with the gas phase - real_t gas_top = Y - Y / 5.0; + real_t gas_top = Y - Y / real_c(5.0); // Diameter of the bubble - real_t D = R * 2; + real_t D = R * real_c(2.0); // distance in between the bubbles - int dist = 4; - auto nx = static_cast< unsigned int >(floor(X / (D + dist * W))); - auto nz = static_cast< unsigned int >(floor(Z / (D + dist * W))); + auto dist = real_c(4.0); + auto nx = uint_c(floor(X / (D + dist * W))); + auto nz = uint_c(floor(Z / (D + dist * W))); // fluctuation of the bubble radii - std::vector< std::vector< real_t > > fluctuation_radius(nx, std::vector< real_t >(nz, 0.0)); - std::vector< std::vector< real_t > > fluctuation_pos(nx, std::vector< real_t >(nz, 0.0)); + std::vector< std::vector< real_t > > fluctuation_radius(nx, std::vector< real_t >(nz, real_c(0.0))); + std::vector< std::vector< real_t > > fluctuation_pos(nx, std::vector< real_t >(nz, real_c(0.0))); - real_t max_fluctuation_radius = R / 5; - real_t max_fluctuation_pos = (dist * W) / 3.0; + real_t max_fluctuation_radius = R / real_c(5.0); + real_t max_fluctuation_pos = (dist * W) / real_c(3.0); for (unsigned int i = 0; i < nx; ++i) { for (unsigned int j = 0; j < nz; ++j) @@ -118,35 +118,35 @@ void init_bubble_field(const shared_ptr< StructuredBlockStorage >& blocks, Block for (unsigned int i = 0; i < nx; ++i) { for (unsigned int j = 0; j < nz; ++j) { - bubbleMidPoint[0] = (i + 1) * (D + (dist * W)) - (D + (dist * W)) / 2.0 + fluctuation_pos[i][j]; + bubbleMidPoint[0] = real_c(i + 1) * (D + (dist * W)) - (D + (dist * W)) / real_c(2.0) + fluctuation_pos[i][j]; bubbleMidPoint[1] = R + W + 4; - bubbleMidPoint[2] = (j + 1) * (D + (dist * W)) - (D + (dist * W)) / 2.0 + fluctuation_pos[i][j]; + bubbleMidPoint[2] = real_c(j + 1) * (D + (dist * W)) - (D + (dist * W)) / real_c(2.0) + fluctuation_pos[i][j]; - real_t Ri = sqrt((globalCell[0] - bubbleMidPoint[0]) * (globalCell[0] - bubbleMidPoint[0]) + - (globalCell[1] - bubbleMidPoint[1]) * (globalCell[1] - bubbleMidPoint[1]) + - (globalCell[2] - bubbleMidPoint[2]) * (globalCell[2] - bubbleMidPoint[2])); - if (globalCell[0] >= i * (D + dist * W) && globalCell[0] <= (i + 1) * (D + dist * W) && - globalCell[2] >= j * (D + dist * W) && globalCell[2] <= (j + 1) * (D + dist * W)) - phaseField->get(x, y, z) = 0.5 + 0.5 * tanh(2.0 * (Ri - (R - fluctuation_radius[i][j])) / W); + real_t Ri = sqrt((real_c(globalCell[0]) - bubbleMidPoint[0]) * (real_c(globalCell[0]) - bubbleMidPoint[0]) + + (real_c(globalCell[1]) - bubbleMidPoint[1]) * (real_c(globalCell[1]) - bubbleMidPoint[1]) + + (real_c(globalCell[2]) - bubbleMidPoint[2]) * (real_c(globalCell[2]) - bubbleMidPoint[2])); + if (real_c(globalCell[0]) >= real_c(i) * (D + dist * W) && real_c(globalCell[0]) <= real_c(i + 1) * (D + dist * W) && + real_c(globalCell[2]) >= real_c(j) * (D + dist * W) && real_c(globalCell[2]) <= real_c(j + 1) * (D + dist * W)) + phaseField->get(x, y, z) = real_c(0.5) + real_c(0.5) * real_c(tanh(2.0 * (Ri - (R - fluctuation_radius[i][j])) / W)); - if (globalCell[0] > nx * (D + dist * W)) phaseField->get(x, y, z) = 1.0; - if (globalCell[2] > nz * (D + dist * W)) phaseField->get(x, y, z) = 1.0; + if (real_c(globalCell[0]) > real_c(nx) * (D + dist * W)) phaseField->get(x, y, z) = 1.0; + if (real_c(globalCell[2]) > real_c(nz) * (D + dist * W)) phaseField->get(x, y, z) = 1.0; } } - if (globalCell[1] > gas_top) { - phaseField->get(x, y, z) = 0.5 + 0.5 * tanh(2.0 * (gas_top + 10 - globalCell[1]) / W); + if (real_c(globalCell[1]) > gas_top) { + phaseField->get(x, y, z) = real_c(0.5) + real_c(0.5) * real_c(tanh(2.0 * (gas_top + 10 - real_c(globalCell[1])) / W)); }) } } void initPhaseField_RTI(const shared_ptr< StructuredBlockStorage >& blocks, BlockDataID phaseFieldID, - const real_t W = 5, const bool pipe = true) + const real_t W = 5.0, const bool pipe = true) { - auto X = blocks->getDomainCellBB().xMax(); - auto Z = blocks->getDomainCellBB().zMax(); - auto halfY = (blocks->getDomainCellBB().yMax()) / 2.0; - real_t perturbation = 0.05; + auto X = real_c(blocks->getDomainCellBB().xMax()); + auto Z = real_c(blocks->getDomainCellBB().zMax()); + auto halfY = real_c((blocks->getDomainCellBB().yMax())) / real_c(2.0); + auto perturbation = real_c(0.05); if (pipe) { @@ -155,10 +155,10 @@ void initPhaseField_RTI(const shared_ptr< StructuredBlockStorage >& blocks, Bloc auto phaseField = block.getData< PhaseField_T >(phaseFieldID); WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ( phaseField, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); - real_t R = sqrt((globalCell[0] - X / 2) * (globalCell[0] - X / 2) + - (globalCell[2] - Z / 2) * (globalCell[2] - Z / 2)); - if (R > X) R = X; real_t tmp = perturbation * X * cos((2.0 * math::pi * R) / X); - phaseField->get(x, y, z) = 0.5 + 0.5 * tanh(((globalCell[1] - halfY) + tmp) / (W / 2.0));) + real_t R = sqrt((real_c(globalCell[0]) - X / 2) * (real_c(globalCell[0]) - X / 2) + + (real_c(globalCell[2]) - Z / 2) * (real_c(globalCell[2]) - Z / 2)); + if (R > X) R = X; real_t tmp = perturbation * X * real_c(cos((2.0 * math::pi * R) / X)); + phaseField->get(x, y, z) = real_c(0.5) + real_c(0.5) * real_c(tanh(((real_c(globalCell[1]) - halfY) + tmp)) / (W / 2.0));) } } else @@ -169,8 +169,8 @@ void initPhaseField_RTI(const shared_ptr< StructuredBlockStorage >& blocks, Bloc WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ( phaseField, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); real_t tmp = perturbation * X * - (cos((2.0 * math::pi * globalCell[0]) / X) + cos((2.0 * math::pi * globalCell[2]) / X)); - phaseField->get(x, y, z) = 0.5 + 0.5 * tanh(((globalCell[1] - halfY) - tmp) / (W / 2.0));) + real_c(cos((real_c(2.0) * math::pi * real_c(globalCell[0]))) / X + cos((2.0 * math::pi * real_c(globalCell[2])) / X)); + phaseField->get(x, y, z) = real_c(0.5) + real_c(0.5) * real_c(tanh(((real_c(globalCell[1]) - halfY) - tmp)) / (W / 2.0));) } } } @@ -182,45 +182,45 @@ void initTubeWithCylinder(const shared_ptr< StructuredBlockStorage >& blocks, Bl { if (eccentricity_or_pipe_ratio) { - auto Mx = blocks->getDomainCellBB().xMax() / 2.0; - auto Mz = blocks->getDomainCellBB().zMax() / 2.0; + auto Mx = real_c(blocks->getDomainCellBB().xMax()) / real_c(2.0); + auto Mz = real_c(blocks->getDomainCellBB().zMax()) / real_c(2.0); - auto R_outer = blocks->getDomainCellBB().xMax() / 2.0 + 1.0; + auto R_outer = real_c(blocks->getDomainCellBB().xMax()) / real_c(2.0) + real_c(1.0); - real_t const shift = eccentricity * Mx / 2; + real_t const shift = eccentricity * Mx / real_c(2.0); for (auto& block : *blocks) { auto flagField = block.template getData< FlagField_T >(flagFieldID); auto boundaryFlag = flagField->getOrRegisterFlag(boundaryFlagUID); - WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ(flagField, Cell globalCell; + WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ(flagField, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); real_t R1; - if (globalCell[1] <= start_transition) { - R1 = sqrt((globalCell[0] - Mx) * (globalCell[0] - Mx) + (globalCell[2] - Mz) * (globalCell[2] - Mz)); - } else if (globalCell[1] > start_transition && globalCell[1] < start_transition + length_transition) { - real_t tmp = math::pi * (globalCell[1] - start_transition) / (length_transition); - real_t shift_tmp = shift * 0.5 * (1 - cos(tmp)); - R1 = sqrt((globalCell[0] - Mx - shift_tmp) * (globalCell[0] - Mx - shift_tmp) + - (globalCell[2] - Mz) * (globalCell[2] - Mz)); + if (real_c(globalCell[1]) <= start_transition) { + R1 = sqrt((real_c(globalCell[0]) - Mx) * (real_c(globalCell[0]) - Mx) + (real_c(globalCell[2]) - Mz) * (real_c(globalCell[2]) - Mz)); + } else if (real_c(globalCell[1]) > start_transition && real_c(globalCell[1]) < start_transition + length_transition) { + real_t tmp = math::pi * (real_c(globalCell[1]) - start_transition) / (length_transition); + real_t shift_tmp = shift * real_c(0.5) * (real_c(1.0) - real_c(cos(tmp))); + R1 = sqrt((real_c(globalCell[0]) - Mx - shift_tmp) * (real_c(globalCell[0]) - Mx - shift_tmp) + + (real_c(globalCell[2]) - Mz) * (real_c(globalCell[2]) - Mz)); } else { - R1 = sqrt((globalCell[0] - Mx - shift) * (globalCell[0] - Mx - shift) + - (globalCell[2] - Mz) * (globalCell[2] - Mz)); + R1 = sqrt((real_c(globalCell[0]) - Mx - shift) * (real_c(globalCell[0]) - Mx - shift) + + (real_c(globalCell[2]) - Mz) * (real_c(globalCell[2]) - Mz)); } - real_t R2 = sqrt((globalCell[0] - Mx) * (globalCell[0] - Mx) + (globalCell[2] - Mz) * (globalCell[2] - Mz)); + real_t R2 = sqrt((real_c(globalCell[0]) - Mx) * (real_c(globalCell[0]) - Mx) + (real_c(globalCell[2]) - Mz) * (real_c(globalCell[2]) - Mz)); if (R1 < R_in) addFlag(flagField->get(x, y, z), boundaryFlag); if (R2 > R_outer) addFlag(flagField->get(x, y, z), boundaryFlag);) } } else { - auto Mx = blocks->getDomainCellBB().xMax() / 2.0; - auto Mz = blocks->getDomainCellBB().zMax() / 2.0; - - auto R_outer = blocks->getDomainCellBB().xMax() / 2.0 + 1.0; + auto Mx = real_c(blocks->getDomainCellBB().xMax()) / real_c(2.0); + auto Mz = real_c(blocks->getDomainCellBB().zMax()) / real_c(2.0); - real_t const shift = eccentricity * R_in; + auto R_outer = real_c(blocks->getDomainCellBB().xMax()) / real_c(2.0) + real_c(1.0); + + auto const shift = real_c(eccentricity * R_in); real_t R_tmp; for (auto& block : *blocks) @@ -229,17 +229,17 @@ void initTubeWithCylinder(const shared_ptr< StructuredBlockStorage >& blocks, Bl auto boundaryFlag = flagField->getOrRegisterFlag(boundaryFlagUID); WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ( flagField, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); - if (globalCell[1] <= start_transition) { + if (real_c(globalCell[1]) <= start_transition) { R_tmp = R_in; - } else if (globalCell[1] > start_transition && globalCell[1] < start_transition + length_transition) { - real_t tmp = math::pi * (globalCell[1] - start_transition) / (length_transition); - real_t shift_tmp = shift * 0.5 * (1 - cos(tmp)); + } else if (real_c(globalCell[1]) > start_transition && real_c(globalCell[1]) < start_transition + length_transition) { + real_t tmp = math::pi * (real_c(globalCell[1]) - start_transition) / (length_transition); + real_t shift_tmp = shift * real_c(0.5) * (real_c(1.0) - real_c(cos(tmp))); R_tmp = R_in + shift_tmp; } else { R_tmp = R_in + shift; } - real_t R2 = sqrt((globalCell[0] - Mx) * (globalCell[0] - Mx) + (globalCell[2] - Mz) * (globalCell[2] - Mz)); + real_t R2 = real_c(sqrt((real_c(globalCell[0]) - Mx) * (real_c(globalCell[0]) - Mx) + (real_c(globalCell[2]) - Mz) * (real_c(globalCell[2]) - Mz))); if (R2 < R_tmp) addFlag(flagField->get(x, y, z), boundaryFlag); if (R2 > R_outer) addFlag(flagField->get(x, y, z), boundaryFlag);) } diff --git a/apps/showcases/PhaseFieldAllenCahn/GPU/multiphase.cpp b/apps/showcases/PhaseFieldAllenCahn/GPU/multiphase.cpp index f2c8f0087..852bd26e5 100644 --- a/apps/showcases/PhaseFieldAllenCahn/GPU/multiphase.cpp +++ b/apps/showcases/PhaseFieldAllenCahn/GPU/multiphase.cpp @@ -100,7 +100,7 @@ int main(int argc, char** argv) const std::string timeStepStrategy = parameters.getParameter< std::string >("timeStepStrategy", "normal"); const uint_t timesteps = parameters.getParameter< uint_t >("timesteps", uint_c(50)); const real_t remainingTimeLoggerFrequency = - parameters.getParameter< real_t >("remainingTimeLoggerFrequency", 3.0); + parameters.getParameter< real_t >("remainingTimeLoggerFrequency", real_c(3.0)); const uint_t scenario = parameters.getParameter< uint_t >("scenario", uint_c(1)); Vector3< int > gpuBlockSize = parameters.getParameter< Vector3< int > >("gpuBlockSize", Vector3< int >(128, 1, 1)); @@ -111,8 +111,8 @@ int main(int argc, char** argv) /////////////////////// // CPU fields - BlockDataID vel_field = field::addToStorage< VelocityField_T >(blocks, "vel", real_t(0), field::fzyx); - BlockDataID phase_field = field::addToStorage< PhaseField_T >(blocks, "phase", real_t(0), field::fzyx); + BlockDataID vel_field = field::addToStorage< VelocityField_T >(blocks, "vel", real_c(0.0), field::fzyx); + BlockDataID phase_field = field::addToStorage< PhaseField_T >(blocks, "phase", real_c(0.0), field::fzyx); // GPU fields BlockDataID lb_phase_field_gpu = cuda::addGPUFieldToStorage< cuda::GPUField< real_t > >( blocks, "lb phase field on GPU", Stencil_phase_T::Size, field::fzyx, 1); @@ -144,7 +144,7 @@ int main(int argc, char** argv) { auto bubbleParameters = config->getOneBlock("Bubble"); const Vector3< real_t > bubbleMidPoint = bubbleParameters.getParameter< Vector3< real_t > >("bubbleMidPoint"); - const real_t bubbleRadius = bubbleParameters.getParameter< real_t >("bubbleRadius", 20.0); + const real_t bubbleRadius = bubbleParameters.getParameter< real_t >("bubbleRadius", real_c(20.0)); const bool bubble = bubbleParameters.getParameter< bool >("bubble", true); initPhaseField_sphere(blocks, phase_field, bubbleRadius, bubbleMidPoint, bubble, interface_thickness); } @@ -155,7 +155,7 @@ int main(int argc, char** argv) else if (scenario == 3) { auto bubbleParameters = config->getOneBlock("Bubble"); - const real_t bubbleRadius = bubbleParameters.getParameter< real_t >("bubbleRadius", 20.0); + const real_t bubbleRadius = bubbleParameters.getParameter< real_t >("bubbleRadius", real_c(20.0)); init_bubble_field(blocks, phase_field, bubbleRadius); } else if (scenario == 4) @@ -166,9 +166,9 @@ int main(int argc, char** argv) const real_t diameter = TorusParameters.getParameter< real_t >("Donut_D"); const real_t donutTime = TorusParameters.getParameter< real_t >("DonutTime"); init_Taylor_bubble(blocks, phase_field, diameter, height, donutTime, midpoint); - center_of_mass[0] = real_t(cellsPerBlock[0]); - center_of_mass[1] = real_t(midpoint); - center_of_mass[2] = real_t(cellsPerBlock[2]); + center_of_mass[0] = real_c(cellsPerBlock[0]); + center_of_mass[1] = real_c(midpoint); + center_of_mass[2] = real_c(cellsPerBlock[2]); } WALBERLA_LOG_INFO_ON_ROOT("initialization of the phase field done") @@ -444,7 +444,7 @@ int main(int argc, char** argv) simTimer.end(); WALBERLA_LOG_INFO_ON_ROOT("Simulation finished") - auto time = simTimer.last(); + auto time = real_c(simTimer.last()); auto nrOfCells = real_c(cellsPerBlock[0] * cellsPerBlock[1] * cellsPerBlock[2]); auto mlupsPerProcess = nrOfCells * real_c(timesteps) / time * 1e-6; WALBERLA_LOG_RESULT_ON_ROOT("MLUPS per process: " << mlupsPerProcess) diff --git a/apps/showcases/PhaseFieldAllenCahn/GPU/multiphase_codegen.py b/apps/showcases/PhaseFieldAllenCahn/GPU/multiphase_codegen.py index a41a6939b..471a3e9f4 100644 --- a/apps/showcases/PhaseFieldAllenCahn/GPU/multiphase_codegen.py +++ b/apps/showcases/PhaseFieldAllenCahn/GPU/multiphase_codegen.py @@ -1,25 +1,26 @@ import numpy as np import sympy as sp -from pystencils import Assignment, fields, TypedSymbol, Target -from pystencils.astnodes import Block, Conditional -from pystencils.simp import sympy_cse +from pystencils import fields, Target +from pystencils.astnodes import Conditional, Block, SympyAssignment +from pystencils.node_collection import NodeCollection +from pystencils.typing import TypedSymbol +from pystencils.simp.simplifications import sympy_cse -from lbmpy import LBMConfig, LBStencil, Method, Stencil +from lbmpy import LBMConfig, LBMOptimisation, LBStencil, Method, Stencil, create_lb_update_rule from lbmpy.creationfunctions import create_lb_method from lbmpy.boundaries import NoSlip from lbmpy.phasefield_allen_cahn.contact_angle import ContactAngle -from lbmpy.phasefield_allen_cahn.force_model import MultiphaseForceModel from lbmpy.phasefield_allen_cahn.kernel_equations import initializer_kernel_phase_field_lb, \ - initializer_kernel_hydro_lb, interface_tracking_force, hydrodynamic_force, get_collision_assignments_hydro, \ - get_collision_assignments_phase + initializer_kernel_hydro_lb, interface_tracking_force, hydrodynamic_force, add_interface_tracking_force, \ + add_hydrodynamic_force, hydrodynamic_force_assignments +from lbmpy.phasefield_allen_cahn.parameter_calculation import AllenCahnParameters import pystencils_walberla from pystencils_walberla import CodeGeneration, generate_sweep, generate_pack_info_for_field, generate_info_header from lbmpy_walberla import generate_boundary, generate_lb_pack_info - with CodeGeneration() as ctx: field_type = "float64" if ctx.double_accuracy else "float32" @@ -29,28 +30,8 @@ with CodeGeneration() as ctx: stencil_hydro = LBStencil(Stencil.D3Q27) assert (stencil_phase.D == stencil_hydro.D) - ######################## - # PARAMETER DEFINITION # - ######################## - - density_liquid = sp.Symbol("rho_H") - density_gas = sp.Symbol("rho_L") - - surface_tension = sp.Symbol("sigma") - mobility = sp.Symbol("mobility") - - gravitational_acceleration = sp.Symbol("gravity") - - relaxation_time_liquid = sp.Symbol("tau_H") - relaxation_time_gas = sp.Symbol("tau_L") - - # phase-field parameter - drho3 = (density_liquid - density_gas) / 3 - # interface thickness - W = sp.Symbol("interface_thickness") - # coefficients related to surface tension - beta = 12.0 * (surface_tension / W) - kappa = 1.5 * surface_tension * W + # In the codegeneration skript we only need the symbolic parameters + parameters = AllenCahnParameters(0, 0, 0, 0, 0) ######################## # FIELDS # @@ -75,79 +56,74 @@ with CodeGeneration() as ctx: ######################################## # relaxation rate for interface tracking LB step - relaxation_rate_allen_cahn = 1.0 / (0.5 + (3.0 * mobility)) + relaxation_rate_allen_cahn = 1.0 / (0.5 + (3.0 * parameters.symbolic_mobility)) # calculate the relaxation rate for hydrodynamic LB step - density = density_gas + C.center * (density_liquid - density_gas) + rho_L = parameters.symbolic_density_light + rho_H = parameters.symbolic_density_heavy + density = rho_L + C.center * (rho_H - rho_L) # force acting on all phases of the model - body_force = np.array([0, gravitational_acceleration * density, 0]) - # calculation of the relaxation time via viscosities - # viscosity = viscosity_gas * viscosity_liquid + C.center\ - # * (density_liquid*viscosity_liquid - viscosity_liquid*viscosity_gas) - # relaxation_time = 3 * viscosity / density + 0.5 - - relaxation_time = 0.5 + relaxation_time_gas + C.center * (relaxation_time_liquid - relaxation_time_gas) - # calculate the relaxation time if the phase-field has values over one - # relaxation_rate = 1.0 / relaxation_time - relaxation_rate = sp.Symbol("s8") - relaxation_rate_cutoff = sp.Piecewise((1 / (0.5 + relaxation_time_liquid), C.center > 0.999), # True value - (1 / relaxation_time, True)) # Else value + body_force = [0, 0, 0] + body_force[1] = parameters.symbolic_gravitational_acceleration * density + + omega = parameters.omega(C) ############### # LBM METHODS # ############### - lbm_config_phase = LBMConfig(stencil=stencil_phase, method=Method.MRT, compressible=True, weighted=True, - relaxation_rates=[1, 1, 1, 1, 1, 1]) + + rates = [0.0] + rates += [relaxation_rate_allen_cahn] * stencil_phase.D + rates += [1.0] * (stencil_phase.Q - stencil_phase.D - 1) + + lbm_config_phase = LBMConfig(stencil=stencil_phase, method=Method.MRT, compressible=True, + delta_equilibrium=False, + force=sp.symbols(f"F_:{stencil_phase.D}"), velocity_input=u, + weighted=True, relaxation_rates=rates, + output={'density': C_tmp}, kernel_type='stream_pull_collide') method_phase = create_lb_method(lbm_config=lbm_config_phase) - method_phase.set_first_moment_relaxation_rate(relaxation_rate_allen_cahn) - lbm_config_hydro = LBMConfig(stencil=stencil_hydro, method=Method.MRT, weighted=True, - relaxation_rates=[relaxation_rate, 1, 1, 1, 1, 1]) + lbm_config_hydro = LBMConfig(stencil=stencil_hydro, method=Method.MRT, compressible=False, + weighted=True, relaxation_rate=omega, + force=sp.symbols(f"F_:{stencil_hydro.D}"), + output={'velocity': u}, kernel_type='collide_stream_push') method_hydro = create_lb_method(lbm_config=lbm_config_hydro) # create the kernels for the initialization of the g and h field - h_updates = initializer_kernel_phase_field_lb(h, C, u, method_phase, W) - g_updates = initializer_kernel_hydro_lb(g, u, method_hydro) + h_updates = initializer_kernel_phase_field_lb(method_phase, C, u, h, parameters) + g_updates = initializer_kernel_hydro_lb(method_hydro, 1, u, g) - force_h = [f / 3 for f in interface_tracking_force(C, stencil_phase, W)] - force_model_h = MultiphaseForceModel(force=force_h) - - force_g = hydrodynamic_force(g, C, method_hydro, relaxation_time, - density_liquid, density_gas, kappa, beta, body_force) - force_model_g = MultiphaseForceModel(force=force_g, rho=density) + force_h = interface_tracking_force(C, stencil_phase, parameters) + hydro_force = hydrodynamic_force(g, C, method_hydro, parameters, body_force) #################### # LBM UPDATE RULES # #################### - phase_field_LB_step = get_collision_assignments_phase(lb_method=method_phase, - velocity_input=u, - output={'density': C_tmp}, - force_model=force_model_h, - symbolic_fields={"symbolic_field": h, - "symbolic_temporary_field": h_tmp}, - kernel_type='stream_pull_collide') + lbm_optimisation = LBMOptimisation(symbolic_field=h, symbolic_temporary_field=h_tmp) + allen_cahn_update_rule = create_lb_update_rule(lbm_config=lbm_config_phase, + lbm_optimisation=lbm_optimisation) + + allen_cahn_update_rule = add_interface_tracking_force(allen_cahn_update_rule, force_h) - phase_field_LB_step = sympy_cse(phase_field_LB_step) + allen_cahn_update_rule = sympy_cse(allen_cahn_update_rule) - phase_field_LB_step = [Conditional(sp.Eq(flag.center(), 2), - Block(phase_field_LB_step), - Block([Assignment(C_tmp.center, C.center)]))] + allen_cahn_update_rule = NodeCollection([Conditional(sp.Eq(flag.center(), 2), + Block(allen_cahn_update_rule.all_assignments), + Block([SympyAssignment(C_tmp.center, C.center)]))]) # --------------------------------------------------------------------------------------------------------- - hydro_LB_step = get_collision_assignments_hydro(lb_method=method_hydro, - density=density, - velocity_input=u, - force_model=force_model_g, - sub_iterations=2, - symbolic_fields={"symbolic_field": g, - "symbolic_temporary_field": g_tmp}, - kernel_type='collide_stream_push') + force_Assignments = hydrodynamic_force_assignments(g, u, C, method_hydro, parameters, body_force) + + lbm_optimisation = LBMOptimisation(symbolic_field=g, symbolic_temporary_field=g_tmp) + hydro_lb_update_rule = create_lb_update_rule(lbm_config=lbm_config_hydro, + lbm_optimisation=lbm_optimisation) - hydro_LB_step.set_sub_expressions_from_dict({**{relaxation_rate: relaxation_rate_cutoff}, - **hydro_LB_step.subexpressions_dict}) + hydro_lb_update_rule = add_hydrodynamic_force(hydro_lb_update_rule, force_Assignments, C, g, parameters) - hydro_LB_step = [Conditional(sp.Eq(flag.center(), 2), Block(hydro_LB_step))] + hydro_lb_update_rule = NodeCollection([Conditional(sp.Eq(flag.center(), 2), + Block(hydro_lb_update_rule.all_assignments))]) - contact_angle = ContactAngle(contact_angle_in_degrees, W) + contact_angle = ContactAngle(contact_angle_in_degrees, parameters.symbolic_interface_thickness, + data_type=field_type) ################### # GENERATE SWEEPS # @@ -178,14 +154,14 @@ with CodeGeneration() as ctx: generate_sweep(ctx, 'initialize_phase_field_distributions', h_updates, target=Target.GPU) generate_sweep(ctx, 'initialize_velocity_based_distributions', g_updates, target=Target.GPU) - generate_sweep(ctx, 'phase_field_LB_step', phase_field_LB_step, + generate_sweep(ctx, 'phase_field_LB_step', allen_cahn_update_rule, field_swaps=[(h, h_tmp), (C, C_tmp)], target=Target.GPU, gpu_indexing_params=sweep_params, varying_parameters=vp) generate_boundary(ctx, 'phase_field_LB_NoSlip', NoSlip(), method_phase, target=Target.GPU, streaming_pattern='pull') - generate_sweep(ctx, 'hydro_LB_step', hydro_LB_step, + generate_sweep(ctx, 'hydro_LB_step', hydro_lb_update_rule, field_swaps=[(g, g_tmp)], target=Target.GPU, gpu_indexing_params=sweep_params, diff --git a/apps/showcases/PhaseFieldAllenCahn/GPU/util.cpp b/apps/showcases/PhaseFieldAllenCahn/GPU/util.cpp index 9912edb76..f6694910c 100644 --- a/apps/showcases/PhaseFieldAllenCahn/GPU/util.cpp +++ b/apps/showcases/PhaseFieldAllenCahn/GPU/util.cpp @@ -46,13 +46,13 @@ void calc_total_velocity(const shared_ptr< StructuredBlockStorage >& blocks, std phaseField, auto fluidFlag = flagField->getFlag(fluidFlagUID); if (flagField->get(x, y, z) == fluidFlag) { - if (phaseField->get(x, y, z) < 0.5) + if (phaseField->get(x, y, z) < real_c(0.5)) { real_t invC = 1 - phaseField->get(x, y, z); real_t U = velField->get(x, y, z, 0); real_t V = velField->get(x, y, z, 1); real_t W = velField->get(x, y, z, 2); - total_velocity[0] += sqrt((U * invC) * (U * invC) + (V * invC) * (V * invC) + (W * invC) * (W * invC)); + total_velocity[0] += real_c(sqrt((U * invC) * (U * invC) + (V * invC) * (V * invC) + (W * invC) * (W * invC))); total_velocity[1] += U * invC; total_velocity[2] += V * invC; total_velocity[3] += W * invC; @@ -69,11 +69,11 @@ void flood_fill(PhaseField_T& phaseField, VelocityField_T& velocityField, CellIn Field< bool, 1 > visit(phaseField.xSize(), phaseField.ySize(), phaseField.zSize(), false, field::fzyx); using namespace stencil; - volume = 0; - nrOfCells = 0; - center_of_mass[0] = 0.0; - center_of_mass[1] = 0.0; - center_of_mass[2] = 0.0; + volume = real_c(0.0); + nrOfCells = uint_c(0); + center_of_mass[0] = real_c( 0.0); + center_of_mass[1] = real_c(0.0); + center_of_mass[2] = real_c(0.0); while (phaseField.get(startCell) > 0.5 && startCell.x() > 0) --startCell.x(); @@ -92,14 +92,14 @@ void flood_fill(PhaseField_T& phaseField, VelocityField_T& velocityField, CellIn nrOfCells++; volume += invC; - total_velocity[0] += sqrt((v_U * invC) * (v_U * invC) + (v_V * invC) * (v_V * invC) + (v_W * invC) * (v_W * invC)); + total_velocity[0] += real_c(sqrt((v_U * invC) * (v_U * invC) + (v_V * invC) * (v_V * invC) + (v_W * invC) * (v_W * invC))); total_velocity[1] += v_U * invC; total_velocity[2] += v_V * invC; total_velocity[3] += v_W * invC; - center_of_mass[0] += (startCell.x() + boundingBox.xMin()); - center_of_mass[1] += (startCell.y() + boundingBox.yMin()); - center_of_mass[2] += (startCell.z() + boundingBox.xMin()); + center_of_mass[0] += real_c(startCell.x() + boundingBox.xMin()); + center_of_mass[1] += real_c(startCell.y() + boundingBox.yMin()); + center_of_mass[2] += real_c(startCell.z() + boundingBox.xMin()); const int DIRS[6] = { N, S, E, W, T, B }; @@ -126,14 +126,14 @@ void flood_fill(PhaseField_T& phaseField, VelocityField_T& velocityField, CellIn volume += invC; total_velocity[0] += - sqrt((v_U * invC) * (v_U * invC) + (v_V * invC) * (v_V * invC) + (v_W * invC) * (v_W * invC)); + real_c(sqrt((v_U * invC) * (v_U * invC) + (v_V * invC) * (v_V * invC) + (v_W * invC) * (v_W * invC))); total_velocity[1] += v_U * invC; total_velocity[2] += v_V * invC; total_velocity[3] += v_W * invC; - center_of_mass[0] += (neighborCell.x() + boundingBox.xMin()); - center_of_mass[1] += (neighborCell.y() + boundingBox.yMin()); - center_of_mass[2] += (neighborCell.z() + boundingBox.xMin()); + center_of_mass[0] += real_c(neighborCell.x() + boundingBox.xMin()); + center_of_mass[1] += real_c(neighborCell.y() + boundingBox.yMin()); + center_of_mass[2] += real_c(neighborCell.z() + boundingBox.xMin()); visit.get(neighborCell) = true; cellQueue.push(neighborCell); diff --git a/apps/showcases/PorousMedia/PorousMediaCumulantLBMKernel.py b/apps/showcases/PorousMedia/PorousMediaCumulantLBMKernel.py index 96cc2f0aa..8bee23b8e 100644 --- a/apps/showcases/PorousMedia/PorousMediaCumulantLBMKernel.py +++ b/apps/showcases/PorousMedia/PorousMediaCumulantLBMKernel.py @@ -1,39 +1,29 @@ import sympy as sp import pystencils as ps -from lbmpy.stencils import get_stencil -from lbmpy.creationfunctions import create_lb_collision_rule, create_lb_update_rule +from lbmpy import Stencil, LBStencil +from lbmpy.creationfunctions import LBMConfig, LBMOptimisation, Method, create_lb_collision_rule from lbmpy_walberla import RefinementScaling, generate_lattice_model from pystencils_walberla import CodeGeneration, generate_sweep, generate_pack_info_from_kernel -stencil = get_stencil("D3Q19", ordering="walberla") -omega = sp.Symbol('omega') -layout = 'fzyx' -pdf_field = ps.fields("pdfs(19): [3D]", layout=layout) - -optimizations = {'cse_global': True, - 'cse_pdfs': False, - 'split': True, - 'symbolic_field': pdf_field, - 'field_layout': layout, - 'pre_simplification': True - } - -params = {'stencil': stencil, - 'method': 'cumulant', - 'relaxation_rate': omega, - 'equilibrium_order': 4, - 'maxwellian_moments': True, - 'compressible': True, - } - -collision_rule = create_lb_collision_rule(optimization=optimizations, **params) -update_rule = create_lb_update_rule(collision_rule=collision_rule, optimization=optimizations) - -refinement_scaling = RefinementScaling() -refinement_scaling.add_standard_relaxation_rate_scaling(omega) with CodeGeneration() as ctx: - generate_lattice_model(ctx, "LbCodeGen_LatticeModel", collision_rule, refinement_scaling=refinement_scaling, - field_layout=layout) + data_type = "float64" if ctx.double_accuracy else "float32" + stencil = LBStencil(Stencil.D3Q19) + omega = sp.Symbol('omega') + layout = 'fzyx' + pdf_field = ps.fields(f"pdfs({stencil.Q}): {data_type}[3D]", layout=layout) + + lbm_config = LBMConfig(stencil=stencil, method=Method.CUMULANT, relaxation_rate=omega, compressible=True) + lbm_opt = LBMOptimisation(cse_global=True, cse_pdfs=False, split=False, + symbolic_field=pdf_field, field_layout=layout, pre_simplification=True) + + collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) + + refinement_scaling = RefinementScaling() + refinement_scaling.add_standard_relaxation_rate_scaling(omega) + + generate_lattice_model(ctx, "LbCodeGen_LatticeModel", collision_rule, refinement_scaling=refinement_scaling, + field_layout=layout) + diff --git a/apps/tutorials/codegen/02_LBMLatticeModelGeneration.cpp b/apps/tutorials/codegen/02_LBMLatticeModelGeneration.cpp index 934ab64ff..2a83abba2 100644 --- a/apps/tutorials/codegen/02_LBMLatticeModelGeneration.cpp +++ b/apps/tutorials/codegen/02_LBMLatticeModelGeneration.cpp @@ -86,7 +86,7 @@ struct ShearFlowInit std::vector< real_t > operator()(const Cell& globalCell) { std::vector< real_t > densityAndVelocity = exprInitFunc_(globalCell); - real_t yPerturbation = noiseMagnitude_ * rng_(); + auto yPerturbation = real_c(noiseMagnitude_ * rng_()); densityAndVelocity[2] += yPerturbation; return densityAndVelocity; @@ -115,7 +115,7 @@ int main(int argc, char** argv) const uint_t timesteps = parameters.getParameter< uint_t >("timesteps", uint_c(10)); const real_t omega = parameters.getParameter< real_t >("omega", real_c(1.8)); const double remainingTimeLoggerFrequency = - parameters.getParameter< double >("remainingTimeLoggerFrequency", 3.0); // in seconds + parameters.getParameter< double >("remainingTimeLoggerFrequency", real_c(3.0)); // in seconds /////////////////// /// Field Setup /// diff --git a/apps/tutorials/codegen/02_LBMLatticeModelGeneration.py b/apps/tutorials/codegen/02_LBMLatticeModelGeneration.py index 224ab742a..494c47bf2 100644 --- a/apps/tutorials/codegen/02_LBMLatticeModelGeneration.py +++ b/apps/tutorials/codegen/02_LBMLatticeModelGeneration.py @@ -21,7 +21,8 @@ lbm_opt = LBMOptimisation(cse_global=True, field_layout=layout) # SRT Method Definition # =========================== -lbm_config = LBMConfig(stencil=stencil, method=Method.SRT, relaxation_rate=omega) +lbm_config = LBMConfig(stencil=stencil, method=Method.SRT, relaxation_rate=omega, + zero_centered=False, delta_equilibrium=False) srt_collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) srt_update_rule = create_lb_update_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) diff --git a/apps/tutorials/codegen/03_AdvancedLBMCodegen.cpp b/apps/tutorials/codegen/03_AdvancedLBMCodegen.cpp index 492d40b8b..5b7790c7d 100644 --- a/apps/tutorials/codegen/03_AdvancedLBMCodegen.cpp +++ b/apps/tutorials/codegen/03_AdvancedLBMCodegen.cpp @@ -87,7 +87,7 @@ void initShearFlowVelocityField(const shared_ptr< StructuredBlockForest >& block real_t velocityMagnitude = config.getParameter< real_t >("velocityMagnitude", real_c(0.08)); real_t noiseMagnitude = config.getParameter< real_t >("noiseMagnitude", real_c(0.1) * velocityMagnitude); - real_t n_y = real_c(blocks->getNumberOfYCells()); + auto n_y = real_c(blocks->getNumberOfYCells()); for (auto blockIt = blocks->begin(); blockIt != blocks->end(); ++blockIt) { @@ -98,7 +98,7 @@ void initShearFlowVelocityField(const shared_ptr< StructuredBlockForest >& block Cell globalCell(cellIt.cell()); blocks->transformBlockLocalToGlobalCell(globalCell, *blockIt); - real_t relative_y = real_c(globalCell.y()) / n_y; + auto relative_y = real_c(globalCell.y()) / n_y; u->get(cellIt.cell(), 0) = relative_y < 0.3 || relative_y > 0.7 ? velocityMagnitude : -velocityMagnitude; @@ -129,7 +129,7 @@ int main(int argc, char** argv) const uint_t timesteps = parameters.getParameter< uint_t >("timesteps", uint_c(10)); const real_t omega = parameters.getParameter< real_t >("omega", real_c(1.8)); const double remainingTimeLoggerFrequency = - parameters.getParameter< double >("remainingTimeLoggerFrequency", 3.0); // in seconds + parameters.getParameter< double >("remainingTimeLoggerFrequency", real_c(3.0)); // in seconds const uint_t VTKwriteFrequency = parameters.getParameter< uint_t >("VTKwriteFrequency", 1000); //////////////////////////////////// diff --git a/apps/tutorials/codegen/03_AdvancedLBMCodegen.py b/apps/tutorials/codegen/03_AdvancedLBMCodegen.py index c94eb81ba..b139c9999 100644 --- a/apps/tutorials/codegen/03_AdvancedLBMCodegen.py +++ b/apps/tutorials/codegen/03_AdvancedLBMCodegen.py @@ -10,59 +10,56 @@ from lbmpy.boundaries import NoSlip from pystencils_walberla import CodeGeneration, generate_sweep, generate_pack_info_from_kernel from lbmpy_walberla import generate_boundary - -# ======================== -# General Parameters -# ======================== - -stencil = LBStencil(Stencil.D2Q9) -omega = sp.Symbol('omega') -layout = 'fzyx' - -# PDF Fields -pdfs, pdfs_tmp = ps.fields(f'pdfs({stencil.Q}), pdfs_tmp({stencil.Q}): [2D]', layout=layout) - -# Velocity Output Field -velocity = ps.fields(f"velocity({stencil.D}): [2D]", layout=layout) -output = {'velocity': velocity} - -# LBM Optimisation -lbm_opt = LBMOptimisation(cse_global=True, - symbolic_field=pdfs, - symbolic_temporary_field=pdfs_tmp, - field_layout=layout) - - -# ================== -# Method Setup -# ================== - -lbm_config = LBMConfig(stencil=stencil, - method=Method.CUMULANT, - relaxation_rate=omega, - compressible=True, - output=output) - -lbm_update_rule = create_lb_update_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) - -lbm_method = lbm_update_rule.method - -# ======================== -# PDF Initialization -# ======================== - -initial_rho = sp.Symbol('rho_0') - -pdfs_setter = macroscopic_values_setter(lbm_method, - initial_rho, - velocity.center_vector, - pdfs.center_vector) - # ===================== # Code Generation # ===================== with CodeGeneration() as ctx: + # ======================== + # General Parameters + # ======================== + data_type = "float64" if ctx.double_accuracy else "float32" + stencil = LBStencil(Stencil.D2Q9) + omega = sp.Symbol('omega') + layout = 'fzyx' + + # PDF Fields + pdfs, pdfs_tmp = ps.fields(f'pdfs({stencil.Q}), pdfs_tmp({stencil.Q}): {data_type}[2D]', layout=layout) + + # Velocity Output Field + velocity = ps.fields(f"velocity({stencil.D}): {data_type}[2D]", layout=layout) + output = {'velocity': velocity} + + # LBM Optimisation + lbm_opt = LBMOptimisation(cse_global=True, + symbolic_field=pdfs, + symbolic_temporary_field=pdfs_tmp, + field_layout=layout) + + # ================== + # Method Setup + # ================== + + lbm_config = LBMConfig(stencil=stencil, + method=Method.CUMULANT, + relaxation_rate=omega, + compressible=True, + output=output) + + lbm_update_rule = create_lb_update_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) + lbm_method = lbm_update_rule.method + + # ======================== + # PDF Initialization + # ======================== + + initial_rho = sp.Symbol('rho_0') + + pdfs_setter = macroscopic_values_setter(lbm_method, + initial_rho, + velocity.center_vector, + pdfs.center_vector) + if ctx.cuda: target = ps.Target.GPU else: diff --git a/apps/tutorials/codegen/HeatEquationKernel.py b/apps/tutorials/codegen/HeatEquationKernel.py index 2aefdba6d..024940a38 100644 --- a/apps/tutorials/codegen/HeatEquationKernel.py +++ b/apps/tutorials/codegen/HeatEquationKernel.py @@ -2,24 +2,26 @@ import sympy as sp import pystencils as ps from pystencils_walberla import CodeGeneration, generate_sweep -u, u_tmp = ps.fields("u, u_tmp: [2D]", layout='fzyx') -kappa = sp.Symbol("kappa") -dx = sp.Symbol("dx") -dt = sp.Symbol("dt") -heat_pde = ps.fd.transient(u) - kappa * (ps.fd.diff(u, 0, 0) + ps.fd.diff(u, 1, 1)) +with CodeGeneration() as ctx: + data_type = "float64" if ctx.double_accuracy else "float32" -discretize = ps.fd.Discretization2ndOrder(dx=dx, dt=dt) -heat_pde_discretized = discretize(heat_pde) -heat_pde_discretized = heat_pde_discretized.args[1] + heat_pde_discretized.args[0].simplify() + u, u_tmp = ps.fields(f"u, u_tmp: {data_type}[2D]", layout='fzyx') + kappa = sp.Symbol("kappa") + dx = sp.Symbol("dx") + dt = sp.Symbol("dt") + heat_pde = ps.fd.transient(u) - kappa * (ps.fd.diff(u, 0, 0) + ps.fd.diff(u, 1, 1)) + discretize = ps.fd.Discretization2ndOrder(dx=dx, dt=dt) + heat_pde_discretized = discretize(heat_pde) + heat_pde_discretized = heat_pde_discretized.args[1] + heat_pde_discretized.args[0].simplify() -@ps.kernel -def update(): - u_tmp.center @= heat_pde_discretized + @ps.kernel + def update(): + u_tmp.center @= heat_pde_discretized -ac = ps.AssignmentCollection(update) -ac = ps.simp.simplifications.add_subexpressions_for_divisions(ac) -with CodeGeneration() as ctx: + ac = ps.AssignmentCollection(update) + ac = ps.simp.simplifications.add_subexpressions_for_divisions(ac) + generate_sweep(ctx, 'HeatEquationKernel', ac) diff --git a/python/lbmpy_walberla/additional_data_handler.py b/python/lbmpy_walberla/additional_data_handler.py index 214347451..32f8c0ee2 100644 --- a/python/lbmpy_walberla/additional_data_handler.py +++ b/python/lbmpy_walberla/additional_data_handler.py @@ -1,5 +1,5 @@ from pystencils import Target -from pystencils.stencil import inverse_direction, offset_to_direction_string +from pystencils.stencil import inverse_direction from lbmpy.advanced_streaming import AccessPdfValues, numeric_offsets, numeric_index diff --git a/python/lbmpy_walberla/packinfo.py b/python/lbmpy_walberla/packinfo.py index 27f26b05b..796ccfd98 100644 --- a/python/lbmpy_walberla/packinfo.py +++ b/python/lbmpy_walberla/packinfo.py @@ -2,9 +2,11 @@ from collections import defaultdict from lbmpy import LBStencil, Stencil from lbmpy.advanced_streaming.utility import Timestep, get_accessor, get_timesteps from lbmpy.advanced_streaming.communication import _extend_dir + +from pystencils import Assignment, Field, Target from pystencils.stencil import inverse_direction + from pystencils_walberla.codegen import comm_directions, generate_pack_info -from pystencils import Assignment, Field, Target def generate_lb_pack_info(generation_context, diff --git a/python/lbmpy_walberla/sparse.py b/python/lbmpy_walberla/sparse.py index 95e45f64e..fc1482b39 100644 --- a/python/lbmpy_walberla/sparse.py +++ b/python/lbmpy_walberla/sparse.py @@ -3,7 +3,9 @@ import numpy as np from lbmpy.sparse import ( create_lb_update_rule_sparse, create_macroscopic_value_getter_sparse, create_macroscopic_value_setter_sparse, create_symbolic_list) -from pystencils import TypedSymbol, create_kernel + +from pystencils import create_kernel +from pystencils.typing import TypedSymbol class ListLbGenerator: diff --git a/python/lbmpy_walberla/templates/LatticeModel.tmpl.cpp b/python/lbmpy_walberla/templates/LatticeModel.tmpl.cpp index 52528b172..dd50337e1 100644 --- a/python/lbmpy_walberla/templates/LatticeModel.tmpl.cpp +++ b/python/lbmpy_walberla/templates/LatticeModel.tmpl.cpp @@ -58,8 +58,8 @@ namespace {{namespace}} { {{stream_kernel|generate_definition(target)}} -const real_t {{class_name}}::w[{{Q}}] = { {{weights}} }; -const real_t {{class_name}}::wInv[{{Q}}] = { {{inverse_weights}} }; +const {{dtype}} {{class_name}}::w[{{Q}}] = { {{weights}} }; +const {{dtype}} {{class_name}}::wInv[{{Q}}] = { {{inverse_weights}} }; void {{class_name}}::Sweep::streamCollide( IBlock * block, const uint_t numberOfGhostLayersToInclude ) { diff --git a/python/lbmpy_walberla/templates/LatticeModel.tmpl.h b/python/lbmpy_walberla/templates/LatticeModel.tmpl.h index 39ae1afd9..d1e299578 100644 --- a/python/lbmpy_walberla/templates/LatticeModel.tmpl.h +++ b/python/lbmpy_walberla/templates/LatticeModel.tmpl.h @@ -20,6 +20,7 @@ #pragma once #include "core/DataTypes.h" #include "core/logging/Logging.h" +#include "core/math/Matrix3.h" #include "field/GhostLayerField.h" #include "field/SwapableCompare.h" @@ -98,8 +99,8 @@ class {{class_name}} public: typedef stencil::{{stencil_name}} Stencil; typedef stencil::{{communication_stencil_name}} CommunicationStencil; - static const real_t w[{{Q}}]; - static const real_t wInv[{{Q}}]; + static const {{dtype}} w[{{Q}}]; + static const {{dtype}} wInv[{{Q}}]; static const bool compressible = {% if compressible %}true{% else %}false{% endif %}; @@ -158,11 +159,11 @@ private: if( targetLevel != currentLevel ) { - real_t level_scale_factor(1); + {{dtype}} level_scale_factor(1); if( currentLevel < targetLevel ) - level_scale_factor = real_c( uint_t(1) << ( targetLevel - currentLevel ) ); + level_scale_factor = {{dtype}}( uint_t(1) << ( targetLevel - currentLevel ) ); else // currentLevel > targetLevel - level_scale_factor = real_t(1) / real_c( uint_t(1) << ( currentLevel - targetLevel ) ); + level_scale_factor = {{dtype}}(1) / {{dtype}}( uint_t(1) << ( currentLevel - targetLevel ) ); {% for scalingType, name, expression in refinement_scaling_info -%} {% if scalingType == 'normal' %} @@ -225,44 +226,44 @@ class EquilibriumDistribution< {{class_name}}, void> public: typedef typename {{class_name}}::Stencil Stencil; - static real_t get( const stencil::Direction direction, - const Vector3< real_t > & u = Vector3< real_t >( real_t(0.0) ), - real_t rho = real_t(1.0) ) + static {{dtype}} get( const stencil::Direction direction, + const Vector3< {{dtype}} > & u = Vector3< {{dtype}} >( {{dtype}}(0.0) ), + {{dtype}} rho = {{dtype}}(1.0) ) { {% if not compressible %} - rho -= real_t(1.0); + rho -= {{dtype}}(1.0); {% endif %} {{equilibrium_from_direction}} } - static real_t getSymmetricPart( const stencil::Direction direction, - const Vector3<real_t> & u = Vector3< real_t >(real_t(0.0)), - real_t rho = real_t(1.0) ) + static {{dtype}} getSymmetricPart( const stencil::Direction direction, + const Vector3<{{dtype}}> & u = Vector3< {{dtype}} >({{dtype}}(0.0)), + {{dtype}} rho = {{dtype}}(1.0) ) { {% if not compressible %} - rho -= real_t(1.0); + rho -= {{dtype}}(1.0); {% endif %} {{symmetric_equilibrium_from_direction}} } - static real_t getAsymmetricPart( const stencil::Direction direction, - const Vector3< real_t > & u = Vector3<real_t>( real_t(0.0) ), - real_t rho = real_t(1.0) ) + static {{dtype}} getAsymmetricPart( const stencil::Direction direction, + const Vector3< {{dtype}} > & u = Vector3<{{dtype}}>( {{dtype}}(0.0) ), + {{dtype}} rho = {{dtype}}(1.0) ) { {% if not compressible %} - rho -= real_t(1.0); + rho -= {{dtype}}(1.0); {% endif %} {{asymmetric_equilibrium_from_direction}} } - static std::vector< real_t > get( const Vector3< real_t > & u = Vector3<real_t>( real_t(0.0) ), - real_t rho = real_t(1.0) ) + static std::vector< {{dtype}} > get( const Vector3< {{dtype}} > & u = Vector3<{{dtype}}>( {{dtype}}(0.0) ), + {{dtype}} rho = {{dtype}}(1.0) ) { {% if not compressible %} - rho -= real_t(1.0); + rho -= {{dtype}}(1.0); {% endif %} - std::vector< real_t > equilibrium( Stencil::Size ); + std::vector< {{dtype}} > equilibrium( Stencil::Size ); for( auto d = Stencil::begin(); d != Stencil::end(); ++d ) { equilibrium[d.toIdx()] = get(*d, u, rho); @@ -278,25 +279,25 @@ template<> struct AdaptVelocityToForce<{{class_name}}, void> { template< typename FieldPtrOrIterator > - static Vector3<real_t> get( FieldPtrOrIterator & it, const {{class_name}} & lm, - const Vector3< real_t > & velocity, const real_t rho ) + static Vector3<{{dtype}}> get( FieldPtrOrIterator & it, const {{class_name}} & lm, + const Vector3< {{dtype}} > & velocity, const {{dtype}} rho ) { auto x = it.x(); auto y = it.y(); auto z = it.z(); {% if macroscopic_velocity_shift %} - return velocity - Vector3<real_t>({{macroscopic_velocity_shift | join(",") }} {% if D == 2 %}, real_t(0.0) {%endif %} ); + return velocity - Vector3<{{dtype}}>({{macroscopic_velocity_shift | join(",") }} {% if D == 2 %}, {{dtype}}(0.0) {%endif %} ); {% else %} return velocity; {% endif %} } - static Vector3<real_t> get( const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, const {{class_name}} & lm, - const Vector3< real_t > & velocity, const real_t rho ) + static Vector3<{{dtype}}> get( const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, const {{class_name}} & lm, + const Vector3< {{dtype}} > & velocity, const {{dtype}} rho ) { {% if macroscopic_velocity_shift %} - return velocity - Vector3<real_t>({{macroscopic_velocity_shift | join(",") }} {% if D == 2 %}, real_t(0.0) {%endif %} ); + return velocity - Vector3<{{dtype}}>({{macroscopic_velocity_shift | join(",") }} {% if D == 2 %}, {{dtype}}(0.0) {%endif %} ); {% else %} return velocity; {% endif %} @@ -312,10 +313,10 @@ struct Equilibrium< {{class_name}}, void > template< typename FieldPtrOrIterator > static void set( FieldPtrOrIterator & it, - const Vector3< real_t > & u = Vector3< real_t >( real_t(0.0) ), real_t rho = real_t(1.0) ) + const Vector3< {{dtype}} > & u = Vector3< {{dtype}} >( {{dtype}}(0.0) ), {{dtype}} rho = {{dtype}}(1.0) ) { {%if not compressible %} - rho -= real_t(1.0); + rho -= {{dtype}}(1.0); {%endif %} {% for eqTerm in equilibrium -%} @@ -325,13 +326,13 @@ struct Equilibrium< {{class_name}}, void > template< typename PdfField_T > static void set( PdfField_T & pdf, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, - const Vector3< real_t > & u = Vector3< real_t >( real_t(0.0) ), real_t rho = real_t(1.0) ) + const Vector3< {{dtype}} > & u = Vector3< {{dtype}} >( {{dtype}}(0.0) ), {{dtype}} rho = {{dtype}}(1.0) ) { {%if not compressible %} - rho -= real_t(1.0); + rho -= {{dtype}}(1.0); {%endif %} - real_t & xyz0 = pdf(x,y,z,0); + {{dtype}} & xyz0 = pdf(x,y,z,0); {% for eqTerm in equilibrium -%} pdf.getF( &xyz0, {{loop.index0 }})= {{eqTerm}}; {% endfor -%} @@ -343,22 +344,22 @@ template<> struct Density<{{class_name}}, void> { template< typename FieldPtrOrIterator > - static inline real_t get( const {{class_name}} & , const FieldPtrOrIterator & it ) + static inline {{dtype}} get( const {{class_name}} & , const FieldPtrOrIterator & it ) { {% for i in range(Q) -%} - const real_t f_{{i}} = it[{{i}}]; + const {{dtype}} f_{{i}} = it[{{i}}]; {% endfor -%} {{density_getters | indent(8)}} return rho; } template< typename PdfField_T > - static inline real_t get( const {{class_name}} & , + static inline {{dtype}} get( const {{class_name}} & , const PdfField_T & pdf, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) { - const real_t & xyz0 = pdf(x,y,z,0); + const {{dtype}} & xyz0 = pdf(x,y,z,0); {% for i in range(Q) -%} - const real_t f_{{i}} = pdf.getF( &xyz0, {{i}}); + const {{dtype}} f_{{i}} = pdf.getF( &xyz0, {{i}}); {% endfor -%} {{density_getters | indent(8)}} return rho; @@ -371,7 +372,7 @@ struct DensityAndVelocity<{{class_name}}> { template< typename FieldPtrOrIterator > static void set( FieldPtrOrIterator & it, const {{class_name}} & lm, - const Vector3< real_t > & u = Vector3< real_t >( real_t(0.0) ), const real_t rho_in = real_t(1.0) ) + const Vector3< {{dtype}} > & u = Vector3< {{dtype}} >( {{dtype}}(0.0) ), const {{dtype}} rho_in = {{dtype}}(1.0) ) { auto x = it.x(); auto y = it.y(); @@ -379,22 +380,22 @@ struct DensityAndVelocity<{{class_name}}> {{density_velocity_setter_macroscopic_values | indent(8)}} {% if D == 2 -%} - const real_t u_2(0.0); + const {{dtype}} u_2(0.0); {% endif %} - Equilibrium<{{class_name}}>::set(it, Vector3<real_t>(u_0, u_1, u_2), rho{%if not compressible %} + real_t(1) {%endif%}); + Equilibrium<{{class_name}}>::set(it, Vector3<{{dtype}}>(u_0, u_1, u_2), rho{%if not compressible %} + {{dtype}}(1) {%endif%}); } template< typename PdfField_T > static void set( PdfField_T & pdf, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, const {{class_name}} & lm, - const Vector3< real_t > & u = Vector3< real_t >( real_t(0.0) ), const real_t rho_in = real_t(1.0) ) + const Vector3< {{dtype}} > & u = Vector3< {{dtype}} >( {{dtype}}(0.0) ), const {{dtype}} rho_in = {{dtype}}(1.0) ) { {{density_velocity_setter_macroscopic_values | indent(8)}} {% if D == 2 -%} - const real_t u_2(0.0); + const {{dtype}} u_2(0.0); {% endif %} - Equilibrium<{{class_name}}>::set(pdf, x, y, z, Vector3<real_t>(u_0, u_1, u_2), rho {%if not compressible %} + real_t(1) {%endif%}); + Equilibrium<{{class_name}}>::set(pdf, x, y, z, Vector3<{{dtype}}>(u_0, u_1, u_2), rho {%if not compressible %} + {{dtype}}(1) {%endif%}); } }; @@ -404,7 +405,7 @@ struct DensityAndVelocityRange<{{class_name}}, FieldIteratorXYZ> { static void set( FieldIteratorXYZ & begin, const FieldIteratorXYZ & end, const {{class_name}} & lm, - const Vector3< real_t > & u = Vector3< real_t >( real_t(0.0) ), const real_t rho_in = real_t(1.0) ) + const Vector3< {{dtype}} > & u = Vector3< {{dtype}} >( {{dtype}}(0.0) ), const {{dtype}} rho_in = {{dtype}}(1.0) ) { for( auto cellIt = begin; cellIt != end; ++cellIt ) { @@ -413,10 +414,10 @@ struct DensityAndVelocityRange<{{class_name}}, FieldIteratorXYZ> const auto z = cellIt.z(); {{density_velocity_setter_macroscopic_values | indent(12)}} {% if D == 2 -%} - const real_t u_2(0.0); + const {{dtype}} u_2(0.0); {% endif %} - Equilibrium<{{class_name}}>::set(cellIt, Vector3<real_t>(u_0, u_1, u_2), rho{%if not compressible %} + real_t(1) {%endif%}); + Equilibrium<{{class_name}}>::set(cellIt, Vector3<{{dtype}}>(u_0, u_1, u_2), rho{%if not compressible %} + {{dtype}}(1) {%endif%}); } } }; @@ -427,7 +428,7 @@ template<> struct DensityAndMomentumDensity<{{class_name}}> { template< typename FieldPtrOrIterator > - static real_t get( Vector3< real_t > & momentumDensity, const {{class_name}} & lm, + static {{dtype}} get( Vector3< {{dtype}} > & momentumDensity, const {{class_name}} & lm, const FieldPtrOrIterator & it ) { const auto x = it.x(); @@ -435,7 +436,7 @@ struct DensityAndMomentumDensity<{{class_name}}> const auto z = it.z(); {% for i in range(Q) -%} - const real_t f_{{i}} = it[{{i}}]; + const {{dtype}} f_{{i}} = it[{{i}}]; {% endfor -%} {{momentum_density_getter | indent(8) }} @@ -446,12 +447,12 @@ struct DensityAndMomentumDensity<{{class_name}}> } template< typename PdfField_T > - static real_t get( Vector3< real_t > & momentumDensity, const {{class_name}} & lm, const PdfField_T & pdf, + static {{dtype}} get( Vector3< {{dtype}} > & momentumDensity, const {{class_name}} & lm, const PdfField_T & pdf, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) { - const real_t & xyz0 = pdf(x,y,z,0); + const {{dtype}} & xyz0 = pdf(x,y,z,0); {% for i in range(Q) -%} - const real_t f_{{i}} = pdf.getF( &xyz0, {{i}}); + const {{dtype}} f_{{i}} = pdf.getF( &xyz0, {{i}}); {% endfor -%} {{momentum_density_getter | indent(8) }} @@ -467,14 +468,14 @@ template<> struct MomentumDensity< {{class_name}}> { template< typename FieldPtrOrIterator > - static void get( Vector3< real_t > & momentumDensity, const {{class_name}} & lm, const FieldPtrOrIterator & it ) + static void get( Vector3< {{dtype}} > & momentumDensity, const {{class_name}} & lm, const FieldPtrOrIterator & it ) { const auto x = it.x(); const auto y = it.y(); const auto z = it.z(); {% for i in range(Q) -%} - const real_t f_{{i}} = it[{{i}}]; + const {{dtype}} f_{{i}} = it[{{i}}]; {% endfor -%} {{momentum_density_getter | indent(8) }} @@ -484,12 +485,12 @@ struct MomentumDensity< {{class_name}}> } template< typename PdfField_T > - static void get( Vector3< real_t > & momentumDensity, const {{class_name}} & lm, const PdfField_T & pdf, + static void get( Vector3< {{dtype}} > & momentumDensity, const {{class_name}} & lm, const PdfField_T & pdf, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) { - const real_t & xyz0 = pdf(x,y,z,0); + const {{dtype}} & xyz0 = pdf(x,y,z,0); {% for i in range(Q) -%} - const real_t f_{{i}} = pdf.getF( &xyz0, {{i}}); + const {{dtype}} f_{{i}} = pdf.getF( &xyz0, {{i}}); {% endfor -%} {{momentum_density_getter | indent(8) }} @@ -504,13 +505,13 @@ template<> struct PressureTensor<{{class_name}}> { template< typename FieldPtrOrIterator > - static void get( Matrix3< real_t > & /* pressureTensor */, const {{class_name}} & /* latticeModel */, const FieldPtrOrIterator & /* it */ ) + static void get( Matrix3< {{dtype}} > & /* pressureTensor */, const {{class_name}} & /* latticeModel */, const FieldPtrOrIterator & /* it */ ) { WALBERLA_ABORT("Not implemented"); } template< typename PdfField_T > - static void get( Matrix3< real_t > & /* pressureTensor */, const {{class_name}} & /* latticeModel */, const PdfField_T & /* pdf */, + static void get( Matrix3< {{dtype}} > & /* pressureTensor */, const {{class_name}} & /* latticeModel */, const PdfField_T & /* pdf */, const cell_idx_t /* x */, const cell_idx_t /* y */, const cell_idx_t /* z */ ) { WALBERLA_ABORT("Not implemented"); @@ -522,27 +523,27 @@ template<> struct ShearRate<{{class_name}}> { template< typename FieldPtrOrIterator > - static inline real_t get( const {{class_name}} & /* latticeModel */, const FieldPtrOrIterator & /* it */, - const Vector3< real_t > & /* velocity */, const real_t /* rho */) + static inline {{dtype}} get( const {{class_name}} & /* latticeModel */, const FieldPtrOrIterator & /* it */, + const Vector3< {{dtype}} > & /* velocity */, const {{dtype}} /* rho */) { WALBERLA_ABORT("Not implemented"); - return real_t(0.0); + return {{dtype}}(0.0); } template< typename PdfField_T > - static inline real_t get( const {{class_name}} & latticeModel, + static inline {{dtype}} get( const {{class_name}} & latticeModel, const PdfField_T & /* pdf */, const cell_idx_t /* x */, const cell_idx_t /* y */, const cell_idx_t /* z */, - const Vector3< real_t > & /* velocity */, const real_t /* rho */ ) + const Vector3< {{dtype}} > & /* velocity */, const {{dtype}} /* rho */ ) { WALBERLA_ABORT("Not implemented"); - return real_t(0.0); + return {{dtype}}(0.0); } - static inline real_t get( const std::vector< real_t > & /* nonEquilibrium */, const real_t /* relaxationParam */, - const real_t /* rho */ = real_t(1) ) + static inline {{dtype}} get( const std::vector< {{dtype}} > & /* nonEquilibrium */, const {{dtype}} /* relaxationParam */, + const {{dtype}} /* rho */ = {{dtype}}(1) ) { WALBERLA_ABORT("Not implemented"); - return real_t(0.0); + return {{dtype}}(0.0); } }; diff --git a/python/lbmpy_walberla/tests/test_walberla_codegen.py b/python/lbmpy_walberla/tests/test_walberla_codegen.py index c36bf659f..4aae0a04e 100644 --- a/python/lbmpy_walberla/tests/test_walberla_codegen.py +++ b/python/lbmpy_walberla/tests/test_walberla_codegen.py @@ -78,6 +78,7 @@ class WalberlaLbmpyCodegenTest(unittest.TestCase): stencil = LBStencil(stencil=Stencil.D3Q27) lbm_config = LBMConfig(stencil=stencil, method=Method.TRT_KBC_N1, + zero_centered=False, relaxation_rates=[1.5, sp.Symbol('omega_free')], compressible=True, entropic=True, omega_output_field=omega_field) @@ -92,7 +93,7 @@ class WalberlaLbmpyCodegenTest(unittest.TestCase): force_field, vel_field = ps.fields("force(3), velocity(3): [3D]", layout='fzyx') stencil = LBStencil(stencil=Stencil.D3Q19) - lbm_config = LBMConfig(stencil=stencil, method=Method.MRT, compressible=True, + lbm_config = LBMConfig(stencil=stencil, method=Method.MRT, compressible=True, zero_centered=False, fluctuating={'seed': 0, 'temperature': 1e-6}, force_model=ForceModel.GUO, relaxation_rates=[omega_shear] * 19, force=force_field.center_vector) diff --git a/python/lbmpy_walberla/walberla_lbm_generation.py b/python/lbmpy_walberla/walberla_lbm_generation.py index cb3d56f41..8eda3e76f 100644 --- a/python/lbmpy_walberla/walberla_lbm_generation.py +++ b/python/lbmpy_walberla/walberla_lbm_generation.py @@ -12,11 +12,12 @@ from lbmpy.updatekernels import create_lbm_kernel, create_stream_only_kernel from pystencils import AssignmentCollection, create_kernel, Target from pystencils.astnodes import SympyAssignment from pystencils.backends.cbackend import CBackend, CustomSympyPrinter, get_headers -from pystencils.data_types import TypedSymbol, type_all_numbers, cast_func +from pystencils.typing import BasicType, CastFunc, TypedSymbol from pystencils.field import Field +from pystencils.node_collection import NodeCollection from pystencils.stencil import offset_to_direction_string from pystencils.sympyextensions import get_symmetric_part -from pystencils.transformations import add_types +from pystencils.typing.transformations import add_types from pystencils_walberla.codegen import KernelInfo, config_from_context from pystencils_walberla.jinja_filters import add_pystencils_filters_to_jinja_env @@ -24,55 +25,75 @@ cpp_printer = CustomSympyPrinter() REFINEMENT_SCALE_FACTOR = sp.Symbol("level_scale_factor") -def __lattice_model(generation_context, class_name, lb_method, stream_collide_ast, collide_ast, stream_ast, +def __type_equilibrium_assignments(assignments, config, subs_dict): + result = assignments.new_with_substitutions(subs_dict) + result = NodeCollection(result.main_assignments) + result.evaluate_terms() + result = add_types(result.all_assignments, config) + return result + + +def __lattice_model(generation_context, class_name, config, lb_method, stream_collide_ast, collide_ast, stream_ast, refinement_scaling): stencil_name = lb_method.stencil.name if not stencil_name: raise ValueError("lb_method uses a stencil that is not supported in waLBerla") communication_stencil_name = stencil_name if stencil_name != "D3Q15" else "D3Q27" - is_float = not generation_context.double_accuracy - dtype_string = "float32" if is_float else "float64" + default_dtype = config.data_type.default_factory() + + cqc = lb_method.conserved_quantity_computation - vel_symbols = lb_method.conserved_quantity_computation.first_order_moment_symbols + vel_symbols = cqc.velocity_symbols rho_sym = sp.Symbol('rho') + reference_density = rho_sym if cqc.compressible else cqc.background_density pdfs_sym = sp.symbols(f'f_:{lb_method.stencil.Q}') - vel_arr_symbols = [IndexedBase(sp.Symbol('u'), shape=(1,))[i] for i in range(len(vel_symbols))] + + vel_arr_symbols = [IndexedBase(TypedSymbol('u', default_dtype), shape=(1,))[i] for i in range(len(vel_symbols))] + subs_dict = {a: b for a, b in zip(vel_symbols, vel_arr_symbols)} + momentum_density_symbols = sp.symbols(f'md_:{len(vel_symbols)}') equilibrium = lb_method.get_equilibrium() - equilibrium = equilibrium.new_with_substitutions({a: b for a, b in zip(vel_symbols, vel_arr_symbols)}) - _, _, equilibrium = add_types(equilibrium.main_assignments, dtype_string, False) - equilibrium = sp.Matrix([e.rhs for e in equilibrium]) + lhs_list = [a.lhs for a in equilibrium.main_assignments] + + equilibrium_matrix = sp.Matrix([e.rhs for e in equilibrium.main_assignments]) + symmetric_equilibrium_matrix = get_symmetric_part(equilibrium_matrix, vel_symbols) + asymmetric_equilibrium_matrix = sp.expand(equilibrium_matrix - symmetric_equilibrium_matrix) + + equilibrium = AssignmentCollection([ps.Assignment(lhs, rhs) + for lhs, rhs in zip(lhs_list, equilibrium_matrix)]) + symmetric_equilibrium = AssignmentCollection([ps.Assignment(lhs, rhs) + for lhs, rhs in zip(lhs_list, symmetric_equilibrium_matrix)]) + asymmetric_equilibrium = AssignmentCollection([ps.Assignment(lhs, rhs) + for lhs, rhs in zip(lhs_list, asymmetric_equilibrium_matrix)]) - symmetric_equilibrium = get_symmetric_part(equilibrium, vel_arr_symbols) - symmetric_equilibrium = symmetric_equilibrium.subs(sp.Rational(1, 2), cast_func(sp.Rational(1, 2), dtype_string)) - asymmetric_equilibrium = sp.expand(equilibrium - symmetric_equilibrium) + equilibrium = __type_equilibrium_assignments(equilibrium, config, subs_dict) + symmetric_equilibrium = __type_equilibrium_assignments(symmetric_equilibrium, config, subs_dict) + asymmetric_equilibrium = __type_equilibrium_assignments(asymmetric_equilibrium, config, subs_dict) force_model = lb_method.force_model macroscopic_velocity_shift = None if force_model: if hasattr(force_model, 'macroscopic_velocity_shift'): macroscopic_velocity_shift = [e.subs(force_model.subs_dict_force) - for e in force_model.macroscopic_velocity_shift(rho_sym)] - macroscopic_velocity_shift = [expression_to_code(e.subs(sp.Rational(1, 2), cast_func(sp.Rational(1, 2), - dtype_string)), - "lm.", ['rho'], dtype=dtype_string) + for e in force_model.macroscopic_velocity_shift(reference_density)] + macroscopic_velocity_shift = [expression_to_code(e, "lm.", ['rho'], dtype=default_dtype) for e in macroscopic_velocity_shift] - cqc = lb_method.conserved_quantity_computation - eq_input_from_input_eqs = cqc.equilibrium_input_equations_from_init_values(sp.Symbol('rho_in'), vel_arr_symbols) - density_velocity_setter_macroscopic_values = equations_to_code(eq_input_from_input_eqs, dtype=dtype_string, + density_velocity_setter_macroscopic_values = equations_to_code(eq_input_from_input_eqs, dtype=default_dtype, variables_without_prefix=['rho_in', 'u']) momentum_density_getter = cqc.output_equations_from_pdfs(pdfs_sym, {'density': rho_sym, 'momentum_density': momentum_density_symbols}) + + is_float = True if issubclass(default_dtype.numpy_dtype.type, np.float32) else False constant_suffix = "f" if is_float else "" required_headers = get_headers(stream_collide_ast) if refinement_scaling: - refinement_scaling_info = [(e0, e1, expression_to_code(e2, '', dtype=dtype_string)) for e0, e1, e2 in + refinement_scaling_info = [(e0, e1, expression_to_code(e2, '', dtype=default_dtype)) for e0, e1, e2 in refinement_scaling.scaling_info] # append '_' to entries since they are used as members for i in range(len(refinement_scaling_info)): @@ -95,17 +116,18 @@ def __lattice_model(generation_context, class_name, lb_method, stream_collide_as 'compressible': lb_method.conserved_quantity_computation.compressible, 'weights': ",".join(str(w.evalf()) + constant_suffix for w in lb_method.weights), 'inverse_weights': ",".join(str((1 / w).evalf()) + constant_suffix for w in lb_method.weights), + 'dtype': "float" if is_float else "double", 'equilibrium_from_direction': stencil_switch_statement(lb_method.stencil, equilibrium), 'symmetric_equilibrium_from_direction': stencil_switch_statement(lb_method.stencil, symmetric_equilibrium), 'asymmetric_equilibrium_from_direction': stencil_switch_statement(lb_method.stencil, asymmetric_equilibrium), - 'equilibrium': [cpp_printer.doprint(e) for e in equilibrium], + 'equilibrium': [cpp_printer.doprint(e.rhs) for e in equilibrium], 'macroscopic_velocity_shift': macroscopic_velocity_shift, 'density_getters': equations_to_code(cqc.output_equations_from_pdfs(pdfs_sym, {"density": rho_sym}), - variables_without_prefix=[e.name for e in pdfs_sym], dtype=dtype_string), + variables_without_prefix=[e.name for e in pdfs_sym], dtype=default_dtype), 'momentum_density_getter': equations_to_code(momentum_density_getter, variables_without_prefix=pdfs_sym, - dtype=dtype_string), + dtype=default_dtype), 'density_velocity_setter_macroscopic_values': density_velocity_setter_macroscopic_values, 'refinement_scaling_info': refinement_scaling_info, @@ -140,7 +162,6 @@ def generate_lattice_model(generation_context, class_name, collision_rule, field # usually a numpy layout is chosen by default i.e. xyzf - which is bad for waLBerla where at least the spatial # coordinates should be ordered in reverse direction i.e. zyx - dtype = np.float64 if config.data_type == "float64" else np.float32 lb_method = collision_rule.method q = lb_method.stencil.Q @@ -154,8 +175,10 @@ def generate_lattice_model(generation_context, class_name, collision_rule, field elif field_layout == 'zyxf': config.cpu_vectorize_info['assume_inner_stride_one'] = False - src_field = ps.Field.create_generic('pdfs', dim, dtype, index_dimensions=1, layout=field_layout, index_shape=(q,)) - dst_field = ps.Field.create_generic('pdfs_tmp', dim, dtype, index_dimensions=1, layout=field_layout, + src_field = ps.Field.create_generic('pdfs', dim, config.data_type['pdfs'].numpy_dtype, + index_dimensions=1, layout=field_layout, index_shape=(q,)) + dst_field = ps.Field.create_generic('pdfs_tmp', dim, config.data_type['pdfs_tmp'].numpy_dtype, + index_dimensions=1, layout=field_layout, index_shape=(q,)) stream_collide_update_rule = create_lbm_kernel(collision_rule, src_field, dst_field, StreamPullTwoFieldsAccessor()) @@ -173,7 +196,7 @@ def generate_lattice_model(generation_context, class_name, collision_rule, field stream_ast = create_kernel(stream_update_rule, config=config) stream_ast.function_name = 'kernel_stream' stream_ast.assumed_inner_stride_one = config.cpu_vectorize_info['assume_inner_stride_one'] - __lattice_model(generation_context, class_name, lb_method, stream_collide_ast, collide_ast, stream_ast, + __lattice_model(generation_context, class_name, config, lb_method, stream_collide_ast, collide_ast, stream_ast, refinement_scaling) @@ -234,11 +257,11 @@ def stencil_switch_statement(stencil, values): case {{direction_name}}: return {{value}}; {% endfor -%} default: - WALBERLA_ABORT("Invalid Direction"); + WALBERLA_ABORT("Invalid Direction") } """) - dir_to_value_dict = {offset_to_direction_string(d): cpp_printer.doprint(v) for d, v in zip(stencil, values)} + dir_to_value_dict = {offset_to_direction_string(d): cpp_printer.doprint(v.rhs) for d, v in zip(stencil, values)} return template.render(dir_to_value_dict=dir_to_value_dict, undefined=StrictUndefined) @@ -271,7 +294,7 @@ def field_and_symbol_substitute(expr, variable_prefix="lm.", variables_without_p return expr.subs(substitutions) -def expression_to_code(expr, variable_prefix="lm.", variables_without_prefix=None, dtype="double"): +def expression_to_code(expr, variable_prefix="lm.", variables_without_prefix=None, dtype=None): """ Takes a sympy expression and creates a C code string from it. Replaces field accesses by walberla field accesses i.e. field_W^1 -> field->get(-1, 0, 0, 1) @@ -282,6 +305,9 @@ def expression_to_code(expr, variable_prefix="lm.", variables_without_prefix=Non :param variables_without_prefix: this variables are not prefixed :return: code string """ + if dtype is None: + dtype = BasicType("float64") + if variables_without_prefix is None: variables_without_prefix = [] return cpp_printer.doprint( @@ -289,18 +315,15 @@ def expression_to_code(expr, variable_prefix="lm.", variables_without_prefix=Non def type_expr(eq, dtype): - def recurse(expr): - for i in range(len(expr.args)): - if expr.args[i] == sp.Rational or expr.args[i] == sp.Float: - expr.args[i] = type_all_numbers(expr.args[i], dtype=dtype) - else: - recurse(expr.args[i]) - - recurse(eq) + # manually cast 0.5 to dtype since this is somehow not done automatically + eq = eq.subs(sp.Rational(1, 2), CastFunc(sp.Rational(1, 2), dtype)) return eq.subs({s: TypedSymbol(s.name, dtype) for s in eq.atoms(sp.Symbol)}) -def equations_to_code(equations, variable_prefix="lm.", variables_without_prefix=None, dtype="double"): +def equations_to_code(equations, variable_prefix="lm.", variables_without_prefix=None, dtype=None): + if dtype is None: + dtype = BasicType("float64") + if variables_without_prefix is None: variables_without_prefix = [] if isinstance(equations, AssignmentCollection): diff --git a/python/pystencils_walberla/boundary.py b/python/pystencils_walberla/boundary.py index 5cf8f1fe5..329b68059 100644 --- a/python/pystencils_walberla/boundary.py +++ b/python/pystencils_walberla/boundary.py @@ -5,7 +5,7 @@ from pystencils.boundaries.boundaryhandling import create_boundary_kernel from pystencils.boundaries.createindexlist import ( boundary_index_array_coordinate_names, direction_member_name, numpy_data_type_for_boundary_object) -from pystencils.data_types import TypedSymbol, create_type +from pystencils.typing import TypedSymbol, create_type from pystencils.stencil import inverse_direction from pystencils_walberla.codegen import config_from_context @@ -46,8 +46,10 @@ def generate_boundary(generation_context, create_kernel_params = config.__dict__ del create_kernel_params['target'] del create_kernel_params['index_fields'] + del create_kernel_params['default_number_int'] + del create_kernel_params['skip_independence_check'] - field_data_type = np.float64 if config.data_type == "float64" else np.float32 + field_data_type = config.data_type[field_name].numpy_dtype index_struct_dtype = numpy_data_type_for_boundary_object(boundary_object, dim) @@ -57,7 +59,7 @@ def generate_boundary(generation_context, field_type=field_type) index_field = Field('indexVector', FieldType.INDEXED, index_struct_dtype, layout=[0], - shape=(TypedSymbol("indexVectorSize", create_type(np.int64)), 1), strides=(1, 1)) + shape=(TypedSymbol("indexVectorSize", create_type("int32")), 1), strides=(1, 1)) if not kernel_creation_function: kernel_creation_function = create_boundary_kernel @@ -79,6 +81,9 @@ def generate_boundary(generation_context, if additional_data_handler is None: additional_data_handler = AdditionalDataHandler(stencil=neighbor_stencil) + default_dtype = config.data_type.default_factory() + is_float = True if issubclass(default_dtype.numpy_dtype.type, np.float32) else False + context = { 'kernel': kernel_family, 'class_name': boundary_object.name, @@ -92,6 +97,7 @@ def generate_boundary(generation_context, 'inner_or_boundary': boundary_object.inner_or_boundary, 'single_link': boundary_object.single_link, 'additional_data_handler': additional_data_handler, + 'dtype': "double" if is_float else "float", 'layout': layout } diff --git a/python/pystencils_walberla/codegen.py b/python/pystencils_walberla/codegen.py index de792b8fc..c5cefc06e 100644 --- a/python/pystencils_walberla/codegen.py +++ b/python/pystencils_walberla/codegen.py @@ -14,8 +14,8 @@ from pystencils.backends.simd_instruction_sets import get_supported_instruction_ from pystencils.stencil import inverse_direction, offset_to_direction_string from pystencils.backends.cuda_backend import CudaSympyPrinter -from pystencils.kernelparameters import SHAPE_DTYPE -from pystencils.data_types import TypedSymbol +from pystencils.typing.typed_sympy import SHAPE_DTYPE +from pystencils.typing import TypedSymbol from pystencils_walberla.jinja_filters import add_pystencils_filters_to_jinja_env from pystencils_walberla.kernel_selection import KernelCallNode, KernelFamily, HighLevelInterfaceSpec @@ -275,6 +275,9 @@ def generate_pack_info(generation_context, class_name: str, config = replace(config, cpu_vectorize_info=None) config_zero_gl = replace(config_zero_gl, cpu_vectorize_info=None) + config = replace(config, allow_double_writes=True) + config_zero_gl = replace(config_zero_gl, allow_double_writes=True) + template_name = "CpuPackInfo.tmpl" if config.target == Target.CPU else 'GpuPackInfo.tmpl' fields_accessed = set() @@ -500,7 +503,7 @@ def config_from_context(generation_context, target=Target.CPU, data_type=None, cpu_vectorize_info['assume_aligned'] = cpu_vectorize_info.get('assume_aligned', False) cpu_vectorize_info['nontemporal'] = cpu_vectorize_info.get('nontemporal', False) - config = CreateKernelConfig(target=target, data_type=data_type, + config = CreateKernelConfig(target=target, data_type=data_type, default_number_float=data_type, cpu_openmp=cpu_openmp, cpu_vectorize_info=cpu_vectorize_info, **kwargs) diff --git a/python/pystencils_walberla/jinja_filters.py b/python/pystencils_walberla/jinja_filters.py index b9cfd32d0..0ee3f3cd1 100644 --- a/python/pystencils_walberla/jinja_filters.py +++ b/python/pystencils_walberla/jinja_filters.py @@ -10,7 +10,7 @@ import sympy as sp from pystencils import Target, Backend from pystencils.backends.cbackend import generate_c -from pystencils.data_types import TypedSymbol, get_base_type +from pystencils.typing import TypedSymbol, get_base_type from pystencils.field import FieldType from pystencils.sympyextensions import prod @@ -78,7 +78,7 @@ def get_field_fsize(field): def get_field_stride(param): field = param.fields[0] - type_str = get_base_type(param.symbol.dtype).base_name + type_str = get_base_type(param.symbol.dtype).c_name stride_names = ['xStride()', 'yStride()', 'zStride()', 'fStride()'] stride_names = [f"{type_str}({param.field_name}->{e})" for e in stride_names] strides = stride_names[:field.spatial_dimensions] @@ -322,12 +322,12 @@ def generate_call(ctx, kernel, ghost_layers_to_include=0, cell_interval=None, st f"{instruction_set['bytes']}, 0);") elif param.is_field_stride: casted_stride = get_field_stride(param) - type_str = param.symbol.dtype.base_name + type_str = param.symbol.dtype.c_name kernel_call_lines.append(f"const {type_str} {param.symbol.name} = {casted_stride};") elif param.is_field_shape: coord = param.symbol.coordinate field = param.fields[0] - type_str = param.symbol.dtype.base_name + type_str = param.symbol.dtype.c_name shape = f"{type_str}({get_end_coordinates(field)[coord]})" assert coord < 3 max_value = f"{field.name}->{('x', 'y', 'z')[coord]}SizeWithGhostLayer()" @@ -364,11 +364,16 @@ def generate_constructor_initializer_list(kernel_info, parameters_to_ignore=None parameters_to_ignore += kernel_info.temporary_fields parameter_initializer_list = [] + # First field pointer for param in kernel_info.parameters: if param.is_field_pointer and param.field_name not in parameters_to_ignore: parameter_initializer_list.append(f"{param.field_name}ID({param.field_name}ID_)") - elif not param.is_field_parameter and param.symbol.name not in parameters_to_ignore: + + # Then free parameters + for param in kernel_info.parameters: + if not param.is_field_parameter and param.symbol.name not in parameters_to_ignore: parameter_initializer_list.append(f"{param.symbol.name}_({param.symbol.name})") + return ", ".join(parameter_initializer_list) @@ -383,11 +388,16 @@ def generate_constructor_parameters(kernel_info, parameters_to_ignore=None): parameters_to_ignore += kernel_info.temporary_fields + varying_parameter_names parameter_list = [] + # First field pointer for param in kernel_info.parameters: if param.is_field_pointer and param.field_name not in parameters_to_ignore: parameter_list.append(f"BlockDataID {param.field_name}ID_") - elif not param.is_field_parameter and param.symbol.name not in parameters_to_ignore: + + # Then free parameters + for param in kernel_info.parameters: + if not param.is_field_parameter and param.symbol.name not in parameters_to_ignore: parameter_list.append(f"{param.symbol.dtype} {param.symbol.name}") + varying_parameters = ["%s %s" % e for e in varying_parameters] return ", ".join(parameter_list + varying_parameters) @@ -427,7 +437,11 @@ def generate_members(ctx, kernel_info, parameters_to_ignore=(), only_fields=Fals continue if param.is_field_pointer and param.field_name not in params_to_skip: result.append(f"BlockDataID {param.field_name}ID;") - elif not param.is_field_parameter and param.symbol.name not in params_to_skip: + + for param in kernel_info.parameters: + if only_fields and not param.is_field_parameter: + continue + if not param.is_field_parameter and param.symbol.name not in params_to_skip: result.append(f"{param.symbol.dtype} {param.symbol.name}_;") for field_name in kernel_info.temporary_fields: diff --git a/python/pystencils_walberla/kernel_selection.py b/python/pystencils_walberla/kernel_selection.py index 5215e599e..b2e831cc8 100644 --- a/python/pystencils_walberla/kernel_selection.py +++ b/python/pystencils_walberla/kernel_selection.py @@ -6,7 +6,7 @@ from jinja2.filters import do_indent from pystencils import Target, TypedSymbol from pystencils.backends.cbackend import get_headers from pystencils.backends.cuda_backend import CudaSympyPrinter -from pystencils.kernelparameters import SHAPE_DTYPE +from pystencils.typing.typed_sympy import SHAPE_DTYPE """ diff --git a/python/pystencils_walberla/templates/Boundary.tmpl.cpp b/python/pystencils_walberla/templates/Boundary.tmpl.cpp index 9c41e7965..a7b1c064e 100644 --- a/python/pystencils_walberla/templates/Boundary.tmpl.cpp +++ b/python/pystencils_walberla/templates/Boundary.tmpl.cpp @@ -72,7 +72,7 @@ void {{class_name}}::run_impl( ) { auto * indexVectors = block->getData<IndexVectors>(indexVectorID); - int64_t indexVectorSize = int64_c( indexVectors->indexVector(type).size() ); + int32_t indexVectorSize = int32_c( indexVectors->indexVector(type).size() ); if( indexVectorSize == 0) return; diff --git a/python/pystencils_walberla/templates/Boundary.tmpl.h b/python/pystencils_walberla/templates/Boundary.tmpl.h index 8a673d32e..03b403aea 100644 --- a/python/pystencils_walberla/templates/Boundary.tmpl.h +++ b/python/pystencils_walberla/templates/Boundary.tmpl.h @@ -80,7 +80,7 @@ public: {% endif -%} CpuIndexVector & indexVector(Type t) { return cpuVectors_[t]; } - {{StructName}} * pointerCpu(Type t) { return &(cpuVectors_[t][0]); } + {{StructName}} * pointerCpu(Type t) { return cpuVectors_[t].data(); } {% if target == 'gpu' -%} {{StructName}} * pointerGpu(Type t) { return gpuVectors_[t]; } @@ -238,7 +238,7 @@ public: {%endif%} {%else%} auto flagWithGLayers = flagField->xyzSizeWithGhostLayer(); - real_t dot = 0.0; real_t maxn = 0.0; + {{dtype}} dot = 0.0; {{dtype}} maxn = 0.0; cell_idx_t calculated_idx = 0; cell_idx_t dx = 0; cell_idx_t dy = 0; {%if dim == 3%} cell_idx_t dz = 0; {% endif %} cell_idx_t sum_x = 0; cell_idx_t sum_y = 0; {%if dim == 3%} cell_idx_t sum_z = 0; {%endif %} @@ -272,7 +272,7 @@ public: { {%- for dirIdx, dirVec, offset in additional_data_handler.stencil_info %} dx = {{dirVec[0]}}; dy = {{dirVec[1]}}; {%if dim == 3%} dz = {{dirVec[2]}}; {% endif %} - dot = real_c( dx*sum_x + dy*sum_y {%if dim == 3%} + dz*sum_z {% endif %}); + dot = {{dtype}}( dx*sum_x + dy*sum_y {%if dim == 3%} + dz*sum_z {% endif %}); if (dot > maxn) { maxn = dot; diff --git a/python/pystencils_walberla/utility.py b/python/pystencils_walberla/utility.py index 8800130bc..c109265ef 100644 --- a/python/pystencils_walberla/utility.py +++ b/python/pystencils_walberla/utility.py @@ -1,5 +1,5 @@ from os import path -from pystencils.data_types import get_base_type +from pystencils.typing import get_base_type from pystencils_walberla.cmake_integration import CodeGenerationContext from lbmpy import LBStencil diff --git a/python/waLBerla_tests/test_blockforest.py b/python/waLBerla_tests/test_blockforest.py index 09a158151..296cb570b 100644 --- a/python/waLBerla_tests/test_blockforest.py +++ b/python/waLBerla_tests/test_blockforest.py @@ -1,14 +1,17 @@ import unittest import numpy as np +import waLBerla as wlb from waLBerla import field, createUniformBlockGrid, AABB +field_data_type = np.float64 if wlb.build_info.build_with_double_accuracy else np.float32 + class BlockforestModuleTest(unittest.TestCase): def testMemoryManagement1(self): """Testing correct reference counting of block data""" blocks = createUniformBlockGrid(blocks=(1, 1, 1), cellsPerBlock=(2, 2, 2)) - field.addToStorage(blocks, "TestField", np.float64) + field.addToStorage(blocks, "TestField", field_data_type) f = blocks[0]["TestField"] strides_before = f.strides del blocks @@ -24,7 +27,7 @@ class BlockforestModuleTest(unittest.TestCase): """Testing correct reference counting of block data Holding only a numpy array pointing to a waLBerla field should still hold the blockstructure alive""" blocks = createUniformBlockGrid(blocks=(1, 1, 1), cellsPerBlock=(2, 2, 2)) - field.addToStorage(blocks, "TestField", np.float64) + field.addToStorage(blocks, "TestField", field_data_type) npf = field.toArray(blocks[0]["TestField"]) npf[:, :, :] = 42.0 del blocks @@ -36,7 +39,7 @@ class BlockforestModuleTest(unittest.TestCase): def testMemoryManagement3(self): """Same as testMemoryManagement2, but with iterators""" blocks = createUniformBlockGrid(blocks=(1, 1, 1), cellsPerBlock=(2, 2, 2)) - field.addToStorage(blocks, "TestField", np.float64) + field.addToStorage(blocks, "TestField", field_data_type) for block in blocks: for name in block.fieldNames: if name == "TestField": diff --git a/python/waLBerla_tests/test_field.py b/python/waLBerla_tests/test_field.py index 04ab5afb4..e97fdd26d 100644 --- a/python/waLBerla_tests/test_field.py +++ b/python/waLBerla_tests/test_field.py @@ -3,12 +3,14 @@ import numpy as np import waLBerla as wlb from waLBerla import field, createUniformBlockGrid +field_data_type = np.float64 if wlb.build_info.build_with_double_accuracy else np.float32 + class FieldModuleTest(unittest.TestCase): def testFieldAsBlockData(self): blocks = createUniformBlockGrid(blocks=(1, 1, 1), cellsPerBlock=(3, 2, 2), periodic=(True, False, False)) - field.addToStorage(blocks, 'myField', np.float64, fSize=3, ghostLayers=0, initValue=0.0) + field.addToStorage(blocks, 'myField', field_data_type, fSize=3, ghostLayers=0, initValue=0.0) my_field = wlb.field.toArray(blocks[0]['myField']) self.assertEqual(my_field[0, 0, 0, 0], 0) my_field[0, 0, 0, 0] = 42.0 @@ -18,8 +20,8 @@ class FieldModuleTest(unittest.TestCase): def testNumpyConversionWithoutGhostLayers(self): blocks = createUniformBlockGrid(blocks=(1, 1, 1), cellsPerBlock=(1, 2, 3), periodic=(True, False, False)) - field.addToStorage(blocks, 'f1', np.float64, fSize=2, ghostLayers=0, initValue=2.0) - field.addToStorage(blocks, 'f2', np.float64, fSize=3, ghostLayers=0, initValue=2.0) + field.addToStorage(blocks, 'f1', field_data_type, fSize=2, ghostLayers=0, initValue=2.0) + field.addToStorage(blocks, 'f2', field_data_type, fSize=3, ghostLayers=0, initValue=2.0) f1np = field.toArray(blocks[0]['f1']) f2np = field.toArray(blocks[0]['f2']) @@ -31,7 +33,7 @@ class FieldModuleTest(unittest.TestCase): size = (10, 5, 4) gl = 3 blocks = createUniformBlockGrid(blocks=(1, 1, 1), cellsPerBlock=size, periodic=(True, False, False)) - field.addToStorage(blocks, 'f', np.float64, fSize=3, ghostLayers=gl, initValue=0.0) + field.addToStorage(blocks, 'f', field_data_type, fSize=3, ghostLayers=gl, initValue=0.0) f = blocks[0]['f'] diff --git a/src/core/DataTypes.h b/src/core/DataTypes.h index 397f2c8d6..2f8687197 100644 --- a/src/core/DataTypes.h +++ b/src/core/DataTypes.h @@ -164,7 +164,7 @@ template< typename T > inline cell_idx_t cell_idx_c( T t ) { return numeric_cast #ifdef WALBERLA_DOUBLE_ACCURACY using real_t = double; #else -typedef float real_t; +using real_t = float; #endif inline constexpr real_t operator"" _r( long double t ) { return static_cast< real_t >(t); } diff --git a/src/python_coupling/export/BasicExport.cpp b/src/python_coupling/export/BasicExport.cpp index 22b444d1b..efbb0226c 100644 --- a/src/python_coupling/export/BasicExport.cpp +++ b/src/python_coupling/export/BasicExport.cpp @@ -629,6 +629,11 @@ void exportBuildInfo(py::module_ &m) m2.attr("build_machine" ) = WALBERLA_BUILD_MACHINE; m2.attr("source_dir") = WALBERLA_SOURCE_DIR; m2.attr("build_dir") = WALBERLA_BUILD_DIR; +#ifdef WALBERLA_DOUBLE_ACCURACY + m2.attr("build_with_double_accuracy") = true; +#else + m2.attr("build_with_double_accuracy") = false; +#endif } diff --git a/tests/cuda/SimpleKernelTest.cpp b/tests/cuda/SimpleKernelTest.cpp index 6b79fa8db..f2f9a2a8b 100644 --- a/tests/cuda/SimpleKernelTest.cpp +++ b/tests/cuda/SimpleKernelTest.cpp @@ -42,23 +42,23 @@ void kernel_double( cuda::FieldAccessor<double> f ); GhostLayerField<double,1> * createCPUField( IBlock* const block, StructuredBlockStorage* const storage ) { return new GhostLayerField<double,1> ( - storage->getNumberOfXCells( *block ), // number of cells in x direction - storage->getNumberOfYCells( *block ), // number of cells in y direction - storage->getNumberOfZCells( *block ), // number of cells in z direction - 1, // number of ghost layers - double(1), // initial value - field::fzyx); + storage->getNumberOfXCells( *block ), // number of cells in x direction + storage->getNumberOfYCells( *block ), // number of cells in y direction + storage->getNumberOfZCells( *block ), // number of cells in z direction + 1, // number of ghost layers + double(1), // initial value + field::fzyx); } cuda::GPUField<double> * createGPUField( IBlock* const block, StructuredBlockStorage* const storage ) { return new cuda::GPUField<double> ( - storage->getNumberOfXCells( *block ), // number of cells in x direction - storage->getNumberOfYCells( *block ), // number of cells in y direction - storage->getNumberOfZCells( *block ), // number of cells in z direction - 1, // fSize - 1, // number of ghost layers - field::fzyx ); + storage->getNumberOfXCells( *block ), // number of cells in x direction + storage->getNumberOfYCells( *block ), // number of cells in y direction + storage->getNumberOfZCells( *block ), // number of cells in z direction + 1, // fSize + 1, // number of ghost layers + field::fzyx ); } @@ -68,11 +68,11 @@ int main( int argc, char ** argv ) debug::enterTestMode(); shared_ptr< StructuredBlockForest > blocks = blockforest::createUniformBlockGrid ( - uint_t(1), uint_t(1), uint_t(1), // number of blocks in x,y,z direction - uint_t(14), uint_t(14), uint_t(14), // how many cells per block (x,y,z) - real_c(0.5), // dx: length of one cell in physical coordinates - false, // one block per process - "false" means all blocks to one process - false, false, false ); // no periodicity + uint_t(1), uint_t(1), uint_t(1), // number of blocks in x,y,z direction + uint_t(14), uint_t(14), uint_t(14), // how many cells per block (x,y,z) + real_c(0.5), // dx: length of one cell in physical coordinates + false, // one block per process - "false" means all blocks to one process + false, false, false ); // no periodicity @@ -98,7 +98,7 @@ int main( int argc, char ** argv ) cuda::fieldCpy( *cpuField, *gpuField ); - WALBERLA_ASSERT_FLOAT_EQUAL( cpuField->get(0,0,0), real_t(2) ); + WALBERLA_ASSERT_FLOAT_EQUAL( cpuField->get(0,0,0), real_t(2) ) } @@ -108,5 +108,5 @@ int main( int argc, char ** argv ) //gui.run(); - return 0; + return EXIT_SUCCESS; } diff --git a/tests/cuda/codegen/CodegenJacobiGPU.cpp b/tests/cuda/codegen/CodegenJacobiGPU.cpp index 7842220f6..93814e0a5 100644 --- a/tests/cuda/codegen/CodegenJacobiGPU.cpp +++ b/tests/cuda/codegen/CodegenJacobiGPU.cpp @@ -49,8 +49,8 @@ using namespace walberla; -typedef GhostLayerField<double,1> ScalarField; -typedef cuda::GPUField<double> GPUField; +typedef GhostLayerField<real_t, 1> ScalarField; +typedef cuda::GPUField<real_t> GPUField; ScalarField * createField( IBlock* const block, StructuredBlockStorage* const storage ) @@ -62,7 +62,7 @@ ScalarField * createField( IBlock* const block, StructuredBlockStorage* const st 1, // one ghost layer double(0), // initial value field::fzyx, // layout - make_shared<cuda::HostFieldAllocator<double> >() // allocator for host pinned memory + make_shared<cuda::HostFieldAllocator<real_t> >() // allocator for host pinned memory ); } @@ -75,7 +75,7 @@ void testJacobi2D() shared_ptr< StructuredBlockForest > blocks = blockforest::createUniformBlockGrid ( uint_t(1) , uint_t(1), uint_t(1), // number of blocks in x,y,z direction xSize, ySize, uint_t(1), // how many cells per block (x,y,z) - real_t(1), // dx: length of one cell in physical coordinates + real_c(1.0), // dx: length of one cell in physical coordinates false, // one block per process - "false" means all blocks to one process true, true, true ); // no periodicity @@ -90,7 +90,7 @@ void testJacobi2D() auto f = blockIt->getData<ScalarField>( cpuFieldID ); for( cell_idx_t y = 0; y < cell_idx_c( f->ySize() / 2 ); ++y ) for( cell_idx_t x = 0; x < cell_idx_c( f->xSize() / 2 ); ++x ) - f->get( x, y, 0 ) = 1.0; + f->get( x, y, 0 ) = real_c(1.0); } typedef blockforest::communication::UniformBufferedScheme<stencil::D2Q9> CommScheme; @@ -114,7 +114,7 @@ void testJacobi2D() auto firstBlock = blocks->begin(); auto f = firstBlock->getData<ScalarField>( cpuFieldID ); - WALBERLA_CHECK_FLOAT_EQUAL(f->get(0,0,0), real_t(1.0 / 4.0)); + WALBERLA_CHECK_FLOAT_EQUAL(f->get(0,0,0), real_c(1.0 / 4.0)) } @@ -128,7 +128,7 @@ void testJacobi3D() shared_ptr< StructuredBlockForest > blocks = blockforest::createUniformBlockGrid ( uint_t(1) , uint_t(1), uint_t(1), // number of blocks in x,y,z direction xSize, ySize, zSize, // how many cells per block (x,y,z) - real_t(1), // dx: length of one cell in physical coordinates + real_c(1.0), // dx: length of one cell in physical coordinates false, // one block per process - "false" means all blocks to one process true, true, true ); // no periodicity @@ -144,7 +144,7 @@ void testJacobi3D() for( cell_idx_t z = 0; z < cell_idx_c( f->zSize() / 2 ); ++z ) for( cell_idx_t y = 0; y < cell_idx_c( f->ySize() / 2 ); ++y ) for( cell_idx_t x = 0; x < cell_idx_c( f->xSize() / 2 ); ++x ) - f->get( x, y, z ) = 1.0; + f->get( x, y, z ) = real_c(1.0); } typedef blockforest::communication::UniformBufferedScheme<stencil::D3Q7> CommScheme; @@ -168,7 +168,7 @@ void testJacobi3D() auto firstBlock = blocks->begin(); auto f = firstBlock->getData<ScalarField>( cpuFieldID ); - WALBERLA_CHECK_FLOAT_EQUAL(f->get(0,0,0), real_t(1.0 / 8.0)); + WALBERLA_CHECK_FLOAT_EQUAL(f->get(0,0,0), real_c(1.0 / 8.0)) } int main( int argc, char ** argv ) @@ -179,5 +179,5 @@ int main( int argc, char ** argv ) testJacobi2D(); testJacobi3D(); - return 0; + return EXIT_SUCCESS; } diff --git a/tests/cuda/codegen/CodegenPoissonGPU.cpp b/tests/cuda/codegen/CodegenPoissonGPU.cpp index d160f7999..ef5ae96c0 100644 --- a/tests/cuda/codegen/CodegenPoissonGPU.cpp +++ b/tests/cuda/codegen/CodegenPoissonGPU.cpp @@ -88,26 +88,26 @@ void testPoisson() { const uint_t xCells = uint_t(200); const uint_t yCells = uint_t(100); - const real_t xSize = real_t(2); - const real_t ySize = real_t(1); + const real_t xSize = real_c(2.0); + const real_t ySize = real_c(1.0); const real_t dx = xSize / real_c( xCells + uint_t(1) ); const real_t dy = ySize / real_c( yCells + uint_t(1) ); // Create blocks shared_ptr< StructuredBlockForest > blocks = blockforest::createUniformBlockGrid ( - math::AABB( real_t(0.5) * dx, real_t(0.5) * dy, real_t(0), - xSize - real_t(0.5) * dx, ySize - real_t(0.5) * dy, dx ), + math::AABB( real_c(0.5) * dx, real_c(0.5) * dy, real_c(0.0), + xSize - real_c(0.5) * dx, ySize - real_c(0.5) * dy, dx ), uint_t(1) , uint_t(1), uint_t(1), // number of blocks in x,y,z direction xCells, yCells, uint_t(1), // how many cells per block (x,y,z) false, // one block per process - "false" means all blocks to one process false, false, false ); // no periodicity - BlockDataID cpuFieldID = field::addToStorage< ScalarField_T >( blocks, "CPU Field src", real_t(0.0) ); + BlockDataID cpuFieldID = field::addToStorage< ScalarField_T >( blocks, "CPU Field src", real_c(0.0) ); BlockDataID gpuField = cuda::addGPUFieldToStorage<ScalarField_T>( blocks, cpuFieldID, "GPU Field src" ); initU( blocks, cpuFieldID ); - BlockDataID cpufId = field::addToStorage< ScalarField_T >( blocks, "CPU Field f", real_t(0.0)); + BlockDataID cpufId = field::addToStorage< ScalarField_T >( blocks, "CPU Field f", real_c(0.0)); BlockDataID gpufId = cuda::addGPUFieldToStorage<ScalarField_T>( blocks, cpufId, "GPU Field f" ); initF( blocks, cpufId ); @@ -145,5 +145,5 @@ int main( int argc, char ** argv ) testPoisson(); - return 0; + return EXIT_SUCCESS; } diff --git a/tests/cuda/codegen/CudaJacobiKernel.py b/tests/cuda/codegen/CudaJacobiKernel.py index 79c2d767c..60fd64c1d 100644 --- a/tests/cuda/codegen/CudaJacobiKernel.py +++ b/tests/cuda/codegen/CudaJacobiKernel.py @@ -4,8 +4,9 @@ from pystencils_walberla import CodeGeneration, generate_sweep with CodeGeneration() as ctx: + field_type = "float64" if ctx.double_accuracy else "float32" # ----- Stencil 2D - created by specifying weights in nested list -------------------------- - src, dst = ps.fields("src, src_tmp: [2D]", layout='fzyx') + src, dst = ps.fields(f"src, src_tmp: {field_type}[2D]", layout='fzyx') stencil = [[1.11, 2.22, 3.33], [4.44, 5.55, 6.66], [7.77, 8.88, 9.99]] @@ -13,7 +14,7 @@ with CodeGeneration() as ctx: generate_sweep(ctx, 'CudaJacobiKernel2D', assignments, field_swaps=[(src, dst)], target=ps.Target.GPU) # ----- Stencil 3D - created by using kernel_decorator with assignments in '@=' format ----- - src, dst = ps.fields("src, src_tmp: [3D]") + src, dst = ps.fields(f"src, src_tmp: {field_type}[3D]") @ps.kernel def kernel_func(): diff --git a/tests/cuda/codegen/CudaPoisson.py b/tests/cuda/codegen/CudaPoisson.py index eedff3609..24e471a8d 100644 --- a/tests/cuda/codegen/CudaPoisson.py +++ b/tests/cuda/codegen/CudaPoisson.py @@ -4,10 +4,11 @@ from pystencils_walberla import CodeGeneration, generate_sweep with CodeGeneration() as ctx: + field_type = "float64" if ctx.double_accuracy else "float32" # ----- Solving the 2D Poisson equation with rhs -------------------------- dx = sp.Symbol("dx") dy = sp.Symbol("dy") - src, dst, rhs = ps.fields("src, src_tmp, rhs: [2D]", layout='fzyx') + src, dst, rhs = ps.fields(f"src, src_tmp, rhs: {field_type}[2D]", layout='fzyx') @ps.kernel def kernel_func(): diff --git a/tests/cuda/codegen/GeneratedFieldPackInfoTestGPU.cpp b/tests/cuda/codegen/GeneratedFieldPackInfoTestGPU.cpp index 4c4bed8b4..47c7d6741 100644 --- a/tests/cuda/codegen/GeneratedFieldPackInfoTestGPU.cpp +++ b/tests/cuda/codegen/GeneratedFieldPackInfoTestGPU.cpp @@ -202,7 +202,7 @@ int main(int argc, char **argv) { testScalarFieldPullReduction( blocks, scalarGPUFieldId ); - return 0; + return EXIT_SUCCESS; } diff --git a/tests/cuda/codegen/GeneratedFieldPackInfoTestGPU.py b/tests/cuda/codegen/GeneratedFieldPackInfoTestGPU.py index bac0b89da..bd0635e2c 100644 --- a/tests/cuda/codegen/GeneratedFieldPackInfoTestGPU.py +++ b/tests/cuda/codegen/GeneratedFieldPackInfoTestGPU.py @@ -3,12 +3,10 @@ import pystencils as ps from pystencils_walberla import CodeGeneration, generate_pack_info_for_field with CodeGeneration() as ctx: - layout = 'fzyx' - field = ps.fields("field: int32[3D]", layout=layout) # communication generate_pack_info_for_field(ctx, 'ScalarFieldCommunicationGPU', field, target=ps.Target.GPU) - generate_pack_info_for_field(ctx, 'ScalarFieldPullReductionGPU', field, target=ps.Target.GPU, operator=op.add, - gl_to_inner=True) + generate_pack_info_for_field(ctx, 'ScalarFieldPullReductionGPU', field, target=ps.Target.GPU, + operator=op.add, gl_to_inner=True) diff --git a/tests/cuda/codegen/MicroBenchmarkGpuLbm.cpp b/tests/cuda/codegen/MicroBenchmarkGpuLbm.cpp index 8516c0933..8b03e0277 100644 --- a/tests/cuda/codegen/MicroBenchmarkGpuLbm.cpp +++ b/tests/cuda/codegen/MicroBenchmarkGpuLbm.cpp @@ -44,8 +44,8 @@ int main( int argc, char **argv ) shared_ptr<StructuredBlockForest> blocks = blockforest::createUniformBlockGrid(1u, 1u, 1u, 128u, 128u, 128u, 1.0, false, false, false, false); - BlockDataID srcID = cuda::addGPUFieldToStorage<cuda::GPUField<double> >(blocks, "src", 19, field::fzyx, 1); - BlockDataID dstID = cuda::addGPUFieldToStorage<cuda::GPUField<double> >(blocks, "dst", 19, field::fzyx, 1); + BlockDataID srcID = cuda::addGPUFieldToStorage<cuda::GPUField<real_t> >(blocks, "src", 19, field::fzyx, 1); + BlockDataID dstID = cuda::addGPUFieldToStorage<cuda::GPUField<real_t> >(blocks, "dst", 19, field::fzyx, 1); int iterations = 3; @@ -60,7 +60,7 @@ int main( int argc, char **argv ) for( auto &block: *blocks ) stream( &block ); - WALBERLA_CUDA_CHECK(cudaDeviceSynchronize()); + WALBERLA_CUDA_CHECK(cudaDeviceSynchronize()) - return 0; + return EXIT_SUCCESS; } diff --git a/tests/cuda/codegen/MicroBenchmarkGpuLbm.py b/tests/cuda/codegen/MicroBenchmarkGpuLbm.py index c461df018..09cefc055 100644 --- a/tests/cuda/codegen/MicroBenchmarkGpuLbm.py +++ b/tests/cuda/codegen/MicroBenchmarkGpuLbm.py @@ -4,18 +4,18 @@ from lbmpy import LBStencil, Stencil from pystencils_walberla import CodeGeneration, generate_sweep with CodeGeneration() as ctx: - f_size = 19 - dtype = 'float64' if ctx.double_accuracy else 'float32' + stencil = LBStencil(Stencil.D3Q19) + field_type = 'float64' if ctx.double_accuracy else 'float32' # Copy sweep - src, dst = ps.fields(f"src({f_size}), dst({f_size}) : {dtype}[3D]", layout='fzyx') + src, dst = ps.fields(f"src({stencil.Q}), dst({stencil.Q}) : {field_type}[3D]", layout='fzyx') - copy_only = [ps.Assignment(dst(i), src(i)) for i in range(f_size)] + copy_only = [ps.Assignment(dst(i), src(i)) for i in range(stencil.Q)] generate_sweep(ctx, 'MicroBenchmarkCopyKernel', copy_only, target=ps.Target.GPU, gpu_indexing_params={'block_size': (128, 1, 1)}) # Stream-only sweep - stencil = LBStencil(Stencil.D3Q19) + stream_only = create_stream_only_kernel(stencil, src_field=src, dst_field=dst) generate_sweep(ctx, 'MicroBenchmarkStreamKernel', stream_only, target=ps.Target.GPU, gpu_indexing_params={'block_size': (128, 1, 1)}) diff --git a/tests/field/codegen/CodegenJacobiCPU.cpp b/tests/field/codegen/CodegenJacobiCPU.cpp index d0a9693ae..3bba9623e 100644 --- a/tests/field/codegen/CodegenJacobiCPU.cpp +++ b/tests/field/codegen/CodegenJacobiCPU.cpp @@ -38,7 +38,7 @@ using namespace walberla; -typedef GhostLayerField<double,1> ScalarField; +typedef GhostLayerField<real_t, 1> ScalarField; void testJacobi2D() @@ -49,12 +49,12 @@ void testJacobi2D() shared_ptr< StructuredBlockForest > blocks = blockforest::createUniformBlockGrid ( uint_t(1) , uint_t(1), uint_t(1), // number of blocks in x,y,z direction xSize, ySize, uint_t(1), // how many cells per block (x,y,z) - real_t(1), // dx: length of one cell in physical coordinates + real_c(1.0), // dx: length of one cell in physical coordinates false, // one block per process - "false" means all blocks to one process true, true, true ); // full periodicity - BlockDataID fieldID = field::addToStorage<ScalarField>(blocks, "Field", real_t(0.0)); + BlockDataID fieldID = field::addToStorage<ScalarField>(blocks, "Field", real_c(0.0)); // Initialize a quarter of the field with ones, the rest remains 0 // Jacobi averages the domain -> every cell should be at 0.25 at sufficiently many timesteps @@ -63,7 +63,7 @@ void testJacobi2D() auto f = blockIt->getData<ScalarField>( fieldID ); for( cell_idx_t y = 0; y < cell_idx_c( f->ySize() / 2 ); ++y ) for( cell_idx_t x = 0; x < cell_idx_c( f->xSize() / 2 ); ++x ) - f->get( x, y, 0 ) = 1.0; + f->get( x, y, 0 ) = real_c(1.0); } typedef blockforest::communication::UniformBufferedScheme<stencil::D2Q9> CommScheme; @@ -84,7 +84,7 @@ void testJacobi2D() auto firstBlock = blocks->begin(); auto f = firstBlock->getData<ScalarField>( fieldID ); - WALBERLA_CHECK_FLOAT_EQUAL(f->get(0,0,0), real_t(1.0 / 4.0)); + WALBERLA_CHECK_FLOAT_EQUAL(f->get(0,0,0), real_c(1.0 / 4.0)); } @@ -97,12 +97,12 @@ void testJacobi3D() shared_ptr< StructuredBlockForest > blocks = blockforest::createUniformBlockGrid ( uint_t(1) , uint_t(1), uint_t(1), // number of blocks in x,y,z direction xSize, ySize, zSize, // how many cells per block (x,y,z) - real_t(1), // dx: length of one cell in physical coordinates + real_c(1.0), // dx: length of one cell in physical coordinates false, // one block per process - "false" means all blocks to one process true, true, true ); // no periodicity - BlockDataID fieldID = field::addToStorage<ScalarField>(blocks, "Field", real_t(0.0)); + BlockDataID fieldID = field::addToStorage<ScalarField>(blocks, "Field", real_c(0.0)); // Initialize a quarter of the field with ones, the rest remains 0 // Jacobi averages the domain -> every cell should be at 0.25 at sufficiently many timesteps @@ -112,7 +112,7 @@ void testJacobi3D() for( cell_idx_t z = 0; z < cell_idx_c( f->zSize() / 2); ++z ) for( cell_idx_t y = 0; y < cell_idx_c( f->ySize() / 2 ); ++y ) for( cell_idx_t x = 0; x < cell_idx_c( f->xSize() / 2 ); ++x ) - f->get( x, y, z ) = 1.0; + f->get( x, y, z ) = real_c(1.0); } typedef blockforest::communication::UniformBufferedScheme<stencil::D3Q7> CommScheme; @@ -132,7 +132,7 @@ void testJacobi3D() auto firstBlock = blocks->begin(); auto f = firstBlock->getData<ScalarField>( fieldID ); - WALBERLA_CHECK_FLOAT_EQUAL(f->get(0,0,0), real_t(1.0 / 8.0)); + WALBERLA_CHECK_FLOAT_EQUAL(f->get(0,0,0), real_c(1.0 / 8.0)); } @@ -144,5 +144,5 @@ int main( int argc, char ** argv ) testJacobi2D(); testJacobi3D(); - return 0; + return EXIT_SUCCESS; } diff --git a/tests/field/codegen/CodegenPoissonCPU.cpp b/tests/field/codegen/CodegenPoissonCPU.cpp index 4ecbab91e..6c5696d40 100644 --- a/tests/field/codegen/CodegenPoissonCPU.cpp +++ b/tests/field/codegen/CodegenPoissonCPU.cpp @@ -67,7 +67,7 @@ void initF( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData CellInterval xyz = f->xyzSize(); for( auto cell = xyz.begin(); cell != xyz.end(); ++cell ) { - f->get( *cell ) = 0.0; + f->get( *cell ) = real_c(0.0); } } } @@ -77,25 +77,25 @@ void testPoisson() const uint_t xCells = uint_t(100); const uint_t yCells = uint_t(100); - const real_t xSize = real_t(1); - const real_t ySize = real_t(1); + const real_t xSize = real_c(1.0); + const real_t ySize = real_c(1.0); const real_t dx = xSize / real_c( xCells + uint_t(1) ); const real_t dy = ySize / real_c( yCells + uint_t(1) ); // Create blocks shared_ptr< StructuredBlockForest > blocks = blockforest::createUniformBlockGrid ( - math::AABB( real_t(0.5) * dx, real_t(0.5) * dy, real_t(0), - xSize - real_t(0.5) * dx, ySize - real_t(0.5) * dy, dx ), + math::AABB( real_c(0.5) * dx, real_c(0.5) * dy, real_c(0.0), + xSize - real_c(0.5) * dx, ySize - real_c(0.5) * dy, dx ), uint_t(1) , uint_t(1), uint_t(1), // number of blocks in x,y,z direction xCells, yCells, uint_t(1), // how many cells per block (x,y,z) false, // one block per process - "false" means all blocks to one process false, false, false ); // no periodicity - BlockDataID fieldID = field::addToStorage<ScalarField_T>(blocks, "Field", real_t(0.0)); + BlockDataID fieldID = field::addToStorage<ScalarField_T>(blocks, "Field", real_c(0.0)); initU( blocks, fieldID ); - BlockDataID fId = field::addToStorage< ScalarField_T >( blocks, "f", real_t(0.0)); + BlockDataID fId = field::addToStorage< ScalarField_T >( blocks, "f", real_c(0.0)); initF( blocks, fId ); typedef blockforest::communication::UniformBufferedScheme<stencil::D2Q9> CommScheme; @@ -115,7 +115,7 @@ void testPoisson() auto firstBlock = blocks->begin(); auto f = firstBlock->getData<ScalarField_T>( fieldID ); - WALBERLA_CHECK_LESS(f->get(50,99,0) - std::sin( math::pi * 0.5 ) * std::sinh( math::pi * 0.99 ), 0.01); + WALBERLA_CHECK_LESS(f->get(50,99,0) - std::sin( math::pi * 0.5 ) * std::sinh( math::pi * 0.99 ), 0.01) } diff --git a/tests/field/codegen/EK.cpp b/tests/field/codegen/EK.cpp index dbfdcb32d..1f795b873 100644 --- a/tests/field/codegen/EK.cpp +++ b/tests/field/codegen/EK.cpp @@ -56,7 +56,7 @@ void initC(const shared_ptr< StructuredBlockStorage > & blocks, BlockDataID cID) void checkC(const shared_ptr< StructuredBlockStorage > & blocks, BlockDataID cID, real_t D, uint_t t) { - real_t sum(0); + real_t sum(0.0); uint_t size(0); for(auto blockIt = blocks->begin(); blockIt != blocks->end(); ++blockIt) { @@ -76,12 +76,12 @@ void checkC(const shared_ptr< StructuredBlockStorage > & blocks, BlockDataID cID const real_t val = c->get(x, y, 0); sum += val; - const real_t x0 = real_c(x) - real_c(c->xSize()/2) + real_t(0.5); - const real_t y0 = real_c(y) - real_c(c->ySize()/2) + real_t(0.5); + const real_t x0 = real_c(x) - real_c(c->xSize()/2) + real_c(0.5); + const real_t y0 = real_c(y) - real_c(c->ySize()/2) + real_c(0.5); const real_t r2 = x0*x0 + y0*y0; // solution to the diffusion equation in 2D - const real_t ref = real_t(size)/(real_t(4)*math::pi*D*real_c(t)) * std::exp(-r2/real_c(4*D*real_c(t))); + const real_t ref = real_c(size)/(real_c(4.0)*math::pi*D*real_c(t)) * std::exp(-r2/real_c(4*D*real_c(t))); real_t rel = std::abs(real_c(1) - val/ref); if(ref >= 1) // we only expect good agreement where the values are larger than sum/size @@ -91,12 +91,12 @@ void checkC(const shared_ptr< StructuredBlockStorage > & blocks, BlockDataID cID std::cout << y << " " << y0 << " " << val << " " << ref << " " << (rel*100) << "%" << std::endl; } - WALBERLA_CHECK_LESS(rel, 0.03); // 3% deviation is okay + WALBERLA_CHECK_LESS(rel, 0.03) // 3% deviation is okay } } } } - WALBERLA_CHECK_FLOAT_EQUAL(sum, real_c(size)); + WALBERLA_CHECK_FLOAT_EQUAL(sum, real_c(size)) } void testEK() @@ -109,13 +109,13 @@ void testEK() shared_ptr< StructuredBlockForest > blocks = blockforest::createUniformBlockGrid ( uint_t(1) , uint_t(1), uint_t(1), // number of blocks in x,y,z direction xSize, ySize, uint_t(1), // how many cells per block (x,y,z) - real_t(1), // dx: length of one cell in physical coordinates + real_c(1.0), // dx: length of one cell in physical coordinates false, // one block per process - "false" means all blocks to one process true, true, true ); // full periodicity - BlockDataID c = field::addToStorage<DensityField_T>(blocks, "c", real_t(0.0), field::fzyx); + BlockDataID c = field::addToStorage<DensityField_T>(blocks, "c", real_c(0.0), field::fzyx); initC(blocks, c); - BlockDataID j = field::addToStorage<FluxField_T>(blocks, "j", real_t(0.0), field::fzyx); + BlockDataID j = field::addToStorage<FluxField_T>(blocks, "j", real_c(0.0), field::fzyx); typedef blockforest::communication::UniformBufferedScheme<stencil::D2Q9> CommScheme; typedef field::communication::PackInfo<DensityField_T> Packing; @@ -127,7 +127,7 @@ void testEK() // Registering the sweep timeloop.add() << BeforeFunction( commScheme, "Communication" ) - << Sweep( pystencils::EKFlux(D, c, j), "EK flux Kernel" ); + << Sweep( pystencils::EKFlux(c, j, D), "EK flux Kernel" ); timeloop.add() << Sweep( pystencils::EKContinuity(c, j), "EK continuity Kernel" ); timeloop.run(); diff --git a/tests/field/codegen/EK.py b/tests/field/codegen/EK.py index 7cf53c035..79985ece0 100644 --- a/tests/field/codegen/EK.py +++ b/tests/field/codegen/EK.py @@ -2,9 +2,11 @@ import sympy as sp import pystencils as ps from pystencils_walberla import CodeGeneration, generate_sweep + def grad(f): return sp.Matrix([ps.fd.diff(f, i) for i in range(f.spatial_dimensions)]) + D = sp.Symbol("D") with CodeGeneration() as ctx: diff --git a/tests/field/codegen/GeneratedFieldPackInfoTest.cpp b/tests/field/codegen/GeneratedFieldPackInfoTest.cpp index 2f8031064..a4835531b 100644 --- a/tests/field/codegen/GeneratedFieldPackInfoTest.cpp +++ b/tests/field/codegen/GeneratedFieldPackInfoTest.cpp @@ -47,9 +47,9 @@ void testScalarField( IBlock * block, BlockDataID fieldId ) GhostLayerField<int,1> & field = *(block->getData<GhostLayerField<int,1> > (fieldId)); field.setWithGhostLayer( 0 ); - WALBERLA_CHECK_EQUAL(field.xSize(), 2); - WALBERLA_CHECK_EQUAL(field.ySize(), 2); - WALBERLA_CHECK_EQUAL(field.zSize(), 2); + WALBERLA_CHECK_EQUAL(field.xSize(), 2) + WALBERLA_CHECK_EQUAL(field.ySize(), 2) + WALBERLA_CHECK_EQUAL(field.zSize(), 2) // initialize the bottom boundary field(0,0,0) = 1; @@ -63,10 +63,10 @@ void testScalarField( IBlock * block, BlockDataID fieldId ) pystencils::ScalarFieldCommunication pi(fieldId); pi.communicateLocal( block, block, stencil::B ); - WALBERLA_CHECK_EQUAL ( field(0,0,+2), 1 ); - WALBERLA_CHECK_EQUAL ( field(0,1,+2), 2 ); - WALBERLA_CHECK_EQUAL ( field(1,0,+2), 3 ); - WALBERLA_CHECK_EQUAL ( field(1,1,+2), 4 ); + WALBERLA_CHECK_EQUAL ( field(0,0,+2), 1 ) + WALBERLA_CHECK_EQUAL ( field(0,1,+2), 2 ) + WALBERLA_CHECK_EQUAL ( field(1,0,+2), 3 ) + WALBERLA_CHECK_EQUAL ( field(1,1,+2), 4 ) // -------------- Buffer Communication Test --------------------- @@ -86,10 +86,10 @@ void testScalarField( IBlock * block, BlockDataID fieldId ) pi.unpackData( block, stencil::T, recvBuf ); - WALBERLA_CHECK_EQUAL ( field(0,0,+2), 1 ); - WALBERLA_CHECK_EQUAL ( field(0,1,+2), 2 ); - WALBERLA_CHECK_EQUAL ( field(1,0,+2), 3 ); - WALBERLA_CHECK_EQUAL ( field(1,1,+2), 4 ); + WALBERLA_CHECK_EQUAL ( field(0,0,+2), 1 ) + WALBERLA_CHECK_EQUAL ( field(0,1,+2), 2 ) + WALBERLA_CHECK_EQUAL ( field(1,0,+2), 3 ) + WALBERLA_CHECK_EQUAL ( field(1,1,+2), 4 ) } void testScalarFieldPullReduction( IBlock * block, BlockDataID fieldId ) @@ -97,9 +97,9 @@ void testScalarFieldPullReduction( IBlock * block, BlockDataID fieldId ) GhostLayerField<int,1> & field = *(block->getData<GhostLayerField<int,1> > (fieldId)); field.setWithGhostLayer( 0 ); - WALBERLA_CHECK_EQUAL(field.xSize(), 2); - WALBERLA_CHECK_EQUAL(field.ySize(), 2); - WALBERLA_CHECK_EQUAL(field.zSize(), 2); + WALBERLA_CHECK_EQUAL(field.xSize(), 2) + WALBERLA_CHECK_EQUAL(field.ySize(), 2) + WALBERLA_CHECK_EQUAL(field.zSize(), 2) // initialize the bottom ghost layer cells field(0,0,-1) = 1; @@ -118,32 +118,32 @@ void testScalarFieldPullReduction( IBlock * block, BlockDataID fieldId ) pi1.communicateLocal( block, block, stencil::B ); // check values in top ghost layer - WALBERLA_CHECK_EQUAL ( field(0,0,2), 0 ); - WALBERLA_CHECK_EQUAL ( field(0,1,2), 0 ); - WALBERLA_CHECK_EQUAL ( field(1,0,2), 0 ); - WALBERLA_CHECK_EQUAL ( field(1,1,2), 0 ); + WALBERLA_CHECK_EQUAL ( field(0,0,2), 0 ) + WALBERLA_CHECK_EQUAL ( field(0,1,2), 0 ) + WALBERLA_CHECK_EQUAL ( field(1,0,2), 0 ) + WALBERLA_CHECK_EQUAL ( field(1,1,2), 0 ) // check values in top interior cells - WALBERLA_CHECK_EQUAL ( field(0,0,1), 2 ); - WALBERLA_CHECK_EQUAL ( field(0,1,1), 3 ); - WALBERLA_CHECK_EQUAL ( field(1,0,1), 4 ); - WALBERLA_CHECK_EQUAL ( field(1,1,1), 5 ); + WALBERLA_CHECK_EQUAL ( field(0,0,1), 2 ) + WALBERLA_CHECK_EQUAL ( field(0,1,1), 3 ) + WALBERLA_CHECK_EQUAL ( field(1,0,1), 4 ) + WALBERLA_CHECK_EQUAL ( field(1,1,1), 5 ) // communicate periodic from top to bottom with standard form to sync ghost layers pystencils::ScalarFieldCommunication pi2 (fieldId); pi2.communicateLocal( block, block, stencil::T ); // check values in bottom ghost layer - WALBERLA_CHECK_EQUAL ( field(0,0,-1), 2 ); - WALBERLA_CHECK_EQUAL ( field(0,1,-1), 3 ); - WALBERLA_CHECK_EQUAL ( field(1,0,-1), 4 ); - WALBERLA_CHECK_EQUAL ( field(1,1,-1), 5 ); + WALBERLA_CHECK_EQUAL ( field(0,0,-1), 2 ) + WALBERLA_CHECK_EQUAL ( field(0,1,-1), 3 ) + WALBERLA_CHECK_EQUAL ( field(1,0,-1), 4 ) + WALBERLA_CHECK_EQUAL ( field(1,1,-1), 5 ) // check values in top interior cells - WALBERLA_CHECK_EQUAL ( field(0,0,1), 2 ); - WALBERLA_CHECK_EQUAL ( field(0,1,1), 3 ); - WALBERLA_CHECK_EQUAL ( field(1,0,1), 4 ); - WALBERLA_CHECK_EQUAL ( field(1,1,1), 5 ); + WALBERLA_CHECK_EQUAL ( field(0,0,1), 2 ) + WALBERLA_CHECK_EQUAL ( field(0,1,1), 3 ) + WALBERLA_CHECK_EQUAL ( field(1,0,1), 4 ) + WALBERLA_CHECK_EQUAL ( field(1,1,1), 5 ) } @@ -159,7 +159,7 @@ int main(int argc, char **argv) uint_t processes = uint_c( MPIManager::instance()->numProcesses() ); auto blocks = createUniformBlockGrid(processes,1 ,1, //blocks 2,2,2, //cells - 1, //dx + real_c(1.0), //dx false, //one block per process true,true,true);//periodicity @@ -172,7 +172,7 @@ int main(int argc, char **argv) // Create a BlockForest with 8x8x8 cells per block blocks = createUniformBlockGrid(processes,1 ,1, //blocks 8,8,8, //cells - 1, //dx + real_c(1.0), //dx false, //one block per process true,true,true);//periodicity @@ -188,7 +188,7 @@ int main(int argc, char **argv) for( auto blockIt = blocks->begin(); blockIt != blocks->end(); ++blockIt ) // block loop testScalarFieldPullReduction( &(*blockIt), scalarFieldId ); - return 0; + return EXIT_SUCCESS; } } // namespace walberla diff --git a/tests/field/codegen/GeneratedFieldPackInfoTest.py b/tests/field/codegen/GeneratedFieldPackInfoTest.py index 8124060c3..91ef712d8 100644 --- a/tests/field/codegen/GeneratedFieldPackInfoTest.py +++ b/tests/field/codegen/GeneratedFieldPackInfoTest.py @@ -3,12 +3,10 @@ import pystencils as ps from pystencils_walberla import CodeGeneration, generate_pack_info_for_field with CodeGeneration() as ctx: - layout = 'fzyx' - field = ps.fields("field: int32[3D]", layout=layout) # communication generate_pack_info_for_field(ctx, 'ScalarFieldCommunication', field, target=ps.Target.CPU) - generate_pack_info_for_field(ctx, 'ScalarFieldPullReduction', field, target=ps.Target.CPU, operator=op.add, - gl_to_inner=True) + generate_pack_info_for_field(ctx, 'ScalarFieldPullReduction', field, target=ps.Target.CPU, + operator=op.add, gl_to_inner=True) diff --git a/tests/field/codegen/JacobiKernel.py b/tests/field/codegen/JacobiKernel.py index 29e677a72..ba39b1b56 100644 --- a/tests/field/codegen/JacobiKernel.py +++ b/tests/field/codegen/JacobiKernel.py @@ -4,8 +4,9 @@ from pystencils_walberla import CodeGeneration, generate_sweep with CodeGeneration() as ctx: + field_type = "float64" if ctx.double_accuracy else "float32" # ----- Stencil 2D - created by specifying weights in nested list -------------------------- - src, dst = ps.fields("src, src_tmp: [2D]", layout='fzyx') + src, dst = ps.fields(f"src, src_tmp: {field_type}[2D]", layout='fzyx') stencil = [[1.11, 2.22, 3.33], [4.44, 5.55, 6.66], [7.77, 8.88, 9.99]] @@ -13,7 +14,7 @@ with CodeGeneration() as ctx: generate_sweep(ctx, 'JacobiKernel2D', assignments, field_swaps=[(src, dst)]) # ----- Stencil 3D - created by using kernel_decorator with assignments in '@=' format ----- - src, dst = ps.fields("src, src_tmp: [3D]", layout='fzyx') + src, dst = ps.fields(f"src, src_tmp: {field_type}[3D]", layout='fzyx') @ps.kernel def kernel_func(): diff --git a/tests/field/codegen/MultipleFieldSwaps.cpp b/tests/field/codegen/MultipleFieldSwaps.cpp index 965bf15a3..5fa7eec87 100644 --- a/tests/field/codegen/MultipleFieldSwaps.cpp +++ b/tests/field/codegen/MultipleFieldSwaps.cpp @@ -32,7 +32,7 @@ using namespace walberla; -typedef GhostLayerField<double,1> ScalarField; +typedef GhostLayerField<real_t ,1> ScalarField; void testMultipleFieldSwaps() { uint_t xSize = 5; @@ -41,14 +41,14 @@ void testMultipleFieldSwaps() shared_ptr< StructuredBlockForest > blocks = blockforest::createUniformBlockGrid ( uint_t(1) , uint_t(1), uint_t(1), // number of blocks in x,y,z direction xSize, ySize, uint_t(1), // how many cells per block (x,y,z) - real_t(1), // dx: length of one cell in physical coordinates + real_c(1.0), // dx: length of one cell in physical coordinates false, // one block per process - "false" means all blocks to one process true, true, true ); // full periodicity - BlockDataID fieldID_1 = field::addToStorage<ScalarField>(blocks, "Field_1", real_t(1.0)); - BlockDataID fieldID_2 = field::addToStorage<ScalarField>(blocks, "Field_2", real_t(1.0)); - BlockDataID fieldID_3 = field::addToStorage<ScalarField>(blocks, "Field_3", real_t(1.0)); + BlockDataID fieldID_1 = field::addToStorage<ScalarField>(blocks, "Field_1", real_c(1.0)); + BlockDataID fieldID_2 = field::addToStorage<ScalarField>(blocks, "Field_2", real_c(1.0)); + BlockDataID fieldID_3 = field::addToStorage<ScalarField>(blocks, "Field_3", real_c(1.0)); pystencils::MultipleFieldSwaps kernel(fieldID_1, fieldID_2, fieldID_3); @@ -63,9 +63,9 @@ void testMultipleFieldSwaps() // clang-format off WALBERLA_FOR_ALL_CELLS_XYZ(field_1, Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); - WALBERLA_CHECK_FLOAT_EQUAL(field_1->get(x, y, z), real_t(2.0)) - WALBERLA_CHECK_FLOAT_EQUAL(field_2->get(x, y, z), real_t(2.0)) - WALBERLA_CHECK_FLOAT_EQUAL(field_3->get(x, y, z), real_t(2.0)) + WALBERLA_CHECK_FLOAT_EQUAL(field_1->get(x, y, z), real_c(2.0)) + WALBERLA_CHECK_FLOAT_EQUAL(field_2->get(x, y, z), real_c(2.0)) + WALBERLA_CHECK_FLOAT_EQUAL(field_3->get(x, y, z), real_c(2.0)) ) // clang-format on } diff --git a/tests/field/codegen/MultipleFieldSwaps.py b/tests/field/codegen/MultipleFieldSwaps.py index d4268d8ea..c8abbfc9b 100644 --- a/tests/field/codegen/MultipleFieldSwaps.py +++ b/tests/field/codegen/MultipleFieldSwaps.py @@ -2,9 +2,10 @@ import pystencils as ps from pystencils_walberla import CodeGeneration, generate_sweep with CodeGeneration() as ctx: - src_1, dst_1 = ps.fields("src1, src1_tmp: [2D]", layout='fzyx') - src_2, dst_2 = ps.fields("src2, src2_tmp: [2D]", layout='fzyx') - src_3, dst_3 = ps.fields("src3, src3_tmp: [2D]", layout='fzyx') + field_type = "float64" if ctx.double_accuracy else "float32" + src_1, dst_1 = ps.fields(f"src1, src1_tmp: {field_type}[2D]", layout='fzyx') + src_2, dst_2 = ps.fields(f"src2, src2_tmp: {field_type}[2D]", layout='fzyx') + src_3, dst_3 = ps.fields(f"src3, src3_tmp: {field_type}[2D]", layout='fzyx') assignments = ps.AssignmentCollection([ps.Assignment(dst_1.center, 2 * src_1.center), ps.Assignment(dst_2.center, 2 * src_2.center), diff --git a/tests/field/codegen/Poisson.py b/tests/field/codegen/Poisson.py index a4da698dd..a4202ad5a 100644 --- a/tests/field/codegen/Poisson.py +++ b/tests/field/codegen/Poisson.py @@ -4,10 +4,11 @@ from pystencils_walberla import CodeGeneration, generate_sweep with CodeGeneration() as ctx: + field_type = "float64" if ctx.double_accuracy else "float32" # ----- Solving the 2D Poisson equation with rhs -------------------------- dx = sp.Symbol("dx") dy = sp.Symbol("dy") - src, dst, rhs = ps.fields("src, src_tmp, rhs: [2D]", layout='fzyx') + src, dst, rhs = ps.fields(f"src, src_tmp, rhs: {field_type}[2D]", layout='fzyx') @ps.kernel def kernel_func(): diff --git a/tests/lbm/codegen/FieldLayoutAndVectorizationTest.cpp b/tests/lbm/codegen/FieldLayoutAndVectorizationTest.cpp index db86a8d31..b1a435546 100644 --- a/tests/lbm/codegen/FieldLayoutAndVectorizationTest.cpp +++ b/tests/lbm/codegen/FieldLayoutAndVectorizationTest.cpp @@ -67,18 +67,18 @@ int main(int argc, char **argv) { walberla::Environment walberlaEnv(argc, argv); auto blocks = blockforest::createUniformBlockGrid( 1, 1, 1, - 32, 32, 32, real_t(1), + 32, 32, 32, real_c(1.0), 0, false, false, true, true, true, //periodicity false ); - real_t omega = real_t(1.6); - Vector3<real_t> initialVel(real_t(0.1), real_t(0), real_t(0)); + real_t omega = real_c(1.6); + Vector3<real_t> initialVel(real_c(0.1), real_c(0.0), real_c(0.0)); using LatticeModel1_T = lbm::FieldLayoutAndVectorizationTest_FZYX_Vec_LatticeModel; LatticeModel1_T latticeModel1(omega); - BlockDataID pdfField1ID = lbm::addPdfFieldToStorage(blocks, "pdf field1", latticeModel1, initialVel, real_t(1), field::fzyx); + BlockDataID pdfField1ID = lbm::addPdfFieldToStorage(blocks, "pdf field1", latticeModel1, initialVel, real_c(1.0), field::fzyx); for(auto blockIt = blocks->begin(); blockIt != blocks->end(); ++blockIt) { auto sweep = LatticeModel1_T::Sweep(pdfField1ID); sweep(&(*blockIt)); @@ -86,7 +86,7 @@ int main(int argc, char **argv) { using LatticeModel2_T = lbm::FieldLayoutAndVectorizationTest_FZYX_NoVec_LatticeModel; LatticeModel2_T latticeModel2(omega); - BlockDataID pdfField2ID = lbm::addPdfFieldToStorage(blocks, "pdf field2", latticeModel2, initialVel, real_t(1), field::fzyx); + BlockDataID pdfField2ID = lbm::addPdfFieldToStorage(blocks, "pdf field2", latticeModel2, initialVel, real_c(1.0), field::fzyx); for(auto blockIt = blocks->begin(); blockIt != blocks->end(); ++blockIt) { auto sweep = LatticeModel2_T::Sweep(pdfField2ID); sweep(&(*blockIt)); @@ -96,7 +96,7 @@ int main(int argc, char **argv) { using LatticeModel3_T = lbm::FieldLayoutAndVectorizationTest_ZYXF_Vec_LatticeModel; LatticeModel3_T latticeModel3(omega); - BlockDataID pdfField3ID = lbm::addPdfFieldToStorage(blocks, "pdf field3", latticeModel3, initialVel, real_t(1), field::zyxf); + BlockDataID pdfField3ID = lbm::addPdfFieldToStorage(blocks, "pdf field3", latticeModel3, initialVel, real_c(1.0), field::zyxf); for(auto blockIt = blocks->begin(); blockIt != blocks->end(); ++blockIt) { auto sweep = LatticeModel3_T::Sweep(pdfField3ID); sweep(&(*blockIt)); @@ -106,7 +106,7 @@ int main(int argc, char **argv) { using LatticeModel4_T = lbm::FieldLayoutAndVectorizationTest_ZYXF_NoVec_LatticeModel; LatticeModel4_T latticeModel4(omega); - BlockDataID pdfField4ID = lbm::addPdfFieldToStorage(blocks, "pdf field4", latticeModel4, initialVel, real_t(1), field::zyxf); + BlockDataID pdfField4ID = lbm::addPdfFieldToStorage(blocks, "pdf field4", latticeModel4, initialVel, real_c(1.0), field::zyxf); for(auto blockIt = blocks->begin(); blockIt != blocks->end(); ++blockIt) { auto sweep = LatticeModel4_T::Sweep(pdfField4ID); sweep(&(*blockIt)); diff --git a/tests/lbm/codegen/FieldLayoutAndVectorizationTest.py b/tests/lbm/codegen/FieldLayoutAndVectorizationTest.py index f04e357bc..e639e0a60 100644 --- a/tests/lbm/codegen/FieldLayoutAndVectorizationTest.py +++ b/tests/lbm/codegen/FieldLayoutAndVectorizationTest.py @@ -10,7 +10,8 @@ from collections import namedtuple with CodeGeneration() as ctx: omega_shear = sp.symbols("omega") - lbm_config = LBMConfig(stencil=LBStencil(Stencil.D2Q9), compressible=False, method=Method.SRT) + lbm_config = LBMConfig(stencil=LBStencil(Stencil.D2Q9), compressible=False, method=Method.SRT, + zero_centered=False, delta_equilibrium=False) collision_rule = create_lb_collision_rule(lbm_config=lbm_config) SetupDefinition = namedtuple('SetupDefinition', ['name', 'field_layout', 'vectorization_dict']) diff --git a/tests/lbm/codegen/FluctuatingMRT.cpp b/tests/lbm/codegen/FluctuatingMRT.cpp index a8a425d9f..62e81c943 100644 --- a/tests/lbm/codegen/FluctuatingMRT.cpp +++ b/tests/lbm/codegen/FluctuatingMRT.cpp @@ -65,18 +65,18 @@ int main( int argc, char ** argv ) const real_t magic_number = 3. / 16; const real_t omega_2 = (4 - 2 * omega) / (4 * magic_number * omega + 2 - omega); const Vector3<real_t> initialVelocity = parameters.getParameter< Vector3<real_t> >( "initialVelocity", Vector3<real_t>() ); - const uint_t timesteps = parameters.getParameter< uint_t > ( "timesteps", uint_c(10) ); - const real_t temperature = real_t(0.01); + const uint_t timesteps = parameters.getParameter< uint_t > ( "timesteps", uint_c(10.0) ); + const real_t temperature = real_c(0.01); const uint_t seed = uint_t(0); - const real_t remainingTimeLoggerFrequency = parameters.getParameter< double >( "remainingTimeLoggerFrequency", 3.0 ); // in seconds + const real_t remainingTimeLoggerFrequency = parameters.getParameter< real_t >( "remainingTimeLoggerFrequency", real_c(3.0) ); // in seconds // create fields - real_t force = 2E-4; // Force to apply on each node on each axis + real_t force = real_c(2E-4); // Force to apply on each node on each axis BlockDataID forceFieldId = field::addToStorage<VectorField_T>( blocks, "Force", force, field::fzyx ); LatticeModel_T latticeModel = LatticeModel_T( forceFieldId, omega, omega, omega_2, omega, seed, temperature, uint_t(0) ); - BlockDataID pdfFieldId = lbm::addPdfFieldToStorage( blocks, "pdf field", latticeModel, initialVelocity, real_t(1), uint_t(1), field::fzyx ); + BlockDataID pdfFieldId = lbm::addPdfFieldToStorage( blocks, "pdf field", latticeModel, initialVelocity, real_c(1.0), uint_t(1), field::fzyx ); BlockDataID flagFieldId = field::addFlagFieldToStorage< FlagField_T >( blocks, "flag field" ); // create and initialize flag field @@ -123,15 +123,15 @@ int main( int argc, char ** argv ) WALBERLA_FOR_ALL_CELLS_XYZ_OMP(v, omp critical, { momentum += rho->get(x, y, z) * v->get(x, y, z); count++; - }); + }) } // check real_t expected_momentum = real_c(count) * force * real_c(timesteps); printf("%g %g %g | %g\n", momentum[0], momentum[1], momentum[2], expected_momentum); - WALBERLA_CHECK_FLOAT_EQUAL(momentum[0], expected_momentum); - WALBERLA_CHECK_FLOAT_EQUAL(momentum[1], expected_momentum); - WALBERLA_CHECK_FLOAT_EQUAL(momentum[2], expected_momentum); + WALBERLA_CHECK_FLOAT_EQUAL(momentum[0], expected_momentum) + WALBERLA_CHECK_FLOAT_EQUAL(momentum[1], expected_momentum) + WALBERLA_CHECK_FLOAT_EQUAL(momentum[2], expected_momentum) return EXIT_SUCCESS; } diff --git a/tests/lbm/codegen/FluctuatingMRT.py b/tests/lbm/codegen/FluctuatingMRT.py index eed48db71..ff9ad6da9 100644 --- a/tests/lbm/codegen/FluctuatingMRT.py +++ b/tests/lbm/codegen/FluctuatingMRT.py @@ -1,16 +1,18 @@ import sympy as sp import pystencils as ps -from lbmpy.creationfunctions import create_lb_collision_rule, create_mrt_orthogonal +from lbmpy.creationfunctions import create_lb_collision_rule from lbmpy.moments import is_bulk_moment, is_shear_moment, get_order from lbmpy.forcemodels import Guo -from lbmpy import LBMConfig, LBMOptimisation, LBStencil, Stencil +from lbmpy import LBMConfig, LBMOptimisation, LBStencil, Stencil, Method from pystencils_walberla import CodeGeneration from lbmpy_walberla import generate_lattice_model with CodeGeneration() as ctx: + data_type = "float64" if ctx.double_accuracy else "float32" + omega_shear = sp.symbols("omega_shear") temperature = sp.symbols("temperature") - force_field, vel_field = ps.fields("force(3), velocity(3): [3D]", layout='fzyx') + force_field, vel_field = ps.fields(f"force(3), velocity(3): {data_type}[3D]", layout='fzyx') def rr_getter(moment_group): """Maps a group of moments to a relaxation rate (shear, bulk, even, odd) @@ -23,7 +25,7 @@ with CodeGeneration() as ctx: order = order[0] if order < 2: - return [0] * len(moment_group) + return [0.0] * len(moment_group) elif any(is_bulk): assert all(is_bulk) return [sp.Symbol("omega_bulk")] * len(moment_group) @@ -36,24 +38,22 @@ with CodeGeneration() as ctx: else: return [sp.Symbol("omega_odd")] * len(moment_group) - method = create_mrt_orthogonal( - stencil=LBStencil(Stencil.D3Q19), - compressible=True, - weighted=True, - relaxation_rates=rr_getter, - force_model=Guo(force_field.center_vector) - ) fluctuating = {'temperature': temperature, 'block_offsets': 'walberla', 'rng_node': ps.rng.PhiloxTwoDoubles if ctx.double_accuracy else ps.rng.PhiloxFourFloats} - lbm_config = LBMConfig(fluctuating=fluctuating) + lbm_config = LBMConfig(stencil=LBStencil(Stencil.D3Q19), method=Method.MRT, compressible=True, + weighted=True, zero_centered=False, relaxation_rates=rr_getter, + force_model=Guo(force=force_field.center_vector), + fluctuating=fluctuating) + lbm_opt = LBMOptimisation(cse_global=True) - collision_rule = create_lb_collision_rule(lb_method=method, lbm_config=lbm_config, lbm_optimisation=lbm_opt) + collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) params = {} if ctx.optimize_for_localhost: params['cpu_vectorize_info'] = {'assume_inner_stride_one': True, 'assume_aligned': True} - generate_lattice_model(ctx, 'FluctuatingMRT_LatticeModel', collision_rule, field_layout='fzyx', **params) + generate_lattice_model(ctx, 'FluctuatingMRT_LatticeModel', collision_rule, field_layout='fzyx', + data_type=data_type, **params) diff --git a/tests/lbm/codegen/GeneratedFreeSlip.cpp b/tests/lbm/codegen/GeneratedFreeSlip.cpp index 24cb15ef5..6220ef4cb 100644 --- a/tests/lbm/codegen/GeneratedFreeSlip.cpp +++ b/tests/lbm/codegen/GeneratedFreeSlip.cpp @@ -83,13 +83,13 @@ int main(int argc, char** argv) const real_t omega = parameters.getParameter< real_t >("omega", real_c(1.4)); const uint_t timesteps = parameters.getParameter< uint_t >("timesteps", uint_c(10)); - const double remainingTimeLoggerFrequency = - parameters.getParameter< double >("remainingTimeLoggerFrequency", 3.0); // in seconds + const real_t remainingTimeLoggerFrequency = + parameters.getParameter< real_t >("remainingTimeLoggerFrequency", real_c(3.0)); // in seconds // create fields BlockDataID pdfFieldID = blocks->addStructuredBlockData< PdfField_T >(pdfFieldAdder, "PDFs"); - BlockDataID velFieldID = field::addToStorage< VelocityField_T >(blocks, "velocity", real_t(0), field::fzyx); - BlockDataID densityFieldID = field::addToStorage< ScalarField_T >(blocks, "density", real_t(1.0), field::fzyx); + BlockDataID velFieldID = field::addToStorage< VelocityField_T >(blocks, "velocity", real_c(0.0), field::fzyx); + BlockDataID densityFieldID = field::addToStorage< ScalarField_T >(blocks, "density", real_c(1.0), field::fzyx); BlockDataID flagFieldId = field::addFlagFieldToStorage< FlagField_T >(blocks, "flag field"); @@ -129,7 +129,7 @@ int main(int argc, char** argv) if (tubeSetup) { - real_t R = sqrt((globalCell[1] - My) * (globalCell[1] - My) + (globalCell[2] - Mz) * (globalCell[2] - Mz)); + real_t R = real_c(sqrt((globalCell[1] - My) * (globalCell[1] - My) + (globalCell[2] - Mz) * (globalCell[2] - Mz))); if (R > real_c(cellsPerBlock[1]) * real_c(0.5)) addFlag(flagField->get(x, y, z), wallFlag); } if (slopedWall) @@ -206,7 +206,8 @@ int main(int argc, char** argv) real_t v2 = velField->get(cell_idx_c(cellsPerBlock[0] / 2), i + 1, cell_idx_c(cellsPerBlock[2] / 2), 0); real_t grad = v2 - v1; // WALBERLA_LOG_DEVEL_VAR(grad) - WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(grad, 0.0, 1e-16) + WALBERLA_CHECK_FLOAT_EQUAL(grad, 0.0) + } } } diff --git a/tests/lbm/codegen/GeneratedFreeSlip.py b/tests/lbm/codegen/GeneratedFreeSlip.py index d0e252ddd..e079cbe75 100644 --- a/tests/lbm/codegen/GeneratedFreeSlip.py +++ b/tests/lbm/codegen/GeneratedFreeSlip.py @@ -12,48 +12,51 @@ from lbmpy_walberla import generate_boundary, generate_lb_pack_info, generate_al import sympy as sp -stencil = LBStencil(Stencil.D3Q19) +with CodeGeneration() as ctx: + data_type = "float64" if ctx.double_accuracy else "float32" + stencil = LBStencil(Stencil.D3Q19) -pdfs, pdfs_tmp = fields(f"pdfs({stencil.Q}), pdfs_tmp({stencil.Q}): double[{stencil.D}D]", layout='fzyx') -velocity_field, density_field = fields(f"velocity({stencil.D}), density(1) : double[{stencil.D}D]", layout='fzyx') -omega = sp.Symbol("omega") + pdfs, pdfs_tmp = fields(f"pdfs({stencil.Q}), pdfs_tmp({stencil.Q}): {data_type}[{stencil.D}D]", + layout='fzyx') + velocity_field, density_field = fields(f"velocity({stencil.D}), density(1) : {data_type}[{stencil.D}D]", + layout='fzyx') + omega = sp.Symbol("omega") -output = { - 'density': density_field, - 'velocity': velocity_field -} + output = { + 'density': density_field, + 'velocity': velocity_field + } -streaming_pattern = 'esotwist' -timesteps = get_timesteps(streaming_pattern) + streaming_pattern = 'esotwist' + timesteps = get_timesteps(streaming_pattern) -lbm_config = LBMConfig(method=Method.SRT, stencil=stencil, relaxation_rate=omega, force=(1e-5, 0, 0), - output=output, streaming_pattern=streaming_pattern) + lbm_config = LBMConfig(method=Method.SRT, stencil=stencil, relaxation_rate=omega, force=(1e-5, 0, 0), + output=output, streaming_pattern=streaming_pattern) -lbm_opt = LBMOptimisation(symbolic_field=pdfs, - cse_global=False, cse_pdfs=False) + lbm_opt = LBMOptimisation(symbolic_field=pdfs, + cse_global=False, cse_pdfs=False) -method = create_lb_method(lbm_config=lbm_config) + method = create_lb_method(lbm_config=lbm_config) -# getter & setter -setter_assignments = macroscopic_values_setter(method, density=density_field.center, - velocity=velocity_field.center_vector, - pdfs=pdfs, streaming_pattern=streaming_pattern, - previous_timestep=timesteps[0]) + # getter & setter + setter_assignments = macroscopic_values_setter(method, density=density_field.center, + velocity=velocity_field.center_vector, + pdfs=pdfs, streaming_pattern=streaming_pattern, + previous_timestep=timesteps[0]) -if not is_inplace(streaming_pattern): - lbm_opt = replace(lbm_opt, symbolic_temporary_field=pdfs_tmp) - field_swaps = [(pdfs, pdfs_tmp)] -else: - field_swaps = [] + if not is_inplace(streaming_pattern): + lbm_opt = replace(lbm_opt, symbolic_temporary_field=pdfs_tmp) + field_swaps = [(pdfs, pdfs_tmp)] + else: + field_swaps = [] -collision_rule = create_lb_collision_rule(lb_method=method, lbm_config=lbm_config, lbm_optimisation=lbm_opt) + collision_rule = create_lb_collision_rule(lb_method=method, lbm_config=lbm_config, lbm_optimisation=lbm_opt) -stencil_typedefs = {'Stencil_T': stencil} -field_typedefs = {'PdfField_T': pdfs, - 'VelocityField_T': velocity_field, - 'ScalarField_T': density_field} + stencil_typedefs = {'Stencil_T': stencil} + field_typedefs = {'PdfField_T': pdfs, + 'VelocityField_T': velocity_field, + 'ScalarField_T': density_field} -with CodeGeneration() as ctx: # sweeps generate_alternating_lbm_sweep(ctx, 'GeneratedFreeSlip_Sweep', collision_rule, lbm_config=lbm_config, lbm_optimisation=lbm_opt, field_swaps=field_swaps) diff --git a/tests/lbm/codegen/GeneratedOutflowBC.cpp b/tests/lbm/codegen/GeneratedOutflowBC.cpp index dba8bdbf8..453a1e7cc 100644 --- a/tests/lbm/codegen/GeneratedOutflowBC.cpp +++ b/tests/lbm/codegen/GeneratedOutflowBC.cpp @@ -70,10 +70,10 @@ Vector3< real_t > ShearProfile::operator()( const Cell& pos, const shared_ptr< S { Cell globalCell; CellInterval domain = SbF->getDomainCellBB(); - real_t h_y = domain.yMax() - domain.yMin(); + real_t h_y = real_c(domain.yMax()) - real_c(domain.yMin()); SbF->transformBlockLocalToGlobalCell(globalCell, block, pos); - real_t u = inflow_velocity_ * (globalCell[1] / h_y); + real_t u = inflow_velocity_ * (real_c(globalCell[1]) / h_y); Vector3< real_t > result(u, 0.0, 0.0); return result; @@ -93,7 +93,7 @@ int main(int argc, char** argv) auto parameters = walberlaEnv.config()->getOneBlock("Parameters"); const real_t omega = parameters.getParameter< real_t >("omega", real_c(1.4)); - const real_t u_max = parameters.getParameter< real_t >("u_max", real_t(0.05)); + const real_t u_max = parameters.getParameter< real_t >("u_max", real_c(0.05)); const uint_t timesteps = parameters.getParameter< uint_t >("timesteps", uint_c(10)); const double remainingTimeLoggerFrequency = @@ -101,8 +101,8 @@ int main(int argc, char** argv) // create fields BlockDataID pdfFieldID = blocks->addStructuredBlockData< PdfField_T >(pdfFieldAdder, "PDFs"); - BlockDataID velFieldID = field::addToStorage< VelocityField_T >(blocks, "velocity", real_t(0), field::fzyx); - BlockDataID densityFieldID = field::addToStorage< ScalarField_T >(blocks, "density", real_t(0), field::fzyx); + BlockDataID velFieldID = field::addToStorage< VelocityField_T >(blocks, "velocity", real_c(0.0), field::fzyx); + BlockDataID densityFieldID = field::addToStorage< ScalarField_T >(blocks, "density", real_c(0.0), field::fzyx); BlockDataID flagFieldId = field::addFlagFieldToStorage< FlagField_T >(blocks, "flag field"); @@ -170,16 +170,16 @@ int main(int argc, char** argv) timeloop.run(); CellInterval domain = blocks->getDomainCellBB(); - real_t h_y = domain.yMax() - domain.yMin(); + real_t h_y = real_c(domain.yMax()) - real_c(domain.yMin()); for (auto& block : *blocks) { auto velField = block.getData<VelocityField_T>(velFieldID); WALBERLA_FOR_ALL_CELLS_XYZ ( velField, - Cell globalCell; + Cell globalCell; blocks->transformBlockLocalToGlobalCell(globalCell, block, Cell(x, y, z)); - WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(velField->get(x, y, z, 0), u_max * (globalCell[1] / h_y), 0.01) + WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(velField->get(x, y, z, 0), u_max * (real_c(globalCell[1]) / h_y), real_c(0.01)) ) } diff --git a/tests/lbm/codegen/GeneratedOutflowBC.py b/tests/lbm/codegen/GeneratedOutflowBC.py index 3fae265e1..a765eee4c 100644 --- a/tests/lbm/codegen/GeneratedOutflowBC.py +++ b/tests/lbm/codegen/GeneratedOutflowBC.py @@ -9,52 +9,55 @@ from lbmpy_walberla import generate_boundary, generate_lb_pack_info import sympy as sp -stencil = LBStencil(Stencil.D2Q9) +with CodeGeneration() as ctx: + data_type = "float64" if ctx.double_accuracy else "float32" + stencil = LBStencil(Stencil.D2Q9) -pdfs, pdfs_tmp = fields(f"pdfs({stencil.Q}), pdfs_tmp({stencil.Q}): double[{stencil.D}D]", layout='fzyx') -velocity_field, density_field = fields(f"velocity({stencil.D}), density(1) : double[{stencil.D}D]", layout='fzyx') -omega = sp.Symbol("omega") -u_max = sp.Symbol("u_max") + pdfs, pdfs_tmp = fields(f"pdfs({stencil.Q}), pdfs_tmp({stencil.Q}): {data_type}[{stencil.D}D]", + layout='fzyx') + velocity_field, density_field = fields(f"velocity({stencil.D}), density(1) : {data_type}[{stencil.D}D]", + layout='fzyx') + omega = sp.Symbol("omega") + u_max = sp.Symbol("u_max") -output = { - 'density': density_field, - 'velocity': velocity_field -} + output = { + 'density': density_field, + 'velocity': velocity_field + } -lbm_config = LBMConfig(method=Method.CUMULANT, stencil=stencil, relaxation_rate=omega, - galilean_correction=stencil.Q == 27, field_name='pdfs', output=output) + lbm_config = LBMConfig(method=Method.CUMULANT, stencil=stencil, relaxation_rate=omega, compressible=True, + galilean_correction=stencil.Q == 27, field_name='pdfs', output=output) -lbm_opt = LBMOptimisation(symbolic_field=pdfs, symbolic_temporary_field=pdfs_tmp, - cse_global=False, cse_pdfs=False) + lbm_opt = LBMOptimisation(symbolic_field=pdfs, symbolic_temporary_field=pdfs_tmp, + cse_global=False, cse_pdfs=False) -method = create_lb_method(lbm_config=lbm_config) + method = create_lb_method(lbm_config=lbm_config) -# getter & setter -setter_assignments = macroscopic_values_setter(method, velocity=velocity_field.center_vector, - pdfs=pdfs, density=1.0) + # getter & setter + setter_assignments = macroscopic_values_setter(method, velocity=velocity_field.center_vector, + pdfs=pdfs, density=1.0) -update_rule = create_lb_update_rule(lb_method=method, lbm_config=lbm_config, lbm_optimisation=lbm_opt) + update_rule = create_lb_update_rule(lb_method=method, lbm_config=lbm_config, lbm_optimisation=lbm_opt) -stencil_typedefs = {'Stencil_T': stencil} -field_typedefs = {'PdfField_T': pdfs, - 'VelocityField_T': velocity_field, - 'ScalarField_T': density_field} + stencil_typedefs = {'Stencil_T': stencil} + field_typedefs = {'PdfField_T': pdfs, + 'VelocityField_T': velocity_field, + 'ScalarField_T': density_field} -with CodeGeneration() as ctx: # sweeps generate_sweep(ctx, 'GeneratedOutflowBC_Sweep', update_rule, field_swaps=[(pdfs, pdfs_tmp)]) generate_sweep(ctx, 'GeneratedOutflowBC_MacroSetter', setter_assignments) # boundaries - ubb_dynamic = UBB(lambda *args: None, dim=stencil.D) + ubb_dynamic = UBB(lambda *args: None, dim=stencil.D, data_type=data_type) ubb_data_handler = UBBAdditionalDataHandler(stencil, ubb_dynamic) if stencil.D == 2: - ubb_static = UBB([sp.Symbol("u_max"), 0]) + ubb_static = UBB([sp.Symbol("u_max"), 0], data_type=data_type) else: - ubb_static = UBB([sp.Symbol("u_max"), 0, 0]) + ubb_static = UBB([sp.Symbol("u_max"), 0, 0], data_type=data_type) - outflow = ExtrapolationOutflow(stencil[4], method) + outflow = ExtrapolationOutflow(stencil[4], method, data_type=data_type) outflow_data_handler = OutflowAdditionalDataHandler(stencil, outflow) # Dynamic UBB which is used to produce a specific velocity profile at the inflow. diff --git a/tests/lbm/codegen/InplaceStreamingCodegen.py b/tests/lbm/codegen/InplaceStreamingCodegen.py index 099ad4617..95f30ff59 100644 --- a/tests/lbm/codegen/InplaceStreamingCodegen.py +++ b/tests/lbm/codegen/InplaceStreamingCodegen.py @@ -12,51 +12,53 @@ from lbmpy.advanced_streaming import Timestep from pystencils import Field -# Common Setup - -stencil = LBStencil(Stencil.D3Q27) -target = Target.CPU -inplace_pattern = 'aa' -two_fields_pattern = 'pull' -namespace = 'lbmpy' - -f_field = Field.create_generic('f', stencil.D, index_shape=(stencil.Q,), layout='fzyx') -f_field_tmp = Field.create_generic('f_tmp', stencil.D, index_shape=(stencil.Q,), layout='fzyx') -u_field = Field.create_generic('u', stencil.D, index_shape=(stencil.D,), layout='fzyx') +with CodeGeneration() as ctx: + # Common Setup + data_type = "float64" if ctx.double_accuracy else "float32" + stencil = LBStencil(Stencil.D3Q27) + target = Target.CPU + inplace_pattern = 'aa' + two_fields_pattern = 'pull' + namespace = 'lbmpy' -output = { - 'velocity': u_field -} + f_field = Field.create_generic('f', stencil.D, dtype=data_type, index_shape=(stencil.Q,), layout='fzyx') + f_field_tmp = Field.create_generic('f_tmp', stencil.D, dtype=data_type, index_shape=(stencil.Q,), layout='fzyx') + u_field = Field.create_generic('u', stencil.D, dtype=data_type, index_shape=(stencil.D,), layout='fzyx') -lbm_config = LBMConfig(stencil=stencil, method=Method.SRT, relaxation_rate=1.5, output=output) -lbm_opt = LBMOptimisation(symbolic_field=f_field, - symbolic_temporary_field=f_field_tmp) + output = { + 'velocity': u_field + } -config = CreateKernelConfig(target=target) + lbm_config = LBMConfig(stencil=stencil, method=Method.SRT, relaxation_rate=1.5, output=output) + lbm_opt = LBMOptimisation(symbolic_field=f_field, + symbolic_temporary_field=f_field_tmp) -collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt, config=config) -lb_method = collision_rule.method -noslip = NoSlip() -ubb = UBB((0.05,) + (0,) * (stencil.D - 1)) + collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) + lb_method = collision_rule.method + noslip = NoSlip() + ubb = UBB((0.05,) + (0.0,) * (stencil.D - 1), data_type=data_type) -outflow_normal = (1,) + (0,) * (stencil.D - 1) -outflow_pull = ExtrapolationOutflow(outflow_normal, lb_method, streaming_pattern=two_fields_pattern) + outflow_normal = (1,) + (0,) * (stencil.D - 1) + outflow_pull = ExtrapolationOutflow(outflow_normal, lb_method, streaming_pattern=two_fields_pattern, + data_type=data_type) -outflow_inplace = ExtrapolationOutflow(outflow_normal, lb_method, streaming_pattern=inplace_pattern) + outflow_inplace = ExtrapolationOutflow(outflow_normal, lb_method, streaming_pattern=inplace_pattern, + data_type=data_type) -init_velocity = (0,) * stencil.D + init_velocity = (0.0,) * stencil.D -init_kernel_pull = macroscopic_values_setter(lb_method, 1, init_velocity, f_field, streaming_pattern=two_fields_pattern) -init_kernel_inplace = macroscopic_values_setter( - lb_method, 1, init_velocity, f_field, streaming_pattern=inplace_pattern, previous_timestep=Timestep.ODD) + init_kernel_pull = macroscopic_values_setter(lb_method, 1.0, init_velocity, f_field, + streaming_pattern=two_fields_pattern) + init_kernel_inplace = macroscopic_values_setter( + lb_method, 1.0, init_velocity, f_field, streaming_pattern=inplace_pattern, previous_timestep=Timestep.ODD) -stencil_typedefs = {'Stencil_T': stencil} -field_typedefs = {'PdfField_T': f_field, 'VelocityField_T': u_field} + stencil_typedefs = {'Stencil_T': stencil} + field_typedefs = {'PdfField_T': f_field, 'VelocityField_T': u_field} -with CodeGeneration() as ctx: # Pull-Pattern classes + config = CreateKernelConfig(data_type=data_type, default_number_float=data_type) ast_pull = create_lb_ast(collision_rule=collision_rule, - streaming_pattern=two_fields_pattern, lbm_optimisation=lbm_opt) + streaming_pattern=two_fields_pattern, lbm_optimisation=lbm_opt, config=config) generate_sweep(ctx, 'PullSweep', ast_pull, field_swaps=[(f_field, f_field_tmp)], namespace=namespace) generate_boundary(ctx, 'PullNoSlip', noslip, lb_method, diff --git a/tests/lbm/codegen/InplaceStreamingCodegenTest.cpp b/tests/lbm/codegen/InplaceStreamingCodegenTest.cpp index 718042efa..f43f5dbd7 100644 --- a/tests/lbm/codegen/InplaceStreamingCodegenTest.cpp +++ b/tests/lbm/codegen/InplaceStreamingCodegenTest.cpp @@ -32,7 +32,6 @@ #include "timeloop/SweepTimeloop.h" -#include <string> using namespace walberla::lbmpy; @@ -151,7 +150,7 @@ int main(int argc, char** argv) { for (uint_t i = 0; i < pullVelocityField->fSize(); i++) { - WALBERLA_CHECK_FLOAT_EQUAL(pullVelocityField->get(c, i), inplaceVelocityField->get(c, i)); + WALBERLA_CHECK_FLOAT_EQUAL(pullVelocityField->get(c, i), inplaceVelocityField->get(c, i)) } } } diff --git a/tests/lbm/codegen/LbCodeGenerationExample.cpp b/tests/lbm/codegen/LbCodeGenerationExample.cpp index 8bb6f96f7..4711fb1b9 100644 --- a/tests/lbm/codegen/LbCodeGenerationExample.cpp +++ b/tests/lbm/codegen/LbCodeGenerationExample.cpp @@ -69,16 +69,16 @@ int main(int argc, char** argv) const uint_t timesteps = parameters.getParameter< uint_t >("timesteps", uint_c(10)); const double remainingTimeLoggerFrequency = - parameters.getParameter< double >("remainingTimeLoggerFrequency", 3.0); // in seconds + parameters.getParameter< double >("remainingTimeLoggerFrequency", real_c(3.0)); // in seconds // create fields - BlockDataID forceFieldId = field::addToStorage< VectorField_T >(blocks, "Force", real_t(0.0), field::fzyx); - BlockDataID velFieldId = field::addToStorage< VectorField_T >(blocks, "Velocity", real_t(0.0), field::fzyx); - BlockDataID omegaFieldId = field::addToStorage< ScalarField_T >(blocks, "Omega", real_t(0.0), field::fzyx); + BlockDataID forceFieldId = field::addToStorage< VectorField_T >(blocks, "Force", real_c(0.0), field::fzyx); + BlockDataID velFieldId = field::addToStorage< VectorField_T >(blocks, "Velocity", real_c(0.0), field::fzyx); + BlockDataID omegaFieldId = field::addToStorage< ScalarField_T >(blocks, "Omega", real_c(0.0), field::fzyx); LatticeModel_T latticeModel = LatticeModel_T(forceFieldId, omegaFieldId, velFieldId, omega); BlockDataID pdfFieldId = - lbm::addPdfFieldToStorage(blocks, "pdf field", latticeModel, initialVelocity, real_t(1), field::fzyx); + lbm::addPdfFieldToStorage(blocks, "pdf field", latticeModel, initialVelocity, real_c(log10(1)), field::fzyx); BlockDataID flagFieldId = field::addFlagFieldToStorage< FlagField_T >(blocks, "flag field"); // create and initialize boundary handling diff --git a/tests/lbm/codegen/LbCodeGenerationExample.py b/tests/lbm/codegen/LbCodeGenerationExample.py index 182a501d4..870c3bf81 100644 --- a/tests/lbm/codegen/LbCodeGenerationExample.py +++ b/tests/lbm/codegen/LbCodeGenerationExample.py @@ -7,11 +7,12 @@ from pystencils_walberla import CodeGeneration, generate_info_header from lbmpy_walberla import RefinementScaling, generate_boundary, generate_lattice_model with CodeGeneration() as ctx: + data_type = "float64" if ctx.double_accuracy else "float32" omega, omega_free = sp.symbols("omega, omega_free") - force_field, vel_field, omega_out = ps.fields("force(3), velocity(3), omega_out: [3D]", layout='fzyx') + force_field, vel_field, omega_out = ps.fields(f"force(3), velocity(3), omega_out: {data_type}[3D]", layout='fzyx') stencil = LBStencil(Stencil.D3Q19) - lbm_config = LBMConfig(stencil=stencil, method=Method.MRT, entropic=True, + lbm_config = LBMConfig(stencil=stencil, method=Method.MRT, entropic=True, zero_centered=False, compressible=True, omega_output_field=omega_out, force=force_field.center_vector, output={'velocity': vel_field}, relaxation_rates=[omega, omega, omega_free, omega_free, omega_free, omega_free]) @@ -33,6 +34,6 @@ with CodeGeneration() as ctx: # for vectorisation on AVX512 due to scatter and gather intrinsics generate_lattice_model(ctx, 'LbCodeGenerationExample_LatticeModel', collision_rule, field_layout='fzyx', refinement_scaling=scaling) - generate_boundary(ctx, 'LbCodeGenerationExample_UBB', UBB([0.05, 0, 0]), collision_rule.method) + generate_boundary(ctx, 'LbCodeGenerationExample_UBB', UBB([0.05, 0, 0], data_type=data_type), collision_rule.method) generate_boundary(ctx, 'LbCodeGenerationExample_NoSlip', NoSlip(), collision_rule.method) generate_info_header(ctx, 'LbCodeGenerationExample') diff --git a/tests/lbm/codegen/LbmPackInfoGenerationTest.py b/tests/lbm/codegen/LbmPackInfoGenerationTest.py index 9e24470bb..87af2b6dc 100644 --- a/tests/lbm/codegen/LbmPackInfoGenerationTest.py +++ b/tests/lbm/codegen/LbmPackInfoGenerationTest.py @@ -14,7 +14,7 @@ with CodeGeneration() as ctx: target = ps.Target.CPU stencil = LBStencil(Stencil.D3Q19) - pdf_field = Field.create_generic('pdfs', stencil.D, index_shape=(stencil.Q,), layout='fzyx') + pdf_field = Field.create_generic('pdfs', stencil.D, index_shape=(stencil.Q,), layout='fzyx', dtype=data_type) lbm_config = LBMConfig(method=Method.SRT, stencil=stencil, streaming_pattern=streaming_pattern, timestep=Timestep.ODD) diff --git a/tests/lbm/codegen/StreamInCellIntervalCodegen.py b/tests/lbm/codegen/StreamInCellIntervalCodegen.py index 4205d0c4d..7391a0d66 100644 --- a/tests/lbm/codegen/StreamInCellIntervalCodegen.py +++ b/tests/lbm/codegen/StreamInCellIntervalCodegen.py @@ -1,13 +1,14 @@ import sympy as sp -from lbmpy.creationfunctions import create_lb_collision_rule, create_lb_update_rule -from lbmpy import LBMConfig +from lbmpy.creationfunctions import create_lb_collision_rule +from lbmpy import LBMConfig, LBMOptimisation, Method, Stencil +from lbmpy.stencils import LBStencil from pystencils_walberla import CodeGeneration from lbmpy_walberla import generate_lattice_model # general parameters -stencil = 'D3Q19' +stencil = LBStencil(Stencil.D3Q19) omega = sp.Symbol('omega') layout = 'fzyx' @@ -20,10 +21,12 @@ method_params = {'stencil': stencil, 'relaxation_rate': omega, 'compressible': True} -lbm_config = LBMConfig(streaming_pattern='pull') +lbm_config = LBMConfig(stencil=stencil, method=Method.SRT, relaxation_rate=omega, compressible=True, + zero_centered=False, delta_equilibrium=False, + streaming_pattern='pull') +lbm_opt = LBMOptimisation(cse_global=True, field_layout=layout) -collision_rule = create_lb_collision_rule(optimization=optimizations, **method_params) -update_rule = create_lb_update_rule(collision_rule=collision_rule, lbm_config=lbm_config, optimization=optimizations) +collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) with CodeGeneration() as ctx: generate_lattice_model(ctx, "GeneratedLatticeModel", collision_rule, field_layout=layout) diff --git a/tests/lbm/codegen/StreamInCellIntervalCodegenTest.cpp b/tests/lbm/codegen/StreamInCellIntervalCodegenTest.cpp index 0698ccc13..7981f5b2b 100644 --- a/tests/lbm/codegen/StreamInCellIntervalCodegenTest.cpp +++ b/tests/lbm/codegen/StreamInCellIntervalCodegenTest.cpp @@ -64,12 +64,12 @@ int main(int argc, char** argv) const std::shared_ptr< StructuredBlockForest > blockForest = blockforest::createUniformBlockGrid(numBlocks[0], numBlocks[1], numBlocks[2], // blocks cellsPerBlock[0], cellsPerBlock[1], cellsPerBlock[2], // cells - real_t(1.0), // dx + real_c(1.0), // dx true, // one block per process true, true, true); // periodicity // relaxation rate - real_t omega = real_t(1.8); + real_t omega = real_c(1.8); // create lattice model LatticeModel_T latticeModel = LatticeModel_T(omega); @@ -87,8 +87,8 @@ int main(int argc, char** argv) { PdfField_T* pdfField = blockIt->getData< PdfField_T >(pdfFieldID); - pdfField->setDensityAndVelocity(cell0, Vector3< real_t >(real_t(0.1), real_t(0.1), real_t(0.1)), real_t(1.1)); - pdfField->setDensityAndVelocity(cell1, Vector3< real_t >(real_t(-0.1), real_t(-0.1), real_t(-0.1)), real_t(0.9)); + pdfField->setDensityAndVelocity(cell0, Vector3< real_t >(real_c(0.1), real_c(0.1), real_c(0.1)), real_c(1.1)); + pdfField->setDensityAndVelocity(cell1, Vector3< real_t >(real_c(-0.1), real_c(-0.1), real_c(-0.1)), real_c(0.9)); } // create communication for PDF fields -- GitLab