From c0549d71b2109f10c1238db8b22362e7826ba61b Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Sun, 5 Jul 2026 15:59:23 +0200 Subject: Just rename from lib to modules --- modules/core/tests/SConscript | 32 +++++ modules/core/tests/chunk.cpp | 47 +++++++ modules/core/tests/collision.cpp | 6 + modules/core/tests/converter.cpp | 26 ++++ modules/core/tests/descriptor.cpp | 39 +++++ modules/core/tests/equilibrium.cpp | 41 ++++++ modules/core/tests/flatten.cpp | 22 +++ modules/core/tests/iterator.cpp | 72 ++++++++++ modules/core/tests/math.cpp | 79 +++++++++++ modules/core/tests/memory.cpp | 58 ++++++++ modules/core/tests/particles.cpp | 281 +++++++++++++++++++++++++++++++++++++ modules/core/tests/vtk_write.cpp | 93 ++++++++++++ 12 files changed, 796 insertions(+) create mode 100644 modules/core/tests/SConscript create mode 100644 modules/core/tests/chunk.cpp create mode 100644 modules/core/tests/collision.cpp create mode 100644 modules/core/tests/converter.cpp create mode 100644 modules/core/tests/descriptor.cpp create mode 100644 modules/core/tests/equilibrium.cpp create mode 100644 modules/core/tests/flatten.cpp create mode 100644 modules/core/tests/iterator.cpp create mode 100644 modules/core/tests/math.cpp create mode 100644 modules/core/tests/memory.cpp create mode 100644 modules/core/tests/particles.cpp create mode 100644 modules/core/tests/vtk_write.cpp (limited to 'modules/core/tests') diff --git a/modules/core/tests/SConscript b/modules/core/tests/SConscript new file mode 100644 index 0000000..d1b381e --- /dev/null +++ b/modules/core/tests/SConscript @@ -0,0 +1,32 @@ +#!/bin/false + +import os +import os.path +import glob + + +Import('env') + +dir_path = Dir('.').abspath + +# Environment for base library +test_cases_env = env.Clone(); + +test_cases_env.Append(LIBS=['forstio-test']); + +test_cases_env.sources = sorted(glob.glob(dir_path + "/*.cpp")) +test_cases_env.headers = sorted(glob.glob(dir_path + "/*.hpp")) + +env.sources += test_cases_env.sources; +env.headers += test_cases_env.headers; + +objects_static = [] +test_cases_env.add_source_files(objects_static, test_cases_env.sources, shared=False); +test_cases_env.program = test_cases_env.Program('#bin/tests', [objects_static]); +# , env.library_static]); + +# Set Alias +env.Alias('test', test_cases_env.program); +env.Alias('check', test_cases_env.program); + +env.targets += ['test','check']; diff --git a/modules/core/tests/chunk.cpp b/modules/core/tests/chunk.cpp new file mode 100644 index 0000000..008d4c6 --- /dev/null +++ b/modules/core/tests/chunk.cpp @@ -0,0 +1,47 @@ +#include + +#include "../c++/chunk.hpp" + +namespace { +namespace sch { +using namespace saw::schema; +} + +SAW_TEST("Chunk Ghost size 0"){ + using namespace kel; + + using TestChunk = lbm::sch::Chunk; + using TestArray = sch::FixedArray; + + SAW_EXPECT((std::is_same_v), "Types are not identical"); +} + +SAW_TEST("Chunk Ghost size 1"){ + using namespace kel; + + using TestChunk = lbm::sch::Chunk; + using TestArray = sch::FixedArray; + + SAW_EXPECT((std::is_same_v), "Types are not identical"); +} + +SAW_TEST("Chunk Ghost size 3"){ + using namespace kel; + + using TestChunk = lbm::sch::Chunk; + using TestArray = sch::FixedArray; + + SAW_EXPECT((std::is_same_v), "Types are not identical"); +} + +SAW_TEST("Chunk 2D setup"){ + using namespace kel; + + using TestChunk = lbm::sch::Chunk; + + auto chunk = saw::heap>(); + chunk->at({{0u,0u}}).set(1.0f); + SAW_EXPECT((chunk->ghost_at({{1u,1u}}).get() == 1.0f),"Check if ghost is at shifted spot."); +} + +} diff --git a/modules/core/tests/collision.cpp b/modules/core/tests/collision.cpp new file mode 100644 index 0000000..cd53336 --- /dev/null +++ b/modules/core/tests/collision.cpp @@ -0,0 +1,6 @@ +#include + +#include "../c++/collision.hpp" + +namespace { +} diff --git a/modules/core/tests/converter.cpp b/modules/core/tests/converter.cpp new file mode 100644 index 0000000..4fc536f --- /dev/null +++ b/modules/core/tests/converter.cpp @@ -0,0 +1,26 @@ +#include + +#include "../c++/converter.hpp" + + +namespace { +namespace sch { +using namespace kel::lbm::sch; + +using T = Float64; +} + +SAW_TEST("Si Meter to Lbm Meter"){ + using namespace kel; + + lbm::converter converter{ + {0.1}, + {0.1} + }; + + saw::data> si_m{1.0}; + + auto lbm_m = converter.meter_si_to_lbm(si_m); + SAW_EXPECT(lbm_m.handle().get() == 10.0, "Correct si to lbm conversion"); +} +} diff --git a/modules/core/tests/descriptor.cpp b/modules/core/tests/descriptor.cpp new file mode 100644 index 0000000..7f743ce --- /dev/null +++ b/modules/core/tests/descriptor.cpp @@ -0,0 +1,39 @@ +#include + +#include "../c++/descriptor.hpp" + + +namespace { +template +void check_opposite_dirs(){ + using namespace kel; + + using dfi = lbm::df_info; + + for(uint64_t k = 0u; k < Descriptor::Q; ++k){ + auto k_inv = dfi::opposite_index[k]; + + for(uint64_t i = 0u; i < Descriptor::D; ++i){ + SAW_EXPECT(dfi::directions[k][i] == (-1*dfi::directions[k_inv][i]), "Opposites are inconsistent"); + } + } +} + +SAW_TEST("Opposites and Dirs D1Q3"){ + using namespace kel; + check_opposite_dirs>(); +} + +SAW_TEST("Opposites and Dirs D2Q5"){ + using namespace kel; + check_opposite_dirs>(); +} +SAW_TEST("Opposites and Dirs D2Q9"){ + using namespace kel; + check_opposite_dirs>(); +} +SAW_TEST("Opposites and Dirs D3Q27"){ + using namespace kel; + check_opposite_dirs>(); +} +} diff --git a/modules/core/tests/equilibrium.cpp b/modules/core/tests/equilibrium.cpp new file mode 100644 index 0000000..20a1f08 --- /dev/null +++ b/modules/core/tests/equilibrium.cpp @@ -0,0 +1,41 @@ +#include + +#include "../c++/equilibrium.hpp" + + +namespace { + +template +void check_equilibrium(){ + using namespace kel; + + using dfi = lbm::df_info; + + saw::data> rho; + rho.at({}).set(1.0); + saw::data> vel; + for(saw::data i{0u}; i.get() < Descriptor::D; ++i){ + vel.at({{i}}) = {0.0}; + } + auto eq = lbm::equilibrium(rho,vel); + + for(saw::data i{0u}; i.get() < Descriptor::Q; ++i){ + SAW_EXPECT(eq.at(i).get() == dfi::weights[i.get()], std::string{"No velocity and normalized rho should be exactly the weights: "} + std::to_string(eq.at(i).get()) + std::string{" "} + std::to_string(dfi::weights[i.get()])); + } +} + +SAW_TEST("Equilibrium at rest D1Q3"){ + using namespace kel; + check_equilibrium>(); +} + +SAW_TEST("Equilibrium at rest D2Q5"){ + using namespace kel; + check_equilibrium>(); +} + +SAW_TEST("Equilibrium at rest D2Q9"){ + using namespace kel; + check_equilibrium>(); +} +} diff --git a/modules/core/tests/flatten.cpp b/modules/core/tests/flatten.cpp new file mode 100644 index 0000000..84b3fa4 --- /dev/null +++ b/modules/core/tests/flatten.cpp @@ -0,0 +1,22 @@ +#include + +#include "../c++/flatten.hpp" + +namespace { +namespace sch { +using namespace saw::schema; +} + +SAW_TEST("Flatten Index Stride"){ + using namespace kel; + + constexpr saw::data zero = lbm::flatten_index::stride<0u>({{2u,4u,3u}}); + constexpr saw::data one = lbm::flatten_index::stride<1u>({{2u,4u,3u}}); + constexpr saw::data two = lbm::flatten_index::stride<2u>({{2u,4u,3u}}); + + SAW_EXPECT(zero.get() == 1u, "Zero is correct"); + SAW_EXPECT(one.get() == 2u, "Zero is correct"); + SAW_EXPECT(two.get() == 8u, "Zero is correct"); +} + +} diff --git a/modules/core/tests/iterator.cpp b/modules/core/tests/iterator.cpp new file mode 100644 index 0000000..919c12c --- /dev/null +++ b/modules/core/tests/iterator.cpp @@ -0,0 +1,72 @@ +#include + +#include "../c++/iterator.hpp" + +#include + +namespace { +namespace sch { +using namespace kel::lbm::sch; +} + +SAW_TEST("Old Iterate"){ + using namespace kel; + + saw::data> start{{0u,0u}}; + saw::data> end{{3u,3u}}; + + lbm::iterate_over([](const saw::data>& index){ + std::cout<<"Index: "< + > tup; + + lbm::ct_tuple_iterator::Schema>::apply([](auto& val) -> saw::error_or { + return saw::make_void(); + },tup); +} + +SAW_TEST("Old Iterate with Distance 1"){ + using namespace kel; + + saw::data> start{{0u,0u}}; + saw::data> end{{4u,4u}}; + + lbm::iterate_over([](const saw::data>& index){ + std::cout<<"Index: "<> start{{0u,0u}}; + saw::data> end{{3u,3u}}; + + lbm::iterator<2u>::apply([](const saw::data>& index){ + std::cout<<"Index: "<> start{{0u,0u}}; + saw::data> end{{4u,4u}}; + + lbm::iterator<2u>::apply([](const saw::data>& index){ + std::cout<<"Index: "< + +#include +#include "../c++/math/n_linear.hpp" + +namespace { +namespace sch { +using namespace saw::schema; +} + +SAW_TEST("Math 1-Linear"){ + using namespace kel; + + saw::data,2u>> field; + { + field.at({{0u}}).at({{0u}}).set(-1.0); + field.at({{1u}}).at({{0u}}).set(2.0); + } + saw::data> pos; + pos.at({{0u}}).set(0.3); +} + +SAW_TEST("Math/Floor Index and Fraction from Position"){ + using namespace kel; + + saw::data> pos; + + { + pos.at({{0u}}) = 43.999; + pos.at({{1u}}) = -50.0; + } + + auto ind_frac = lbm::position_to_index_and_fraction(pos); + auto& ind = ind_frac.template get<0u>(); + for(uint64_t i = 0u; i < 2u; ++i){ + std::cout<(); + for(uint64_t i = 0u; i < 2u; ++i){ + std::cout<> pos; + + { + pos.at({{0u}}) = 43.999; + pos.at({{1u}}) = -50.0; + } + + saw::data> bound; + { + bound.at({{0u}}) = 32u; + bound.at({{1u}}) = 16u; + } + + auto ind_frac = lbm::position_to_index_and_fraction_bounded(pos,bound); + auto& ind = ind_frac.template get<0u>(); + for(uint64_t i = 0u; i < 2u; ++i){ + std::cout<(); + for(uint64_t i = 0u; i < 2u; ++i){ + std::cout< + +#include "../c++/memory.hpp" + +namespace { +namespace sch { +using namespace saw::schema; + +using TStruct = Struct< + Member, + Member, + Member +>; + +using TChunk = kel::lbm::sch::Chunk; +using TBChunk = kel::lbm::sch::Chunk; + +using TChunkStruct = Struct< + Member, + Member +>; +} + +SAW_TEST("Memory Estimate"){ + using namespace kel::lbm; + + SAW_EXPECT((memory_estimate().get() == 4u), "Float32 isn't 4 bytes" ); + SAW_EXPECT((memory_estimate>().get() == 60u), "FixedArray isn't 60 bytes"); + SAW_EXPECT((memory_estimate, sch::UInt8>().get() == 61u), "FixedArray + UInt8 isn't 61 bytes"); +} + +SAW_TEST("Memory Estimate Struct"){ + using namespace kel::lbm; + + SAW_EXPECT((memory_estimate().get() == 13u), "TStruct isn't 13 bytes" ); + // SAW_EXPECT((memory_estimate().get() == 13u), "TStruct isn't 13 bytes" ); +} + +SAW_TEST("Memory Estimate Scalar"){ + using namespace kel::lbm; + + SAW_EXPECT((memory_estimate>().get() == 1u), "Scalar of UInt8 isn't 1 bytes" ); + // SAW_EXPECT((memory_estimate().get() == 13u), "TStruct isn't 13 bytes" ); +} + +SAW_TEST("Memory Estimate Chunk"){ + using namespace kel::lbm; + + SAW_EXPECT((memory_estimate().get() == 480u), std::string{"TChunk isn't 480 bytes, but is "} + std::to_string(memory_estimate().get()) ); +} + +SAW_TEST("Memory Estimate Struct of Chunk"){ + using namespace kel::lbm; + + SAW_EXPECT((memory_estimate().get() == 960u), std::string{"TChunkStruct isn't 960 bytes, but is "} + std::to_string(memory_estimate().get()) ); +} + +} diff --git a/modules/core/tests/particles.cpp b/modules/core/tests/particles.cpp new file mode 100644 index 0000000..133c343 --- /dev/null +++ b/modules/core/tests/particles.cpp @@ -0,0 +1,281 @@ +#include + +#include +#include "../c++/particle/particle.hpp" + +namespace { +namespace sch { +using namespace kel::lbm::sch; + +using T = Float64; +} +SAW_TEST("Verlet step 2D - Planar"){ + using namespace kel; + + saw::data> particle; + auto& body = particle.template get<"rigid_body">(); + auto& pos = body.template get<"position">(); + auto& pos_old = body.template get<"position_old">(); + + // auto& rot = body.template get<"rotation">(); + auto& acc = body.template get<"acceleration">(); + + acc.at({{0}}).set({1.0}); + + saw::data> dt; + dt.at({}).set(0.5); + lbm::verlet_step_lambda(particle,dt); + + SAW_EXPECT(pos.at({{0}}).get() == 0.25, std::string{"Incorrect Pos X: "} + std::to_string(pos.at({{0}}).get())); + SAW_EXPECT(pos.at({{1}}).get() == 0.0, std::string{"Incorrect Pos Y: "} + std::to_string(pos.at({{1}}).get())); +} +/* +SAW_TEST("No Collision Spheroid 2D"){ + using namespace kel; + + saw::data> part_a; + { + auto& body = part_a.template get<"rigid_body">(); + auto& pos = body.template get<"position">(); + + pos.at({{0u}}) = 0.1; + pos.at({{1u}}) = 0.2; + + } + saw::data> part_b; + { + auto& body = part_b.template get<"rigid_body">(); + auto& pos = body.template get<"position">(); + + pos.at({{0u}}) = -2.1; + pos.at({{1u}}) = 0.0; + } + + bool have_collided = lbm::broadphase_collision_check(part_a,part_b); + SAW_EXPECT(not have_collided, "Particles shouldn't collide"); +} +*/ +/* +SAW_TEST("Collision Spheroid 2D"){ + using namespace kel; + + saw::data> part_a; + { + auto& body = part_a.template get<"rigid_body">(); + auto& pos = body.template get<"position">(); + auto& coll = part_a.template get<"collision">(); + auto& radius = coll.template get<"radius">(); + + radius.at({}).set(1.0); + + pos.at({{0u}}) = 0.1; + pos.at({{1u}}) = 0.2; + + } + saw::data> part_b; + { + auto& body = part_b.template get<"rigid_body">(); + auto& pos = body.template get<"position">(); + auto& coll = part_b.template get<"collision">(); + auto& radius = coll.template get<"radius">(); + + radius.at({}).set(1.0); + + pos.at({{0u}}) = -1.5; + pos.at({{1u}}) = 0.0; + } + + bool have_collided = lbm::broadphase_collision_check(part_a,part_b); + SAW_EXPECT(have_collided, "Particles should collide"); +} +*/ +/* +SAW_TEST("Moving particles 2D"){ + using namespace kel; + + saw::data> part_a; + { + auto& body = part_a.template get<"rigid_body">(); + auto& pos = body.template get<"position">(); + auto& pos_old = body.template get<"position_old">(); + auto& coll = part_a.template get<"collision">(); + auto& radius = coll.template get<"radius">(); + auto& acc = body.template get<"acceleration">(); + + radius.at({}).set(1.0); + + pos.at({{0u}}) = -5.0; + pos.at({{1u}}) = 0.2; + pos_old = pos; + acc.at({{0u}}) = 0.1; + + } + saw::data> part_b; + { + auto& body = part_b.template get<"rigid_body">(); + auto& pos = body.template get<"position">(); + auto& pos_old = body.template get<"position_old">(); + auto& coll = part_b.template get<"collision">(); + auto& radius = coll.template get<"radius">(); + auto& acc = body.template get<"acceleration">(); + + radius.at({}).set(1.0); + + pos.at({{0u}}) = 5.0; + pos.at({{1u}}) = 0.0; + pos_old = pos; + acc.at({{0u}}) = -0.1; + } + + saw::data> dt; + dt.at({}).set(0.5); + bool has_collided = false; + for(uint64_t i = 0u; i < 32u; ++i){ + lbm::verlet_step_lambda(part_a,dt); + lbm::verlet_step_lambda(part_b,dt); + + has_collided = lbm::broadphase_collision_check(part_a,part_b); + if(has_collided){ + std::cout<<"Collided at: "<> part_a; + { + auto& body = part_a.template get<"rigid_body">(); + auto& pos = body.template get<"position">(); + auto& pos_old = body.template get<"position_old">(); + auto& acc = body.template get<"acceleration">(); + + pos.at({{0u}}) = -5.0; + pos.at({{1u}}) = 0.2; + pos_old = pos; + } +} +/* + +SAW_TEST("Particle Collision Impulse"){ + using namespace kel; + + saw::data> part_a; + { + auto& body = part_a.template get<"rigid_body">(); + auto& pos = body.template get<"position">(); + auto& pos_old = body.template get<"position_old">(); + auto& coll = part_a.template get<"collision">(); + auto& radius = coll.template get<"radius">(); + auto& acc = body.template get<"acceleration">(); + + radius.at({}).set(1.0); + + pos.at({{0u}}) = -5.0; + pos.at({{1u}}) = 0.2; + pos_old = pos; + acc.at({{0u}}) = 0.1; + + } + saw::data> part_b; + { + auto& body = part_b.template get<"rigid_body">(); + auto& pos = body.template get<"position">(); + auto& pos_old = body.template get<"position_old">(); + auto& coll = part_b.template get<"collision">(); + auto& radius = coll.template get<"radius">(); + auto& acc = body.template get<"acceleration">(); + + radius.at({}).set(1.5); + + pos.at({{0u}}) = 5.0; + pos.at({{1u}}) = 0.0; + pos_old = pos; + acc.at({{0u}}) = -0.1; + } +} +*/ +/* + +SAW_TEST("Minor Test for mask"){ + using namespace kel; + + lbm::particle_circle_geometry geo; + + auto mask = geo.generate_mask(9u,1u); + + auto& grid = mask.template get<"grid">(); + + for(saw::data i{0u}; i < grid.template get_dim_size<0>(); ++i){ + for(saw::data j{0u}; j < grid.template get_dim_size<1>(); ++j){ + std::cout<> reference_mask{{{4+2,4+2}}}; + //reference_mask.at({{0,0}}); +} +*/ +/* +SAW_TEST("Verlet integration test 2D"){ + using namespace kel; + lbm::particle_system> system; + + { + saw::data> particle; + auto& rb = particle.template get<"rigid_body">(); + auto& acc = rb.template get<"acceleration">(); + auto& pos = rb.template get<"position">(); + auto& pos_old = rb.template get<"position_old">(); + pos = {{1e-1,1e-1}}; + pos_old = {{0.0, 0.0}}; + acc = {{0.0,-1e1}}; + + auto eov = system.add_particle(std::move(particle)); + SAW_EXPECT(eov.is_value(), "Expected no error :)"); + } + { + auto& p = system.at({0u}); + auto& rb = p.template get<"rigid_body">(); + auto& pos = rb.template get<"position">(); + + for(saw::data i{0u}; i < saw::data{2u}; ++i){ + std::cout<{1e-1}); + + { + auto& p = system.at({0u}); + auto& rb = p.template get<"rigid_body">(); + auto& pos = rb.template get<"position">(); + + for(saw::data i{0u}; i < saw::data{2u}; ++i){ + std::cout< + +#include +#include "../c++/write_vtk.hpp" + +#include + +namespace { +namespace sch { +using namespace kel::lbm::sch; + +using T = Float64; +using D2Q5 = Descriptor<2,5>; +using D2Q9 = Descriptor<2,9>; + +template +using DfCell = Cell; + +template +using CellInfo = Cell; + +/** + * Basic type for simulation + */ +template +using CellStruct = Struct< + Member, "dfs">, + Member, "dfs_old">, + Member, "info"> +>; + +template +using MacroStruct = Struct< + Member, "velocity">, + Member +>; + +} +/* +SAW_TEST("VTK Write test example"){ + using namespace kel; + + // write_vtk(); + + std::stringstream sstream; + + saw::data, 2>> cells{{{2u,2u}}}; + + auto& cell_0 = cells.at({{{0,0}}}); + cell_0.template get<"velocity">()= {{0.5,-0.1}}; + cell_0.template get<"pressure">().set(1.1); + + auto eov = lbm::impl::lbm_vtk_writer, 2>>::apply(sstream, cells); + SAW_EXPECT(eov.is_value(), "vtk writer failed to write"); + + // I want to print it to see it for myself. For now I have no tooling to more easily view associated and potentially generated files + std::cout<::type; +} + +SAW_TEST("VTK Write raw test example"){ + using namespace kel; + + // write_vtk(); + + std::stringstream sstream; + + saw::data, 2>> cells{{{2u,2u}}}; + + auto meta = cells.dims(); + + auto& cell_0 = cells.at({{{0,0}}}); + cell_0.template get<"velocity">()= {{0.5,-0.1}}; + cell_0.template get<"pressure">().set(1.1); + + auto eov = lbm::impl::lbm_vtk_writer_raw,2u>::apply(sstream, &cell_0, meta); + SAW_EXPECT(eov.is_value(), "vtk writer failed to write"); + + // I want to print it to see it for myself. For now I have no tooling to more easily view associated and potentially generated files + std::cout<::type; +} +*/ + +} -- cgit v1.2.3