diff --git a/Python/actuator_line/configActuatorLine.txt b/Python/actuator_line/configActuatorLine.txt
index 4b38bc41c1d5b510e7b262423fff861dc1a9c030..c45d170f039274ab355f3fe1dc044536f1f29e6f 100644
--- a/Python/actuator_line/configActuatorLine.txt
+++ b/Python/actuator_line/configActuatorLine.txt
@@ -32,7 +32,7 @@ QuadricLimiterD = 100000.0
 
 ##################################################
 readPrecursor = false
-nTimestepsReadPrecursor = 10
+nTimestepsReadPrecursor = 1
 precursorFile = precursor/Precursor
 
 ##################################################
diff --git a/pythonbindings/pyfluids-stubs/bindings/__init__.pyi b/pythonbindings/pyfluids-stubs/bindings/__init__.pyi
new file mode 100644
index 0000000000000000000000000000000000000000..f4bc6784201f9032af3193462b7681c7e58cdeab
--- /dev/null
+++ b/pythonbindings/pyfluids-stubs/bindings/__init__.pyi
@@ -0,0 +1,4 @@
+class ostream_redirect:
+    def __init__(self, stdout: bool = ..., stderr: bool = ...) -> None: ...
+    def __enter__(self) -> None: ...
+    def __exit__(self, *args) -> None: ...
diff --git a/pythonbindings/pyfluids-stubs/bindings/basics/__init__.pyi b/pythonbindings/pyfluids-stubs/bindings/basics/__init__.pyi
new file mode 100644
index 0000000000000000000000000000000000000000..60259efe05c3bd95ed899f4e46cf30c9fff5d118
--- /dev/null
+++ b/pythonbindings/pyfluids-stubs/bindings/basics/__init__.pyi
@@ -0,0 +1,48 @@
+from typing import ClassVar
+
+from typing import overload
+
+class ConfigurationFile:
+    def __init__(self) -> None: ...
+    def contains(self, key: str) -> bool: ...
+    @overload
+    def get_bool_value(self, key: str) -> bool: ...
+    @overload
+    def get_bool_value(self, key: str, default_value: bool) -> bool: ...
+    @overload
+    def get_double_value(self, key: str) -> float: ...
+    @overload
+    def get_double_value(self, key: str, default_value: float) -> float: ...
+    @overload
+    def get_float_value(self, key: str) -> float: ...
+    @overload
+    def get_float_value(self, key: str, default_value: float) -> float: ...
+    @overload
+    def get_int_value(self, key: str) -> int: ...
+    @overload
+    def get_int_value(self, key: str, default_value: int) -> int: ...
+    @overload
+    def get_string_value(self, key: str) -> str: ...
+    @overload
+    def get_string_value(self, key: str, default_value: str) -> str: ...
+    @overload
+    def get_uint_value(self, key: str) -> int: ...
+    @overload
+    def get_uint_value(self, key: str, default_value: int) -> int: ...
+    def load(self, file: str) -> bool: ...
+
+class LbmOrGks:
+    __members__: ClassVar[dict] = ...  # read-only
+    GKS: ClassVar[LbmOrGks] = ...
+    LBM: ClassVar[LbmOrGks] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
diff --git a/pythonbindings/pyfluids-stubs/bindings/basics/logger.pyi b/pythonbindings/pyfluids-stubs/bindings/basics/logger.pyi
new file mode 100644
index 0000000000000000000000000000000000000000..2f3d84f41cb895e2b5769240fe9c8b17214c8a09
--- /dev/null
+++ b/pythonbindings/pyfluids-stubs/bindings/basics/logger.pyi
@@ -0,0 +1,49 @@
+from typing import Any, ClassVar
+
+log: None
+
+class Level:
+    __members__: ClassVar[dict] = ...  # read-only
+    INFO_HIGH: ClassVar[Level] = ...
+    INFO_INTERMEDIATE: ClassVar[Level] = ...
+    INFO_LOW: ClassVar[Level] = ...
+    LOGGER_ERROR: ClassVar[Level] = ...
+    WARNING: ClassVar[Level] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class Logger:
+    def __init__(self, *args, **kwargs) -> None: ...
+    @staticmethod
+    def add_stdout() -> None: ...
+    @staticmethod
+    def enable_printed_rank_numbers() -> None: ...
+    @staticmethod
+    def set_debug_level(level: int) -> None: ...
+    @staticmethod
+    def time_stamp(time_stemp: TimeStamp) -> None: ...
+
+class TimeStamp:
+    __members__: ClassVar[dict] = ...  # read-only
+    DISABLE: ClassVar[TimeStamp] = ...
+    ENABLE: ClassVar[TimeStamp] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
diff --git a/pythonbindings/pyfluids-stubs/bindings/gpu/__init__.pyi b/pythonbindings/pyfluids-stubs/bindings/gpu/__init__.pyi
new file mode 100644
index 0000000000000000000000000000000000000000..947b2cd2705131cd16412e270a15b04c48c5e069
--- /dev/null
+++ b/pythonbindings/pyfluids-stubs/bindings/gpu/__init__.pyi
@@ -0,0 +1,402 @@
+from typing import Any, Callable, ClassVar, List, Optional
+
+from typing import overload
+import numpy
+import pyfluids.bindings.basics
+import pyfluids.bindings.gpu.grid_generator as grid_generator
+
+class ActuatorFarm(PreCollisionInteractor):
+    def __init__(self, number_of_blades_per_turbine: int, density: float, number_of_nodes_per_blade: int, epsilon: float, level: int, delta_t: float, delta_x: float, use_host_arrays: bool) -> None: ...
+    def add_turbine(self, posX: float, posY: float, posZ: float, diameter: float, omega: float, azimuth: float, yaw: float, bladeRadii: List[float]) -> None: ...
+    def calc_blade_forces(self) -> None: ...
+    def get_all_azimuths(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_coords_x(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_coords_x_device(self) -> int: ...
+    def get_all_blade_coords_y(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_coords_y_device(self) -> int: ...
+    def get_all_blade_coords_z(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_coords_z_device(self) -> int: ...
+    def get_all_blade_forces_x(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_forces_x_device(self) -> int: ...
+    def get_all_blade_forces_y(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_forces_y_device(self) -> int: ...
+    def get_all_blade_forces_z(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_forces_z_device(self) -> int: ...
+    def get_all_blade_radii(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_radii_device(self) -> int: ...
+    def get_all_blade_velocities_x(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_velocities_x_device(self) -> int: ...
+    def get_all_blade_velocities_y(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_velocities_y_device(self) -> int: ...
+    def get_all_blade_velocities_z(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_velocities_z_device(self) -> int: ...
+    def get_all_omegas(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_turbine_pos_x(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_turbine_pos_y(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_turbine_pos_z(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_yaws(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_azimuth(self, turbine: int) -> float: ...
+    def get_turbine_blade_coords_x(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_coords_x_device(self, turbine: int) -> int: ...
+    def get_turbine_blade_coords_y(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_coords_y_device(self, turbine: int) -> int: ...
+    def get_turbine_blade_coords_z(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_coords_z_device(self, turbine: int) -> int: ...
+    def get_turbine_blade_forces_x(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_forces_x_device(self, turbine: int) -> int: ...
+    def get_turbine_blade_forces_y(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_forces_y_device(self, turbine: int) -> int: ...
+    def get_turbine_blade_forces_z(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_forces_z_device(self, turbine: int) -> int: ...
+    def get_turbine_blade_radii(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_radii_device(self, turbine: int) -> int: ...
+    def get_turbine_blade_velocities_x(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_velocities_x_device(self, turbine: int) -> int: ...
+    def get_turbine_blade_velocities_y(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_velocities_y_device(self, turbine: int) -> int: ...
+    def get_turbine_blade_velocities_z(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_velocities_z_device(self, turbine: int) -> int: ...
+    def get_turbine_omega(self, turbine: int) -> float: ...
+    def get_turbine_pos(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_yaw(self, turbine: int) -> float: ...
+    def set_all_azimuths(self, azimuths: numpy.ndarray[numpy.float32]) -> None: ...
+    def set_all_blade_coords(self, blade_coords_x: numpy.ndarray[numpy.float32], blade_coords_y: numpy.ndarray[numpy.float32], blade_coords_z: numpy.ndarray[numpy.float32]) -> None: ...
+    def set_all_blade_forces(self, blade_forces_x: numpy.ndarray[numpy.float32], blade_forces_y: numpy.ndarray[numpy.float32], blade_forces_z: numpy.ndarray[numpy.float32]) -> None: ...
+    def set_all_blade_velocities(self, blade_velocities_x: numpy.ndarray[numpy.float32], blade_velocities_y: numpy.ndarray[numpy.float32], blade_velocities_z: numpy.ndarray[numpy.float32]) -> None: ...
+    def set_all_omegas(self, omegas: numpy.ndarray[numpy.float32]) -> None: ...
+    def set_all_yaws(self, yaws: numpy.ndarray[numpy.float32]) -> None: ...
+    def set_turbine_azimuth(self, turbine: int, azimuth: float) -> None: ...
+    def set_turbine_blade_coords(self, turbine: int, blade_coords_x: numpy.ndarray[numpy.float32], blade_coords_y: numpy.ndarray[numpy.float32], blade_coords_z: numpy.ndarray[numpy.float32]) -> None: ...
+    def set_turbine_blade_forces(self, turbine: int, blade_forces_x: numpy.ndarray[numpy.float32], blade_forces_y: numpy.ndarray[numpy.float32], blade_forces_z: numpy.ndarray[numpy.float32]) -> None: ...
+    def set_turbine_blade_velocities(self, turbine: int, blade_velocities_x: numpy.ndarray[numpy.float32], blade_velocities_y: numpy.ndarray[numpy.float32], blade_velocities_z: numpy.ndarray[numpy.float32]) -> None: ...
+    def set_turbine_omega(self, turbine: int, omega: float) -> None: ...
+    def set_turbine_yaw(self, turbine: int, yaw: float) -> None: ...
+    @property
+    def delta_t(self) -> float: ...
+    @property
+    def delta_x(self) -> float: ...
+    @property
+    def density(self) -> float: ...
+    @property
+    def number_of_blades_per_turbine(self) -> int: ...
+    @property
+    def number_of_indices(self) -> int: ...
+    @property
+    def number_of_nodes(self) -> int: ...
+    @property
+    def number_of_nodes_per_blade(self) -> int: ...
+    @property
+    def number_of_turbines(self) -> int: ...
+
+class BoundaryConditionFactory:
+    def __init__(self) -> None: ...
+    def set_geometry_boundary_condition(self, boundary_condition_type) -> None: ...
+    def set_no_slip_boundary_condition(self, boundary_condition_type) -> None: ...
+    def set_precursor_boundary_condition(self, boundary_condition_type) -> None: ...
+    def set_pressure_boundary_condition(self, boundary_condition_type) -> None: ...
+    def set_slip_boundary_condition(self, boundary_condition_type) -> None: ...
+    def set_stress_boundary_condition(self, boundary_condition_type) -> None: ...
+    def set_velocity_boundary_condition(self, boundary_condition_type) -> None: ...
+
+class Communicator:
+    def __init__(self, *args, **kwargs) -> None: ...
+    @staticmethod
+    def get_instance() -> Communicator: ...
+    def get_number_of_process(self) -> int: ...
+    def get_pid(self) -> int: ...
+
+class CudaMemoryManager:
+    def __init__(self, parameter: Parameter) -> None: ...
+
+class FileType:
+    __members__: ClassVar[dict] = ...  # read-only
+    VTK: ClassVar[FileType] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class GridProvider:
+    def __init__(self, *args, **kwargs) -> None: ...
+    @staticmethod
+    def make_grid_generator(builder: grid_generator.GridBuilder, para: Parameter, cuda_memory_manager: CudaMemoryManager, communicator: Communicator) -> GridProvider: ...
+
+class GridScaling:
+    __members__: ClassVar[dict] = ...  # read-only
+    NotSpecified: ClassVar[GridScaling] = ...
+    ScaleCompressible: ClassVar[GridScaling] = ...
+    ScaleRhoSq: ClassVar[GridScaling] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class GridScalingFactory:
+    def __init__(self) -> None: ...
+    def set_scaling_factory(self, scaling_type) -> None: ...
+
+class NoSlipBC:
+    __members__: ClassVar[dict] = ...  # read-only
+    NoSlip3rdMomentsCompressible: ClassVar[NoSlipBC] = ...
+    NoSlipBounceBack: ClassVar[NoSlipBC] = ...
+    NoSlipCompressible: ClassVar[NoSlipBC] = ...
+    NoSlipImplicitBounceBack: ClassVar[NoSlipBC] = ...
+    NoSlipIncompressible: ClassVar[NoSlipBC] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class OutputVariable:
+    __members__: ClassVar[dict] = ...  # read-only
+    Distributions: ClassVar[OutputVariable] = ...
+    Velocities: ClassVar[OutputVariable] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class Parameter:
+    @overload
+    def __init__(self, number_of_processes: int, my_ID: int, config_data: Optional[pyfluids.bindings.basics.ConfigurationFile]) -> None: ...
+    @overload
+    def __init__(self, number_of_processes: int, my_ID: int) -> None: ...
+    @overload
+    def __init__(self, config_data: pyfluids.bindings.basics.ConfigurationFile) -> None: ...
+    def add_actuator(self, actuator: PreCollisionInteractor) -> None: ...
+    def add_probe(self, probe: PreCollisionInteractor) -> None: ...
+    def get_SGS_constant(self) -> float: ...
+    def get_density_ratio(self) -> float: ...
+    def get_force_ratio(self) -> float: ...
+    def get_is_body_force(self) -> bool: ...
+    def get_output_path(self) -> str: ...
+    def get_output_prefix(self) -> str: ...
+    def get_velocity(self) -> float: ...
+    def get_velocity_ratio(self) -> float: ...
+    def get_viscosity(self) -> float: ...
+    def get_viscosity_ratio(self) -> float: ...
+    def set_AD_kernel(self, ad_kernel: str) -> None: ...
+    def set_calc_turbulence_intensity(self, calc_velocity_and_fluctuations: bool) -> None: ...
+    def set_comp_on(self, is_comp: bool) -> None: ...
+    def set_density_ratio(self, density_ratio: float) -> None: ...
+    def set_devices(self, devices: List[int]) -> None: ...
+    def set_diff_on(self, is_diff: bool) -> None: ...
+    def set_forcing(self, forcing_x: float, forcing_y: float, forcing_z: float) -> None: ...
+    def set_has_wall_model_monitor(self, has_wall_monitor: bool) -> None: ...
+    def set_initial_condition(self, init_func: Callable[[float,float,float],List[float]]) -> None: ...
+    def set_initial_condition_log_law(self, u_star: float, z0: float, velocity_ratio: float) -> None: ...
+    def set_initial_condition_perturbed_log_law(self, u_star: float, z0: float, length_x: float, length_z: float, height: float, velocity_ratio: float) -> None: ...
+    def set_initial_condition_uniform(self, velocity_x: float, velocity_y: float, velocity_z: float) -> None: ...
+    def set_is_body_force(self, is_body_force: bool) -> None: ...
+    def set_main_kernel(self, kernel: str) -> None: ...
+    def set_max_dev(self, max_dev: int) -> None: ...
+    def set_max_level(self, number_of_levels: int) -> None: ...
+    def set_outflow_pressure_correction_factor(self, correction_factor: float) -> None: ...
+    def set_output_path(self, o_path: str) -> None: ...
+    def set_output_prefix(self, o_prefix: str) -> None: ...
+    def set_print_files(self, print_files: bool) -> None: ...
+    def set_quadric_limiters(self, quadric_limiter_p: float, quadric_limiter_m: float, quadric_limiter_d: float) -> None: ...
+    def set_temperature_BC(self, temp_bc: float) -> None: ...
+    def set_temperature_init(self, temp: float) -> None: ...
+    def set_timestep_end(self, tend: int) -> None: ...
+    def set_timestep_of_coarse_level(self, timestep: int) -> None: ...
+    def set_timestep_out(self, tout: int) -> None: ...
+    def set_timestep_start_out(self, t_start_out: int) -> None: ...
+    def set_use_streams(self, use_streams: bool) -> None: ...
+    def set_velocity_LB(self, velocity: float) -> None: ...
+    def set_velocity_ratio(self, velocity_ratio: float) -> None: ...
+    def set_viscosity_LB(self, viscosity: float) -> None: ...
+    def set_viscosity_ratio(self, viscosity_ratio: float) -> None: ...
+
+class PreCollisionInteractor:
+    def __init__(self, *args, **kwargs) -> None: ...
+
+class PrecursorBC:
+    __members__: ClassVar[dict] = ...  # read-only
+    DistributionsPrecursor: ClassVar[PrecursorBC] = ...
+    NotSpecified: ClassVar[PrecursorBC] = ...
+    VelocityPrecursor: ClassVar[PrecursorBC] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class PrecursorWriter(PreCollisionInteractor):
+    def __init__(self, filename: str, output_path: str, x_pos: float, y_min: float, y_max: float, z_min: float, z_max: float, t_start_out: int, t_save: int, output_variable: OutputVariable, max_timesteps_per_file: int) -> None: ...
+
+class PressureBC:
+    __members__: ClassVar[dict] = ...  # read-only
+    NotSpecified: ClassVar[PressureBC] = ...
+    OutflowNonReflective: ClassVar[PressureBC] = ...
+    OutflowNonReflectivePressureCorrection: ClassVar[PressureBC] = ...
+    PressureEquilibrium: ClassVar[PressureBC] = ...
+    PressureEquilibrium2: ClassVar[PressureBC] = ...
+    PressureNonEquilibriumCompressible: ClassVar[PressureBC] = ...
+    PressureNonEquilibriumIncompressible: ClassVar[PressureBC] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class SideType:
+    __members__: ClassVar[dict] = ...  # read-only
+    GEOMETRY: ClassVar[SideType] = ...
+    MX: ClassVar[SideType] = ...
+    MY: ClassVar[SideType] = ...
+    MZ: ClassVar[SideType] = ...
+    PX: ClassVar[SideType] = ...
+    PY: ClassVar[SideType] = ...
+    PZ: ClassVar[SideType] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class Simulation:
+    @overload
+    def __init__(self, parameter: Parameter, memoryManager: CudaMemoryManager, communicator, gridProvider: GridProvider, bcFactory: BoundaryConditionFactory, gridScalingFactory: GridScalingFactory) -> None: ...
+    @overload
+    def __init__(self, parameter: Parameter, memoryManager: CudaMemoryManager, communicator, gridProvider: GridProvider, bcFactory: BoundaryConditionFactory) -> None: ...
+    @overload
+    def __init__(self, parameter: Parameter, memoryManager: CudaMemoryManager, communicator, gridProvider: GridProvider, bcFactory: BoundaryConditionFactory, tmFactory: TurbulenceModelFactory, gridScalingFactory: GridScalingFactory) -> None: ...
+    def addEnstrophyAnalyzer(self, t_analyse: int) -> None: ...
+    def addKineticEnergyAnalyzer(self, t_analyse: int) -> None: ...
+    def run(self) -> None: ...
+
+class SlipBC:
+    __members__: ClassVar[dict] = ...  # read-only
+    NotSpecified: ClassVar[SlipBC] = ...
+    SlipBounceBack: ClassVar[SlipBC] = ...
+    SlipCompressible: ClassVar[SlipBC] = ...
+    SlipCompressibleTurbulentViscosity: ClassVar[SlipBC] = ...
+    SlipIncompressible: ClassVar[SlipBC] = ...
+    SlipPressureCompressibleTurbulentViscosity: ClassVar[SlipBC] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class StressBC:
+    __members__: ClassVar[dict] = ...  # read-only
+    NotSpecified: ClassVar[StressBC] = ...
+    StressBounceBack: ClassVar[StressBC] = ...
+    StressCompressible: ClassVar[StressBC] = ...
+    StressPressureBounceBack: ClassVar[StressBC] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class TurbulenceModel:
+    __members__: ClassVar[dict] = ...  # read-only
+    AMD: ClassVar[TurbulenceModel] = ...
+    NONE: ClassVar[TurbulenceModel] = ...
+    QR: ClassVar[TurbulenceModel] = ...
+    Smagorinsky: ClassVar[TurbulenceModel] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class TurbulenceModelFactory:
+    def __init__(self, para: Parameter) -> None: ...
+    def read_config_file(self, config_data: pyfluids.bindings.basics.ConfigurationFile) -> None: ...
+    def set_model_constant(self, model_constant: float) -> None: ...
+    def set_turbulence_model(self, turbulence_model: TurbulenceModel) -> None: ...
+
+class VTKFileCollection(VelocityFileCollection):
+    def __init__(self, prefix: str) -> None: ...
+
+class VelocityBC:
+    __members__: ClassVar[dict] = ...  # read-only
+    NotSpecified: ClassVar[VelocityBC] = ...
+    VelocityAndPressureCompressible: ClassVar[VelocityBC] = ...
+    VelocityCompressible: ClassVar[VelocityBC] = ...
+    VelocityIncompressible: ClassVar[VelocityBC] = ...
+    VelocitySimpleBounceBackCompressible: ClassVar[VelocityBC] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class VelocityFileCollection:
+    def __init__(self, *args, **kwargs) -> None: ...
+
+def create_file_collection(prefix: str, type: FileType) -> VelocityFileCollection: ...
diff --git a/pythonbindings/pyfluids-stubs/bindings/gpu/grid_generator.pyi b/pythonbindings/pyfluids-stubs/bindings/gpu/grid_generator.pyi
new file mode 100644
index 0000000000000000000000000000000000000000..cf0329015b296b6f009a2fb0000afd799dd87363
--- /dev/null
+++ b/pythonbindings/pyfluids-stubs/bindings/gpu/grid_generator.pyi
@@ -0,0 +1,66 @@
+from typing import Any, List
+
+from typing import overload
+import pyfluids.bindings.basics
+import pyfluids.bindings.gpu
+
+class BoundingBox:
+    def __init__(self, min_x: float, max_x: float, min_y: float, max_y: float, min_z: float, max_z: float) -> None: ...
+
+class Conglomerate(Object):
+    def __init__(self, *args, **kwargs) -> None: ...
+    def add(self, object: Object) -> None: ...
+    @staticmethod
+    def make_shared() -> Conglomerate: ...
+    def subtract(self, object: Object) -> None: ...
+
+class Cuboid(Object):
+    def __init__(self, min_x1: float, min_x2: float, min_x3: float, max_x1: float, max_x2: float, max_x3: float) -> None: ...
+
+class GridBuilder:
+    def __init__(self, *args, **kwargs) -> None: ...
+    def get_number_of_grid_levels(self) -> int: ...
+
+class GridFactory:
+    def __init__(self, *args, **kwargs) -> None: ...
+    @staticmethod
+    def make() -> GridFactory: ...
+
+class LevelGridBuilder(GridBuilder):
+    def __init__(self, *args, **kwargs) -> None: ...
+    def set_no_slip_boundary_condition(self, side_type: pyfluids.bindings.gpu.SideType) -> None: ...
+    def set_periodic_boundary_condition(self, periodic_x: bool, periodic_y: bool, periodic_z: bool) -> None: ...
+    def set_precursor_boundary_condition(self, side_type: pyfluids.bindings.gpu.SideType, file_collection: pyfluids.bindings.gpu.VelocityFileCollection, n_t_read: int, velocity_x: float = ..., velocity_y: float = ..., velocity_z: float = ..., file_level_to_grid_level_map: List[int] = ...) -> None: ...
+    def set_pressure_boundary_condition(self, side_type: pyfluids.bindings.gpu.SideType, rho: float) -> None: ...
+    def set_slip_boundary_condition(self, side_type: pyfluids.bindings.gpu.SideType, normal_x: float, normal_y: float, normal_z: float) -> None: ...
+    def set_stress_boundary_condition(self, side_type: pyfluids.bindings.gpu.SideType, normal_x: float, normal_y: float, normal_z: float, sampling_offset: int, z0: float, dx: float) -> None: ...
+    def set_velocity_boundary_condition(self, side_type: pyfluids.bindings.gpu.SideType, vx: float, vy: float, vz: float) -> None: ...
+
+class MultipleGridBuilder(LevelGridBuilder):
+    def __init__(self, *args, **kwargs) -> None: ...
+    def add_coarse_grid(self, start_x: float, start_y: float, start_z: float, end_x: float, end_y: float, end_z: float, delta: float) -> None: ...
+    @overload
+    def add_geometry(self, solid_object: Object) -> None: ...
+    @overload
+    def add_geometry(self, solid_object: Object, level: int) -> None: ...
+    @overload
+    def add_grid(self, grid_shape: Object) -> None: ...
+    @overload
+    def add_grid(self, grid_shape: Object, level_fine: int) -> None: ...
+    def build_grids(self, lbm_or_gks: pyfluids.bindings.basics.LbmOrGks, enable_thin_walls: bool) -> None: ...
+    def get_number_of_levels(self) -> int: ...
+    @staticmethod
+    def make_shared(grid_factory: GridFactory) -> MultipleGridBuilder: ...
+
+class Object:
+    def __init__(self, *args, **kwargs) -> None: ...
+
+class Sphere(Object):
+    def __init__(self, *args, **kwargs) -> None: ...
+    @staticmethod
+    def make_shared() -> Sphere: ...
+
+class TriangularMesh(Object):
+    def __init__(self, *args, **kwargs) -> None: ...
+    @staticmethod
+    def make() -> TriangularMesh: ...
diff --git a/pythonbindings/pyfluids-stubs/bindings/gpu/probes.pyi b/pythonbindings/pyfluids-stubs/bindings/gpu/probes.pyi
new file mode 100644
index 0000000000000000000000000000000000000000..a844bc9c5be78f3fca4d04540a7998b8b7386233
--- /dev/null
+++ b/pythonbindings/pyfluids-stubs/bindings/gpu/probes.pyi
@@ -0,0 +1,51 @@
+from typing import ClassVar, List
+
+import pyfluids.bindings.gpu
+
+class PlanarAverageProbe(Probe):
+    def __init__(self, probe_name: str, output_path: str, t_start_avg: int, t_start_tmp_avg: int, t_avg: int, t_start_out: int, t_out: int, plane_normal: str) -> None: ...
+
+class PlaneProbe(Probe):
+    def __init__(self, probe_name: str, output_path: str, t_start_avg: int, t_avg: int, t_start_out: int, t_out: int) -> None: ...
+    def set_probe_plane(self, pos_x: float, pos_y: float, pos_z: float, delta_x: float, delta_y: float, delta_z: float) -> None: ...
+
+class PointProbe(Probe):
+    def __init__(self, probe_name: str, output_path: str, t_start_avg: int, t_avg: int, t_start_out: int, t_out: int, output_timeseries: bool) -> None: ...
+    def add_probe_points_from_list(self, point_coords_x: List[float], point_coords_y: List[float], point_coords_z: List[float]) -> None: ...
+    def add_probe_points_from_x_normal_plane(self, pos_x: float, pos0_y: float, pos0_z: float, pos1_y: float, pos1_z: float, n_y: int, n_z: int) -> None: ...
+
+class Probe(pyfluids.bindings.gpu.PreCollisionInteractor):
+    def __init__(self, *args, **kwargs) -> None: ...
+    def add_all_available_statistics(self) -> None: ...
+    def add_statistic(self, variable: Statistic) -> None: ...
+    def set_file_name_to_n_out(self) -> None: ...
+
+class Statistic:
+    __members__: ClassVar[dict] = ...  # read-only
+    Instantaneous: ClassVar[Statistic] = ...
+    Means: ClassVar[Statistic] = ...
+    SpatialCovariances: ClassVar[Statistic] = ...
+    SpatialFlatness: ClassVar[Statistic] = ...
+    SpatialMeans: ClassVar[Statistic] = ...
+    SpatialSkewness: ClassVar[Statistic] = ...
+    SpatioTemporalCovariances: ClassVar[Statistic] = ...
+    SpatioTemporalFlatness: ClassVar[Statistic] = ...
+    SpatioTemporalMeans: ClassVar[Statistic] = ...
+    SpatioTemporalSkewness: ClassVar[Statistic] = ...
+    Variances: ClassVar[Statistic] = ...
+    __entries: ClassVar[dict] = ...
+    def __init__(self, arg0: int) -> None: ...
+    def __eq__(self, arg0: object) -> bool: ...
+    def __getstate__(self) -> int: ...
+    def __hash__(self) -> int: ...
+    def __index__(self) -> int: ...
+    def __int__(self) -> int: ...
+    def __ne__(self, arg0: object) -> bool: ...
+    def __setstate__(self, arg0: int) -> None: ...
+    @property
+    def name(self) -> str: ...
+
+class WallModelProbe(Probe):
+    def __init__(self, probe_name: str, output_path: str, t_start_avg: int, t_start_tmp_avg: int, t_avg: int, t_start_out: int, t_out: int) -> None: ...
+    def set_evaluate_pressure_gradient(self, eval_press_grad: bool) -> None: ...
+    def set_force_output_to_stress(self, output_stress: bool) -> None: ...
diff --git a/pythonbindings/pyfluids-stubs/bindings/lbm.pyi b/pythonbindings/pyfluids-stubs/bindings/lbm.pyi
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/pythonbindings/pyfluids-stubs/bindings/logger.pyi b/pythonbindings/pyfluids-stubs/bindings/logger.pyi
new file mode 100644
index 0000000000000000000000000000000000000000..3c1f4b59bbb3eb0df259e2f54da8d4571c971e22
--- /dev/null
+++ b/pythonbindings/pyfluids-stubs/bindings/logger.pyi
@@ -0,0 +1,10 @@
+class Logger:
+    def __init__(self, *args, **kwargs) -> None: ...
+    def change_log_path(self) -> None: ...
+    def initialize_logger(self) -> None: ...
+
+def vf_log_critical(message: str) -> None: ...
+def vf_log_debug(message: str) -> None: ...
+def vf_log_info(message: str) -> None: ...
+def vf_log_trace(message: str) -> None: ...
+def vf_log_warning(message: str) -> None: ...