The numerical kernels involved in the application are generated by the script AdaptiveMeshRefinementExample.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'
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_opt = LBMOptimisation(cse_global=True,
symbolic_field=pdfs,
symbolic_temporary_field=pdfs_tmp,
field_layout=layout)
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="AdaptiveMeshRefinementExample",
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)
#include "field/all.h"
#include "geometry/all.h"
#include "InfoHeader.h"
{
using PdfField_T = lbm_generated::PdfField< StorageSpecification_T >;
class VelocityGradientRefinement
{
public:
{}
void operator()(std::vector< std::pair< const Block*, uint_t > >& minTargetLevels,
std::vector< const Block* >&, const BlockForest&) const
{
for (auto& [block, targetLevel] : minTargetLevels)
{
const uint_t currentLevel = block->getLevel();
if (sphereBox.intersects(block->getAABB()))
{
continue;
}
const auto* u = block->getData< VelocityField_T >(
velFieldId_);
{
{
maxGradientSq = std::max(maxGradientSq,
real_c(0.25) * (dx * dx + dy * dy + dz * dz));
}
}
targetLevel = currentLevel +
uint_t(1);
else if (maxGradientSq < lowerLimit_ && currentLevel >
uint_t(0))
targetLevel = currentLevel -
uint_t(1);
}
}
private:
};
int main(
int argc,
char** argv)
{
if (!env.config()) {
WALBERLA_ABORT(
"No configuration file specified!") }
mpi::MPIManager::instance()->useWorldComm();
auto parameters = env.config()->getOneBlock("Parameters");
const uint_t timesteps = parameters.getParameter<
uint_t >(
"timesteps");
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");
const uint_t refinementFrequency = parameters.getParameter<
uint_t >(
"refinementFrequency",
uint_c(100));
const real_t lowerRefinementLimit = parameters.getParameter<
real_t >(
"lowerRefinementLimit",
real_c(1e-5));
const real_t upperRefinementLimit = parameters.getParameter<
real_t >(
"upperRefinementLimit",
real_c(1e-4));
const uint_t numProcs =
uint_c(mpi::MPIManager::instance()->numProcesses());
setupBfs.init(domainAABB, rootBlocks[0], rootBlocks[1], rootBlocks[2], false, false, false);
auto 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();
forest->recalculateBlockLevelsInRefresh(true);
forest->alwaysRebalanceInRefresh(true);
forest->allowRefreshChangingDepth(true);
forest->allowMultipleRefreshCycles(true);
forest->reevaluateMinTargetLevelsAfterForcedRefinement(true);
forest->checkForEarlyOutInRefresh(true);
forest->checkForLateOutInRefresh(true);
forest->setRefreshPhantomBlockMigrationPreparationFunction(
auto communication = std::make_shared< blockforest::communication::NonUniformBufferedScheme< LBMCommunicationStencil_T > >(blocks);
auto boundariesConfig = env.config()->getOneBlock("Boundaries");
FlagUID objBoundaryUID("NoSlip");
auto setupFlagField = [&]() {
for (auto& block : *blocks)
{
auto * flagField = block.getData<
FlagField_T>(flagFieldId);
if ( !flagField->flagExists(objBoundaryUID))
flagField->registerFlag(objBoundaryUID);
auto flag = flagField->getFlag(objBoundaryUID);
auto midPoint = blocks->getGlobalCellCenterFromBlockLocalCell(
cell, block);
flagField->addFlag(
cell, flag);
}
)
}
};
setupFlagField();
for (auto& block : *blocks)
{
auto* velField = block.getData< VelocityField_T >(velFieldId);
for (
uint_t d = 0; d <
uint_c(3); ++d) velField->get(x, y, z, d) = initialVel[d];
)
sweepCollection.initialise(&block,
cell_idx_c(2));
}
auto refillBoundaries = [&]() {
};
blocks, pdfFieldId, sweepCollection, boundaryCollection,
communication, packInfo);
refinementLevels);
auto adaptiveRefinementStep = [&]() {
for (auto& block : *blocks)
sweepCollection.calculateMacroscopicParameters(&block);
forest->setRefreshMinTargetLevelDeterminationFunction(refinementCriterion);
forest->refresh();
for (auto& block : *blocks)
packInfo->recalculateNonuniformCommData(&block);
setupFlagField();
refillBoundaries();
<< forest->getNumberOfBlocks() << " blocks on root process")
};
adaptiveRefinementStep();
if (refinementFrequency > 0)
{
[&, refinementFrequency]() {
if (step >
uint_c(0) && step % refinementFrequency == 0)
{
adaptiveRefinementStep();
}
},
"Adaptive mesh refinement");
}
timeloop.addFuncBeforeTimeStep(LBMMeshRefinement,
"Recursive LBM time step");
if (vtkWriteFrequency > 0)
{
auto vtkOutput =
vtk::createVTKOutput_BlockData(*blocks,
"vtk", vtkWriteFrequency, 0,
true,
"vtk_out",
"simulation_step",
false,
true,
true,
false, 0,
false);
auto velocityWriter = make_shared< field::VTKWriter< VelocityField_T > >(velFieldId, "velocity");
auto densityWriter = make_shared< field::VTKWriter< ScalarField_T > >(densityId, "density");
vtkOutput->addCellDataWriter(velocityWriter);
vtkOutput->addCellDataWriter(densityWriter);
vtkOutput->addCellInclusionFilter(fluidFilter);
vtkOutput->addBeforeFunction([&]() {
for (auto& block : *blocks)
sweepCollection.calculateMacroscopicParameters(&block);
});
*blocks, "domain_decomposition", vtkWriteFrequency, "vtk_out", "simulation_step", false, true, true, false);
}
simTimer.start();
simTimer.end();
performance.logResultOnRoot(timesteps, simTimer.max());
timingPool.unifyRegisteredTimersAcrossProcesses();
return EXIT_SUCCESS;
}
}
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_LOG_INFO_ON_ROOT(msg)
Definition Logging.h:669
RAII Object to initialize waLBerla using command line parameters.
Definition Environment.h:39
Adaptive refinement criterion.
Definition AdaptiveMeshRefinementExample.cpp:73
void operator()(std::vector< std::pair< const Block *, uint_t > > &minTargetLevels, std::vector< const Block * > &, const BlockForest &) const
Definition AdaptiveMeshRefinementExample.cpp:81
VelocityGradientRefinement(const ConstBlockDataID &velFieldId, const geometry::Sphere &sphere, const real_t lowerLimit, const real_t upperLimit, const uint_t maxLevel)
Definition AdaptiveMeshRefinementExample.cpp:75
ConstBlockDataID velFieldId_
Definition AdaptiveMeshRefinementExample.cpp:125
geometry::Sphere sphere_
Definition AdaptiveMeshRefinementExample.cpp:126
uint_t maxLevel_
Definition AdaptiveMeshRefinementExample.cpp:129
real_t lowerLimit_
Definition AdaptiveMeshRefinementExample.cpp:127
real_t upperLimit_
Definition AdaptiveMeshRefinementExample.cpp:128
This class implements Hilber and Morton space filling curves for load balancing.
Definition DynamicCurve.h:101
Definition SetupBlockForest.h:43
void addWorkloadMemorySUIDAssignmentFunction(WorkloadMemorySUIDAssignmentFunction function, const Set< SUID > &requiredSelectors=Set< SUID >::emptySet(), const Set< SUID > &incompatibleSelectors=Set< SUID >::emptySet(), const std::string &identifier=std::string())
Definition SetupBlockForest.h:691
Definition StaticCurve.h:49
A representation of a Cell's coordinates (in 3D).
Definition Cell.h:48
Definition BlockDataID.h:42
Definition FlagFieldCellFilter.h:36
Class representing a Sphere.
Definition Sphere.h:47
const AABB & boundingBox() const
Definition Sphere.h:61
Definition BasicRecursiveTimeStep.h:46
void scale(const value_type factor)
Scales this GenericAABB.
Definition GenericAABB.impl.h:1601
Efficient, generic implementation of a 3-dimensional vector.
Definition Vector3.h:92
Definition RemainingTimeLogger.h:47
Collective header file for module core.
void uniformWorkloadAndMemoryAssignment(SetupBlockForest &forest)
Definition Initialization.cpp:792
Definition ReducePackInfo.h:34
@ fzyx
Value-sorted data layout (f should be outermost loop).
Definition Layout.h:34
BlockDataID addFlagFieldToStorage(const shared_ptr< BlockStorage_T > &blocks, const std::string &identifier, const uint_t nrOfGhostLayers=uint_t{1}, const bool alwaysInitialize=false, const std::function< void(FlagField_T *field, IBlock *const block) > &initFunction=std::function< void(FlagField_T *field, IBlock *const block) >(), const Set< SUID > &requiredSelectors=Set< SUID >::emptySet(), const Set< SUID > &incompatibleSelectors=Set< SUID >::emptySet())
Definition AddToStorage.h:59
BlockDataID addToStorage(const shared_ptr< BlockStorage_T > &blocks, const std::string &identifier, const typename GhostLayerField_T::value_type &initValue=typename GhostLayerField_T::value_type(), const Layout layout=fzyx, const uint_t nrOfGhostLayers=uint_t{1}, const bool alwaysInitialize=false, const std::function< void(GhostLayerField_T *field, IBlock *const block) > &initFunction=std::function< void(GhostLayerField_T *field, IBlock *const block) >(), const Set< SUID > &requiredSelectors=Set< SUID >::emptySet(), const Set< SUID > &incompatibleSelectors=Set< SUID >::emptySet())
Definition AddToStorage.h:151
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
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
BlockDataID addPdfFieldToStorage(const shared_ptr< BlockStorage_T > &blocks, const std::string &identifier, const LatticeStorageSpecification_T &storageSpecification, const uint_t ghostLayers, const field::Layout &layout=field::fzyx, const Set< SUID > &requiredSelectors=Set< SUID >::emptySet(), const Set< SUID > &incompatibleSelectors=Set< SUID >::emptySet(), const shared_ptr< field::FieldAllocator< typename LatticeStorageSpecification_T::value_type > > alloc=nullptr)
Definition AddToStorage.h:118
GenericAABB< real_t > AABB
Definition AABBFwd.h:33
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
shared_ptr< VTKOutput > createVTKOutput_DomainDecomposition(const BlockStorage &bs, const std::string &identifier=std::string("domain_decomposition"), const uint_t writeFrequency=1, 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)
Definition VTKOutput.h:530
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
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
int cell_idx_t
Definition DataTypes.h:180
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
const FlagUID & UBBFlagUID()
Definition 04_LBComplexGeometry.cpp:120
const FlagUID & FreeSlipFlagUID()
Definition 04_LBComplexGeometry.cpp:119
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
cell_idx_t cell_idx_c(T t)
cast to type cell_idx_t using "cell_idx_c(x)"
Definition DataTypes.h:188
const FlagUID & OutflowFlagUID()
Definition 04_LBComplexGeometry.cpp:121
walberla::uint8_t flag_t
Definition 02_LBMLatticeModelGeneration.cpp:63
const FlagUID & NoSlipFlagUID()
Definition 04_LBComplexGeometry.cpp:116
Collective header file for module timeloop.