From 973942790e12e43b467c8e87da112fffd53f4380 Mon Sep 17 00:00:00 2001
From: Frederik Hennig <frederik.hennig@fau.de>
Date: Wed, 5 Mar 2025 13:53:23 +0100
Subject: [PATCH] adapt to latest walberla and pystencils-sfg revisions

---
 CMakeLists.txt                                | 11 +--
 cmake/codegen-requirements.txt                |  4 +-
 src/sfg_walberla/api.py                       | 75 ++++++++++---------
 src/sfg_walberla/boundaries/freeslip.py       |  8 +-
 src/sfg_walberla/boundaries/hbb.py            |  5 +-
 src/sfg_walberla/reflection.py                |  9 +--
 src/sfg_walberla/sweep.py                     | 43 +++++------
 tests/FreeSlip/CMakeLists.txt                 |  2 +-
 .../ForceDrivenChannel/CMakeLists.txt         |  2 +-
 .../examples/FreeSlipBubble/CMakeLists.txt    |  2 +-
 .../examples/SparseSpiral/CMakeLists.txt      |  2 +-
 11 files changed, 79 insertions(+), 84 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f9e7057..5a7a53f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,19 +7,20 @@ list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake )
 
 include( PrepareSFG )
 
-add_library( sfg_walberla INTERFACE )
+add_library( walberla_codegen INTERFACE )
+add_library( walberla::codegen ALIAS walberla_codegen )
 
-target_sources( sfg_walberla
+target_sources( walberla_codegen
     INTERFACE
     include/sfg/SparseIteration.hpp
     include/sfg/GenericHbbBoundary.hpp
     include/sfg/IrregularFreeSlip.hpp
 )
 
-target_include_directories( sfg_walberla INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include )
+target_include_directories( walberla_codegen INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include )
 
 target_link_libraries(
-    sfg_walberla
+    walberla_codegen
     INTERFACE
-    core stencil domain_decomposition blockforest field
+    walberla::core walberla::stencil walberla::domain_decomposition walberla::blockforest walberla::field
 )
diff --git a/cmake/codegen-requirements.txt b/cmake/codegen-requirements.txt
index 70dd9bb..d123706 100644
--- a/cmake/codegen-requirements.txt
+++ b/cmake/codegen-requirements.txt
@@ -4,5 +4,5 @@ git+https://i10git.cs.fau.de/pycodegen/pystencils.git@v2.0-dev
 # lbmpy: feature branch for pystencils-2.0 compatibility
 git+https://i10git.cs.fau.de/pycodegen/lbmpy.git@fhennig/pystencils2.0-compat
 
-# pystencils-sfg: (development branch with updated CMake modules and cpptypes)
-git+https://i10git.cs.fau.de/pycodegen/pystencils-sfg.git@e467692fe48479ba2867d7a2e753e6be7dea4132
+# pystencils-sfg: latest supported revision
+git+https://i10git.cs.fau.de/pycodegen/pystencils-sfg.git@8949bedba3a8704dff520580202fc273fb0202de
diff --git a/src/sfg_walberla/api.py b/src/sfg_walberla/api.py
index 207c433..0120b23 100644
--- a/src/sfg_walberla/api.py
+++ b/src/sfg_walberla/api.py
@@ -12,10 +12,9 @@ from pystencils.types import (
     PsStructType,
 )
 from pystencilssfg.lang import (
-    IFieldExtraction,
     AugExpr,
-    SrcField,
-    SrcVector,
+    SupportsFieldExtraction,
+    SupportsVectorExtraction,
     Ref,
     ExprLike,
     cpptype,
@@ -38,7 +37,7 @@ class _PlainCppClass(AugExpr):
         super().__init__(dtype)
 
 
-class Vector2(SrcVector):
+class Vector2(AugExpr, SupportsVectorExtraction):
     _template = cpptype("walberla::Vector2< {element_type} >", "core/math/Vector2.h")
 
     def __init__(
@@ -48,14 +47,14 @@ class Vector2(SrcVector):
         dtype = self._template(element_type=element_type, const=const, ref=ref)
         super().__init__(dtype)
 
-    def extract_component(self, coordinate: int) -> AugExpr:
+    def _extract_component(self, coordinate: int) -> AugExpr:
         if coordinate > 1:
             raise ValueError(f"Cannot extract component {coordinate} from Vector2")
 
         return AugExpr(self._element_type).bind("{}[{}]", self, coordinate)
 
 
-class Vector3(SrcVector):
+class Vector3(AugExpr, SupportsVectorExtraction):
     _template = cpptype("walberla::Vector3< {element_type} >", "core/math/Vector3.h")
 
     def __init__(
@@ -65,7 +64,7 @@ class Vector3(SrcVector):
         dtype = self._template(element_type=element_type, const=const, ref=ref)
         super().__init__(dtype)
 
-    def extract_component(self, coordinate: int) -> AugExpr:
+    def _extract_component(self, coordinate: int) -> AugExpr:
         if coordinate > 2:
             raise ValueError(f"Cannot extract component {coordinate} from Vector3")
 
@@ -184,7 +183,7 @@ class StructuredBlockForest(AugExpr):
         return AugExpr(uint_t).bind("{}.getLevel({})", self, block)
 
 
-class GenericWalberlaField(SrcField):
+class GenericWalberlaField(AugExpr, SupportsFieldExtraction):
     """Common base class for GhostLayerField and GpuField defining their shared interface."""
 
     def __init__(
@@ -209,6 +208,8 @@ class GenericWalberlaField(SrcField):
 
         super().__init__(obj_type)
 
+        self._extraction = GhostLayerFieldExtraction(self, None)
+
     @property
     def _a(self) -> AugExpr:
         """Member access"""
@@ -221,10 +222,16 @@ class GenericWalberlaField(SrcField):
     def field_type(self) -> PsCustomType:
         return self._field_type
 
-    def get_extraction(self) -> IFieldExtraction:
-        return GhostLayerFieldExtraction(self, None)
+    def _extract_ptr(self) -> AugExpr:
+        return self._extraction._extract_ptr()
+
+    def _extract_size(self, coordinate: int) -> AugExpr | None:
+        return self._extraction._extract_size(coordinate)
 
-    def with_cell_interval(self, ci: CellInterval | None):
+    def _extract_stride(self, coordinate: int) -> AugExpr | None:
+        return self._extraction._extract_stride(coordinate)
+
+    def with_cell_interval(self, ci: CellInterval | None) -> GhostLayerFieldExtraction:
         return GhostLayerFieldExtraction(self, ci)
 
     def cloneUninitialized(self) -> AugExpr:
@@ -292,7 +299,7 @@ class GpuFieldPtr(GenericWalberlaField):
         super().__init__(element_type, field_type, ptr=True)
 
 
-class GhostLayerFieldExtraction(IFieldExtraction):
+class GhostLayerFieldExtraction(SupportsFieldExtraction):
     def __init__(
         self,
         field_ptr: AugExpr,
@@ -301,7 +308,7 @@ class GhostLayerFieldExtraction(IFieldExtraction):
         self._field_ptr = field_ptr
         self._ci = cell_interval
 
-    def ptr(self) -> AugExpr:
+    def _extract_ptr(self) -> AugExpr:
         data_at: AugExpr | str
         if self._ci is not None:
             ci = self._ci
@@ -311,7 +318,7 @@ class GhostLayerFieldExtraction(IFieldExtraction):
 
         return AugExpr.format("{}->dataAt({})", self._field_ptr, data_at)
 
-    def size(self, coordinate: int) -> AugExpr | None:
+    def _extract_size(self, coordinate: int) -> AugExpr | None:
         size_call = ["xSize()", "ySize()", "zSize()", "fSize()"][coordinate]
 
         if self._ci is not None and coordinate < 3:
@@ -319,7 +326,7 @@ class GhostLayerFieldExtraction(IFieldExtraction):
         else:
             return AugExpr.format("{}->{}", self._field_ptr, size_call)
 
-    def stride(self, coordinate: int) -> AugExpr | None:
+    def _extract_stride(self, coordinate: int) -> AugExpr | None:
         stride_call = ("xStride()", "yStride()", "zStride()", "fStride()")[coordinate]
         return AugExpr.format("{}->{}", self._field_ptr, stride_call)
 
@@ -352,7 +359,7 @@ class SparseIndexList(AugExpr):
         return BlockDataID().bind("{}.bufferId()", self)
 
 
-class IndexListBufferPtr(SrcField):
+class IndexListBufferPtr(AugExpr, SupportsFieldExtraction):
     _template = cpptype(
         "walberla::sfg::internal::IndexListBuffer< {IndexStruct} >",
         "sfg/SparseIteration.hpp",
@@ -374,26 +381,22 @@ class IndexListBufferPtr(SrcField):
     def vector(self) -> AugExpr:
         return AugExpr().format("{}->vector()", self)
 
-    def get_extraction(self) -> IFieldExtraction:
-        class IdxVectorExtraction(IFieldExtraction):
-            def ptr(_) -> AugExpr:
-                return self.pointerCpu()
-
-            def size(_, coordinate: int) -> AugExpr | None:
-                if coordinate == 0:
-                    return AugExpr.format("{}.size()", self.vector())
-                elif coordinate == 1:
-                    return AugExpr.format("1")
-                else:
-                    raise ValueError()
-
-            def stride(_, coordinate: int) -> AugExpr | None:
-                if coordinate <= 1:
-                    return AugExpr.format("1")
-                else:
-                    raise ValueError()
-
-        return IdxVectorExtraction()
+    def _extract_ptr(self) -> AugExpr:
+        return self.pointerCpu()
+
+    def _extract_size(self, coordinate: int) -> AugExpr | None:
+        if coordinate == 0:
+            return AugExpr.format("{}.size()", self.vector())
+        elif coordinate == 1:
+            return AugExpr.format("1")
+        else:
+            raise ValueError()
+
+    def _extract_stride(self, coordinate: int) -> AugExpr | None:
+        if coordinate <= 1:
+            return AugExpr.format("1")
+        else:
+            raise ValueError()
 
 
 CellIdx = PsStructType(
diff --git a/src/sfg_walberla/boundaries/freeslip.py b/src/sfg_walberla/boundaries/freeslip.py
index 863d49e..cfdc946 100644
--- a/src/sfg_walberla/boundaries/freeslip.py
+++ b/src/sfg_walberla/boundaries/freeslip.py
@@ -91,9 +91,11 @@ class FreeSlip(CustomGenerator):
             sfg.private(
                 sfg.method(
                     "irregularFromIndexVector",
-                    returns=sweep_type.get_dtype(),
-                    inline=True,
-                )(sfg.expr("return {};", sweep_type.ctor(**sweep_ctor_args))),
+                )
+                .returns(sweep_type.get_dtype())
+                .inline()(
+                    sfg.expr("return {};", sweep_type.ctor(**sweep_ctor_args))
+                ),
             ),
         )
 
diff --git a/src/sfg_walberla/boundaries/hbb.py b/src/sfg_walberla/boundaries/hbb.py
index d041f1b..bce5c1d 100644
--- a/src/sfg_walberla/boundaries/hbb.py
+++ b/src/sfg_walberla/boundaries/hbb.py
@@ -1,15 +1,12 @@
 """Code generation for half-way bounce-back LBM boundary conditions in waLBerla"""
 
-from pystencils import Field, FieldType, TypedSymbol, Target, AssignmentCollection, DynamicType
-
-from pystencils.types import PsStructType, create_type
+from pystencils import Field, FieldType, TypedSymbol, Target, AssignmentCollection
 
 from pystencilssfg import SfgComposer
 from pystencilssfg.composer.class_composer import SfgClassComposer
 from pystencilssfg.composer.custom import CustomGenerator
 from pystencilssfg.lang import AugExpr
 
-from lbmpy import LBStencil
 from lbmpy.methods import AbstractLbMethod
 from lbmpy.boundaries.boundaryconditions import LbBoundary
 from lbmpy.advanced_streaming.indexing import Timestep
diff --git a/src/sfg_walberla/reflection.py b/src/sfg_walberla/reflection.py
index 13e422d..1b8d202 100644
--- a/src/sfg_walberla/reflection.py
+++ b/src/sfg_walberla/reflection.py
@@ -5,14 +5,9 @@ from pystencilssfg.ir import SfgClass
 
 class GeneratedClassWrapperBase(CppClass):
     _class: SfgClass
-    _namespace: str | None
 
     def __init_subclass__(cls) -> None:
-        typename = (
-            f"{cls._namespace}::{cls._class.class_name}"
-            if cls._namespace is not None
-            else cls._class.class_name
-        )
+        typename = cls._class.fqname
         cls.template = cpptype(typename)
 
     def ctor(self, **kwargs) -> AugExpr:
@@ -22,7 +17,7 @@ class GeneratedClassWrapperBase(CppClass):
                 break
         else:
             raise Exception(
-                f"No constructor of class {self._class.class_name} matches the argument names {kwargs.keys()}"
+                f"No constructor of class {self._class.fqname} matches the argument names {kwargs.keys()}"
             )
 
         ctor_args = [kwargs[name] for name in ctor_argnames]
diff --git a/src/sfg_walberla/sweep.py b/src/sfg_walberla/sweep.py
index a79d133..07d037d 100644
--- a/src/sfg_walberla/sweep.py
+++ b/src/sfg_walberla/sweep.py
@@ -28,10 +28,9 @@ from pystencilssfg.lang import (
     SfgVar,
     AugExpr,
     Ref,
-    SrcVector,
     strip_ptr_ref,
+    SupportsVectorExtraction,
 )
-from pystencilssfg.lang.types import CppTypeFactory, cpptype
 from .reflection import GeneratedClassWrapperBase
 from .api import (
     StructuredBlockForest,
@@ -74,22 +73,19 @@ class SweepClassProperties:
 
             if self.getter:
                 methods.append(
-                    sfg.method(
-                        f"{self.name}",
-                        returns=Ref(constify(self.dtype)),
-                        const=True,
-                        inline=True,
-                    )(f"return {self.name}_;")
+                    sfg.method(f"{self.name}")
+                    .returns(Ref(constify(self.dtype)))
+                    .const()
+                    .inline()(f"return {self.name}_;")
                 )
 
             if self.setter:
                 methods.append(
-                    sfg.method(
-                        f"{self.name}",
-                        returns=Ref(self.dtype),
-                        const=False,
-                        inline=True,
-                    )(f"return {self.name}_;")
+                    sfg.method(f"{self.name}")
+                    .returns(Ref(self.dtype))
+                    .inline()(
+                        f"return {self.name}_;"
+                    )
                 )
 
             return methods
@@ -325,11 +321,9 @@ class ShadowFieldCache:
             cache_ptrs.append(sfg.var(cache_ptr_name, unique_ptr_type))
 
             getters.append(
-                sfg.method(
-                    self._getter(orig_name),
-                    returns=orig.wlb_field_ptr.get_dtype(),
-                    inline=True,
-                )(
+                sfg.method(self._getter(orig_name))
+                .returns(orig.wlb_field_ptr.get_dtype())
+                .inline()(
                     sfg.branch(f"{cache_ptr_name} == nullptr")(
                         AugExpr.format(
                             "{}.reset({});",
@@ -350,7 +344,9 @@ class ShadowFieldCache:
         return f"shadow_{str(orig)}_"
 
 
-def combine_vectors(scalars: set[SfgVar]) -> dict[SrcVector, tuple[SfgVar, ...]]:
+def combine_vectors(
+    scalars: set[SfgVar],
+) -> dict[SupportsVectorExtraction, tuple[SfgVar, ...]]:
     """Attempt to combine vector component symbols into vectors.
 
     This function modifies the `scalars` parameter in-place by removing grouped scalar
@@ -367,7 +363,7 @@ def combine_vectors(scalars: set[SfgVar]) -> dict[SrcVector, tuple[SfgVar, ...]]
         except ValueError:
             pass
 
-    all_vectors: dict[SrcVector, tuple[SfgVar, ...]] = dict()
+    all_vectors: dict[SupportsVectorExtraction, tuple[SfgVar, ...]] = dict()
 
     for name, entries in potential_vectors.items():
         entries = sorted(entries, key=lambda t: t[0])
@@ -618,12 +614,13 @@ class Sweep(CustomGenerator):
             *shadows_cache.render(sfg),
         )
 
-        gen_class = sfg.context.get_class(self._name)
+        gen_class = sfg._cursor.get_entity(self._name)
         assert gen_class is not None
+        from pystencilssfg.ir.entities import SfgClass
+        assert isinstance(gen_class, SfgClass)
 
         class GenClassWrapper(GeneratedClassWrapperBase):
             _class = gen_class
-            _namespace = sfg.context.fully_qualified_namespace
 
         self._generated_class = GenClassWrapper
 
diff --git a/tests/FreeSlip/CMakeLists.txt b/tests/FreeSlip/CMakeLists.txt
index e47cae2..8401480 100644
--- a/tests/FreeSlip/CMakeLists.txt
+++ b/tests/FreeSlip/CMakeLists.txt
@@ -1,6 +1,6 @@
 add_executable( TestIrregularFreeSlip TestIrregularFreeSlip.cpp )
 walberla_generate_sources( TestIrregularFreeSlip SCRIPTS IrregularFreeSlip.py )
-target_link_libraries( TestIrregularFreeSlip core blockforest field geometry sfg_walberla )
+target_link_libraries( TestIrregularFreeSlip PRIVATE walberla::core walberla::blockforest walberla::field walberla::geometry walberla::codegen )
 add_test( NAME TestIrregularFreeSlip COMMAND TestIrregularFreeSlip )
 
 add_dependencies( SfgTests TestIrregularFreeSlip )
diff --git a/user_manual/examples/ForceDrivenChannel/CMakeLists.txt b/user_manual/examples/ForceDrivenChannel/CMakeLists.txt
index 3e21d3e..dc8b929 100644
--- a/user_manual/examples/ForceDrivenChannel/CMakeLists.txt
+++ b/user_manual/examples/ForceDrivenChannel/CMakeLists.txt
@@ -10,5 +10,5 @@ walberla_generate_sources( Ex_ForceDrivenChannel
 target_link_libraries(
     Ex_ForceDrivenChannel
     PRIVATE 
-    core stencil blockforest geometry vtk sfg_walberla 
+    walberla::core walberla::stencil walberla::blockforest walberla::geometry walberla::vtk walberla::codegen 
 )
diff --git a/user_manual/examples/FreeSlipBubble/CMakeLists.txt b/user_manual/examples/FreeSlipBubble/CMakeLists.txt
index cd3e7af..a47e511 100644
--- a/user_manual/examples/FreeSlipBubble/CMakeLists.txt
+++ b/user_manual/examples/FreeSlipBubble/CMakeLists.txt
@@ -3,4 +3,4 @@ walberla_link_files_to_builddir( *.prm )
 add_executable( FreeSlipBubble FreeSlipBubble.cpp )
 
 walberla_generate_sources( FreeSlipBubble SCRIPTS LbmAlgorithms.py )
-target_link_libraries( FreeSlipBubble core blockforest field geometry stencil sfg_walberla )
+target_link_libraries( FreeSlipBubble walberla::core walberla::blockforest walberla::field walberla::geometry walberla::stencil walberla::codegen )
diff --git a/user_manual/examples/SparseSpiral/CMakeLists.txt b/user_manual/examples/SparseSpiral/CMakeLists.txt
index 6ec9191..d973f8a 100644
--- a/user_manual/examples/SparseSpiral/CMakeLists.txt
+++ b/user_manual/examples/SparseSpiral/CMakeLists.txt
@@ -1,5 +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 )
+target_link_libraries( SparseSpiral PRIVATE walberla::core walberla::blockforest walberla::field walberla::vtk walberla::codegen )
 
-- 
GitLab