40#include <helper_timer.h>
97 return std::string(fname +
"_Restart_" + std::to_string(
myID) +
"_" + std::to_string(step));
124 communicator(*
vf::parallel::MPICommunicator::getInstance())
126 communicator(*
vf::parallel::NullCommunicator::getInstance())
133 init(*gridGenerator, bcFactory, tmFactory, scalingFactory);
142 init(
gridProvider, bcFactory, tmFactory, scalingFactory);
153 para->initLBMSimulationParameter();
161 para->setRe(para->getVelocity() * (
real)1.0 / para->getViscosity());
163 restart_object = std::make_shared<ASCIIRestartObject>();
165 VF_LOG_TRACE(
"vis_ratio: {}", para->getViscosityRatio());
169 cudaMemoryManager->setMemsizeGPU(0,
true);
171 allocNeighborsOffsetsScalesAndBoundaries(
gridProvider, bcFactory);
174 VF_LOG_INFO(
"Start initializing precollision interactors");
188 if (para->getUseStreams()) {
191 para->getStreamManager()->createCudaEvents();
195 if (para->getKernelNeedsFluidNodeIndicesToRun()) {
203 kernels = kernelFactory->makeKernels(para);
204 for (
const auto& kernel : kernels) {
205 kernel->checkKernelParameters(para->getMaxLevel(), para->getVelocity(),
206 para->getParH(para->getMaxLevel())->viscosity);
209 if (para->getDiffOn()) {
211 adKernels = kernelFactory->makeAdvectionDiffusionKernels(para);
212 std::vector<PreProcessorType>
preProADTypes = adKernels.at(0)->getPreProcessorTypes();
213 preProcessorAD = preProcessorFactory->makePreProcessor(
preProADTypes, para);
220 std::vector<PreProcessorType>
preProTypes = kernels.at(0)->getPreProcessorTypes();
221 preProcessor = preProcessorFactory->makePreProcessor(
preProTypes, para);
226 if (para->getCalcDragLift())
232 if (para->getCalcMean()) {
234 if (para->getDiffOn())
237 allocMean(para.get(), cudaMemoryManager.get());
243 if (para->getCalcTurbulenceIntensity()) {
244 VF_LOG_TRACE(
"alloc arrays for calculating Turbulence Intensity");
251 if (para->getCalc2ndOrderMoments()) {
255 if (para->getCalc3rdOrderMoments()) {
259 if (para->getCalcHighOrderMoments()) {
267 if (para->getUseMeasurePoints()) {
269 ReaderMeasurePoints::readMeasurePoints(para.get(), cudaMemoryManager.get());
283 initLattice(para, preProcessor, preProcessorAD, cudaMemoryManager);
289 if (para->getDevices().size() > 2) {
290 VF_LOG_INFO(
"Find indices of edge nodes for multiGPU communication");
296 if (para->getDoCheckPoint() || para->getDoRestart()) {
297 VF_LOG_INFO(
"Alloc Memory for CheckPoint / Restart");
298 for (
int lev = para->getCoarse();
lev <= para->getFine();
lev++) {
299 cudaMemoryManager->cudaAllocFsForCheckPointAndRestart(
lev);
306 if (para->getDoRestart()) {
309 const auto name =
getFileName(para->getFName(), para->getTimeDoRestart(), para->getMyProcessID());
310 restart_object->deserialize(name, para);
313 for (
int lev = para->getCoarse();
lev <= para->getFine();
lev++) {
315 cudaMemoryManager->cudaCopyFsForRestart(
lev);
319 para->getParD(
lev)->rho, para->getParD(
lev)->pressure, para->getParD(
lev)->typeOfGridNode,
320 para->getParD(
lev)->neighborX, para->getParD(
lev)->neighborY,
321 para->getParD(
lev)->neighborZ, para->getParD(
lev)->numberOfNodes,
322 para->getParD(
lev)->numberofthreads, para->getParD(
lev)->distributions.f[0],
323 para->getParD(
lev)->isEvenTimestep);
332 this->updateGrid27 = std::make_unique<UpdateGrid27>(para, communicator, cudaMemoryManager, kernels, adKernels, bcFactory,
333 tmFactory, scalingFactory);
339 dataWriter->writeInit(para, cudaMemoryManager);
343 VF_LOG_INFO(
"Allocating host memory for DistributionWriter.");
347 VF_LOG_INFO(
"used Device Memory: {} MB", cudaMemoryManager->getMemsizeGPU() / 1000000.0);
349 performanceOutput = std::make_unique<PerformanceMeasurement>(*para);
356 this->kineticEnergyAnalyzer = std::make_unique<KineticEnergyAnalyzer>(this->para,
tAnalyse);
361 this->enstrophyAnalyzer = std::make_unique<EnstrophyAnalyzer>(this->para,
tAnalyse);
378 previousTimestepForAveraging = para->getTimeCalcMedStart();
379 previousTimestepForTurbulenceIntensityCalculation = 0;
380 timestepForMeasuringPoints = 0;
382 para->setStepEnsight(0);
384 averageTimer.
start();
402 for(
uint timestep = para->getTimestepStart(); timestep <= para->getTimestepEnd(); timestep++) {
446 this->updateGrid27->updateGrid(0, timestep);
451 if (this->kineticEnergyAnalyzer || this->enstrophyAnalyzer) {
452 updateGrid27->exchangeData(0);
454 if (this->kineticEnergyAnalyzer)
455 this->kineticEnergyAnalyzer->run(timestep);
456 if (this->enstrophyAnalyzer)
457 this->enstrophyAnalyzer->run(timestep);
462 if (para->getCalcMean() && ((
int)timestep >= para->getTimeCalcMedStart()) && ((
int)
timestep <= para->getTimeCalcMedEnd()))
464 for (
int lev=para->getCoarse();
lev <= para->getFine();
lev++)
481 para->getParD(
lev)->meanVelocityInYdirection,
482 para->getParD(
lev)->meanVelocityInZdirection,
483 para->getParD(
lev)->meanDensity,
484 para->getParD(
lev)->meanPressure,
485 para->getParD(
lev)->typeOfGridNode,
486 para->getParD(
lev)->neighborX,
487 para->getParD(
lev)->neighborY,
488 para->getParD(
lev)->neighborZ,
489 para->getParD(
lev)->numberOfNodes,
490 para->getParD(
lev)->numberofthreads,
491 para->getParD(
lev)->distributions.f[0],
492 para->getParD(
lev)->isEvenTimestep);
496 if (para->getCalcTurbulenceIntensity()) {
497 for (
int lev = para->getCoarse();
lev <= para->getFine();
lev++) {
499 para->getParD(
lev)->vxx,
500 para->getParD(
lev)->vyy,
501 para->getParD(
lev)->vzz,
502 para->getParD(
lev)->vxy,
503 para->getParD(
lev)->vxz,
504 para->getParD(
lev)->vyz,
505 para->getParD(
lev)->vx_mean,
506 para->getParD(
lev)->vy_mean,
507 para->getParD(
lev)->vz_mean,
508 para->getParD(
lev)->distributions.f[0],
509 para->getParD(
lev)->typeOfGridNode,
510 para->getParD(
lev)->neighborX,
511 para->getParD(
lev)->neighborY,
512 para->getParD(
lev)->neighborZ,
513 para->getParD(
lev)->numberOfNodes,
514 para->getParD(
lev)->isEvenTimestep,
515 para->getParD(
lev)->numberofthreads
523 if (para->getDoCheckPoint() && para->getTimeDoCheckPoint() > 0 && timestep % para->getTimeDoCheckPoint() == 0 &&
524 timestep > 0 && !para->overWritingRestart(timestep)) {
526 VF_LOG_INFO(
"Copy data for CheckPoint t = {}....", timestep);
527 for (
int lev = para->getCoarse();
lev <= para->getFine();
lev++) {
528 cudaMemoryManager->cudaCopyFsForCheckPoint(
lev);
530 VF_LOG_INFO(
"Write data for CheckPoint t = {}...", timestep);
531 const auto name =
getFileName(para->getFName(), timestep, para->getMyProcessID());
532 restart_object->serialize(name, para);
534 averageTimer.
start();
541 if (para->getUseMeasurePoints()) {
542 if ((timestep % para->getTimestepForMeasurePoints()) == 0) {
543 unsigned int valuesPerClockCycle = (
unsigned int)(para->getclockCycleForMeasurePoints() / para->getTimestepForMeasurePoints());
544 for (
int lev = para->getCoarse();
lev <= para->getFine();
lev++) {
546 para->getParD(
lev)->velocityInXdirectionAtMeasurePoints,
547 para->getParD(
lev)->velocityInYdirectionAtMeasurePoints,
548 para->getParD(
lev)->velocityInZdirectionAtMeasurePoints,
549 para->getParD(
lev)->densityAtMeasurePoints,
550 para->getParD(
lev)->indicesOfMeasurePoints,
551 para->getParD(
lev)->numberOfMeasurePoints,
553 timestepForMeasuringPoints,
554 para->getParD(
lev)->typeOfGridNode,
555 para->getParD(
lev)->neighborX,
556 para->getParD(
lev)->neighborY,
557 para->getParD(
lev)->neighborZ,
558 para->getParD(
lev)->numberOfNodes,
559 para->getParD(
lev)->distributions.f[0],
560 para->getParD(
lev)->numberofthreads,
561 para->getParD(
lev)->isEvenTimestep);
563 timestepForMeasuringPoints++;
566 if ((timestep % (
unsigned int)para->getclockCycleForMeasurePoints()) == 0) {
567 for (
int lev = para->getCoarse();
lev <= para->getFine();
lev++) {
568 cudaMemoryManager->cudaCopyMeasurePointsToHost(
lev);
569 para->copyMeasurePointsArrayToVector(
lev);
570 VF_LOG_INFO(
"Write MeasurePoints at level = {} and timestep = {}",
lev, timestep);
571 for (
int j = 0;
j < (
int)para->getParH(
lev)->MeasurePointVector.size();
j++)
577 timestepForMeasuringPoints = 0;
584 if (para->getTimestepOut() > 0 && timestep % para->getTimestepOut() == 0 && timestep >= para->getTimestepStartOut()) {
587 performanceOutput->log(averageTimer, timestep, communicator);
589 if (para->getPrintFiles()) {
590 readAndWriteFiles(timestep);
592 averageTimer.
start();
600 performanceOutput->log(averageTimer, para->getTimestepEnd(), communicator);
609void Simulation::readAndWriteFiles(
uint timestep)
613 for (
int lev = para->getCoarse();
lev <= para->getFine();
lev++) {
615 updateGrid27->exchangeData(
lev);
650 para->getParD(
lev)->velocityY,
651 para->getParD(
lev)->velocityZ,
652 para->getParD(
lev)->rho,
653 para->getParD(
lev)->pressure,
654 para->getParD(
lev)->typeOfGridNode,
655 para->getParD(
lev)->neighborX,
656 para->getParD(
lev)->neighborY,
657 para->getParD(
lev)->neighborZ,
658 para->getParD(
lev)->numberOfNodes,
659 para->getParD(
lev)->numberofthreads,
660 para->getParD(
lev)->distributions.f[0],
661 para->getParD(
lev)->isEvenTimestep);
664 cudaMemoryManager->cudaCopyPrint(
lev);
665 if (para->getCalcMean()) {
666 cudaMemoryManager->cudaCopyMeanPrint(
lev);
670 std::string fname = para->getFName() +
"_ID_" + StringUtil::toString<int>(para->getMyProcessID()) +
"_t_" + StringUtil::toString<int>(timestep);
671 if (this->kineticEnergyAnalyzer)
672 this->kineticEnergyAnalyzer->writeToFile(fname);
673 if (this->enstrophyAnalyzer)
674 this->enstrophyAnalyzer->writeToFile(fname);
676 if (para->getDiffOn())
677 cudaMemoryManager->cudaCopyConcentrationDeviceToHost(
lev);
697 if (para->getCalc2ndOrderMoments())
calc2ndMoments(para.get(), cudaMemoryManager.get());
698 if (para->getCalc3rdOrderMoments())
calc3rdMoments(para.get(), cudaMemoryManager.get());
704 if (para->getCalcMean() && ((
int)timestep > para->getTimeCalcMedStart()) && ((
int)
timestep <= para->getTimeCalcMedEnd()) && ((timestep%(
unsigned int)para->getclockCycleForMeasurePoints())==0)) {
705 unsigned int tdiff = timestep - previousTimestepForAveraging;
709 previousTimestepForAveraging = timestep;
713 if (para->getCalcTurbulenceIntensity()) {
714 uint t_diff = timestep - previousTimestepForTurbulenceIntensityCalculation;
719 dataWriter->writeTimestep(para, timestep);
721 if (para->getCalcTurbulenceIntensity()) {
722 previousTimestepForTurbulenceIntensityCalculation = timestep;
726 if (para->getCalcDragLift())
728 printDragLift(para.get(), cudaMemoryManager.get(), timestep);
746 for (
int lev = para->getCoarse();
lev <= para->getFine();
lev++) {
747 cudaMemoryManager->cudaFreeCoord(
lev);
748 cudaMemoryManager->cudaFreeSP(
lev);
749 if (para->getCalcMean()) {
750 cudaMemoryManager->cudaFreeMeanSP(
lev);
753 if (para->getMaxLevel() > 1) {
754 for (
int lev = para->getCoarse();
lev < para->getFine();
lev++) {
755 cudaMemoryManager->cudaFreeInterfaceCF(
lev);
756 cudaMemoryManager->cudaFreeInterfaceFC(
lev);
757 cudaMemoryManager->cudaFreeInterfaceOffCF(
lev);
758 cudaMemoryManager->cudaFreeInterfaceOffFC(
lev);
764 for (
int lev = para->getCoarse();
lev <= para->getFine();
lev++) {
765 cudaMemoryManager->cudaFreeNoSlipBC(
lev);
766 cudaMemoryManager->cudaFreeSlipBC(
lev);
767 cudaMemoryManager->cudaFreeVeloBC(
lev);
768 cudaMemoryManager->cudaFreeGeomBC(
lev);
769 cudaMemoryManager->cudaFreeStressBC(
lev);
770 cudaMemoryManager->cudaFreePrecursorBC(
lev);
771 cudaMemoryManager->cudaFreeOutflowBC(
lev);
772 cudaMemoryManager->cudaFreeDirectionalBoundaryCondition(
lev);
777 if (para->getDiffOn()) {
778 for (
int lev = para->getCoarse();
lev < para->getFine();
lev++) {
779 cudaMemoryManager->cudaFreeConcentration(
lev);
780 cudaMemoryManager->cudaFreeConcentrationNoFluxBC(
lev);
781 cudaMemoryManager->cudaFreeConcentrationFluxBC(
lev);
782 cudaMemoryManager->cudaFreeConcentrationDirichletBC(
lev);
783 cudaMemoryManager->cudaFreeConcentrationNeumannBC(
lev);
784 cudaMemoryManager->cudaFreeSurfaceLayerBC(
lev);
785 cudaMemoryManager->cudaFreeDirectionalADBoundaryCondition(
lev);
787 if(para->getUseTurbulentDiffusivity())
788 cudaMemoryManager->cudaFreeTurbulentDiffusivity(
lev);
789 if(para->getBuoyancyEnabled())
790 cudaMemoryManager->cudaFreeLocalReferenceTemperature(
lev);
796 if (para->getCalc2ndOrderMoments()) {
797 for (
int lev = para->getCoarse();
lev <= para->getFine();
lev++) {
798 cudaMemoryManager->cudaFree2ndMoments(
lev);
803 if (para->getCalc3rdOrderMoments()) {
804 for (
int lev = para->getCoarse();
lev <= para->getFine();
lev++) {
805 cudaMemoryManager->cudaFree3rdMoments(
lev);
810 if (para->getCalcHighOrderMoments()) {
811 for (
int lev = para->getCoarse();
lev <= para->getFine();
lev++) {
812 cudaMemoryManager->cudaFreeHigherMoments(
lev);
820 if (para->getNumprocs() > 1) {
821 for (
int lev = para->getCoarse();
lev < para->getFine();
lev++) {
822 auto& parH = para->getParHostAsReference(
lev);
823 auto& parD = para->getParDeviceAsReference(
lev);
825 for (
uint i = 0;
i < para->getNumberOfProcessNeighborsX(
lev,
"send");
i++) {
826 cudaMemoryManager->cudaFreeProcessNeighbor(parH.sendProcessNeighborsX[
i], parD.sendProcessNeighborsX[
i]);
827 cudaMemoryManager->cudaFreeProcessNeighbor(parH.recvProcessNeighborsX[
i], parD.recvProcessNeighborsX[
i]);
830 for (
uint i = 0;
i < para->getNumberOfProcessNeighborsY(
lev,
"send");
i++) {
831 cudaMemoryManager->cudaFreeProcessNeighbor(parH.sendProcessNeighborsY[
i], parD.sendProcessNeighborsY[
i]);
832 cudaMemoryManager->cudaFreeProcessNeighbor(parH.recvProcessNeighborsY[
i], parD.recvProcessNeighborsY[
i]);
835 for (
uint i = 0;
i < para->getNumberOfProcessNeighborsZ(
lev,
"send");
i++) {
836 cudaMemoryManager->cudaFreeProcessNeighbor(parH.sendProcessNeighborsZ[
i], parD.sendProcessNeighborsZ[
i]);
837 cudaMemoryManager->cudaFreeProcessNeighbor(parH.recvProcessNeighborsZ[
i], parD.recvProcessNeighborsZ[
i]);
843 if (para->getCalcTurbulenceIntensity()) {
848 if (para->getUseStreams()) {
849 para->getStreamManager()->destroyCudaEvents();
850 para->getStreamManager()->terminateStreams();
#define VF_LOG_TRACE(...)
double getTimeInSeconds() const
static void copyDistributionsToHost(const Parameter ¶, const CudaMemoryManager &cudaMemoryManager)
Copy distributions from device to host. Call this function before writing data.
static void writeDistributions(const Parameter ¶, uint timestep)
write the distributions for all levels
static void allocateDistributionsOnHost(const CudaMemoryManager &cudaMemoryManager)
allocate memory for the distributions on the host
static std::shared_ptr< GridProvider > makeGridGenerator(std::shared_ptr< GridBuilder > builder, std::shared_ptr< Parameter > para, std::shared_ptr< CudaMemoryManager > cudaMemoryManager, vf::parallel::Communicator &communicator)
static void writeMeasurePoints(Parameter *para, int level, int index, int t)
void setFactories(std::unique_ptr< KernelFactory > &&kernelFactory, std::unique_ptr< PreProcessorFactory > &&preProcessorFactory)
Simulation(std::shared_ptr< Parameter > para, std::shared_ptr< GridBuilder > builder, const BoundaryConditionFactory *bcFactory, GridScalingFactory *scalingFactory=nullptr)
void addKineticEnergyAnalyzer(uint tAnalyse)
void addEnstrophyAnalyzer(uint tAnalyse)
void setDataWriter(std::shared_ptr< DataWriter > dataWriter)
void finalize()
finalize simulation. Only needs to be called when using calculateTimestep!
void calculateTimestep(uint timestep)
can be used as an alternative to run(), if the simulation needs to be controlled from the outside (e....
void initTimers()
needed to initialize the simulation timers if calculateTimestep is used instead of run()
An abstract class for communication between processes in parallel computation.
virtual int mapCudaDevicesOnHosts(const std::vector< unsigned int > &devices, int numberOfDevices) const =0
std::shared_ptr< T > SPtr
void logPostSimulation(const MetaData &meta_data)
void writeYAML(const MetaData &meta_data, const std::string &filename)
void logPreSimulation(const MetaData &meta_data)
void verifyAndSetDevice(int deviceId)
void CalcTurbulenceIntensityDevice(real *vxx, real *vyy, real *vzz, real *vxy, real *vxz, real *vyz, real *vx_mean, real *vy_mean, real *vz_mean, real *DD, uint *typeOfGridNode, unsigned int *neighborX, unsigned int *neighborY, unsigned int *neighborZ, unsigned long long numberOfLBnodes, bool isEvenTimestep, uint numberOfThreads)
void resetMean(Parameter *para)
void findEdgeNodesCommMultiGPU(Parameter ¶meter)
Function for finding edge nodes in the multi-gpu implementation.
void calcTurbulenceIntensity(Parameter *para, CudaMemoryManager *cudaMemoryManager, uint tdiff)
void printDragLift(Parameter *para, CudaMemoryManager *cudaMemoryManager, int timestep)
std::string getFileName(const std::string &fname, int step, int myID)
void allocMeanAD(Parameter *para, CudaMemoryManager *cudaMemoryManager)
void allocMean(Parameter *para, CudaMemoryManager *cudaMemoryManager)
void calc3rdMoments(Parameter *para, CudaMemoryManager *cudaMemoryManager)
void initHigherOrderMoments(Parameter *para)
void allocHigherOrderMoments(Parameter *para, CudaMemoryManager *cudaMemoryManager)
void allocTurbulenceIntensity(Parameter *para, CudaMemoryManager *cudaMemoryManager)
void alloc2ndMoments(Parameter *para, CudaMemoryManager *cudaMemoryManager)
void initLattice(SPtr< Parameter > para, SPtr< PreProcessor > preProcessor, SPtr< PreProcessor > preProcessorAD, SPtr< CudaMemoryManager > cudaMemoryManager)
void allocDragLift(Parameter *para, CudaMemoryManager *cudaMemoryManager)
void init3rdMoments(Parameter *para)
void alloc3rdMoments(Parameter *para, CudaMemoryManager *cudaMemoryManager)
void calc2ndMoments(Parameter *para, CudaMemoryManager *cudaMemoryManager)
void calcMean(Parameter *para, uint tdiff)
void calcHigherOrderMoments(Parameter *para, CudaMemoryManager *cudaMemoryManager)
void resetVelocityFluctuationsAndMeans(Parameter *para, CudaMemoryManager *cudaMemoryManager)
void init2ndMoments(Parameter *para)
vf::basics::MetaData createMetaData(const Parameter ¶meter)
void cudaFreeTurbulenceIntensityArrays(Parameter *para, CudaMemoryManager *cudaMemoryManager)