From 7a97e8468757bd6b29f149d77f20d5ce888616ff Mon Sep 17 00:00:00 2001 From: Frederik Hennig <frederik.hennig@fau.de> Date: Tue, 21 Jan 2025 17:18:17 +0100 Subject: [PATCH] update user manual --- .../{IndexVectors.hpp => SparseIteration.hpp} | 0 src/sfg_walberla/api.py | 2 +- tests/CMakeLists.txt | 2 -- tests/SparseIteration/CMakeLists.txt | 6 ---- user_manual/CMakeLists.txt | 3 +- .../AdvectionDiffusionSweep.py | 8 ----- user_manual/FullyPeriodicAde/CMakeLists.txt | 0 user_manual/Makefile | 3 +- user_manual/conf.py | 2 +- user_manual/examples.mk | 2 +- user_manual/examples/CMakeLists.txt | 3 ++ .../ForceDrivenChannel/CMakeLists.txt | 0 .../ForceDrivenChannel/Channel.prm | 0 .../ForceDrivenChannel/ForceDrivenChannel.cpp | 0 .../ForceDrivenChannel/ForceDrivenChannel.md | 0 .../ForceDrivenChannel/LbmAlgorithms.py | 0 .../GeneratorScriptBasics/BasicCodegen.py | 0 .../GeneratorScriptBasics/BasicCodegenApp.cpp | 0 .../GeneratorScriptBasics/CMakeLists.txt | 0 .../GeneratorScriptBasics.md | 0 .../examples/SparseSpiral/CMakeLists.txt | 5 +++ .../examples/SparseSpiral/SparseSpiral.cpp | 36 ++++++++++++------- .../examples/SparseSpiral/SpiralSweep.py | 4 +-- user_manual/guides/SparseSweeps.md | 34 ++++++++++++++++++ user_manual/index.md | 31 ++++++++-------- user_manual/reference/PythonEnvironment.md | 21 ++++++----- 26 files changed, 99 insertions(+), 63 deletions(-) rename include/sfg/{IndexVectors.hpp => SparseIteration.hpp} (100%) delete mode 100644 tests/SparseIteration/CMakeLists.txt delete mode 100644 user_manual/FullyPeriodicAde/AdvectionDiffusionSweep.py delete mode 100644 user_manual/FullyPeriodicAde/CMakeLists.txt create mode 100644 user_manual/examples/CMakeLists.txt rename user_manual/{ => examples}/ForceDrivenChannel/CMakeLists.txt (100%) rename user_manual/{ => examples}/ForceDrivenChannel/Channel.prm (100%) rename user_manual/{ => examples}/ForceDrivenChannel/ForceDrivenChannel.cpp (100%) rename user_manual/{ => examples}/ForceDrivenChannel/ForceDrivenChannel.md (100%) rename user_manual/{ => examples}/ForceDrivenChannel/LbmAlgorithms.py (100%) rename user_manual/{ => examples}/GeneratorScriptBasics/BasicCodegen.py (100%) rename user_manual/{ => examples}/GeneratorScriptBasics/BasicCodegenApp.cpp (100%) rename user_manual/{ => examples}/GeneratorScriptBasics/CMakeLists.txt (100%) rename user_manual/{ => examples}/GeneratorScriptBasics/GeneratorScriptBasics.md (100%) create mode 100644 user_manual/examples/SparseSpiral/CMakeLists.txt rename tests/SparseIteration/TestSparseSweeps.cpp => user_manual/examples/SparseSpiral/SparseSpiral.cpp (67%) rename tests/SparseIteration/SparseSweep.py => user_manual/examples/SparseSpiral/SpiralSweep.py (82%) create mode 100644 user_manual/guides/SparseSweeps.md diff --git a/include/sfg/IndexVectors.hpp b/include/sfg/SparseIteration.hpp similarity index 100% rename from include/sfg/IndexVectors.hpp rename to include/sfg/SparseIteration.hpp diff --git a/src/sfg_walberla/api.py b/src/sfg_walberla/api.py index b6a1aeb..0be30b8 100644 --- a/src/sfg_walberla/api.py +++ b/src/sfg_walberla/api.py @@ -305,7 +305,7 @@ def glfield(field: Field, ci: str | AugExpr | None = None): class IndexListBufferPtr(SrcField): _template = cpptype( - "walberla::sfg::internal::IndexListBuffer< {IndexStruct} >", "sfg/IndexVectors.hpp" + "walberla::sfg::internal::IndexListBuffer< {IndexStruct} >", "sfg/SparseIteration.hpp" ) def __init__(self, idx_struct: PsStructType): diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b75a729..59a075a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -15,5 +15,3 @@ add_subdirectory(${CMAKE_SOURCE_DIR}/.. ${CMAKE_BINARY_DIR}/sfg-walberla) # Test Directories include(CTest) - -add_subdirectory( SparseIteration ) diff --git a/tests/SparseIteration/CMakeLists.txt b/tests/SparseIteration/CMakeLists.txt deleted file mode 100644 index 23666fa..0000000 --- a/tests/SparseIteration/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ - -add_executable( TestSparseSweeps TestSparseSweeps.cpp ) -walberla_generate_sources( TestSparseSweeps SCRIPTS SparseSweep.py ) -target_link_libraries( TestSparseSweeps PRIVATE core blockforest field sfg_walberla ) - -add_test( NAME TestSparseSweeps COMMAND TestSparseSweeps ) diff --git a/user_manual/CMakeLists.txt b/user_manual/CMakeLists.txt index 59c36c2..fa52a83 100644 --- a/user_manual/CMakeLists.txt +++ b/user_manual/CMakeLists.txt @@ -13,5 +13,4 @@ FetchContent_MakeAvailable(walberla) add_subdirectory(${CMAKE_SOURCE_DIR}/.. ${CMAKE_BINARY_DIR}/sfg-walberla) -add_subdirectory( GeneratorScriptBasics ) -add_subdirectory( ForceDrivenChannel ) +add_subdirectory( examples ) diff --git a/user_manual/FullyPeriodicAde/AdvectionDiffusionSweep.py b/user_manual/FullyPeriodicAde/AdvectionDiffusionSweep.py deleted file mode 100644 index 876da3b..0000000 --- a/user_manual/FullyPeriodicAde/AdvectionDiffusionSweep.py +++ /dev/null @@ -1,8 +0,0 @@ -from pystencilssfg import SourceFileGenerator - -from sfg_walberla import Sweep -from sfg_walberla.symbolic import cell - - -with SourceFileGenerator() as sfg: - pass diff --git a/user_manual/FullyPeriodicAde/CMakeLists.txt b/user_manual/FullyPeriodicAde/CMakeLists.txt deleted file mode 100644 index e69de29..0000000 diff --git a/user_manual/Makefile b/user_manual/Makefile index d931dfa..a25a0fb 100644 --- a/user_manual/Makefile +++ b/user_manual/Makefile @@ -9,6 +9,7 @@ SOURCEDIR = . BUILDDIR = _sphinx_build ZIPPED_EXAMPLES := zipped-examples +EXAMPLES_DIR := examples include examples.mk @@ -33,7 +34,7 @@ clean: ZipExamples: $(foreach example, $(EXAMPLES), $(ZIPPED_EXAMPLES)/$(example).zip) -$(ZIPPED_EXAMPLES)/%.zip: %/* +$(ZIPPED_EXAMPLES)/%.zip: $(EXAMPLES_DIR)/%/* @$(dir_guard) @echo Zipping $(<D) @zip -r $@ $(<D) diff --git a/user_manual/conf.py b/user_manual/conf.py index cfa54f3..01a1b95 100644 --- a/user_manual/conf.py +++ b/user_manual/conf.py @@ -6,7 +6,7 @@ # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information -project = 'waLBerla next-codegen' +project = 'sfg-waLBerla' copyright = '2024, Frederik Hennig' author = 'Frederik Hennig' diff --git a/user_manual/examples.mk b/user_manual/examples.mk index 2d78f20..4ab97ae 100644 --- a/user_manual/examples.mk +++ b/user_manual/examples.mk @@ -1 +1 @@ -EXAMPLES = GeneratorScriptBasics ForceDrivenChannel +EXAMPLES = GeneratorScriptBasics SparseSpiral ForceDrivenChannel diff --git a/user_manual/examples/CMakeLists.txt b/user_manual/examples/CMakeLists.txt new file mode 100644 index 0000000..b141992 --- /dev/null +++ b/user_manual/examples/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory( GeneratorScriptBasics ) +add_subdirectory( ForceDrivenChannel ) +add_subdirectory( SparseSpiral ) \ No newline at end of file diff --git a/user_manual/ForceDrivenChannel/CMakeLists.txt b/user_manual/examples/ForceDrivenChannel/CMakeLists.txt similarity index 100% rename from user_manual/ForceDrivenChannel/CMakeLists.txt rename to user_manual/examples/ForceDrivenChannel/CMakeLists.txt diff --git a/user_manual/ForceDrivenChannel/Channel.prm b/user_manual/examples/ForceDrivenChannel/Channel.prm similarity index 100% rename from user_manual/ForceDrivenChannel/Channel.prm rename to user_manual/examples/ForceDrivenChannel/Channel.prm diff --git a/user_manual/ForceDrivenChannel/ForceDrivenChannel.cpp b/user_manual/examples/ForceDrivenChannel/ForceDrivenChannel.cpp similarity index 100% rename from user_manual/ForceDrivenChannel/ForceDrivenChannel.cpp rename to user_manual/examples/ForceDrivenChannel/ForceDrivenChannel.cpp diff --git a/user_manual/ForceDrivenChannel/ForceDrivenChannel.md b/user_manual/examples/ForceDrivenChannel/ForceDrivenChannel.md similarity index 100% rename from user_manual/ForceDrivenChannel/ForceDrivenChannel.md rename to user_manual/examples/ForceDrivenChannel/ForceDrivenChannel.md diff --git a/user_manual/ForceDrivenChannel/LbmAlgorithms.py b/user_manual/examples/ForceDrivenChannel/LbmAlgorithms.py similarity index 100% rename from user_manual/ForceDrivenChannel/LbmAlgorithms.py rename to user_manual/examples/ForceDrivenChannel/LbmAlgorithms.py diff --git a/user_manual/GeneratorScriptBasics/BasicCodegen.py b/user_manual/examples/GeneratorScriptBasics/BasicCodegen.py similarity index 100% rename from user_manual/GeneratorScriptBasics/BasicCodegen.py rename to user_manual/examples/GeneratorScriptBasics/BasicCodegen.py diff --git a/user_manual/GeneratorScriptBasics/BasicCodegenApp.cpp b/user_manual/examples/GeneratorScriptBasics/BasicCodegenApp.cpp similarity index 100% rename from user_manual/GeneratorScriptBasics/BasicCodegenApp.cpp rename to user_manual/examples/GeneratorScriptBasics/BasicCodegenApp.cpp diff --git a/user_manual/GeneratorScriptBasics/CMakeLists.txt b/user_manual/examples/GeneratorScriptBasics/CMakeLists.txt similarity index 100% rename from user_manual/GeneratorScriptBasics/CMakeLists.txt rename to user_manual/examples/GeneratorScriptBasics/CMakeLists.txt diff --git a/user_manual/GeneratorScriptBasics/GeneratorScriptBasics.md b/user_manual/examples/GeneratorScriptBasics/GeneratorScriptBasics.md similarity index 100% rename from user_manual/GeneratorScriptBasics/GeneratorScriptBasics.md rename to user_manual/examples/GeneratorScriptBasics/GeneratorScriptBasics.md diff --git a/user_manual/examples/SparseSpiral/CMakeLists.txt b/user_manual/examples/SparseSpiral/CMakeLists.txt new file mode 100644 index 0000000..6ec9191 --- /dev/null +++ b/user_manual/examples/SparseSpiral/CMakeLists.txt @@ -0,0 +1,5 @@ + +add_executable( SparseSpiral SparseSpiral.cpp ) +walberla_generate_sources( SparseSpiral SCRIPTS SpiralSweep.py ) +target_link_libraries( SparseSpiral PRIVATE core blockforest field vtk sfg_walberla ) + diff --git a/tests/SparseIteration/TestSparseSweeps.cpp b/user_manual/examples/SparseSpiral/SparseSpiral.cpp similarity index 67% rename from tests/SparseIteration/TestSparseSweeps.cpp rename to user_manual/examples/SparseSpiral/SparseSpiral.cpp index 272930b..f2b469b 100644 --- a/tests/SparseIteration/TestSparseSweeps.cpp +++ b/user_manual/examples/SparseSpiral/SparseSpiral.cpp @@ -2,13 +2,14 @@ #include "blockforest/all.h" #include "field/GhostLayerField.h" #include "field/AddToStorage.h" -#include "sfg/IndexVectors.hpp" +#include "field/vtk/all.h" +#include "sfg/SparseIteration.hpp" #include <array> -#include "gen/TestSparseSweeps/SparseSweep.hpp" +#include "gen/SparseSpiral/SparseSweep.hpp" -namespace TestSparseSweeps +namespace SparseSpiral { using namespace walberla; @@ -17,16 +18,22 @@ namespace TestSparseSweeps using PointField = field::GhostLayerField<real_t, 3>; + constexpr real_t radius { 15.0 }; + constexpr Vector3< real_t > center { 20, 20, 0 }; + constexpr real_t height { 120. }; + constexpr real_t width { 4.0 }; + Vector3<real_t> pointOnSpiral(real_t z) { - real_t two_pi_z{2.0 * math::pi * z}; - return Vector3<real_t>{cos(two_pi_z), sin(two_pi_z), z}; + real_t t{4.0 * math::pi * z / height}; + return center + Vector3<real_t>{radius * cos(t), radius * sin(t), z}; } void main(int argc, char **argv) { + Environment env{ argc, argv }; - AABB domainAabb{0., 0., 0., 40., 40., 120.}; + AABB domainAabb{0., 0., 0., 40., 40., height }; array<uint_t, 3> gridSize{4, 4, 12}; array<uint_t, 3> cpb{10, 10, 10}; @@ -42,18 +49,18 @@ namespace TestSparseSweeps { Vector3<real_t> globalPoint{blocks->getCellCenter(globalCell)}; Vector3<real_t> spiralPoint{pointOnSpiral(globalPoint[2])}; - return (globalPoint - spiralPoint).sqrLength() < 2.0; + return (globalPoint - spiralPoint).sqrLength() < width; }; CellInterval allCells{{0, 0, 0}, {cell_idx_c(cpb[0]), cell_idx_c(cpb[1]), cell_idx_c(cpb[2])}}; for (auto &b : *blocks) { - vector<sfg::CellIdx> idxVec{indexList.get(b)}; + vector<sfg::CellIdx> & idxVec{indexList.get(b)}; for (Cell c : allCells) { Cell globalCell{c}; - blocks->transformBlockLocalToGlobalCell(c, b); + blocks->transformBlockLocalToGlobalCell(globalCell, b); if (isOnSpiral(globalCell)) { idxVec.emplace_back(c); @@ -61,7 +68,7 @@ namespace TestSparseSweeps } } - gen::SparseSetCoordinates sweep{blocks, fID, indexList.bufferId()}; + gen::SpiralSweep sweep{blocks, fID, indexList.bufferId()}; for (auto &b : *blocks) { @@ -74,7 +81,7 @@ namespace TestSparseSweeps for (Cell c : allCells) { Cell globalCell{c}; - blocks->transformBlockLocalToGlobalCell(c, b); + blocks->transformBlockLocalToGlobalCell(globalCell, b); if (isOnSpiral(c)) { Vector3< real_t > cellCenter { blocks->getCellCenter(globalCell) }; @@ -84,11 +91,14 @@ namespace TestSparseSweeps } } } + + auto vtkWriter = field::createVTKOutput< PointField >(fID, *blocks, "f", 1, 0); + vtkWriter(); } } int main(int argc, char **argv) { - TestSparseSweeps::main(argc, argv); + SparseSpiral::main(argc, argv); return 0; -} \ No newline at end of file +} diff --git a/tests/SparseIteration/SparseSweep.py b/user_manual/examples/SparseSpiral/SpiralSweep.py similarity index 82% rename from tests/SparseIteration/SparseSweep.py rename to user_manual/examples/SparseSpiral/SpiralSweep.py index 4489d3b..f9808a5 100644 --- a/tests/SparseIteration/SparseSweep.py +++ b/user_manual/examples/SparseSpiral/SpiralSweep.py @@ -4,7 +4,7 @@ from sfg_walberla.symbolic import cell from pystencils import fields, Assignment with SourceFileGenerator() as sfg: - sfg.namespace("TestSparseSweeps::gen") + sfg.namespace("SparseSpiral::gen") f = fields("f(3): [3D]", layout="fzyx") asms = [ @@ -13,7 +13,7 @@ with SourceFileGenerator() as sfg: Assignment(f.center(2), cell.z()), ] - sweep = Sweep("SparseSetCoordinates", asms) + sweep = Sweep("SpiralSweep", asms) sweep.sparse = True sfg.generate(sweep) diff --git a/user_manual/guides/SparseSweeps.md b/user_manual/guides/SparseSweeps.md new file mode 100644 index 0000000..03fea2e --- /dev/null +++ b/user_manual/guides/SparseSweeps.md @@ -0,0 +1,34 @@ +# Sparse Sweeps + +:::{admonition} Example Code +The code shown in this guide is taken from the *SparseSpiral* example: +{download}`SparseSpiral.zip </zipped-examples/SparseSpiral.zip>` +::: + + +`sfg-walberla` supports the generation of sparse sweeps, which operate only on a subset of cells +defined by a user-provided *index list*. + +To turn your sweep into a sparse sweep, simply set its `sparse` property to `True`. +To illustrate, here's a sparse sweep that stores the coordinates of each cell +in a field: + +```{literalinclude} ../examples/SparseSpiral/SpiralSweep.py +:caption: SpiralSweep.py +:lines: 10-17 +:dedent: 4 +``` + +In your C++ code, you must set up an index list which lists all cells the sweep should operate on. +Due to waLBerla's block-structured nature, the index list will actually be a collection of cell vectors, +with one vector per block. +The SFG library provides `sfg::SparseIndexList` for this, which is defined in `sfg/SparseIteration.hpp`. +The following code sample create and populate an index list, using a prediate here called `isOnSpiral`. +The index list's internal block data ID must then be passed to the sweep's constructor. + +:::{literalinclude} ../examples/SparseSpiral/SparseSpiral.cpp +:caption: SparseSpiral.cpp +:lines: 46,56-72 +:dedent: 8 +:language: C++ +::: diff --git a/user_manual/index.md b/user_manual/index.md index 473b4f1..a48e3fe 100644 --- a/user_manual/index.md +++ b/user_manual/index.md @@ -1,19 +1,13 @@ # The Next Generation of waLBerla Code Generation -Welcome to *The Next Generation of waLBerla Code Generation*. -This book is aimed at teaching you how to use the next generation of code generators for waLBerla -by walking through a set of example applications, each designed to highlight specific features. - -The next-gen code generators for waLBerla are based on bleeding-edge developments in -[pystencils 2.0][pystencils_2_0] and [pystencils-sfg][pystencils-sfg], -and are currently located in the separate [sfg-walberla][sfg-walberla] repository. +Welcome to the `sfg-walberla` project, +where the next generation of code generators for waLBerla is being developed. +These are based on bleeding-edge developments in +[pystencils 2.0][pystencils_2_0] and [pystencils-sfg][pystencils-sfg]. This project is still unstable and immature, but growing steadily. -Until the next-gen code generators are stabilized and merged with the waLBerla master, -setting up a build system and development environment for working with them is slightly more -complicated. Since you will need such an environment to follow along with the examples -in this book, start by reading the chapter [](EnvSetup). -Afterward, you are free to explore the remainder of the book. +In this user manual, you will find guidance and information about how to use the new +code generation infrastructure in your simulation applications. ## Table of Contents @@ -22,14 +16,21 @@ Afterward, you are free to explore the remainder of the book. :maxdepth: 1 CMakeSetup/CMakeSetup -GeneratorScriptBasics/GeneratorScriptBasics +examples/GeneratorScriptBasics/GeneratorScriptBasics +::: + +:::{toctree} +:caption: User Guides +:maxdepth: 1 + +guides/SparseSweeps ::: :::{toctree} -:caption: Basic LBM Simulations +:caption: Examples :maxdepth: 1 -ForceDrivenChannel/ForceDrivenChannel +examples/ForceDrivenChannel/ForceDrivenChannel ::: :::{toctree} diff --git a/user_manual/reference/PythonEnvironment.md b/user_manual/reference/PythonEnvironment.md index 298d83a..df15308 100644 --- a/user_manual/reference/PythonEnvironment.md +++ b/user_manual/reference/PythonEnvironment.md @@ -5,9 +5,9 @@ used by the waLBerla code generation system. ## Using the Private Virtual Environment -If the CMake cache variable `WALBERLA_CODEGEN_PRIVATE_VENV` is enabled, -`sfg-walberla` creates a new Python virtual environment within the CMake build tree, +By default, `sfg-walberla` creates a new Python virtual environment within the CMake build tree, and there installs all packages required for code generation. +This can be disabled by setting the `WALBERLA_CODEGEN_PRIVATE_VENV` CMake cache variable to `FALSE`. ### Install Additional Packages @@ -26,14 +26,13 @@ editable install, or `-r <requirements-file>` to install packages from a require ## Using an External Virtual Environment -To have even more control over your Python environment, you can configure sfg-walberla to -forego creating a private virtual environment, and instead use the Python interpreter -supplied from the outside. +If `WALBERLA_CODEGEN_PRIVATE_VENV` is set to `FALSE`, sfg-walberla will use the Python interpreter +found in the CMake environment for running the code generators. +You can customize your Python interpreter by setting the `Python_EXECUTABLE` or `Python_ROOT_DIR` hints. -To explicitly specify a Python interpreter, you need to set the `WALBERLA_CODEGEN_PRIVATE_VENV` cache -variable to `FALSE`, and set `Python_EXECUTABLE` to point at your Python binary. -For instance, at configuration time: +:::{seealso} +[FindPython CMake Module](https://cmake.org/cmake/help/latest/module/FindPython.html) +::: -```bash -cmake -S . -B build -DWALBERLA_CODEGEN_PRIVATE_VENV=FALSE -DPython_EXECUTABLE=<path-to-python> -``` +Sfg-walberla will check if the required packages are installed into the given external Python environment, +and raise an error if any are missing. -- GitLab