waLBerla 7.3
Loading...
Searching...
No Matches
Mesh Refinement For Flow Around A Sphere

View on GitLab

This example application shows the mesh refinement functionalities for a flow around a sphere.

Code Generation

The numerical kernels involved in the application are generated by the script MeshRefinementExample.py:

import sympy as sp
import pystencils as ps
from lbmpy import LBMConfig, LBMOptimisation, LBStencil, Method, Stencil
from lbmpy.creationfunctions import create_lb_collision_rule, create_lb_method
from lbmpy.boundaries import NoSlip, FreeSlip, UBB, ExtrapolationOutflow
from pystencils_walberla import CodeGeneration, generate_info_header
from lbmpy_walberla import generate_lbm_package, lbm_boundary_generator
with CodeGeneration() as ctx:
data_type = "float64" if ctx.double_accuracy else "float32"
stencil = LBStencil(Stencil.D3Q19)
omega = sp.Symbol('omega')
target = ps.Target.CPU
layout = 'fzyx'
# Fields
pdfs, pdfs_tmp = ps.fields(f'pdfs({stencil.Q}),pdfs_tmp({stencil.Q}): {data_type}[{stencil.D}D]', layout=layout)
velocity = ps.fields(f"velocity({stencil.D}):{data_type}[{stencil.D}D]", layout=layout)
density = ps.fields(f"density({1}):{data_type}[{stencil.D}D]", layout=layout)
macroscopic_fields = {'density': density, 'velocity': velocity}
# LBM Optimisation
lbm_opt = LBMOptimisation(cse_global=True,
symbolic_field=pdfs,
symbolic_temporary_field=pdfs_tmp,
field_layout=layout)
# ==================
# Method Setup
# ==================
lbm_config = LBMConfig(stencil=stencil, output=macroscopic_fields)
lbm_method = create_lb_method(lbm_config=lbm_config)
collision_rule = create_lb_collision_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt)
freeslip = lbm_boundary_generator("FreeSlipBC", flag_uid="FreeSlip", boundary_object=FreeSlip(stencil))
noslip = lbm_boundary_generator(class_name='NoSlipBC', flag_uid='NoSlip',
boundary_object=NoSlip(calculate_force_on_boundary=True),
field_data_type=data_type)
outflow = lbm_boundary_generator( class_name='OutflowBC', flag_uid='Outflow',
boundary_object=ExtrapolationOutflow(stencil[4], lbm_method),
field_data_type=data_type)
inlet_velocity = (sp.symbols("u_x"), 0, 0) if stencil.D == 3 else (sp.symbols("u_x"), 0)
ubb = lbm_boundary_generator(class_name='UBBBC', flag_uid='UBB',
boundary_object=UBB(inlet_velocity, density=1.0, data_type=data_type, dim=stencil.D),
field_data_type=data_type)
generate_lbm_package(ctx, name="MeshRefinementExample",
collision_rule=collision_rule, lbm_config=lbm_config, lbm_optimisation=lbm_opt,
nonuniform=True, boundaries=[outflow, ubb, noslip, freeslip],
macroscopic_fields=macroscopic_fields, target=target, data_type=data_type,
pdfs_data_type=data_type, cpu_openmp=ctx.openmp)
field_typedefs = {'VelocityField_T': velocity, 'ScalarField_T': density}
stencil_typedefs = {'Stencil_T': stencil}
generate_info_header(ctx, 'InfoHeader', stencil_typedefs=stencil_typedefs, field_typedefs=field_typedefs)

Application Frame

The simulation app itself is implemented in MeshRefinementExample.cpp:

//======================================================================================================================
//
// 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/>.
//
//
//======================================================================================================================
#include "blockforest/all.h"
#include "core/all.h"
#include "field/all.h"
#include "geometry/all.h"
#include "lbm/all.h"
#include "timeloop/all.h"
#include "InfoHeader.h"
namespace walberla
{
constexpr uint_t FieldGhostLayer{2};
using StorageSpecification_T = lbm::MeshRefinementExampleStorageSpecification;
using LBMCommunicationStencil_T = StorageSpecification_T::CommunicationStencil;
using PdfField_T = lbm_generated::PdfField< StorageSpecification_T >;
using SweepCollection_T = lbm::MeshRefinementExampleSweepCollection;
using FlagField_T = FlagField< flag_t >;
using BoundaryCollection_T = lbm::MeshRefinementExampleBoundaryCollection< FlagField_T >;
const FlagUID& FluidFlagUID() { static const FlagUID uid("Fluid"); return uid; }
class AABBRefinement
{
public:
AABBRefinement(AABB objectAABB, const uint_t depth) : objectAABB_(objectAABB), refinementDepth_(depth){};
void operator()(SetupBlockForest& forest) const
{
auto extendedAABB = AABB(objectAABB_.minCorner()[0] - objectAABB_.xSize() * 0.0_r, objectAABB_.minCorner()[1] - objectAABB_.ySize() * 0.0_r, objectAABB_.minCorner()[2] - objectAABB_.zSize() * 0.0_r,
objectAABB_.maxCorner()[0] + 0.3_r * objectAABB_.xSize(), objectAABB_.maxCorner()[1] + objectAABB_.ySize() * 0.0_r, objectAABB_.maxCorner()[2] + objectAABB_.zSize() * 0.0_r);
for(auto & block : forest) {
auto blockAABB = block.getAABB();
if (extendedAABB.intersects(blockAABB)) {
if( block.getLevel() < refinementDepth_)
block.setMarker( true );
}
}
}
private:
};
int main(int argc, char** argv)
{
Environment env(argc, argv);
if (!env.config()) { WALBERLA_ABORT("No configuration file specified!"); }
mpi::MPIManager::instance()->useWorldComm();
// Get parameters from config file
auto parameters = env.config()->getOneBlock("Parameters");
const uint_t timesteps = parameters.getParameter< uint_t >("timesteps");
const Vector3<uint_t> rootBlocks = parameters.getParameter< Vector3<uint_t> >("rootBlocks");
Vector3<uint_t> cellsPerBlock = parameters.getParameter< Vector3< uint_t > >("cellsPerBlock");
Vector3<real_t> sphereCenter = parameters.getParameter< Vector3< real_t > >("sphereCenter");
const real_t sphereRadius = parameters.getParameter< real_t >("sphereRadius");
const uint_t refinementLevels = parameters.getParameter< uint_t >("refinementLevels");
const uint_t vtkWriteFrequency = parameters.getParameter< uint_t >("vtkWriteFrequency");
const real_t omega = parameters.getParameter< real_t >("omega");
auto aabb = AABB(0,0,0,1.0, 1.0, 1.0);
geometry::Sphere sphere(sphereCenter, sphereRadius);
// Create block forest
const uint_t numProcs = uint_c(mpi::MPIManager::instance()->numProcesses());
SetupBlockForest setupBfs;
AABBRefinement refinement( sphere.boundingBox(), refinementLevels );
setupBfs.addRefinementSelectionFunction(std::function<void(SetupBlockForest &)>(refinement));
setupBfs.addWorkloadMemorySUIDAssignmentFunction(blockforest::uniformWorkloadAndMemoryAssignment);
setupBfs.init(aabb, rootBlocks[0], rootBlocks[1], rootBlocks[2], false, false, false);
setupBfs.balanceLoad(blockforest::StaticLevelwiseCurveBalanceWeighted(), numProcs);
shared_ptr< BlockForest > forest = std::make_shared< BlockForest >(uint_c(MPIManager::instance()->worldRank()), setupBfs);
auto blocks = std::make_shared< StructuredBlockForest >(forest, cellsPerBlock[0], cellsPerBlock[1], cellsPerBlock[2]);
blocks->createCellBoundingBoxes();
// Data fields
const BlockDataID pdfFieldCpuId = lbm_generated::addPdfFieldToStorage(blocks, "pdfs", StorageSpec, FieldGhostLayer, field::fzyx);
const BlockDataID velocityFieldCpuId = field::addToStorage< VelocityField_T >(blocks, "velocity", real_c(0.0), field::fzyx, FieldGhostLayer);
const BlockDataID densityFieldCpuId = field::addToStorage< ScalarField_T >(blocks, "density", real_c(1.0), field::fzyx, FieldGhostLayer);
const BlockDataID flagFieldId = field::addFlagFieldToStorage< FlagField_T >(blocks, "flag field", FieldGhostLayer);
SweepCollection_T sweepCollection( blocks, densityFieldCpuId, pdfFieldCpuId, velocityFieldCpuId, omega);
// Initialize Velocity and PDF field
Vector3<real_t> initialVel(0.1_r, 0, 0);
for (auto& block : *blocks)
{
auto velField = block.getData<VelocityField_T>(velocityFieldCpuId);
for (uint_t d = 0; d < LBMCommunicationStencil_T::D; ++d) {
velField->get(x,y,z,d) = initialVel[d];
}
)
sweepCollection.initialise(&block, 0);
}
// Boundary handling
auto boundariesConfig = env.config()->getOneBlock("Boundaries");
geometry::initBoundaryHandling< FlagField_T >(*blocks, flagFieldId, boundariesConfig);
FlagUID objBoundaryUID("NoSlip");
for (auto& block : *blocks)
{
auto * flagField = block.getData<FlagField_T>(flagFieldId);
if ( !flagField->flagExists(objBoundaryUID))
flagField->registerFlag(objBoundaryUID);
auto flag = flagField->getFlag(objBoundaryUID);
Cell cell(x,y,z);
auto midPoint = blocks->getGlobalCellCenterFromBlockLocalCell(cell, block);
if (contains(sphere, midPoint)) {
flagField->addFlag(cell, flag);
}
)
}
BoundaryCollection_T boundaryCollection( blocks, flagFieldId, pdfFieldCpuId, FluidFlagUID(), initialVel[0] );
// Communication
auto communication = std::make_shared< blockforest::communication::NonUniformBufferedScheme< LBMCommunicationStencil_T > >(blocks);
auto packInfo = lbm_generated::setupNonuniformPdfCommunication< PdfField_T >(blocks, pdfFieldCpuId);
communication->addPackInfo(packInfo);
// Timeloop
SweepTimeloop timeloop(blocks->getBlockStorage(), timesteps);
blocks, pdfFieldCpuId, sweepCollection, boundaryCollection, communication, packInfo);
LBMMeshRefinement.addRefinementToTimeLoop(timeloop, 0);
timeloop.addFuncAfterTimeStep(timing::RemainingTimeLogger(timeloop.getNrOfTimeSteps(), 10), "remaining time logger");
// VTK output
if (vtkWriteFrequency > 0)
{
auto vtkOutput = vtk::createVTKOutput_BlockData(*blocks, "vtk", vtkWriteFrequency, 0);
auto velocityWriter = make_shared< field::VTKWriter< VelocityField_T > >(velocityFieldCpuId, "velocity");
auto densityWriter = make_shared< field::VTKWriter< ScalarField_T > >(densityFieldCpuId, "density");
vtkOutput->addCellDataWriter(velocityWriter);
vtkOutput->addCellDataWriter(densityWriter);
fluidFilter.addFlag(FluidFlagUID());
vtkOutput->addCellInclusionFilter(fluidFilter);
timeloop.addFuncAfterTimeStep(vtk::writeFiles(vtkOutput), "VTK Output");
vtk::writeDomainDecomposition(blocks, "domain_decomposition", "vtk_out", "write_call", true, true, 0);
}
// Run Simulation
WcTimer simTimer;
WcTimingPool timingPool;
simTimer.start();
timeloop.run(timingPool);
simTimer.end();
double time = simTimer.max();
// Performance metrics
lbm_generated::PerformanceEvaluation<FlagField_T> const performance(blocks, flagFieldId, FluidFlagUID());
performance.logResultOnRoot(timesteps, time);
timingPool.unifyRegisteredTimersAcrossProcesses();
timingPool.logResultOnRoot( timing::REDUCE_TOTAL, true );
return EXIT_SUCCESS;
}
} // namespace walberla
int main(int argc, char** argv) { walberla::main(argc, argv); }
int main(int argc, char **argv)
Definition 01_BlocksAndFields.cpp:58
#define WALBERLA_ABORT(msg)
Definition Abort.h:62
#define WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ(...)
Definition IteratorMacros.h:1214
#define WALBERLA_MPI_WORLD_BARRIER()
Definition MPIManager.h:330
Definition MeshRefinementExample.cpp:55
AABBRefinement(AABB objectAABB, const uint_t depth)
Definition MeshRefinementExample.cpp:57
const uint_t refinementDepth_
Definition MeshRefinementExample.cpp:73
const AABB objectAABB_
Definition MeshRefinementExample.cpp:72
void operator()(SetupBlockForest &forest) const
Definition MeshRefinementExample.cpp:59
RAII Object to initialize waLBerla using command line parameters.
Definition Environment.h:39
Definition BlockForest.h:51
Definition SetupBlockForest.h:43
Definition StructuredBlockForest.h:34
A representation of a Cell's coordinates (in 3D).
Definition Cell.h:48
Definition FlagFieldCellFilter.h:36
void logInfoOnRoot() const
Definition BlockForestEvaluation.h:88
Definition BlockForestEvaluation.h:175
Definition BasicRecursiveTimeStep.h:46
Class for evaluating the performance of LBM simulations using fields.
Definition PerformanceEvaluation.h:211
Efficient, generic implementation of a 3-dimensional vector.
Definition Vector3.h:92
Encapsulates MPI Rank/Communicator information.
Definition MPIManager.h:60
Definition RemainingTimeLogger.h:47
Collective header file for module core.
Collective header file for module domain_decomposition.
Collective header file for module lbm.
Definition AABBRefinementSelection.h:35
Definition Cell.h:39
Definition ReducePackInfo.h:34
Definition Config.cpp:32
Definition AccuracyEvaluation.h:48
Definition AABBBody.h:29
bool contains(const AABB &aabb, const Vector3< real_t > &point)
Definition AABBBody.h:55
void setNonBoundaryCellsToDomain(StructuredBlockStorage &blocks, BlockDataID boundaryHandlingId)
Definition InitBoundaryHandling.h:120
void initBoundaryHandling(StructuredBlockStorage &blocks, BlockDataID boundaryHandlingId, const Config::BlockHandle &geometryBlock)
Convenience function for setting up boundary handling via a block in the configuration file.
Definition InitBoundaryHandling.h:84
Definition CombinedInPlacePackInfo.h:24
std::shared_ptr< NonuniformGeneratedPdfPackInfo< PdfField_T > > setupNonuniformPdfCommunication(const std::weak_ptr< StructuredBlockForest > &blocks, const BlockDataID pdfFieldID, const std::string &dataIdentifier="NonuniformCommData")
Sets up a NonuniformGeneratedPdfPackInfo.
Definition NonuniformGeneratedPdfPackInfo.impl.h:47
GenericAABB< real_t > AABB
Definition AABBFwd.h:33
Definition BlockID.h:401
Definition ITimeloop.h:27
@ REDUCE_TOTAL
Collects all timing samples from all processes and accumulates the data.
Definition ReduceType.h:37
shared_ptr< VTKOutput > createVTKOutput_BlockData(const StructuredBlockStorage &sbs, const std::string &identifier=std::string("block_data"), const uint_t writeFrequency=1, const uint_t ghostLayers=0, const bool forcePVTU=false, const std::string &baseFolder=std::string("vtk_out"), const std::string &executionFolder=std::string("simulation_step"), const bool continuousNumbering=false, const bool binary=true, const bool littleEndian=true, const bool useMPIIO=true, const uint_t initialExecutionCount=0, const bool amrFileFormat=false, const bool oneFilePerProcess=false)
Definition VTKOutput.h:588
VTKOutput::Write writeFiles(const shared_ptr< VTKOutput > &vtk, const bool immediatelyWriteCollectors=true, const int simultaneousIOOperations=0, const Set< SUID > &requiredStates=Set< SUID >::emptySet(), const Set< SUID > &incompatibleStates=Set< SUID >::emptySet())
Definition VTKOutput.h:710
void writeDomainDecomposition(const StructuredBlockStorage &sbs, const std::string &identifier=std::string("domain_decomposition"), const std::string &baseFolder=std::string("vtk_out"), const std::string &executionFolder=std::string("write_call"), const bool binary=true, const bool littleEndian=true, const int simultaneousIOOperations=0, const Set< SUID > &requiredStates=Set< SUID >::emptySet(), const Set< SUID > &incompatibleStates=Set< SUID >::emptySet(), bool useMPIIO=true)
Definition VTKOutput.h:648
Storage for detected contacts which can be used to perform actions for all contacts,...
Definition FreeSlip.hpp:42
timing::Timer< timing::WcPolicy > WcTimer
Definition Timer.h:594
FlagField< flag_t > FlagField_T
Definition 02_LBMLatticeModelGeneration.cpp:64
uint_t uint_c(T t)
cast to type uint_t using "uint_c(x)"
Definition DataTypes.h:169
lbm::PdfField< LatticeModel_T > PdfField_T
[typedefs]
Definition 02_LBMLatticeModelGeneration.cpp:60
StorageSpecification_T::CommunicationStencil LBMCommunicationStencil_T
Definition 04_LBComplexGeometry.cpp:92
typename timeloop::SweepTimeloop< > SweepTimeloop
Definition SweepTimeloop.h:198
timing::TimingPool< timing::WcPolicy > WcTimingPool
Definition TimingPool.h:697
real_t real_c(T t)
cast to type real_t using "real_c(x)"
Definition DataTypes.h:241
lbm::LBComplexGeometryBoundaryCollection< FlagField_T > BoundaryCollection_T
Definition 04_LBComplexGeometry.cpp:113
constexpr uint_t FieldGhostLayer
Definition 04_LBComplexGeometry.cpp:89
lbm::LBComplexGeometrySweepCollection SweepCollection_T
Definition 04_LBComplexGeometry.cpp:104
int main(int argc, char **argv)
Main Function ///.
Definition 01_BlocksAndFields.cpp:36
lbm::LBComplexGeometryStorageSpecification StorageSpecification_T
Definition 04_LBComplexGeometry.cpp:91
const FlagUID & FluidFlagUID()
Definition 04_LBComplexGeometry.cpp:115
float real_t
Definition DataTypes.h:197
std::size_t uint_t
Definition DataTypes.h:161
std::uint32_t uint32_t
32 bit unsigned integer
Definition DataTypes.h:126
walberla::uint8_t flag_t
Definition 02_LBMLatticeModelGeneration.cpp:63
Collective header file for module timeloop.