#include "basics/tests/testUtilities.h" #include <filesystem> #include <iostream> #include <string> #include "LBM/Simulation.h" #include "Parameter.h" #include "PointerDefinitions.h" #include "basics/config/ConfigurationFile.h" #include "Factories/BoundaryConditionFactory.h" #include "Factories/GridScalingFactory.h" #include "Communication/Communicator.h" #include "DataStructureInitializer/GridReaderGenerator/GridGenerator.h" #include "GPU/CudaMemoryManager.h" #include "gpu/GridGenerator/grid/GridBuilder/MultipleGridBuilder.h" TEST(ParameterTest, passingEmptyFileWithoutPath_ShouldNotThrow) { // assuming that the config files is stored parallel to this file. std::filesystem::path filePath = __FILE__; filePath.replace_filename("parameterTest_emptyfile.cfg"); vf::basics::ConfigurationFile config; config.load(filePath.string()); EXPECT_NO_THROW(Parameter para(1, 0, &config)); } // TODO: test setPossNeighborFilesX // TODO: test default values TEST(ParameterTest, check_all_Parameter_CanBePassedToConstructor) { // assuming that the config files is stored parallel to this file. std::filesystem::path filePath = __FILE__; filePath.replace_filename("parameterTest.cfg"); vf::basics::ConfigurationFile config; config.load(filePath.string()); Parameter para(1, 0, &config); // test optional parameter EXPECT_THAT(para.getOutputPath(), testing::Eq("/output/path/")); EXPECT_THAT( para.getGridPath(), testing::Eq("/path/to/grid/")); // ... all grid files (e.g. multi-gpu/ multi-level) could be tested as well EXPECT_THAT(para.getgeoVec(), testing::Eq("/path/to/grid/geoVec.dat")); EXPECT_THAT(para.getMaxDev(), testing::Eq(2)); EXPECT_THAT(para.getDevices(), testing::ElementsAreArray({ 2, 3 })); EXPECT_THAT(para.getOutputPrefix(), testing::Eq("MyPrefix")); EXPECT_THAT(para.getPrintFiles(), testing::Eq(true)); EXPECT_THAT(para.getIsGeometryValues(), testing::Eq(true)); EXPECT_THAT(para.getCalc2ndOrderMoments(), testing::Eq(true)); EXPECT_THAT(para.getCalc3rdOrderMoments(), testing::Eq(true)); EXPECT_THAT(para.getCalcHighOrderMoments(), testing::Eq(true)); EXPECT_THAT(para.getCalcMedian(), testing::Eq(true)); EXPECT_THAT(para.getCalcCp(), testing::Eq(true)); EXPECT_THAT(para.getCalcDragLift(), testing::Eq(true)); EXPECT_THAT(para.getWriteVeloASCIIfiles(), testing::Eq(true)); EXPECT_THAT(para.getCalcPlaneConc(), testing::Eq(true)); EXPECT_THAT(para.getConcFile(), testing::Eq(true)); EXPECT_THAT(para.getUseMeasurePoints(), testing::Eq(true)); EXPECT_THAT(para.getUseWale(), testing::Eq(true)); EXPECT_THAT(para.getUseInitNeq(), testing::Eq(true)); EXPECT_THAT(para.getSimulatePorousMedia(), testing::Eq(true)); EXPECT_THAT(para.getD3Qxx(), testing::Eq(99)); EXPECT_THAT(para.getTimestepEnd(), testing::Eq(33)); EXPECT_THAT(para.getTimestepOut(), testing::Eq(22)); EXPECT_THAT(para.getTimestepStartOut(), testing::Eq(11)); EXPECT_THAT(para.getTimeCalcMedStart(), testing::Eq(22)); EXPECT_THAT(para.getTimeCalcMedEnd(), testing::Eq(44)); EXPECT_THAT(para.getPressInID(), testing::Eq(25)); EXPECT_THAT(para.getPressOutID(), testing::Eq(26)); EXPECT_THAT(para.getPressInZ(), testing::Eq(27)); EXPECT_THAT(para.getPressOutZ(), testing::Eq(28)); EXPECT_THAT(para.getDiffOn(), testing::Eq(true)); EXPECT_THAT(para.getDiffMod(), testing::Eq(99)); EXPECT_THAT(para.getDiffusivity(), RealEq(1.11)); EXPECT_THAT(para.getTemperatureInit(), RealEq(2.22)); EXPECT_THAT(para.getTemperatureBC(), RealEq(3.33)); EXPECT_THAT(para.getViscosity(), RealEq(4.44)); EXPECT_THAT(para.getVelocity(), RealEq(5.55)); EXPECT_THAT(para.getViscosityRatio(), RealEq(6.66)); EXPECT_THAT(para.getVelocityRatio(), RealEq(7.77)); EXPECT_THAT(para.getDensityRatio(), RealEq(8.88)); EXPECT_THAT(para.getPressureRatio(), RealEq(9.99)); EXPECT_THAT(para.getRealX(), RealEq(0.1)); EXPECT_THAT(para.getRealY(), RealEq(0.2)); EXPECT_THAT(para.getFactorPressBC(), RealEq(0.3)); EXPECT_THAT(para.getReadGeo(), testing::Eq(true)); EXPECT_THAT(para.getGeometryFileC(), testing::Eq("/pass/to/c")); EXPECT_THAT(para.getGeometryFileM(), testing::Eq("/pass/to/m")); EXPECT_THAT(para.getGeometryFileF(), testing::Eq("/pass/to/f")); EXPECT_THAT(para.getclockCycleForMP(), RealEq(0.4)); EXPECT_THAT(para.getTimestepForMP(), testing::Eq(4)); std::vector<real> forces{ 2.0, 2.1, 2.2 }; double *forces_actual = para.getForcesDouble(); for (size_t i = 0; i < forces.size(); ++i) { EXPECT_THAT((real)forces_actual[i], RealEq(forces[i])); } std::vector<real> limiters{ 3.0, 3.1, 3.2 }; double *limiters_actual = para.getQuadricLimitersDouble(); for (size_t i = 0; i < limiters.size(); ++i) { EXPECT_THAT((real)limiters_actual[i], RealEq(limiters[i])); } EXPECT_THAT(para.getCalcParticles(), testing::Eq(true)); EXPECT_THAT(para.getParticleBasicLevel(), testing::Eq(1)); EXPECT_THAT(para.getParticleInitLevel(), testing::Eq(2)); EXPECT_THAT(para.getNumberOfParticles(), testing::Eq(1111)); EXPECT_THAT(para.getStartXHotWall(), RealEq(4.1)); EXPECT_THAT(para.getEndXHotWall(), RealEq(4.2)); EXPECT_THAT(para.getTimeDoCheckPoint(), testing::Eq(33)); EXPECT_THAT(para.getTimeDoRestart(), testing::Eq(44)); EXPECT_THAT(para.getDoCheckPoint(), testing::Eq(true)); EXPECT_THAT(para.getDoRestart(), testing::Eq(true)); EXPECT_THAT(para.getMaxLevel(), testing::Eq(1)); // NOGL - 1 EXPECT_THAT(para.getGridX(), testing::ElementsAreArray({ 100, 101 })); EXPECT_THAT(para.getGridY(), testing::ElementsAreArray({ 200, 201 })); EXPECT_THAT(para.getGridZ(), testing::ElementsAreArray({ 300, 301 })); EXPECT_THAT(para.getDistX(), testing::ElementsAreArray({ 400, 401 })); EXPECT_THAT(para.getDistY(), testing::ElementsAreArray({ 500, 501 })); EXPECT_THAT(para.getDistZ(), testing::ElementsAreArray({ 600, 601 })); EXPECT_THAT(para.getMainKernel(), testing::Eq("KernelName")); EXPECT_THAT(para.getMultiKernelOn(), testing::Eq(true)); EXPECT_THAT(para.getMultiKernelLevel(), testing::ElementsAreArray({ 3, 2, 1 })); std::vector<std::string> kernel{ "Kernel1", "Kernel2", "Kernel3" }; auto kernel_actual = para.getMultiKernel(); for (size_t i = 0; i < kernel.size(); ++i) { EXPECT_THAT(kernel_actual[i], testing::Eq(kernel[i])); } EXPECT_THAT(para.getCoarse(), testing::Eq(0)); EXPECT_THAT(para.getFine(), testing::Eq(1)); // NOGL - 1 EXPECT_THAT(para.parH.size(), testing::Eq(2)); EXPECT_THAT(para.parD.size(), testing::Eq(2)); } TEST(ParameterTest, defaultGridPath) { Parameter para; EXPECT_THAT(para.getGridPath(), testing::Eq("grid/")); EXPECT_THAT(para.getConcentration(), testing::Eq("grid/conc.dat")); } TEST(ParameterTest, defaultGridPathMultiGPU) { Parameter para(2, 1); EXPECT_THAT(para.getGridPath(), testing::Eq("grid/1/")); EXPECT_THAT(para.getConcentration(), testing::Eq("grid/1/conc.dat")); } TEST(ParameterTest, setGridPathOverridesDefaultGridPath) { Parameter para(2, 1); para.setGridPath("gridPathTest"); EXPECT_THAT(para.getGridPath(), testing::Eq("gridPathTest/1/")); EXPECT_THAT(para.getConcentration(), testing::Eq("gridPathTest/1/conc.dat")); } TEST(ParameterTest, setGridPathOverridesConfigFile) { // assuming that the config files is stored parallel to this file. std::filesystem::path filePath = __FILE__; filePath.replace_filename("parameterTest.cfg"); vf::basics::ConfigurationFile config; config.load(filePath.string()); auto para = Parameter(2, 0, &config); para.setGridPath("gridPathTest"); EXPECT_THAT(para.getGridPath(), testing::Eq("gridPathTest/0/")); EXPECT_THAT(para.getConcentration(), testing::Eq("gridPathTest/0/conc.dat")); } TEST(ParameterTest, userMissedSlash) { Parameter para; para.setGridPath("gridPathTest"); EXPECT_THAT(para.getGridPath(), testing::Eq("gridPathTest/")); EXPECT_THAT(para.getConcentration(), testing::Eq("gridPathTest/conc.dat")); } TEST(ParameterTest, userMissedSlashMultiGPU) { Parameter para(2, 0); para.setGridPath("gridPathTest"); EXPECT_THAT(para.getGridPath(), testing::Eq("gridPathTest/0/")); EXPECT_THAT(para.getConcentration(), testing::Eq("gridPathTest/0/conc.dat")); } class MockGridGenerator : public GridGenerator { public: MockGridGenerator(std::shared_ptr<GridBuilder> builder, std::shared_ptr<Parameter> para, std::shared_ptr<CudaMemoryManager> cudaMemoryManager, vf::gpu::Communicator &communicator) : GridGenerator(builder, para, cudaMemoryManager, communicator) { } void initalGridInformations() override { para->setGridX({ 2, 8 }); para->setGridY({ 2, 8 }); para->setGridZ({ 2, 8 }); para->setDistX({ 0, 0 }); para->setDistY({ 0, 0 }); para->setDistZ({ 0, 0 }); } void allocArrays_CoordNeighborGeo() override{}; void setBoundingBox() override{}; void allocArrays_OffsetScale() override{}; void allocArrays_BoundaryValues() override{}; void allocArrays_BoundaryQs() override{}; }; TEST(ParameterTest, whenCreatingParameterClassWithGridRefinement_afterCallingInitLBMSimulationParameter_shouldNotThrow) { auto para = std::make_shared<Parameter>(); para->setMaxLevel(2); para->setGridX({ 2, 8 }); para->setGridY({ 2, 8 }); para->setGridZ({ 2, 8 }); para->setDistX({ 0, 0 }); para->setDistY({ 0, 0 }); para->setDistZ({ 0, 0 }); EXPECT_THAT(para->getParH(1), testing::Eq(nullptr)); // Parameter initialization incomplete para->initLBMSimulationParameter(); EXPECT_THAT(para->getParH(1), testing::Ne(nullptr)); } TEST(ParameterTest, whenCreatingParameterClassWithGridRefinement_afterCallingSimulationConstructor_shouldNotThrow) { spdlog::set_level(spdlog::level::warn); // avoids logger spam in output auto para = std::make_shared<Parameter>(); para->setMaxLevel(2); SPtr<CudaMemoryManager> cudaMemoryManager = std::make_shared<CudaMemoryManager>(para); vf::gpu::Communicator &communicator = vf::gpu::Communicator::getInstance(); auto gridFactory = GridFactory::make(); auto gridBuilder = MultipleGridBuilder::makeShared(gridFactory); SPtr<GridProvider> gridGenerator = std::make_shared<MockGridGenerator>(gridBuilder, para, cudaMemoryManager, communicator); BoundaryConditionFactory bcFactory = BoundaryConditionFactory(); GridScalingFactory scalingFactory = GridScalingFactory(); EXPECT_THAT(para->getParH(1), testing::Eq(nullptr)); // Parameter initialization incomplete // Simulation() calls para->initLBMSimulationParameter() --> that function completes the initialization of Parameter Simulation sim(para, cudaMemoryManager, communicator, *gridGenerator, &bcFactory, &scalingFactory); EXPECT_THAT(para->getParH(1), testing::Ne(nullptr)); EXPECT_NO_THROW(cudaMemoryManager->cudaAllocLevelForcing(1)); // throws if para->getParH(1) is a null pointer } class ParameterTestCumulantK17 : public testing::Test { protected: void SetUp() override { } bool stdoutContainsWarning() { std::string output = testing::internal::GetCapturedStdout(); return output.find("warning") != std::string::npos; } Parameter para; }; TEST_F(ParameterTestCumulantK17, CumulantK17_VelocityIsTooHigh_expectWarning) { para.setVelocityLB(0.11); para.setMainKernel("CumulantK17"); testing::internal::CaptureStdout(); para.initLBMSimulationParameter(); EXPECT_TRUE(stdoutContainsWarning()); } TEST_F(ParameterTestCumulantK17, CumulantK17_VelocityIsOk_expectNoWarning) { para.setVelocityLB(0.09); para.setMainKernel("CumulantK17"); testing::internal::CaptureStdout(); para.initLBMSimulationParameter(); EXPECT_FALSE(stdoutContainsWarning()); } TEST_F(ParameterTestCumulantK17, NotCumulantK17_VelocityIsTooHigh_expectNoWarning) { para.setVelocityLB(42); para.setMainKernel("K"); testing::internal::CaptureStdout(); para.initLBMSimulationParameter(); EXPECT_FALSE(stdoutContainsWarning()); } TEST_F(ParameterTestCumulantK17, CumulantK17_ViscosityIsTooHigh_expectWarning) { para.setViscosityLB(0.024); para.setMainKernel("CumulantK17"); testing::internal::CaptureStdout(); para.initLBMSimulationParameter(); EXPECT_TRUE(stdoutContainsWarning()); } TEST_F(ParameterTestCumulantK17, CumulantK17_ViscosityIsOk_expectNoWarning) { para.setViscosityLB(0.023); para.setMainKernel("CumulantK17"); testing::internal::CaptureStdout(); para.initLBMSimulationParameter(); EXPECT_FALSE(stdoutContainsWarning()); } TEST_F(ParameterTestCumulantK17, NotCumulantK17_ViscosityIsTooHigh_expectNoWarning) { para.setViscosityLB(10); para.setMainKernel("K"); testing::internal::CaptureStdout(); para.initLBMSimulationParameter(); EXPECT_FALSE(stdoutContainsWarning()); }