Commit 997402d4 authored by Michael Kuron's avatar Michael Kuron
Browse files

Merge branch 'fluctuating_mrt_momentum_test' into 'master'

Test generated fluctuating MRT LB momentum balance

See merge request walberla/walberla!355
parents 50d09921 2babe361
...@@ -106,6 +106,7 @@ waLBerla_compile_test( FILES codegen/LbCodeGenerationExample.cpp DEPENDS LbCodeG ...@@ -106,6 +106,7 @@ waLBerla_compile_test( FILES codegen/LbCodeGenerationExample.cpp DEPENDS LbCodeG
waLBerla_generate_target_from_python(NAME FluctuatingMRTGenerated FILE codegen/FluctuatingMRT.py waLBerla_generate_target_from_python(NAME FluctuatingMRTGenerated FILE codegen/FluctuatingMRT.py
OUT_FILES FluctuatingMRT_LatticeModel.cpp FluctuatingMRT_LatticeModel.h ) OUT_FILES FluctuatingMRT_LatticeModel.cpp FluctuatingMRT_LatticeModel.h )
waLBerla_compile_test( FILES codegen/FluctuatingMRT.cpp DEPENDS FluctuatingMRTGenerated) waLBerla_compile_test( FILES codegen/FluctuatingMRT.cpp DEPENDS FluctuatingMRTGenerated)
waLBerla_execute_test( NAME FluctuatingMRT COMMAND $<TARGET_FILE:FluctuatingMRT> ${CMAKE_CURRENT_SOURCE_DIR}/codegen/FluctuatingMRT.prm PROCESSES 1)
waLBerla_generate_target_from_python(NAME FieldLayoutAndVectorizationTestGenerated FILE codegen/FieldLayoutAndVectorizationTest.py waLBerla_generate_target_from_python(NAME FieldLayoutAndVectorizationTestGenerated FILE codegen/FieldLayoutAndVectorizationTest.py
OUT_FILES FieldLayoutAndVectorizationTest_FZYX_Vec_LatticeModel.cpp FieldLayoutAndVectorizationTest_FZYX_Vec_LatticeModel.h OUT_FILES FieldLayoutAndVectorizationTest_FZYX_Vec_LatticeModel.cpp FieldLayoutAndVectorizationTest_FZYX_Vec_LatticeModel.h
......
...@@ -18,19 +18,21 @@ ...@@ -18,19 +18,21 @@
// //
//====================================================================================================================== //======================================================================================================================
/* This tests momentum balance for a fluctuating MRT LB with a constant
force applied
*/
#include "blockforest/all.h" #include "blockforest/all.h"
#include "core/all.h" #include "core/all.h"
#include "domain_decomposition/all.h" #include "domain_decomposition/all.h"
#include "field/all.h" #include "field/all.h"
#include "geometry/all.h" #include "geometry/all.h"
#include "gui/all.h"
#include "timeloop/all.h" #include "timeloop/all.h"
#include "lbm/field/PdfField.h"
#include "lbm/field/AddToStorage.h"
#include "lbm/communication/PdfFieldPackInfo.h" #include "lbm/communication/PdfFieldPackInfo.h"
#include "lbm/gui/Connection.h" #include "lbm/field/Adaptors.h"
#include "lbm/vtk/VTKOutput.h" #include "lbm/field/AddToStorage.h"
#include "lbm/field/PdfField.h"
#include "FluctuatingMRT_LatticeModel.h" #include "FluctuatingMRT_LatticeModel.h"
...@@ -59,18 +61,21 @@ int main( int argc, char ** argv ) ...@@ -59,18 +61,21 @@ int main( int argc, char ** argv )
// read parameters // read parameters
auto parameters = walberlaEnv.config()->getOneBlock( "Parameters" ); auto parameters = walberlaEnv.config()->getOneBlock( "Parameters" );
const real_t omega = parameters.getParameter< real_t > ( "omega", real_c( 1.4 ) ); const real_t omega = parameters.getParameter< real_t > ( "omega", real_c(1.4) );
const real_t magic_number = 3. / 16;
const real_t omega_2 = (4 - 2 * omega) / (4 * magic_number * omega + 2 - omega);
const Vector3<real_t> initialVelocity = parameters.getParameter< Vector3<real_t> >( "initialVelocity", Vector3<real_t>() ); 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 uint_t timesteps = parameters.getParameter< uint_t > ( "timesteps", uint_c(10) );
const real_t temperature = real_t(0.01); const real_t temperature = real_t(0.01);
const uint_t seed = uint_t(0); const uint_t seed = uint_t(0);
const double remainingTimeLoggerFrequency = parameters.getParameter< double >( "remainingTimeLoggerFrequency", 3.0 ); // in seconds const real_t remainingTimeLoggerFrequency = parameters.getParameter< double >( "remainingTimeLoggerFrequency", 3.0 ); // in seconds
// create fields // create fields
BlockDataID forceFieldId = field::addToStorage<VectorField_T>( blocks, "Force", real_t( 0.0 ), field::fzyx); real_t force = 2E-4; // Force to apply on each node on each axis
BlockDataID forceFieldId = field::addToStorage<VectorField_T>( blocks, "Force", force, field::fzyx );
LatticeModel_T latticeModel = LatticeModel_T( forceFieldId, omega, 0, omega, omega, seed, temperature, uint_t(0) ); LatticeModel_T latticeModel = LatticeModel_T( forceFieldId, omega, omega, omega_2, omega, seed, temperature, uint_t(0) );
BlockDataID pdfFieldId = lbm::addPdfFieldToStorage( blocks, "pdf field", latticeModel, initialVelocity, real_t(1), uint_t(1), field::fzyx ); BlockDataID pdfFieldId = lbm::addPdfFieldToStorage( blocks, "pdf field", latticeModel, initialVelocity, real_t(1), uint_t(1), field::fzyx );
BlockDataID flagFieldId = field::addFlagFieldToStorage< FlagField_T >( blocks, "flag field" ); BlockDataID flagFieldId = field::addFlagFieldToStorage< FlagField_T >( blocks, "flag field" );
...@@ -86,8 +91,8 @@ int main( int argc, char ** argv ) ...@@ -86,8 +91,8 @@ int main( int argc, char ** argv )
communication.addPackInfo( make_shared< lbm::PdfFieldPackInfo< LatticeModel_T > >( pdfFieldId ) ); communication.addPackInfo( make_shared< lbm::PdfFieldPackInfo< LatticeModel_T > >( pdfFieldId ) );
// set the RNG counter to match the time step and propagate it to the fields' copies of the lattice model // set the RNG counter to match the time step and propagate it to the fields' copies of the lattice model
timeloop.add() << BeforeFunction( [&](){ latticeModel.time_step_ = uint32_c(timeloop.getCurrentTimeStep()); }, "set RNG counter" ) timeloop.add() << BeforeFunction( [&]() { latticeModel.time_step_ = uint32_c(timeloop.getCurrentTimeStep()); }, "set RNG counter" )
<< Sweep( [&]( IBlock * block ){ << Sweep( [&]( IBlock * block ) {
auto field = block->getData< PdfField_T >( pdfFieldId ); auto field = block->getData< PdfField_T >( pdfFieldId );
field->latticeModel().time_step_ = latticeModel.time_step_; field->latticeModel().time_step_ = latticeModel.time_step_;
}, "set RNG counter" ); }, "set RNG counter" );
...@@ -101,25 +106,32 @@ int main( int argc, char ** argv ) ...@@ -101,25 +106,32 @@ int main( int argc, char ** argv )
"LBM stability check" ); "LBM stability check" );
// log remaining time // log remaining time
timeloop.addFuncAfterTimeStep( timing::RemainingTimeLogger( timeloop.getNrOfTimeSteps(), remainingTimeLoggerFrequency ), "remaining time logger" ); timeloop.addFuncAfterTimeStep( timing::RemainingTimeLogger(timeloop.getNrOfTimeSteps(), remainingTimeLoggerFrequency), "remaining time logger" );
// add VTK output to time loop auto densityAdaptorId = field::addFieldAdaptor<lbm::Adaptor<LatticeModel_T>::Density> ( blocks, pdfFieldId, "DensityAdaptor" );
lbm::VTKOutput< LatticeModel_T, FlagField_T >::addToTimeloop( timeloop, blocks, walberlaEnv.config(), pdfFieldId, flagFieldId, fluidFlagUID ); auto velocityAdaptorId = field::addFieldAdaptor<lbm::Adaptor<LatticeModel_T>::VelocityVector>( blocks, pdfFieldId, "VelocityAdaptor" );
// create adaptors, so that the GUI also displays density and velocity timeloop.run();
// 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 ) ) // Calculate momentum
Vector3<real_t> momentum; // observed momentum
int count = 0; // count of lb nodes traversed
for (auto block = blocks->begin(); block != blocks->end(); ++block)
{ {
GUI gui ( timeloop, blocks, argc, argv ); auto v = block->getData< lbm::Adaptor< LatticeModel_T >::VelocityVector >(velocityAdaptorId);
lbm::connectToGui<LatticeModel_T> ( gui ); auto rho = block->getData< lbm::Adaptor< LatticeModel_T >::Density >(densityAdaptorId);
gui.run(); WALBERLA_FOR_ALL_CELLS_XYZ_OMP(v, omp critical, {
momentum += rho->get(x, y, z) * v->get(x, y, z);
count++;
});
} }
else
timeloop.run(); // check
real_t expected_momentum = real_c(count) * force * real_c(timesteps);
printf("%g %g %g | %g\n", momentum[0], momentum[1], momentum[2], expected_momentum);
WALBERLA_CHECK_FLOAT_EQUAL(momentum[0], expected_momentum);
WALBERLA_CHECK_FLOAT_EQUAL(momentum[1], expected_momentum);
WALBERLA_CHECK_FLOAT_EQUAL(momentum[2], expected_momentum);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
Parameters
{
omega 0.5;
timesteps 2;
useGui 0;
remainingTimeLoggerFrequency 3; // in seconds
}
DomainSetup
{
blocks < 1, 1, 1 >;
cellsPerBlock < 30, 30, 10 >;
periodic < 1, 1, 1 >;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment