diff --git a/tests/lbm/CMakeLists.txt b/tests/lbm/CMakeLists.txt index 8f735fb94c96198cf6153050a56c8bb89cdaab53..7ffa9167b581853dbef5ffa4d203923f7e2069e1 100644 --- a/tests/lbm/CMakeLists.txt +++ b/tests/lbm/CMakeLists.txt @@ -77,3 +77,7 @@ waLBerla_python_file_generates(codegen/LbCodeGenerationExample.py LbCodeGenerationExample_UBB.cpp ) waLBerla_compile_test( FILES codegen/LbCodeGenerationExample.py codegen/LbCodeGenerationExample.cpp) +waLBerla_python_file_generates(codegen/FluctuatingMRT.py + FluctuatingMRT_LatticeModel.cpp ) +waLBerla_compile_test( FILES codegen/FluctuatingMRT.py + codegen/FluctuatingMRT.cpp) \ No newline at end of file diff --git a/tests/lbm/codegen/FluctuatingMRT.cpp b/tests/lbm/codegen/FluctuatingMRT.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2b9ccdba11237b4b8a3129e02eaae668e2c24e3c --- /dev/null +++ b/tests/lbm/codegen/FluctuatingMRT.cpp @@ -0,0 +1,119 @@ +//====================================================================================================================== +// +// This file is part of waLBerla. waLBerla is free software: you can +// redistribute it and/or modify it under the terms of the GNU General Public +// License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// waLBerla is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file SrtWithForceField.cpp +//! \author Michael Kuron <mkuron@icp.uni-stuttgart.de> +// +//====================================================================================================================== + +#include "blockforest/all.h" +#include "core/all.h" +#include "domain_decomposition/all.h" +#include "field/all.h" +#include "geometry/all.h" +#include "gui/all.h" +#include "timeloop/all.h" + +#include "lbm/field/PdfField.h" +#include "lbm/field/AddToStorage.h" +#include "lbm/communication/PdfFieldPackInfo.h" +#include "lbm/gui/Connection.h" +#include "lbm/vtk/VTKOutput.h" + +#include "FluctuatingMRT_LatticeModel.h" + + +using namespace walberla; + +typedef lbm::FluctuatingMRT_LatticeModel LatticeModel_T; +typedef LatticeModel_T::Stencil Stencil_T; +typedef LatticeModel_T::CommunicationStencil CommunicationStencil_T; +typedef lbm::PdfField< LatticeModel_T > PdfField_T; + +typedef GhostLayerField< real_t, LatticeModel_T::Stencil::D > VectorField_T; +typedef GhostLayerField< real_t, 1 > ScalarField_T; + +typedef walberla::uint8_t flag_t; +typedef FlagField< flag_t > FlagField_T; + + + +int main( int argc, char ** argv ) +{ + walberla::Environment walberlaEnv( argc, argv ); + + auto blocks = blockforest::createUniformBlockGridFromConfig( walberlaEnv.config() ); + + // read parameters + auto parameters = walberlaEnv.config()->getOneBlock( "Parameters" ); + + const real_t omega = parameters.getParameter< real_t > ( "omega", real_c( 1.4 ) ); + const Vector3<real_t> initialVelocity = parameters.getParameter< Vector3<real_t> >( "initialVelocity", Vector3<real_t>() ); + const uint_t timesteps = parameters.getParameter< uint_t > ( "timesteps", uint_c( 10 ) ); + const real_t temperature = real_t(0.01); + const uint_t seed = uint_t(0); + + const double remainingTimeLoggerFrequency = parameters.getParameter< double >( "remainingTimeLoggerFrequency", 3.0 ); // in seconds + + // create fields + BlockDataID forceFieldId = field::addToStorage<VectorField_T>( blocks, "Force", real_t( 0.0 )); + + LatticeModel_T latticeModel = LatticeModel_T( forceFieldId, omega, omega, seed, temperature, uint_t(0) ); + BlockDataID pdfFieldId = lbm::addPdfFieldToStorage( blocks, "pdf field", latticeModel, initialVelocity, real_t(1) ); + BlockDataID flagFieldId = field::addFlagFieldToStorage< FlagField_T >( blocks, "flag field" ); + + // create and initialize boundary handling + const FlagUID fluidFlagUID( "Fluid" ); + + // create time loop + SweepTimeloop timeloop( blocks->getBlockStorage(), timesteps ); + + // create communication for PdfField + blockforest::communication::UniformBufferedScheme< CommunicationStencil_T > communication( blocks ); + communication.addPackInfo( make_shared< lbm::PdfFieldPackInfo< LatticeModel_T > >( pdfFieldId ) ); + + // add LBM sweep and communication to time loop + timeloop.add() << BeforeFunction( [&](){ latticeModel.time_step = uint32_c(timeloop.getCurrentTimeStep()); }, "set RNG counter" ) + << BeforeFunction( communication, "communication" ) + << Sweep( LatticeModel_T::Sweep( pdfFieldId ), "LB stream & collide" ); + + // LBM stability check + timeloop.addFuncAfterTimeStep( makeSharedFunctor( field::makeStabilityChecker< PdfField_T, FlagField_T >( walberlaEnv.config(), blocks, pdfFieldId, + flagFieldId, fluidFlagUID ) ), + "LBM stability check" ); + + // log remaining time + timeloop.addFuncAfterTimeStep( timing::RemainingTimeLogger( timeloop.getNrOfTimeSteps(), remainingTimeLoggerFrequency ), "remaining time logger" ); + + // add VTK output to time loop + lbm::VTKOutput< LatticeModel_T, FlagField_T >::addToTimeloop( timeloop, blocks, walberlaEnv.config(), pdfFieldId, flagFieldId, fluidFlagUID ); + + // create adaptors, so that the GUI also displays density and velocity + // adaptors are like fields with the difference that they do not store values + // but calculate the values based on other fields ( here the PdfField ) + field::addFieldAdaptor<lbm::Adaptor<LatticeModel_T>::Density> ( blocks, pdfFieldId, "DensityAdaptor" ); + field::addFieldAdaptor<lbm::Adaptor<LatticeModel_T>::VelocityVector>( blocks, pdfFieldId, "VelocityAdaptor" ); + + if( parameters.getParameter<bool>( "useGui", false ) ) + { + GUI gui ( timeloop, blocks, argc, argv ); + lbm::connectToGui<LatticeModel_T> ( gui ); + gui.run(); + } + else + timeloop.run(); + + return EXIT_SUCCESS; +} diff --git a/tests/lbm/codegen/FluctuatingMRT.py b/tests/lbm/codegen/FluctuatingMRT.py new file mode 100644 index 0000000000000000000000000000000000000000..b996fe43c53dbf3fff48452cc02b3b684eaedd15 --- /dev/null +++ b/tests/lbm/codegen/FluctuatingMRT.py @@ -0,0 +1,22 @@ +import sympy as sp +import pystencils as ps +from lbmpy.creationfunctions import create_lb_collision_rule +from pystencils_walberla import CodeGeneration +from lbmpy_walberla import generate_lattice_model + +with CodeGeneration() as ctx: + omega_shear, omega_bulk = sp.symbols("omega_shear, omega_bulk") + temperature = sp.symbols("temperature") + force_field, vel_field = ps.fields("force(3), velocity(3): [3D]", layout='fzyx') + + collision_rule = create_lb_collision_rule( + stencil='D3Q19', compressible=True, fluctuating={ + 'temperature' : temperature, + 'block_offsets' : 'walberla', + }, + method='mrt3', relaxation_rates=[omega_shear, omega_bulk], + force_model='guo', force=force_field.center_vector, + optimization={'cse_global': True} + ) + + generate_lattice_model(ctx, 'FluctuatingMRT_LatticeModel', collision_rule)