diff --git a/apps/benchmarks/FluidParticleCoupling/CMakeLists.txt b/apps/benchmarks/FluidParticleCoupling/CMakeLists.txt index a22871bb3eb9db47c10b47ca3a08f7812d5d5068..c42c1e497a02f30875f566b62cfeac33bfc21338 100644 --- a/apps/benchmarks/FluidParticleCoupling/CMakeLists.txt +++ b/apps/benchmarks/FluidParticleCoupling/CMakeLists.txt @@ -8,10 +8,13 @@ waLBerla_python_file_generates(GeneratedLBMWithForce.py GeneratedLBMWithForce.cpp GeneratedLBMWithForce.h ) + +if( WALBERLA_BUILD_WITH_CODEGEN ) + waLBerla_add_executable ( NAME SphereWallCollision FILES SphereWallCollision.cpp GeneratedLBM.py DEPENDS blockforest boundary core domain_decomposition field lbm lbm_mesapd_coupling mesa_pd postprocessing timeloop vtk ) -waLBerla_add_executable ( NAME SettlingSphereTenCate FILES SettlingSphereInBox.cpp GeneratedLBM.py +waLBerla_add_executable ( NAME SettlingSphereInBox FILES SettlingSphereInBox.cpp GeneratedLBM.py DEPENDS blockforest boundary core domain_decomposition field lbm lbm_mesapd_coupling mesa_pd postprocessing timeloop vtk ) waLBerla_add_executable ( NAME SphereMovingWithPrescribedVelocity FILES SphereMovingWithPrescribedVelocity.cpp GeneratedLBM.py @@ -26,8 +29,35 @@ waLBerla_add_executable ( NAME DragForceSphere FILES DragForceSphere.cpp Generat waLBerla_add_executable ( NAME ForcesOnSphereNearPlane FILES ForcesOnSphereNearPlane.cpp GeneratedLBM.py DEPENDS blockforest boundary core domain_decomposition field lbm lbm_mesapd_coupling mesa_pd postprocessing timeloop vtk ) -waLBerla_add_executable ( NAME ObliqueDryCollision FILES ObliqueDryCollision.cpp - DEPENDS blockforest core mesa_pd postprocessing ) - waLBerla_add_executable ( NAME ObliqueWetCollision FILES ObliqueWetCollision.cpp GeneratedLBM.py - DEPENDS blockforest boundary core domain_decomposition field lbm lbm_mesapd_coupling mesa_pd postprocessing timeloop vtk ) \ No newline at end of file + DEPENDS blockforest boundary core domain_decomposition field lbm lbm_mesapd_coupling mesa_pd postprocessing timeloop vtk ) + +else() + +waLBerla_add_executable ( NAME SphereWallCollision FILES SphereWallCollision.cpp + DEPENDS blockforest boundary core domain_decomposition field lbm lbm_mesapd_coupling mesa_pd postprocessing timeloop vtk ) + +waLBerla_add_executable ( NAME SettlingSphereInBox FILES SettlingSphereInBox.cpp + DEPENDS blockforest boundary core domain_decomposition field lbm lbm_mesapd_coupling mesa_pd postprocessing timeloop vtk ) + +waLBerla_add_executable ( NAME SphereMovingWithPrescribedVelocity FILES SphereMovingWithPrescribedVelocity.cpp + DEPENDS blockforest boundary core domain_decomposition field lbm mesa_pd lbm_mesapd_coupling postprocessing timeloop vtk ) + +waLBerla_add_executable ( NAME LubricationForceEvaluation FILES LubricationForceEvaluation.cpp + DEPENDS blockforest boundary core domain_decomposition field lbm lbm_mesapd_coupling mesa_pd postprocessing timeloop vtk ) + +waLBerla_add_executable ( NAME DragForceSphere FILES DragForceSphere.cpp + DEPENDS blockforest boundary core domain_decomposition field lbm lbm_mesapd_coupling mesa_pd postprocessing timeloop vtk ) + +waLBerla_add_executable ( NAME ForcesOnSphereNearPlane FILES ForcesOnSphereNearPlane.cpp + DEPENDS blockforest boundary core domain_decomposition field lbm lbm_mesapd_coupling mesa_pd postprocessing timeloop vtk ) + +waLBerla_add_executable ( NAME ObliqueWetCollision FILES ObliqueWetCollision.cpp + DEPENDS blockforest boundary core domain_decomposition field lbm lbm_mesapd_coupling mesa_pd postprocessing timeloop vtk ) + +endif() + + + +waLBerla_add_executable ( NAME ObliqueDryCollision FILES ObliqueDryCollision.cpp + DEPENDS blockforest core mesa_pd postprocessing ) \ No newline at end of file diff --git a/apps/benchmarks/FluidParticleCoupling/DragForceSphere.cpp b/apps/benchmarks/FluidParticleCoupling/DragForceSphere.cpp index 2f269c5d944d021820fe9f63af86ff5c3671798d..a28651957a527509cc3575172614ff2242a6c869 100644 --- a/apps/benchmarks/FluidParticleCoupling/DragForceSphere.cpp +++ b/apps/benchmarks/FluidParticleCoupling/DragForceSphere.cpp @@ -77,9 +77,9 @@ #include <iomanip> #include <iostream> +#ifdef WALBERLA_BUILD_WITH_CODEGEN #include "GeneratedLBMWithForce.h" - -#define USE_TRT_LIKE_LATTICE_MODEL +#endif namespace drag_force_sphere_mem { @@ -91,7 +91,13 @@ namespace drag_force_sphere_mem using namespace walberla; using walberla::uint_t; + +#ifdef WALBERLA_BUILD_WITH_CODEGEN using LatticeModel_T = lbm::GeneratedLBMWithForce; +#else +using ForceModel_T = lbm::force_model::LuoConstant; +using LatticeModel_T = lbm::D3Q19< lbm::collision_model::D3Q19MRT, false, ForceModel_T>; +#endif using Stencil_T = LatticeModel_T::Stencil; using PdfField_T = lbm::PdfField<LatticeModel_T>; @@ -517,8 +523,7 @@ int main( int argc, char **argv ) /////////////////////// // ADD DATA TO BLOCKS // //////////////////////// - - + real_t lambda_e = lbm::collision_model::TRT::lambda_e( omega ); real_t lambda_d = (useSRT) ? lambda_e : lbm::collision_model::TRT::lambda_d( omega, magicNumber ); real_t omegaBulk = (useSRT) ? lambda_e : lbm_mesapd_coupling::omegaBulkFromOmega(omega, bulkViscRateFactor); @@ -527,30 +532,23 @@ int main( int argc, char **argv ) BlockDataID omegaBulkFieldID = field::addToStorage<ScalarField_T>( blocks, "omega bulk field", omegaBulk, field::fzyx, uint_t(0) ); // create the lattice model - - // generated MRT -#ifdef USE_TRT_LIKE_LATTICE_MODEL - WALBERLA_LOG_INFO_ON_ROOT("Using TRT-like lattice model!"); +#ifdef WALBERLA_BUILD_WITH_CODEGEN + WALBERLA_LOG_INFO_ON_ROOT("Using generated TRT-like lattice model!"); WALBERLA_LOG_INFO_ON_ROOT(" - magic number " << magicNumber); WALBERLA_LOG_INFO_ON_ROOT(" - omegaBulk = " << omegaBulk << ", bulk visc. = " << lbm_mesapd_coupling::bulkViscosityFromOmegaBulk(omegaBulk) << " (bvrf " << bulkViscRateFactor << ")"); WALBERLA_LOG_INFO_ON_ROOT(" - lambda_e " << lambda_e << ", lambda_d " << lambda_d << ", omegaBulk " << omegaBulk ); WALBERLA_LOG_INFO_ON_ROOT(" - use omega bulk adaption = " << useOmegaBulkAdaption << " (adaption layer size = " << adaptionLayerSize << ")"); LatticeModel_T latticeModel = LatticeModel_T(omegaBulkFieldID, setup.extForce, lambda_d, lambda_e); - //LatticeModel_T latticeModel = LatticeModel_T(setup.extForce, omegaBulk, lambda_d, lambda_e); - //LatticeModel_T latticeModel = LatticeModel_T(setup.extForce, lambda_e, lambda_d); #else - WALBERLA_LOG_INFO_ON_ROOT("Using other lattice model!"); - // generated KBC - LatticeModel_T latticeModel = LatticeModel_T(setup.extForce, omega); + WALBERLA_LOG_INFO_ON_ROOT("Using waLBerla built-in MRT lattice model and ignoring omega bulk field since not supported!"); + WALBERLA_LOG_INFO_ON_ROOT(" - magic number " << magicNumber); + WALBERLA_LOG_INFO_ON_ROOT(" - omegaBulk = " << omegaBulk << ", bulk visc. = " << lbm_mesapd_coupling::bulkViscosityFromOmegaBulk(omegaBulk) << " (bvrf " << bulkViscRateFactor << ")"); + WALBERLA_LOG_INFO_ON_ROOT(" - lambda_e " << lambda_e << ", lambda_d " << lambda_d << ", omegaBulk " << omegaBulk ); + + LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d ), ForceModel_T( Vector3<real_t> ( setup.extForce, 0, 0 ) )); #endif - // set s_e and s_eps to omegaBulk - // s_e allows to set a specific bulk viscosity that is different from the SRT/TRT default: nu_b = 2/3 nu_shear - // Khirevich et al propose to set s_eps in the same way to avoid huge differences in s_e and s_eps (would be omega in SRT/TRT) that could lead to stability problems - // to not break TRT properties, it is proposed to set Lambda_bulk = conste * Lambda_shear (Khirevich), where conste sets the ratio between bulk and shear viscosity-terms (1 in SRT/TRT -> nu_b = 2/3 nu_shear) - // all in all, this allows to set the bulk viscosity but to retain the "TRT" properties, i.e. independent drag force of tau - //LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d ), ForceModel_T( Vector3<real_t> ( setup.extForce, 0, 0 ) )); // add PDF field BlockDataID pdfFieldID = lbm::addPdfFieldToStorage< LatticeModel_T >( blocks, "pdf field (fzyx)", latticeModel, @@ -636,9 +634,9 @@ int main( int argc, char **argv ) using DragForceEval_T = DragForceEvaluator<ParticleAccessor_T>; auto forceEval = make_shared< DragForceEval_T >( &timeloop, &setup, blocks, flagFieldID, pdfFieldID, accessor, sphereID ); - auto lbmSweep = LatticeModel_T::Sweep( pdfFieldID ); - +#ifdef WALBERLA_BUILD_WITH_CODEGEN + auto lbmSweep = LatticeModel_T::Sweep( pdfFieldID ); // splitting stream and collide is currently buggy in lbmpy with vectorization -> build without optimize for local host and vectorization // collide LBM step timeloop.add() << Sweep([&lbmSweep](IBlock * const block){lbmSweep.collide(block);}, "collide LB sweep" ); @@ -650,16 +648,21 @@ int main( int argc, char **argv ) // stream LBM step timeloop.add() << Sweep([&lbmSweep](IBlock * const block){lbmSweep.stream(block);}, "stream LB sweep" ) << AfterFunction( SharedFunctor< DragForceEval_T >( forceEval ), "drag force evaluation" ); +#else + auto lbmSweep = lbm::makeCellwiseSweep< LatticeModel_T, FlagField_T >( pdfFieldID, flagFieldID, Fluid_Flag ); + + // collision sweep + timeloop.add() << Sweep( lbm::makeCollideSweep( lbmSweep ), "cell-wise LB sweep (collide)" ); -/* // add LBM communication function and boundary handling sweep (does the hydro force calculations and the no-slip treatment) timeloop.add() << BeforeFunction( optimizedPDFCommunicationScheme, "LBM Communication" ) << Sweep( BoundaryHandling_T::getBlockSweep( boundaryHandlingID ), "Boundary Handling" ); - // stream + collide LBM step - timeloop.add() << Sweep( lbmSweep, "LB sweep" ) + // streaming & force evaluation + timeloop.add() << Sweep( lbm::makeStreamSweep( lbmSweep ), "cell-wise LB sweep (stream)" ) << AfterFunction( SharedFunctor< DragForceEval_T >( forceEval ), "drag force evaluation" ); -*/ +#endif + // resetting force timeloop.addFuncAfterTimeStep( [ps,accessor](){ps->forEachParticle(false, mesa_pd::kernel::SelectAll(), *accessor, lbm_mesapd_coupling::ResetHydrodynamicForceTorqueKernel(),*accessor);}, "reset force on sphere"); diff --git a/apps/benchmarks/FluidParticleCoupling/ForcesOnSphereNearPlane.cpp b/apps/benchmarks/FluidParticleCoupling/ForcesOnSphereNearPlane.cpp index eae674e9aa141bcee24ae4057b9da15a057a35f7..77524bf2da21e491336e7ada054fb3ac76483747 100644 --- a/apps/benchmarks/FluidParticleCoupling/ForcesOnSphereNearPlane.cpp +++ b/apps/benchmarks/FluidParticleCoupling/ForcesOnSphereNearPlane.cpp @@ -78,10 +78,11 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" -#include "GeneratedLBM.h" #include <functional> -#define USE_TRT_LIKE_LATTICE_MODEL +#ifdef WALBERLA_BUILD_WITH_CODEGEN +#include "GeneratedLBM.h" +#endif namespace forces_on_sphere_near_plane { @@ -97,8 +98,11 @@ using walberla::uint_t; // TYPEDEFS // ////////////// +#ifdef WALBERLA_BUILD_WITH_CODEGEN using LatticeModel_T = lbm::GeneratedLBM; -//using LatticeModel_T = lbm::D3Q19< lbm::collision_model::D3Q19MRT>; +#else +using LatticeModel_T = lbm::D3Q19< lbm::collision_model::D3Q19MRT>; +#endif using Stencil_T = LatticeModel_T::Stencil; using PdfField_T = lbm::PdfField<LatticeModel_T>; @@ -439,10 +443,6 @@ int main( int argc, char **argv ) const real_t domainWidth = real_t(16) * diameter; //y const real_t domainHeight = real_t( 8) * diameter; //z - //const real_t domainLength = real_t(3) * diameter; //x - //const real_t domainWidth = real_t(3) * diameter; //y - //const real_t domainHeight = real_t(8) * diameter; //z - Vector3<uint_t> domainSize( uint_c( std::ceil(domainLength)), uint_c( std::ceil(domainWidth)), uint_c( std::ceil(domainHeight)) ); @@ -559,15 +559,14 @@ int main( int argc, char **argv ) BlockDataID omegaBulkFieldID = field::addToStorage<ScalarField_T>( blocks, "omega bulk field", omegaBulk, field::fzyx, uint_t(0) ); // create the lattice model -#ifdef USE_TRT_LIKE_LATTICE_MODEL real_t lambda_e = lbm::collision_model::TRT::lambda_e( omega ); real_t lambda_d = lbm::collision_model::TRT::lambda_d( omega, magicNumber ); - //LatticeModel_T latticeModel = LatticeModel_T(omegaBulk, lambda_d, lambda_e); +#ifdef WALBERLA_BUILD_WITH_CODEGEN + WALBERLA_LOG_INFO_ON_ROOT("Using generated TRT-like lattice model!"); LatticeModel_T latticeModel = LatticeModel_T(omegaBulkFieldID, lambda_d, lambda_e); - //LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d )); #else - // generated KBC - LatticeModel_T latticeModel = LatticeModel_T(omega); + WALBERLA_LOG_INFO_ON_ROOT("Using waLBerla built-in MRT lattice model and ignoring omega bulk field since not supported!"); + LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d )); #endif // add PDF field @@ -593,7 +592,7 @@ int main( int argc, char **argv ) ps->forEachParticle(false, lbm_mesapd_coupling::RegularParticlesSelector(), *accessor, movingParticleMappingKernel, *accessor, CLI_Flag); // map planes - ps->forEachParticle(false, lbm_mesapd_coupling::GlobalParticlesSelector(), *accessor, movingParticleMappingKernel, *accessor, CLI_Flag); //TODO: was SBB_Flag? + ps->forEachParticle(false, lbm_mesapd_coupling::GlobalParticlesSelector(), *accessor, movingParticleMappingKernel, *accessor, CLI_Flag); // initialize Couette velocity profile in whole domain if(initializeVelocityProfile) @@ -628,10 +627,6 @@ int main( int argc, char **argv ) if( vtkIOFreq != uint_t(0) ) { - // flag field (written only once in the first time step, ghost layers are also written) - //auto flagFieldVTK = vtk::createVTKOutput_BlockData( blocks, "flag_field", vtkIOFreq, uint_t(0), false, baseFolderVTK ); - //flagFieldVTK->addCellDataWriter( make_shared< field::VTKWriter< FlagField_T > >( flagFieldID, "FlagField" ) ); - //timeloop.addFuncBeforeTimeStep( vtk::writeFiles( flagFieldVTK ), "VTK (flag field data)" ); auto pdfFieldVTK = vtk::createVTKOutput_BlockData( blocks, "fluid_field", vtkIOFreq, uint_t(0), false, baseFolderVTK ); @@ -639,16 +634,6 @@ int main( int argc, char **argv ) fluidFilter.addFlag( Fluid_Flag ); pdfFieldVTK->addCellInclusionFilter( fluidFilter ); - //AABB sliceAABB( real_t(0), real_c(domainSize[1])*real_t(0.5)-real_t(1), real_t(0), - // real_c(domainSize[0]), real_c(domainSize[1])*real_t(0.5)+real_t(1), real_c(domainSize[2]) ); - //vtk::AABBCellFilter aabbSliceFilter( sliceAABB ); - //pdfFieldVTK->addCellInclusionFilter( aabbSliceFilter ); - - //vtk::ChainedFilter combinedSliceFilter; - //combinedSliceFilter.addFilter( fluidFilter ); - //combinedSliceFilter.addFilter( aabbSliceFilter ); - //pdfFieldVTK->addCellInclusionFilter( combinedSliceFilter ); - pdfFieldVTK->addCellDataWriter( make_shared< lbm::VelocityVTKWriter< LatticeModel_T, float > >( pdfFieldID, "VelocityFromPDF" ) ); pdfFieldVTK->addCellDataWriter( make_shared< lbm::DensityVTKWriter < LatticeModel_T, float > >( pdfFieldID, "DensityFromPDF" ) ); @@ -656,14 +641,19 @@ int main( int argc, char **argv ) } auto bhSweep = BoundaryHandling_T::getBlockSweep( boundaryHandlingID ); - auto lbmSweep = LatticeModel_T::Sweep( pdfFieldID ); // add LBM communication function and boundary handling sweep (does the hydro force calculations and the no-slip treatment) timeloop.add() << BeforeFunction( optimizedPDFCommunicationScheme, "LBM Communication" ) << Sweep(bhSweep, "Boundary Handling" ); // stream + collide LBM step +#ifdef WALBERLA_BUILD_WITH_CODEGEN + auto lbmSweep = LatticeModel_T::Sweep( pdfFieldID ); timeloop.add() << Sweep( lbmSweep, "LB sweep" ); +#else + auto lbmSweep = lbm::makeCellwiseSweep< LatticeModel_T, FlagField_T >( pdfFieldID, flagFieldID, Fluid_Flag ); + timeloop.add() << Sweep( makeSharedSweep( lbmSweep ), "cell-wise LB sweep" ); +#endif // add force evaluation and logging diff --git a/apps/benchmarks/FluidParticleCoupling/GeneratedLBM.py b/apps/benchmarks/FluidParticleCoupling/GeneratedLBM.py index 37d1a35ee5e3c18f79764ec4308cd4f2a93bbbbc..43b08e8ec940daa31e4fa126d100a1076a59416c 100644 --- a/apps/benchmarks/FluidParticleCoupling/GeneratedLBM.py +++ b/apps/benchmarks/FluidParticleCoupling/GeneratedLBM.py @@ -7,182 +7,38 @@ from pystencils_walberla import CodeGeneration from lbmpy.creationfunctions import create_lb_collision_rule from lbmpy.moments import MOMENT_SYMBOLS, is_even, get_order from lbmpy.stencils import get_stencil -from lbmpy.maxwellian_equilibrium import get_moments_of_discrete_maxwellian_equilibrium from lbmpy.forcemodels import * -from collections import OrderedDict -from lbmpy.methods import create_with_discrete_maxwellian_eq_moments with CodeGeneration() as ctx: - - # methods: TRTlike, KBC, SRT, cumulant - generatedMethod = "TRTlike" - - print("Generating " + generatedMethod + " LBM method") - - # - # x,y,z = MOMENT_SYMBOLS - # - # e_sq = x**2 + y**2 + z**2 - # - # moments = [0] * 19 - # - # moments[0] = sp.sympify(1) - # moments[1] = 19 * e_sq - 30 - # moments[2] = (21 * e_sq**2 - 53 * e_sq + 24) / 2 - # - # moments[3] = x - # moments[5] = y - # moments[7] = z - # - # moments[4] = (5*e_sq - 9) * x - # moments[6] = (5*e_sq - 9) * y - # moments[8] = (5*e_sq - 9) * z - # - # moments[9] = 3 * x**2 - e_sq - # moments[11] = y**2 - z**2 - # - # moments[13] = x * y - # moments[14] = y * z - # moments[15] = x * z - # - # moments[10] = (3* e_sq - 5)*(3*x**2 - e_sq) - # moments[12] = (3* e_sq - 5)*(y**2 - z**2) - # moments[16] = (y**2 - z**2) * x - # moments[17] = (z**2 - x**2) * y - # moments[18] = (x**2 - y**2) * z - # - # m_eq = get_moments_of_discrete_maxwellian_equilibrium(stencil, moments, order=2, c_s_sq=sp.Rational(1,3)) - # - # rr_dict = OrderedDict(zip(moments, omega)) - # - # forcing = sp.symbols("forcing_:%d" % 3) - # forcing=(sp.symbols("fx"),0,0) - # forcemodel=Luo(forcing) #None - # method = create_with_discrete_maxwellian_eq_moments(stencil, rr_dict, compressible=False, force_model=forcemodel) - # at this stage, we have the MRT model from the LBM book! - - #this is the schiller / walberla MRT - - if generatedMethod == "TRTlike": - stencil = get_stencil("D3Q19", 'walberla') - omega = sp.symbols("omega_:%d" % len(stencil)) - method = create_lb_method(stencil=stencil, method='mrt', maxwellian_moments=False) - - def modification_func(moment, eq, rate): - omegaVisc = sp.Symbol("omega_visc") - omegaBulk = ps.fields("omega_bulk: [3D]", layout='fzyx')# sp.Symbol("omega_bulk") - omegaMagic = sp.Symbol("omega_magic") - if get_order(moment) <= 1: - return moment, eq, 0 - elif rate == omega[1]: - return moment, eq, omegaBulk.center_vector - elif rate == omega[2]: - return moment, eq, omegaBulk.center_vector - elif is_even(moment): - return moment, eq, omegaVisc - else: - return moment, eq, omegaMagic - - my_method = create_lb_method_from_existing(method, modification_func) - - # optimizations - - collision_rule = create_lb_collision_rule(lb_method=my_method, - optimization={"cse_global": True, - "cse_pdfs": False, - #"split": True - } ) - - generate_lattice_model(ctx, 'GeneratedLBM', collision_rule) - - elif generatedMethod == "KBC": - methodName = 'trt-kbc-n4' - #omega_field = ps.fields("omegaField(1): [3D]", layout='fzyx') omega_output_field=omega_field.center, - collision_rule = create_lb_collision_rule(method=methodName,entropic=True, stencil=get_stencil("D3Q27", 'walberla'), compressible=True, - optimization={"cse_global": True, - "cse_pdfs": False, - "split": True}) - generate_lattice_model(ctx, 'GeneratedLBM', collision_rule) - - elif generatedMethod == "SRT": - methodName = 'srt' - collision_rule = create_lb_collision_rule(method=methodName,stencil=get_stencil("D3Q19", 'walberla'), + stencil = get_stencil("D3Q19", 'walberla') + omega = sp.symbols("omega_:%d" % len(stencil)) + method = create_lb_method(stencil=stencil, method='mrt', maxwellian_moments=False) + + def modification_func(moment, eq, rate): + omegaVisc = sp.Symbol("omega_visc") + omegaBulk = ps.fields("omega_bulk: [3D]", layout='fzyx')# sp.Symbol("omega_bulk") + omegaMagic = sp.Symbol("omega_magic") + if get_order(moment) <= 1: + return moment, eq, 0 + elif rate == omega[1]: + return moment, eq, omegaBulk.center_vector + elif rate == omega[2]: + return moment, eq, omegaBulk.center_vector + elif is_even(moment): + return moment, eq, omegaVisc + else: + return moment, eq, omegaMagic + + my_method = create_lb_method_from_existing(method, modification_func) + + collision_rule = create_lb_collision_rule(lb_method=my_method, optimization={"cse_global": True, - "cse_pdfs": False, - "split": True}) - generate_lattice_model(ctx, 'GeneratedLBM', collision_rule) - - elif generatedMethod == "cumulant": - - x,y,z = MOMENT_SYMBOLS - - cumulants = [0] * 27 - - cumulants[0] = sp.sympify(1) #000 - - cumulants[1] = x #100 - cumulants[2] = y #010 - cumulants[3] = z #001 - - cumulants[4] = x*y #110 - cumulants[5] = x*z #101 - cumulants[6] = y*z #011 - - cumulants[7] = x**2 - y**2 #200 - 020 - cumulants[8] = x**2 - z**2 #200 - 002 - cumulants[9] = x**2 + y**2 + z**2 #200 + 020 + 002 - - cumulants[10] = x*y**2 + x*z**2 #120 + 102 - cumulants[11] = x**2*y + y*z**2 #210 + 012 - cumulants[12] = x**2*z + y**2*z #201 + 021 - cumulants[13] = x*y**2 - x*z**2 #120 - 102 - cumulants[14] = x**2*y - y*z**2 #210 - 012 - cumulants[15] = x**2*z - y**2*z #201 - 021 - - cumulants[16] = x*y*z #111 - - cumulants[17] = x**2*y**2 - 2*x**2*z**2 + y**2*z**2 # 220- 2*202 +022 - cumulants[18] = x**2*y**2 + x**2*z**2 - 2*y**2*z**2 # 220 + 202 - 2*002 - cumulants[19] = x**2*y**2 + x**2*z**2 + y**2*z**2 # 220 + 202 + 022 - - cumulants[20] = x**2*y*z # 211 - cumulants[21] = x*y**2*z # 121 - cumulants[22] = x*y*z**2 # 112 - - cumulants[23] = x**2*y**2*z # 221 - cumulants[24] = x**2*y*z**2 # 212 - cumulants[25] = x*y**2*z**2 # 122 - - cumulants[26] = x**2*y**2*z**2 # 222 - - - from lbmpy.moments import get_order - def get_relaxation_rate(cumulant, omega): - if get_order(cumulant) <= 1: - return 0 - elif get_order(cumulant) == 2 and cumulant != x**2 + y**2 + z**2: - return omega - else: - return 1 - - stencil = get_stencil("D3Q27", 'walberla') - - omega = sp.Symbol("omega") - rr_dict = OrderedDict((c, get_relaxation_rate(c, omega)) - for c in cumulants) - - from lbmpy.methods import create_with_continuous_maxwellian_eq_moments - my_method = create_with_continuous_maxwellian_eq_moments(stencil, rr_dict, cumulant=True, compressible=True) - - collision_rule = create_lb_collision_rule(lb_method=my_method, - optimization={"cse_global": True, - "cse_pdfs": False}) + "cse_pdfs": False + } ) - generate_lattice_model(ctx, 'GeneratedLBM', collision_rule) + generate_lattice_model(ctx, 'GeneratedLBM', collision_rule) - else: - print("Invalid generated method string! " + generatedMethod) diff --git a/apps/benchmarks/FluidParticleCoupling/GeneratedLBMWithForce.py b/apps/benchmarks/FluidParticleCoupling/GeneratedLBMWithForce.py index 00200a679512ecfcce9dd57113cac2fcf116cbd0..665fc0226d3a30f66a01d5f46006dd83b481d7db 100644 --- a/apps/benchmarks/FluidParticleCoupling/GeneratedLBMWithForce.py +++ b/apps/benchmarks/FluidParticleCoupling/GeneratedLBMWithForce.py @@ -7,75 +7,35 @@ from pystencils_walberla import CodeGeneration from lbmpy.creationfunctions import create_lb_collision_rule from lbmpy.moments import MOMENT_SYMBOLS, is_even, get_order from lbmpy.stencils import get_stencil -from lbmpy.maxwellian_equilibrium import get_moments_of_discrete_maxwellian_equilibrium from lbmpy.forcemodels import * -from collections import OrderedDict -from lbmpy.methods import create_with_discrete_maxwellian_eq_moments with CodeGeneration() as ctx: forcing=(sp.symbols("fx"),0,0) - forcemodel=Luo(forcing) #None - - # methods: TRTlike, KBC, SRT - generatedMethod = "TRTlike" - - if generatedMethod == "TRTlike": - stencil = get_stencil("D3Q19", 'walberla') - omega = sp.symbols("omega_:%d" % len(stencil)) - - methodWithForce = create_lb_method(stencil=stencil, method='mrt', maxwellian_moments=False,force_model=forcemodel) - - def modification_func(moment, eq, rate): - omegaVisc = sp.Symbol("omega_visc") - omegaBulk = ps.fields("omega_bulk: [3D]", layout='fzyx')# = sp.Symbol("omega_bulk") - #omegaBulk = sp.Symbol("omega_bulk") - omegaMagic = sp.Symbol("omega_magic") - if get_order(moment) <= 1: - return moment, eq, 0 - elif rate == omega[1]: - return moment, eq, omegaBulk.center_vector - elif rate == omega[2]: - return moment, eq, omegaBulk.center_vector - elif is_even(moment): - return moment, eq, omegaVisc - else: - return moment, eq, omegaMagic - - my_methodWithForce = create_lb_method_from_existing(methodWithForce, modification_func) - - collision_rule = create_lb_collision_rule(lb_method=my_methodWithForce) - # , - # optimization={"cse_global": True, - # "cse_pdfs": False, - # "split": True, - # "vectorization":{'instruction_set': 'avx', - # 'nontemporal': True, - # 'assume_inner_stride_one': True}}) - - generate_lattice_model(ctx, 'GeneratedLBMWithForce', collision_rule) - - elif generatedMethod == "SRT": - collision_rule = create_lb_collision_rule(method='srt',stencil=get_stencil("D3Q19", 'walberla'), force_model=forcemodel, - optimization={"cse_global": True, - "cse_pdfs": False, - #"split": True - }) - generate_lattice_model(ctx, 'GeneratedLBMWithForce', collision_rule) - - elif generatedMethod == "TRT": - collision_rule = create_lb_collision_rule(method='trt',stencil=get_stencil("D3Q19", 'walberla'), force_model=forcemodel, maxwellian_moments=False) - generate_lattice_model(ctx, 'GeneratedLBMWithForce', collision_rule) - - - elif generatedMethod == "KBC": - collision_rule = create_lb_collision_rule(method='trt-kbc-n4',entropic=True, stencil=get_stencil("D3Q27", 'walberla'), compressible=True, force_model=forcemodel, - optimization={"cse_global": True, - "cse_pdfs": False, - #"split": True - }) - generate_lattice_model(ctx, 'GeneratedLBMWithForce', collision_rule) - - else: - print("Invalid generated method string! " + generatedMethod) + forcemodel=Luo(forcing) + + stencil = get_stencil("D3Q19", 'walberla') + omega = sp.symbols("omega_:%d" % len(stencil)) + + methodWithForce = create_lb_method(stencil=stencil, method='mrt', maxwellian_moments=False,force_model=forcemodel) + + def modification_func(moment, eq, rate): + omegaVisc = sp.Symbol("omega_visc") + omegaBulk = ps.fields("omega_bulk: [3D]", layout='fzyx') + omegaMagic = sp.Symbol("omega_magic") + if get_order(moment) <= 1: + return moment, eq, 0 + elif rate == omega[1]: + return moment, eq, omegaBulk.center_vector + elif rate == omega[2]: + return moment, eq, omegaBulk.center_vector + elif is_even(moment): + return moment, eq, omegaVisc + else: + return moment, eq, omegaMagic + + my_methodWithForce = create_lb_method_from_existing(methodWithForce, modification_func) + + collision_rule = create_lb_collision_rule(lb_method=my_methodWithForce) + generate_lattice_model(ctx, 'GeneratedLBMWithForce', collision_rule) diff --git a/apps/benchmarks/FluidParticleCoupling/LubricationForceEvaluation.cpp b/apps/benchmarks/FluidParticleCoupling/LubricationForceEvaluation.cpp index 6182af2dcd78f41e8b5da294644560b7502e50e7..0be7fe660efa3adc5d4199bdb8f85e7fb9c00e0c 100644 --- a/apps/benchmarks/FluidParticleCoupling/LubricationForceEvaluation.cpp +++ b/apps/benchmarks/FluidParticleCoupling/LubricationForceEvaluation.cpp @@ -84,11 +84,11 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" -#include "GeneratedLBM.h" - #include <functional> -#define USE_TRT_LIKE_LATTICE_MODEL +#ifdef WALBERLA_BUILD_WITH_CODEGEN +#include "GeneratedLBM.h" +#endif namespace lubrication_force_evaluation { @@ -100,7 +100,11 @@ namespace lubrication_force_evaluation using namespace walberla; using walberla::uint_t; +#ifdef WALBERLA_BUILD_WITH_CODEGEN using LatticeModel_T = lbm::GeneratedLBM; +#else +using LatticeModel_T = lbm::D3Q19< lbm::collision_model::D3Q19MRT>; +#endif using Stencil_T = LatticeModel_T::Stencil; using PdfField_T = lbm::PdfField<LatticeModel_T>; @@ -351,7 +355,7 @@ int main( int argc, char **argv ) uint_t randomSeed = uint_c(std::chrono::system_clock::now().time_since_epoch().count()); mpi::broadcastObject(randomSeed); // root process chooses seed and broadcasts it - std::mt19937 randomNumberGenerator(randomSeed); + std::mt19937 randomNumberGenerator(static_cast<unsigned int>(randomSeed)); Vector3<real_t> domainCenter( real_c(xSize) * real_t(0.5), real_c(ySize) * real_t(0.5), real_c(zSize) * real_t(0.5) ); Vector3<real_t> offsetVector(math::realRandom<real_t>(real_t(0), real_t(1), randomNumberGenerator), @@ -499,17 +503,14 @@ int main( int argc, char **argv ) BlockDataID omegaBulkFieldID = field::addToStorage<ScalarField_T>( blocks, "omega bulk field", omegaBulk, field::fzyx, uint_t(0) ); // create the lattice model -#ifdef USE_TRT_LIKE_LATTICE_MODEL - WALBERLA_LOG_INFO_ON_ROOT("Using TRTlike model!"); real_t lambda_e = lbm::collision_model::TRT::lambda_e( omega ); real_t lambda_d = lbm::collision_model::TRT::lambda_d( omega, magicNumber ); +#ifdef WALBERLA_BUILD_WITH_CODEGEN + WALBERLA_LOG_INFO_ON_ROOT("Using generated TRT-like lattice model!"); LatticeModel_T latticeModel = LatticeModel_T(omegaBulkFieldID, lambda_d, lambda_e); - //LatticeModel_T latticeModel = LatticeModel_T(omegaBulk, lambda_d, lambda_e); - //LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d )); #else - WALBERLA_LOG_INFO_ON_ROOT("Using KBC model!"); - // generated KBC - LatticeModel_T latticeModel = LatticeModel_T(omega); + WALBERLA_LOG_INFO_ON_ROOT("Using waLBerla built-in MRT lattice model and ignoring omega bulk field since not supported!"); + LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d )); #endif // add PDF field @@ -621,7 +622,13 @@ int main( int argc, char **argv ) << Sweep( BoundaryHandling_T::getBlockSweep( boundaryHandlingID ), "Boundary Handling" ); // stream + collide LBM step - timeloop.add() << Sweep( LatticeModel_T::Sweep( pdfFieldID ), "LB stream & collide" ); +#ifdef WALBERLA_BUILD_WITH_CODEGEN + auto lbmSweep = LatticeModel_T::Sweep( pdfFieldID ); + timeloop.add() << Sweep( lbmSweep, "LB sweep" ); +#else + auto lbmSweep = lbm::makeCellwiseSweep< LatticeModel_T, FlagField_T >( pdfFieldID, flagFieldID, Fluid_Flag ); + timeloop.add() << Sweep( makeSharedSweep( lbmSweep ), "cell-wise LB sweep" ); +#endif //////////////////////// diff --git a/apps/benchmarks/FluidParticleCoupling/ObliqueWetCollision.cpp b/apps/benchmarks/FluidParticleCoupling/ObliqueWetCollision.cpp index c8601416f4e27d421b913ea52dd56dde3abee7e4..966a55925f85fea9a051687ae6836afbfc27ca7b 100644 --- a/apps/benchmarks/FluidParticleCoupling/ObliqueWetCollision.cpp +++ b/apps/benchmarks/FluidParticleCoupling/ObliqueWetCollision.cpp @@ -97,11 +97,11 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" -#include "GeneratedLBM.h" - #include <functional> -#define USE_TRT_LIKE_LATTICE_MODEL +#ifdef WALBERLA_BUILD_WITH_CODEGEN +#include "GeneratedLBM.h" +#endif namespace oblique_wet_collision { @@ -113,7 +113,11 @@ namespace oblique_wet_collision using namespace walberla; using walberla::uint_t; +#ifdef WALBERLA_BUILD_WITH_CODEGEN using LatticeModel_T = lbm::GeneratedLBM; +#else +using LatticeModel_T = lbm::D3Q19< lbm::collision_model::D3Q19MRT>; +#endif using Stencil_T = LatticeModel_T::Stencil; using PdfField_T = lbm::PdfField<LatticeModel_T>; @@ -216,7 +220,7 @@ class SpherePropertyLogger { public: SpherePropertyLogger( const shared_ptr< ParticleAccessor_T > & ac, walberla::id_t sphereUid, - const std::string fileNameLogging, const std::string fileNameForceLogging, bool fileIO, + const std::string & fileNameLogging, const std::string & fileNameForceLogging, bool fileIO, real_t diameter, real_t uIn, real_t impactRatio, uint_t numberOfSubSteps, real_t fGravX, real_t fGravZ) : ac_( ac ), sphereUid_( sphereUid ), fileNameLogging_( fileNameLogging ), fileNameForceLogging_( fileNameForceLogging ), fileIO_(fileIO), @@ -599,7 +603,9 @@ int main( int argc, char **argv ) const real_t dx_SI = diameter_SI / diameter; const real_t sphereVolume = math::pi / real_t(6) * diameter * diameter * diameter; - real_t dt_SI, viscosity, omega; + real_t dt_SI; + real_t viscosity; + real_t omega; real_t uIn = real_t(1); real_t accelerationFactor = real_t(0); bool applyArtificialGravityAfterAccelerating = false; @@ -828,17 +834,14 @@ int main( int argc, char **argv ) //LatticeModel_T latticeModel = LatticeModel_T( lbm::collision_model::TRT::constructWithMagicNumber( real_t(1) / relaxationTime ) ); // generated MRT -#ifdef USE_TRT_LIKE_LATTICE_MODEL - WALBERLA_LOG_INFO_ON_ROOT("Using TRT-like lattice model!"); real_t lambda_e = lbm::collision_model::TRT::lambda_e( omega ); real_t lambda_d = lbm::collision_model::TRT::lambda_d( omega, magicNumber ); - //LatticeModel_T latticeModel = LatticeModel_T(omegaBulk, lambda_d, lambda_e); +#ifdef WALBERLA_BUILD_WITH_CODEGEN + WALBERLA_LOG_INFO_ON_ROOT("Using generated TRT-like lattice model!"); LatticeModel_T latticeModel = LatticeModel_T(omegaBulkFieldID, lambda_d, lambda_e); - //LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d )); #else - WALBERLA_LOG_INFO_ON_ROOT("Using different lattice model!"); - // generated model with a single omega - LatticeModel_T latticeModel = LatticeModel_T(omega); + WALBERLA_LOG_INFO_ON_ROOT("Using waLBerla built-in MRT lattice model and ignoring omega bulk field since not supported!"); + LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d )); #endif // add PDF field @@ -931,13 +934,6 @@ int main( int argc, char **argv ) auto particleVtkWriter = vtk::createVTKOutput_PointData(particleVtkOutput, "Particles", vtkIOFreq, baseFolder, "simulation_step"); timeloop.addFuncBeforeTimeStep( vtk::writeFiles( particleVtkWriter ), "VTK (sphere data)" ); - // flag field (written only once in the first time step, ghost layers are also written) - /* - auto flagFieldVTK = vtk::createVTKOutput_BlockData( blocks, "flag_field", timesteps, FieldGhostLayers, false, baseFolder ); - flagFieldVTK->addCellDataWriter( make_shared< field::VTKWriter< FlagField_T > >( flagFieldID, "FlagField" ) ); - timeloop.addFuncBeforeTimeStep( vtk::writeFiles( flagFieldVTK ), "VTK (flag field data)" ); - */ - // pdf field, as slice auto pdfFieldVTK = vtk::createVTKOutput_BlockData( blocks, "fluid_field", vtkIOFreq, 0, false, baseFolder ); @@ -1022,10 +1018,13 @@ int main( int argc, char **argv ) << Sweep( BoundaryHandling_T::getBlockSweep( boundaryHandlingID ), "Boundary Handling" ); // stream + collide LBM step - // generated LBM sweep - timeloop.add() << Sweep( LatticeModel_T::Sweep( pdfFieldID ), "LB stream & collide" ); - // walberla sweeps: - //timeloop.add() << Sweep( makeSharedSweep( lbm::makeCellwiseSweep< LatticeModel_T, FlagField_T >( pdfFieldID, flagFieldID, Fluid_Flag ) ), "cell-wise LB sweep" ); +#ifdef WALBERLA_BUILD_WITH_CODEGEN + auto lbmSweep = LatticeModel_T::Sweep( pdfFieldID ); + timeloop.add() << Sweep( lbmSweep, "LB sweep" ); +#else + auto lbmSweep = lbm::makeCellwiseSweep< LatticeModel_T, FlagField_T >( pdfFieldID, flagFieldID, Fluid_Flag ); + timeloop.add() << Sweep( makeSharedSweep( lbmSweep ), "cell-wise LB sweep" ); +#endif // evaluation functionality std::string loggingFileName( baseFolder + "/LoggingObliqueWetCollision.txt"); @@ -1048,8 +1047,9 @@ int main( int argc, char **argv ) uint_t numBounces = uint_t(0); uint_t tImpact = uint_t(0); - real_t curVel(real_t(0)), oldVel(real_t(0)); - real_t maxSettlingVel = real_t(0); + real_t curVel(real_t(0)); + real_t oldVel(real_t(0)); + real_t maxSettlingVel(real_t(0)); real_t minGapSize(real_t(0)); @@ -1194,7 +1194,7 @@ int main( int argc, char **argv ) if( artificiallyAccelerateSphere ) { lbm_mesapd_coupling::RegularParticlesSelector sphereSelector; - real_t newSphereVel = uIn * (exp(-accelerationFactor * real_t(i) / responseTime ) - real_t(1)); + real_t newSphereVel = uIn * (std::exp(-accelerationFactor * real_t(i) / responseTime ) - real_t(1)); ps->forEachParticle(useOpenMP, sphereSelector, *accessor, [newSphereVel,impactAngle](const size_t idx, ParticleAccessor_T& ac){ ac.setLinearVelocity(idx, Vector3<real_t>( -std::sin(impactAngle), real_t(0), std::cos(impactAngle) ) * newSphereVel); diff --git a/apps/benchmarks/FluidParticleCoupling/SettlingSphereInBox.cpp b/apps/benchmarks/FluidParticleCoupling/SettlingSphereInBox.cpp index 6fa7822310fd770d223ec3beeefd3279b7aca029..b8a2b2c1929518665c6dc6f84fbe2b6d78558afc 100644 --- a/apps/benchmarks/FluidParticleCoupling/SettlingSphereInBox.cpp +++ b/apps/benchmarks/FluidParticleCoupling/SettlingSphereInBox.cpp @@ -87,11 +87,11 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" -#include "GeneratedLBM.h" - #include <functional> -#define USE_TRT_LIKE_LATTICE_MODEL +#ifdef WALBERLA_BUILD_WITH_CODEGEN +#include "GeneratedLBM.h" +#endif namespace settling_sphere_in_box { @@ -103,8 +103,11 @@ namespace settling_sphere_in_box using namespace walberla; using walberla::uint_t; +#ifdef WALBERLA_BUILD_WITH_CODEGEN using LatticeModel_T = lbm::GeneratedLBM; -//using LatticeModel_T = lbm::D3Q19< lbm::collision_model::D3Q19MRT>; +#else +using LatticeModel_T = lbm::D3Q19< lbm::collision_model::D3Q19MRT>; +#endif using Stencil_T = LatticeModel_T::Stencil; using PdfField_T = lbm::PdfField<LatticeModel_T>; @@ -426,7 +429,8 @@ int main( int argc, char **argv ) const real_t diameter_SI = real_t(15e-3); const real_t densitySphere_SI = real_t(1120); - real_t densityFluid_SI, dynamicViscosityFluid_SI; + real_t densityFluid_SI; + real_t dynamicViscosityFluid_SI; real_t expectedSettlingVelocity_SI; switch( fluidType ) { @@ -600,17 +604,14 @@ int main( int argc, char **argv ) BlockDataID omegaBulkFieldID = field::addToStorage<ScalarField_T>( blocks, "omega bulk field", omegaBulk, field::fzyx, uint_t(0) ); // create the lattice model -#ifdef USE_TRT_LIKE_LATTICE_MODEL - WALBERLA_LOG_INFO_ON_ROOT("Using TRTlike model!"); real_t lambda_e = lbm::collision_model::TRT::lambda_e( omega ); real_t lambda_d = lbm::collision_model::TRT::lambda_d( omega, magicNumber ); +#ifdef WALBERLA_BUILD_WITH_CODEGEN + WALBERLA_LOG_INFO_ON_ROOT("Using generated TRT-like lattice model!"); LatticeModel_T latticeModel = LatticeModel_T(omegaBulkFieldID, lambda_d, lambda_e); - //LatticeModel_T latticeModel = LatticeModel_T(omegaBulk, lambda_d, lambda_e); - //LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d )); #else - WALBERLA_LOG_INFO_ON_ROOT("Using KBC model!"); - // generated KBC - LatticeModel_T latticeModel = LatticeModel_T(omega); + WALBERLA_LOG_INFO_ON_ROOT("Using waLBerla built-in MRT lattice model and ignoring omega bulk field since not supported!"); + LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d )); #endif @@ -759,32 +760,21 @@ int main( int argc, char **argv ) timeloop.add() << Sweep( makeSharedSweep(omegaBulkAdapter), "Omega Bulk Adapter"); } - bool useStreamCollide = true; + + // add LBM communication function and boundary handling sweep (does the hydro force calculations and the no-slip treatment) auto bhSweep = BoundaryHandling_T::getBlockSweep( boundaryHandlingID ); + timeloop.add() << BeforeFunction( optimizedPDFCommunicationScheme, "LBM Communication" ) + << Sweep(bhSweep, "Boundary Handling" ); - // generated sweeps + // stream + collide LBM step +#ifdef WALBERLA_BUILD_WITH_CODEGEN auto lbmSweep = LatticeModel_T::Sweep( pdfFieldID ); - if( useStreamCollide ) - { - // add LBM communication function and boundary handling sweep (does the hydro force calculations and the no-slip treatment) - timeloop.add() << BeforeFunction( optimizedPDFCommunicationScheme, "LBM Communication" ) - << Sweep(bhSweep, "Boundary Handling" ); - - // stream + collide LBM step - timeloop.add() << Sweep( lbmSweep, "LB sweep" ); - } - else - { - // collide LBM step - timeloop.add() << Sweep([&lbmSweep](IBlock * const block){lbmSweep.collide(block);}, "cell-wise collide LB sweep" ); - - // add LBM communication function and boundary handling sweep (does the hydro force calculations and the no-slip treatment) - timeloop.add() << BeforeFunction( optimizedPDFCommunicationScheme, "LBM Communication" ) - << Sweep( BoundaryHandling_T::getBlockSweep( boundaryHandlingID ), "Boundary Handling" ); + timeloop.add() << Sweep( lbmSweep, "LB sweep" ); +#else + auto lbmSweep = lbm::makeCellwiseSweep< LatticeModel_T, FlagField_T >( pdfFieldID, flagFieldID, Fluid_Flag ); + timeloop.add() << Sweep( makeSharedSweep( lbmSweep ), "cell-wise LB sweep" ); +#endif - // stream LBM step - timeloop.add() << Sweep([&lbmSweep](IBlock * const block){lbmSweep.stream(block);}, "cell-wise stream LB sweep" ); - } // evaluation functionality std::string loggingFileName( baseFolder + "/LoggingSettlingSphere_"); diff --git a/apps/benchmarks/FluidParticleCoupling/SphereMovingWithPrescribedVelocity.cpp b/apps/benchmarks/FluidParticleCoupling/SphereMovingWithPrescribedVelocity.cpp index 9e1b866792a5e5088c5e6940f8b89aa9074ede81..644a887df3aeb44096f2f267934bb9729035a89d 100644 --- a/apps/benchmarks/FluidParticleCoupling/SphereMovingWithPrescribedVelocity.cpp +++ b/apps/benchmarks/FluidParticleCoupling/SphereMovingWithPrescribedVelocity.cpp @@ -91,11 +91,11 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" -#include "GeneratedLBM.h" - #include <functional> -#define USE_TRT_LIKE_LATTICE_MODEL +#ifdef WALBERLA_BUILD_WITH_CODEGEN +#include "GeneratedLBM.h" +#endif namespace sphere_moving_with_prescribed_velocity { @@ -107,8 +107,11 @@ namespace sphere_moving_with_prescribed_velocity using namespace walberla; using walberla::uint_t; +#ifdef WALBERLA_BUILD_WITH_CODEGEN using LatticeModel_T = lbm::GeneratedLBM; -//using LatticeModel_T = lbm::D3Q19< lbm::collision_model::D3Q19MRT>; +#else +using LatticeModel_T = lbm::D3Q19< lbm::collision_model::D3Q19MRT>; +#endif using Stencil_T = LatticeModel_T::Stencil; using PdfField_T = lbm::PdfField<LatticeModel_T>; @@ -458,8 +461,6 @@ int main( int argc, char **argv ) filesystem::create_directory( tpath ); } - //if(adaptionLayerSize > real_t(2)) WALBERLA_LOG_WARNING_ON_ROOT("Adaption layer size is larger than permitted by parallel setup!"); - ////////////////////////// // NUMERICAL PARAMETERS // ////////////////////////// @@ -557,15 +558,14 @@ int main( int argc, char **argv ) BlockDataID omegaBulkFieldID = field::addToStorage<ScalarField_T>( blocks, "omega bulk field", omegaBulk, field::fzyx, uint_t(0) ); // create the lattice model -#ifdef USE_TRT_LIKE_LATTICE_MODEL real_t lambda_e = lbm::collision_model::TRT::lambda_e( omega ); real_t lambda_d = lbm::collision_model::TRT::lambda_d( omega, magicNumber ); - //LatticeModel_T latticeModel = LatticeModel_T(omegaBulk, lambda_d, lambda_e); +#ifdef WALBERLA_BUILD_WITH_CODEGEN + WALBERLA_LOG_INFO_ON_ROOT("Using generated TRT-like lattice model!"); LatticeModel_T latticeModel = LatticeModel_T(omegaBulkFieldID, lambda_d, lambda_e); - //LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d )); #else - // generated KBC - LatticeModel_T latticeModel = LatticeModel_T(omega); + WALBERLA_LOG_INFO_ON_ROOT("Using waLBerla built-in MRT lattice model and ignoring omega bulk field since not supported!"); + LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d )); #endif // add PDF field @@ -604,9 +604,6 @@ int main( int argc, char **argv ) mesa_pd::mpi::ReduceProperty reduceProperty; // set up coupling functionality - //Vector3<real_t> gravitationalForce( real_t(0), real_t(0), -(densityRatio - real_t(1)) * gravitationalAcceleration * sphereVolume ); - //lbm_mesapd_coupling::AddForceOnParticlesKernel addGravitationalForce(gravitationalForce); - lbm_mesapd_coupling::AddHydrodynamicInteractionKernel addHydrodynamicInteraction; lbm_mesapd_coupling::ResetHydrodynamicForceTorqueKernel resetHydrodynamicForceTorque; lbm_mesapd_coupling::AverageHydrodynamicForceTorqueKernel averageHydrodynamicForceTorque; @@ -653,11 +650,6 @@ int main( int argc, char **argv ) auto particleVtkWriter = vtk::createVTKOutput_PointData(particleVtkOutput, "Particles", vtkIOFreq, baseFolder, "simulation_step"); timeloop.addFuncBeforeTimeStep( vtk::writeFiles( particleVtkWriter ), "VTK (sphere data)" ); - // flag field (written only once in the first time step, ghost layers are also written) - //auto flagFieldVTK = vtk::createVTKOutput_BlockData( blocks, "flag_field", timesteps, FieldGhostLayers, false, baseFolder ); - //flagFieldVTK->addCellDataWriter( make_shared< field::VTKWriter< FlagField_T > >( flagFieldID, "FlagField" ) ); - //timeloop.addFuncBeforeTimeStep( vtk::writeFiles( flagFieldVTK ), "VTK (flag field data)" ); - // pdf field auto pdfFieldVTK = vtk::createVTKOutput_BlockData( blocks, "fluid_field", vtkIOFreq, 0, false, baseFolder ); @@ -720,33 +712,19 @@ int main( int argc, char **argv ) timeloop.add() << Sweep( makeSharedSweep(omegaBulkAdapter), "Omega Bulk Adapter"); } - - bool useStreamCollide = true; + // add LBM communication function and boundary handling sweep (does the hydro force calculations and the no-slip treatment) auto bhSweep = BoundaryHandling_T::getBlockSweep( boundaryHandlingID ); + timeloop.add() << BeforeFunction( optimizedPDFCommunicationScheme, "LBM Communication" ) + << Sweep(bhSweep, "Boundary Handling" ); - // generated sweeps + // stream + collide LBM step +#ifdef WALBERLA_BUILD_WITH_CODEGEN auto lbmSweep = LatticeModel_T::Sweep( pdfFieldID ); - if( useStreamCollide ) - { - // add LBM communication function and boundary handling sweep (does the hydro force calculations and the no-slip treatment) - timeloop.add() << BeforeFunction( optimizedPDFCommunicationScheme, "LBM Communication" ) - << Sweep(bhSweep, "Boundary Handling" ); - - // stream + collide LBM step - timeloop.add() << Sweep( lbmSweep, "LB sweep" ); - } - else - { - // collide LBM step - timeloop.add() << Sweep([&lbmSweep](IBlock * const block){lbmSweep.collide(block);}, "cell-wise collide LB sweep" ); - - // add LBM communication function and boundary handling sweep (does the hydro force calculations and the no-slip treatment) - timeloop.add() << BeforeFunction( optimizedPDFCommunicationScheme, "LBM Communication" ) - << Sweep( BoundaryHandling_T::getBlockSweep( boundaryHandlingID ), "Boundary Handling" ); - - // stream LBM step - timeloop.add() << Sweep([&lbmSweep](IBlock * const block){lbmSweep.stream(block);}, "cell-wise stream LB sweep" ); - } + timeloop.add() << Sweep( lbmSweep, "LB sweep" ); +#else + auto lbmSweep = lbm::makeCellwiseSweep< LatticeModel_T, FlagField_T >( pdfFieldID, flagFieldID, Fluid_Flag ); + timeloop.add() << Sweep( makeSharedSweep( lbmSweep ), "cell-wise LB sweep" ); +#endif // evaluation functionality std::string loggingFileName( baseFolder + "/LoggingPrescribedMovingSphere"); @@ -760,7 +738,6 @@ int main( int argc, char **argv ) if( conserveMomentum ) loggingFileName += "_conserveMomentum"; if( artificiallyAccelerateSphere ) loggingFileName += "_acc"; if( !fileNameEnding.empty()) loggingFileName += "_" + fileNameEnding; - //loggingFileName += "_SBB"; loggingFileName += ".txt"; if( fileIO ) @@ -806,7 +783,7 @@ int main( int argc, char **argv ) if( artificiallyAccelerateSphere ) { // accelerating after reading from a checkpoint file does not make sense, as current actual runtime is not known - real_t newSphereVel = velocity * (exp(-accelerationFactor * real_t(i) ) - real_t(1)); + real_t newSphereVel = velocity * (std::exp(-accelerationFactor * real_t(i) ) - real_t(1)); ps->forEachParticle(useOpenMP, sphereSelector, *accessor, [newSphereVel](const size_t idx, ParticleAccessor_T& ac){ ac.setLinearVelocity(idx, Vector3<real_t>(real_t(0), real_t(0), newSphereVel));}, *accessor); } diff --git a/apps/benchmarks/FluidParticleCoupling/SphereWallCollision.cpp b/apps/benchmarks/FluidParticleCoupling/SphereWallCollision.cpp index 61a3844f14a27fc0c6bfc89e953a419f6653ed11..8a339e6915f29dff6fcaea552b68923deb5540ce 100644 --- a/apps/benchmarks/FluidParticleCoupling/SphereWallCollision.cpp +++ b/apps/benchmarks/FluidParticleCoupling/SphereWallCollision.cpp @@ -97,11 +97,11 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" -#include "GeneratedLBM.h" - #include <functional> -#define USE_TRT_LIKE_LATTICE_MODEL +#ifdef WALBERLA_BUILD_WITH_CODEGEN +#include "GeneratedLBM.h" +#endif namespace sphere_wall_collision { @@ -113,7 +113,11 @@ namespace sphere_wall_collision using namespace walberla; using walberla::uint_t; +#ifdef WALBERLA_BUILD_WITH_CODEGEN using LatticeModel_T = lbm::GeneratedLBM; +#else +using LatticeModel_T = lbm::D3Q19< lbm::collision_model::D3Q19MRT>; +#endif using Stencil_T = LatticeModel_T::Stencil; using PdfField_T = lbm::PdfField<LatticeModel_T>; @@ -292,7 +296,7 @@ public: return position_; } - void writeResult(std::string filename, uint_t tImpact) + void writeResult(const std::string & filename, uint_t tImpact) { WALBERLA_ROOT_SECTION() { @@ -455,22 +459,16 @@ real_t getForce(walberla::id_t uid, ParticleAccessor_T & ac) return force; } - -real_t getAcceleratedSphereVelocity(real_t accelerationRate, uint_t timestep, real_t tref, real_t finalVelocity) -{ - return finalVelocity * (std::exp(-real_c(timestep)/(tref*accelerationRate))-real_t(1)); -} - template< typename DensityInterpolator_T> void logDensityToFile(const shared_ptr<StructuredBlockStorage> & blocks, BlockDataID densityInterpolatorID, real_t surfaceDistance, - Vector3<real_t> spherePosition, real_t diameter, std::string fileName, uint_t timestep, real_t averageDensityInSystem ) + Vector3<real_t> spherePosition, real_t diameter, const std::string & fileName, uint_t timestep, real_t averageDensityInSystem ) { real_t evalRadius = real_t(0.5) * diameter + surfaceDistance; std::vector< Vector3<real_t> > evaluationPositions; evaluationPositions.push_back(spherePosition + Vector3<real_t>(real_t(0), real_t(0), evalRadius)); - evaluationPositions.push_back(spherePosition + Vector3<real_t>(evalRadius / sqrt(real_t(2)), real_t(0), evalRadius / sqrt(real_t(2)))); + evaluationPositions.push_back(spherePosition + Vector3<real_t>(evalRadius / real_c(sqrt(real_t(2))), real_t(0), real_c(evalRadius / sqrt(real_t(2))))); evaluationPositions.push_back(spherePosition + Vector3<real_t>(evalRadius, real_t(0), real_t(0))); - evaluationPositions.push_back(spherePosition + Vector3<real_t>(evalRadius / sqrt(real_t(2)), real_t(0), -evalRadius / sqrt(real_t(2)))); + evaluationPositions.push_back(spherePosition + Vector3<real_t>(evalRadius / real_c(sqrt(real_t(2))), real_t(0), -evalRadius / real_c(sqrt(real_t(2))))); evaluationPositions.push_back(spherePosition + Vector3<real_t>(real_t(0), real_t(0), -evalRadius)); std::vector<real_t> densityAtPos(evaluationPositions.size(), real_t(0)); @@ -689,7 +687,7 @@ int main( int argc, char **argv ) { uint_t seed1 = uint_c(std::chrono::system_clock::now().time_since_epoch().count()); mpi::broadcastObject(seed1); // root process chooses seed and broadcasts it - std::mt19937 g1 (seed1); + std::mt19937 g1 (static_cast<unsigned int>(seed1)); real_t initialPositionOffset = real_t(0.5)*math::realRandom<real_t>(real_t(-1), real_t(1), g1); initialSpherePosition += initialPositionOffset; @@ -901,22 +899,14 @@ int main( int argc, char **argv ) BlockDataID omegaBulkFieldID = field::addToStorage<ScalarField_T>( blocks, "omega bulk field", omegaBulk, field::fzyx, uint_t(0) ); // create the lattice model - - // TRT - //LatticeModel_T latticeModel = LatticeModel_T( lbm::collision_model::TRT::constructWithMagicNumber( real_t(1) / relaxationTime ) ); - - // generated MRT -#ifdef USE_TRT_LIKE_LATTICE_MODEL - WALBERLA_LOG_INFO_ON_ROOT("Using TRT-like lattice model!"); real_t lambda_e = lbm::collision_model::TRT::lambda_e( omega ); real_t lambda_d = lbm::collision_model::TRT::lambda_d( omega, magicNumber ); - //LatticeModel_T latticeModel = LatticeModel_T(omegaBulk, lambda_d, lambda_e); +#ifdef WALBERLA_BUILD_WITH_CODEGEN + WALBERLA_LOG_INFO_ON_ROOT("Using generated TRT-like lattice model!"); LatticeModel_T latticeModel = LatticeModel_T(omegaBulkFieldID, lambda_d, lambda_e); - //LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d )); #else - WALBERLA_LOG_INFO_ON_ROOT("Using different lattice model!"); - // generated model with a single omega - LatticeModel_T latticeModel = LatticeModel_T(omega); + WALBERLA_LOG_INFO_ON_ROOT("Using waLBerla built-in MRT lattice model and ignoring omega bulk field since not supported!"); + LatticeModel_T latticeModel = LatticeModel_T(lbm::collision_model::D3Q19MRT( omegaBulk, omegaBulk, lambda_d, lambda_e, lambda_e, lambda_d )); #endif // add PDF field @@ -1025,7 +1015,6 @@ int main( int argc, char **argv ) auto particleVtkOutput = make_shared<mesa_pd::vtk::ParticleVtkOutput>(ps); particleVtkOutput->addOutput<mesa_pd::data::SelectParticleOwner>("owner"); particleVtkOutput->addOutput<mesa_pd::data::SelectParticleUid>("uid"); - particleVtkOutput->addOutput<mesa_pd::data::SelectParticleShapeID>("shapeID"); particleVtkOutput->addOutput<mesa_pd::data::SelectParticleLinearVelocity>("velocity"); particleVtkOutput->setParticleSelector( [sphereShape](const mesa_pd::data::ParticleStorage::iterator& pIt) {return pIt->getShapeID() == sphereShape;} ); //limit output to sphere auto particleVtkWriter = vtk::createVTKOutput_PointData(particleVtkOutput, "Particles", vtkIOFreq, baseFolder, "simulation_step"); @@ -1089,10 +1078,13 @@ int main( int argc, char **argv ) << Sweep( BoundaryHandling_T::getBlockSweep( boundaryHandlingID ), "Boundary Handling" ); // stream + collide LBM step - // generated LBM sweep - timeloop.add() << Sweep( LatticeModel_T::Sweep( pdfFieldID ), "LB stream & collide" ); - // walberla sweeps: - //timeloop.add() << Sweep( makeSharedSweep( lbm::makeCellwiseSweep< LatticeModel_T, FlagField_T >( pdfFieldID, flagFieldID, Fluid_Flag ) ), "cell-wise LB sweep" ); +#ifdef WALBERLA_BUILD_WITH_CODEGEN + auto lbmSweep = LatticeModel_T::Sweep( pdfFieldID ); + timeloop.add() << Sweep( lbmSweep, "LB sweep" ); +#else + auto lbmSweep = lbm::makeCellwiseSweep< LatticeModel_T, FlagField_T >( pdfFieldID, flagFieldID, Fluid_Flag ); + timeloop.add() << Sweep( makeSharedSweep( lbmSweep ), "cell-wise LB sweep" ); +#endif // this is carried out after the particle integration, it corrects the flag field and restores missing PDF information // then, the checkpointing file can be written, as otherwise some cells are invalid and can not be recovered @@ -1134,8 +1126,6 @@ int main( int argc, char **argv ) } - - // evaluation functionality std::string loggingFileName( baseFolder + "/LoggingSphereWallCollision.txt"); if( fileIO ) @@ -1162,8 +1152,9 @@ int main( int argc, char **argv ) uint_t tImpact = uint_t(0); std::vector<uint_t> impactTimes; - real_t curVel(real_t(0)), oldVel(real_t(0)); - real_t maxSettlingVel = real_t(0); + real_t curVel(real_t(0)); + real_t oldVel(real_t(0)); + real_t maxSettlingVel(real_t(0)); std::vector<real_t> maxSettlingVelBetweenBounces; real_t minGapSize(real_t(0)); @@ -1328,7 +1319,7 @@ int main( int argc, char **argv ) { // overwrite velocity of particle with prescribed one lbm_mesapd_coupling::RegularParticlesSelector sphereSelector; - real_t newSphereVel = uIn * (exp(-accelerationFactor * real_t(i) ) - real_t(1)); + real_t newSphereVel = uIn * (std::exp(-accelerationFactor * real_t(i) ) - real_t(1)); ps->forEachParticle(useOpenMP, sphereSelector, *accessor, [newSphereVel](const size_t idx, ParticleAccessor_T& ac){ ac.setLinearVelocity(idx, Vector3<real_t>(real_t(0), real_t(0), newSphereVel));}, *accessor); }